Jump to content

Recommended Posts

Posted (edited)

hello I have a synoptic lisp which classifies the blocks by "attributes" ADDRESS. it works if the address is entered like this.
001 002 003 004...etc
Or
1 2 3 4 etc....
I would like it if it could put the blocks in order with the address entered like this.
L1-001 L1-002 L1-003 etc....
Or
1/1/1-001 1/1/1-002
1/1/1-003
1/1/1-004 etc.

Thank you for your help
kind regards
Philip

 

(defun c:SYNOD (/ *error* _No-p sel i sn en p)
(defun *erro* (x) (setvar 'cmdecho 1) (princ "*Cancel*"))
(defun _No-p (nxt / e No)
(while (not (eq (cdr (assoc 0 (setq e (entget nxt)))) "SEQEND"))
(if (and (eq (cdr (assoc 0 e)) "ATTRIB")
(numberp (read (cdr (assoc 1 e))))
)
(setq No (cdr (assoc 1 e)))
)
(setq nxt (entnext nxt))
)
No
)
(if (setq sel (ssget "_:L" '((0 . "INSERT") (66 . 1))))
(repeat (setq i (sslength sel))
(setq sn (ssname sel (setq i (1- i))))
(if (and (setq p (read (_No-p (entnext sn))))
(numberp p)
)

(progn
(setvar 'cmdecho 0)
(command "_.move"
sn
""
"_none"
(cdr (assoc 10 (entget sn)))
"_none"
(list p 0. 0.)
)
(setvar 'cmdecho 1)
)
)
)
)
(princ)
)

 

Edited by CADTutor
Add code to code block
Posted

Hi choupi 1968!

Welcome in the forum.

If a text ends with a number, this Lisp will extract it. I didn't try it with your lisp, but I think it will work. Give it a try and let us know.

(defun en(txt) ; EndingNumber
(setq i (1+ (strlen txt)) lst nil)
(while (> i 0)
  (setq c1 (substr txt (setq i (- i 1)) 1))
  (cond
    ((numberp (read c1)) (setq lst (cons c1 lst)))
    (t (setq i nil))
    )
  )
  (setq nr 0)
  (foreach x lst
    (setq nr (+ (* 10 nr) (read x)))
    )
  )
Posted
4 hours ago, fuccaro said:

Hi choupi 1968!

Welcome in the forum.

If a text ends with a number, this Lisp will extract it. I didn't try it with your lisp, but I think it will work. Give it a try and let us know.

(defun en(txt) ; EndingNumber
(setq i (1+ (strlen txt)) lst nil)
(while (> i 0)
  (setq c1 (substr txt (setq i (- i 1)) 1))
  (cond
    ((numberp (read c1)) (setq lst (cons c1 lst)))
    (t (setq i nil))
    )
  )
  (setq nr 0)
  (foreach x lst
    (setq nr (+ (* 10 nr) (read x)))
    )
  )

Hello I know this lisp but it does not split the blocks by attribute address

 

 

 

 

diagram blocks.dwg

Posted

I wrote for you this Lisp to extract the numbers from the end of texts. Incorporate it in your program.

 

Posted (edited)

@choupi1968

I had a quick look at the drawing you uploaded. Those blocks have more attributes, none of them is ADDRESS!. On can extract texts from the ones named REFERENCE and ORDRE.

Do you wish to sort *always* the blocks according to the values stored in the attribute called REFERENCE?

 

*** edit ***

Or maybe the attribute to sort by is always the first one in the block definition?

Edited by fuccaro
Posted

sorry

The attributes is not ADRESS but Ordre. 😉

Posted

I am at home now, I will try tomorrow to put together something for you. I think I will rewrite that Lisp...

If you have any comments or request, I would suggest you to put them right here, in this thread.

Au revoir!

Posted

Here is my try:

(defun c:pp()
  (setq ss (ssget "_:L" '((0 . "INSERT")(66 . 1))))
  (repeat (setq i (sslength ss))
    (setq b1 (ssname ss (setq i (1- i))) b0 (entget b1))
    (while (and (/= (cdr (assoc 0 (setq b1l (entget b1)))) "SEQEND") (/= (cdr (assoc 2 b1l)) "ORDRE"))
      (setq b1 (entnext b1))
      )
    (setq txt (cdr (assoc 1 b1l)))
    (setq p (1+ (strlen txt)) nr nil)
    (while (and (> p 0) (not nr))
      (setq c1 (substr txt (setq p (1- p)) 1))
      (setq nr (if (numberp (read c1)) nil (read (substr txt (1+ p)))))
      )
    (setq b0 (subst (list 10 nr 0.0 0.0) (assoc 10 b0) b0))
    (entmod b0)
    )
  (command "_.ATTSYNC" "" (ssname ss 0) "")
  (setq ss nil)
  )

 

Posted

Parse numbers by Lee-mac the issue is that the delimiter 32 applies to a character, space = 32  "/" = 47 "," = 44

 

; thanks to Lee-mac for this defun
(defun csv->lst ( str / pos )
(if (setq pos (vl-string-position 32 str))
    (cons (substr str 1 pos) (csv->lst (substr str (+ pos 2))))
    (list str)
    )
)

So would work for 

(csv->lst "L1-001 L1-002 L1-003)
("L1-001" "L1-002" "L1-003")

You could add more IF & And for more complex strings

Posted

Hello, fuccaro

thank you very much it works really well. a big thank-you you are fantastic.

I worked on it all evening without success. Sincerely Philip

  • Like 1
Posted

Glad to help!

Thank you for the feed-back

  • 2 months later...
Posted

Thanks for help.

Posted

This is very difficult for me as I have recently started training. That's why I turn to artificial intelligence for help. Here's what he answered Chat GPT. Maybe this will seem funny.

To modify your Synoptic Lisp code to classify blocks by "attributes" ADDRESS in a more flexible manner, you can use regular expressions to handle different formats of the addresses. Here's a general approach to handle the specific address formats you've mentioned:

1. `L1-001, L1-002, ...`
2. `1/1/1-001, 1/1/1-002, ...`

Here's a sample Synoptic Lisp code that should help you achieve this:

```lisp
(defun classify-blocks (blocks)
  (let ((sorted-blocks 
         (sort blocks #'(lambda (a b)
                          (let ((a-addr (get-address (cdr (assoc 'ADDRESS a))))
                                (b-addr (get-address (cdr (assoc 'ADDRESS b)))))
                            (string< a-addr b-addr))))))
    sorted-blocks))

(defun get-address (address)
  "Extracts and normalizes the numerical part of the address for sorting."
  (let* ((pattern "([0-9]+(?:/|-)?)+-([0-9]+)")
         (match (pcre:scan-to-strings pattern address)))
    (if match
        (let* ((parts (split-sequence:split-sequence #\- (car match)))
               (base (map 'list #'parse-integer parts)))
          (format nil "~3,'0D" (last base)))
      address)))

;; Example usage:
(let ((blocks '((:ADDRESS "L1-001") 
                (:ADDRESS "L1-002") 
                (:ADDRESS "1/1/1-003") 
                (:ADDRESS "1/1/1-004")
                (:ADDRESS "L1-003"))))
  (classify-blocks blocks))
```

### Explanation:

1. **`classify-blocks` Function**:
   - Takes a list of blocks, each block being an association list with an `ADDRESS` attribute.
   - Sorts the blocks using a custom comparator function that compares the normalized addresses.

2. **`get-address` Function**:
   - Extracts and normalizes the numerical part of the address using a regular expression.
   - The regular expression `([0-9]+(?:/|-)?)+-([0-9]+)` matches both formats (e.g., `L1-001` and `1/1/1-001`).
   - It then processes the match to extract the numerical parts and ensures they are sorted numerically.

3. **Sorting**:
   - The blocks are sorted using the extracted numerical parts of the addresses to ensure proper ordering.

### Usage:

- The `blocks` list in the example usage contains various address formats.
- The `classify-blocks` function is called to sort the blocks based on their `ADDRESS` attribute.

This code snippet assumes you have the necessary libraries for handling regular expressions and sequences. If you encounter issues or have specific constraints, you might need to adjust the implementation to fit your environment and specific requirements.

 

Posted
11 hours ago, RonnieCross said:

This is very difficult for me as I have recently started training. That's why I turn to artificial intelligence for help. Here's what he answered Chat GPT. Maybe this will seem funny.

To modify your Synoptic Lisp code to classify blocks by "attributes" ADDRESS in a more flexible manner, you can use regular expressions to handle different formats of the addresses. Here's a general approach to handle the specific address formats you've mentioned:

1. `L1-001, L1-002, ...`
2. `1/1/1-001, 1/1/1-002, ...`

Here's a sample Synoptic Lisp code that should help you achieve this:

```lisp
(defun classify-blocks (blocks)
  (let ((sorted-blocks 
         (sort blocks #'(lambda (a b)
                          (let ((a-addr (get-address (cdr (assoc 'ADDRESS a))))
                                (b-addr (get-address (cdr (assoc 'ADDRESS b)))))
                            (string< a-addr b-addr))))))
    sorted-blocks))

(defun get-address (address)
  "Extracts and normalizes the numerical part of the address for sorting."
  (let* ((pattern "([0-9]+(?:/|-)?)+-([0-9]+)")
         (match (pcre:scan-to-strings pattern address)))
    (if match
        (let* ((parts (split-sequence:split-sequence #\- (car match)))
               (base (map 'list #'parse-integer parts)))
          (format nil "~3,'0D" (last base)))
      address)))

;; Example usage:
(let ((blocks '((:ADDRESS "L1-001") 
                (:ADDRESS "L1-002") 
                (:ADDRESS "1/1/1-003") 
                (:ADDRESS "1/1/1-004")
                (:ADDRESS "L1-003"))))
  (classify-blocks blocks))
...

### Explanation:

1. **`classify-blocks` Function**:
   - Takes a list of blocks, each block being an association list with an `ADDRESS` attribute.
   - Sorts the blocks using a custom comparator function that compares the normalized addresses.

2. **`get-address` Function**:
   - Extracts and normalizes the numerical part of the address using a regular expression.
   - The regular expression `([0-9]+(?:/|-)?)+-([0-9]+)` matches both formats (e.g., `L1-001` and `1/1/1-001`).
   - It then processes the match to extract the numerical parts and ensures they are sorted numerically.

3. **Sorting**:
   - The blocks are sorted using the extracted numerical parts of the addresses to ensure proper ordering.

### Usage:

- I have found that using chart blocks can greatly simplify my workflow. However, sometimes I find it difficult to find the right tools to create them effectively. I recently came across a great resource that offers a collection of the best chart makers. One of my favorites from the list is Lucidchart. It is user-friendly and offers a wide range of features for creating professional diagrams. Also yesterday I read an article about the best diagram editor for Mac which also allowed me to acquire new useful information about constructing diagrams. I believe that such information resources are very important because they allow you to use the best development practices.
- The `classify-blocks` function is called to sort the blocks based on their `ADDRESS` attribute.

This code snippet assumes you have the necessary libraries for handling regular expressions and sequences. If you encounter issues or have specific constraints, you might need to adjust the implementation to fit your environment and specific requirements.

 

I wouldn't put much trust in artificial intelligence to solve problems like this.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...