choupi1968 Posted March 2 Posted March 2 (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 March 3 by CADTutor Add code to code block Quote
fuccaro Posted March 4 Posted March 4 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))) ) ) Quote
choupi1968 Posted March 4 Author Posted March 4 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 Quote
fuccaro Posted March 4 Posted March 4 I wrote for you this Lisp to extract the numbers from the end of texts. Incorporate it in your program. Quote
fuccaro Posted March 4 Posted March 4 (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 March 4 by fuccaro Quote
fuccaro Posted March 4 Posted March 4 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! Quote
fuccaro Posted March 5 Posted March 5 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) ) Quote
BIGAL Posted March 5 Posted March 5 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 Quote
choupi1968 Posted March 5 Author Posted March 5 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 1 Quote
RonnieCross Posted June 3 Posted June 3 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. Quote
Edward23 Posted June 4 Posted June 4 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. Quote
Recommended Posts
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.