Jump to content

Insert a block based upon search/found criteria?


ILoveMadoka

Recommended Posts

Up til now I have had 3 separate routines for inserting a block based upon the existence of an inserted block in a drawing. 

 

(if (tblsearch "BLOCK" "BlockA")  (command "-insert" "Block1" "0,0" "" "" ""))

(if (tblsearch "BLOCK" "BlockB")  (command "-insert" "Block2" "0,0" "" "" ""))

(if (tblsearch "BLOCK" "BlockC")  (command "-insert" "Block3" "0,0" "" "" ""))

 

I was wanting to combine them into a single routine similar to this;

 

(defun c:foo ()

  (cond 

     (if (tblsearch "BLOCK" "BlockA")
        (command "-insert" "Block1" "0,0" "" "" ""))

    (if (tblsearch "BLOCK" "BlockB")
        (command "-insert" "Block2" "0,0" "" "" ""))

    (if (tblsearch "BLOCK" "BlockC")
        (command "-insert" "Block3" "0,0" "" "" ""))

  )

(princ))

 

[Which does not work correctly BTW - it does not go beyond the first step]


I also wondered "what if more than one block exists?"
Ideally only one of these blocks "should" exist in a drawing in my situation.

 

How can I test for the existence of more than one block first and return an error if found or
insert the appropriate block meeting the criteria otherwise?


I read about using wcmatch if I set

 

(setq myblks (list "BlockA" "BlockB" "BlockC"))

 

Not sure how to incorporate that if it is the better way


I have pieces and parts but cannot put it together 

Help please..

 

ps:

 

When using multiple searches, how to you proceed to the next search if the criteria is not met?

 

 (if (tblsearch "BLOCK" "BlockA")         (command "-insert" "Block1" "0,0" "" "" ""))

 

 

Edited by ILoveMadoka
Link to comment
Share on other sites

So in your cond I don't think you need the 'if', it should run through until it finds the first condition that is true - in this case if you have BlockA and BlockC it will insert Block1 and not Block3... you can order your inserts in order of priority.

 

You might also consider a 'T' condition - if none of the above conditions are met, do "T"

 

(defun c:foo ()
  (cond 
    ((tblsearch "BLOCK" "BlockA")
      (command "-insert" "Block1" "0,0" "" "" "")
    )
    ((tblsearch "BLOCK" "BlockB")
       (command "-insert" "Block2" "0,0" "" "" "")
    )
    ((tblsearch "BLOCK" "BlockC")
      (command "-insert" "Block3" "0,0" "" "" "")
    )
  )
  (princ)
)

 

(tablesearch "block") will return a list of all the blocks in the drawing, you can search this using "member" and the block name (tblsearch will return just the specified block if it exists)

 

 

Edited by Steven P
  • Agree 1
Link to comment
Share on other sites

Something like this?

 

(defun c:foo ()
  (cond 
    ((tblsearch "BLOCK" "BlockA")
      (command "-insert" "Block1" "0,0" "" "" "")
    )
    ((tblsearch "BLOCK" "BlockB")
       (command "-insert" "Block2" "0,0" "" "" "")
    )
    ((tblsearch "BLOCK" "BlockC")
      (command "-insert" "Block3" "0,0" "" "" "")
    )
      (t nil)
  )
  (princ)
)

 

That answers one question. <Thank you!>

 

Link to comment
Share on other sites

For the other questions..

How do I search for any of the three possible error combinations?

How do I test if more than one of these blocks is present and exit with a message if so?

If I have BlockA & BlockC = exit with error message.

 

I think wcmatch only searches for one string

 

Will I use this and member? [I don't know how to do that..]

 

(setq myblks (list "BlockA" "BlockB" "BlockC"))


 

Link to comment
Share on other sites

Would also bring up that using generic block names between drawings that get modified in the drawing itself could bring issues.

 

I worked in production and our projects would be exported to CNC. for speed we used blocks that stored shapes and depth. everything could be exported to a spread sheet and updated there and then imported back into the drawing.

 

when someone said  part of project x is in project y we would open Y copy the section we needed and paste into the new project. problem is if the Block A was already defined in the new project it wouldn't bring over Block A from the old project it would bring the insertion put but use the block reference that is already in the new drawing. if their was any difference between the two block's depth or shape difference it would just bring everything over and not throw an error or say anything about changes. and I didn't know anything was different when this happened. the shape was the same but depth info was almost 2" difference. required additional machining and a "investigation" on why this happened

 

 

On 8/2/2024 at 10:48 AM, ILoveMadoka said:

For the other questions..

How do I test if more than one of these blocks is present and exit with a message if so?

 

(setq myblks (list "BlockA" "BlockB" "BlockC"))


 


 

(setq myblks '("BlockA" "BlockB" "BlockC"))
(foreach blk myblks
  (if (tblsearch "BLOCK" blk)
    (prompt (strcat "\n" blk " Found"))
  )
)

 

Edited by mhupp
fixed typo blkl to blk
  • Like 1
Link to comment
Share on other sites

I understand...

 

I'm using generic names for simplicity sake.
The actual application will have different names...

=
 

(setq myblks '("BlockA" "BlockB" "BlockC"))
    foreach blk myblks
        (if (tblsearch "BLOCK" blkl)
             (prompt (strcat "\n" blk " Found")
        )
)

 

 this returns 

 

"BlockA" "BlockB" "BlockC"

 

even in a drawing with no blocks.

I'm confused about how to apply..
Still quite the novice (if that)

but thank you...

Link to comment
Share on other sites

had a typo of blkl instead of blk so nothing was found when searching the block table since blkl wasn't a defined variable. As for displaying the list AutoLISP always prints the value of the last evaluated expression to the command line when exiting the function. in some cases you want this when your using it to return a list or some other value. when you don't want this to happen you just use a (princ) so nothing is outputted

 

 

(defun c:Foo1 ()
  (princ "Hello, World!") ;will display as "Hello, World!
  (princ)                
)

(defun c:Foo2 ()
  (princ "Hello, World!")  ;will display as "Hello, World!Hello, World!"           
)

 

to get what you want you are going to have to combine Steven's and my code

 

(defun c:foo ()
  (setq myblks '("BlockA" "BlockB" "BlockC"))
  (foreach blk myblks
    (if (tblsearch "BLOCK" blk)
      (cond 
        ((eq blk "BlockA")
          (command "-insert" "Block1" "0,0" "" "" "")
        )
        ((eq blk "BlockB")
          (command "-insert" "Block2" "0,0" "" "" "")
        )
        ((eq blk "BlockC")
         (command "-insert" "Block3" "0,0" "" "" "")
        )
      )
	)
  )
  (princ)
)

 

Edited by mhupp
code update
  • Like 1
Link to comment
Share on other sites

An association list is nice for this and can easily be generated if A=1 B=2 etc.

(defun c:foo (/ a myblks)
  (setq
    myblks (mapcar
	     '(lambda (x) (list x (strcat "Block" (itoa (- (ascii (substr x (strlen x))) 64)))))
	     '("BlockA" "BlockB" "BlockC")
	   )
  )
  ;; (("BlockA" "Block1") ("BlockB" "Block2") ("BlockC" "Block3")) 
  (foreach blk myblks
    (if	(and (tblsearch "BLOCK" blk) (set a (assoc blk myblks)))
      (command "-insert" (cadr a) "0,0" "" "" "")
    )
  )
  (princ)
)

 

  • Like 1
Link to comment
Share on other sites

If you guys are trying to lead me to the water...
I'm not smart enough to drink unfortunately.... 😕

I cannot put the pieces together.


I see some promise in this (none of these can be true)

I need to <Exit> with an error if any of these are true.

 

(("BlockA" "BlockB") ("BlockB" "BlockC") ("BlockA" "BlockC")) 

 

==== === ==== =====  ==== === ==== ===== ==== === ==== ===== 

==== === ==== =====  ==== === ==== ===== ==== === ==== ===== 

 

;;;this code <Steven P> works
 

(defun c:foo ()
  (cond 
    ((tblsearch "BLOCK" "BlockA")
      (command "-insert" "Block1" "0,0" "" "" "")
    )
    ((tblsearch "BLOCK" "BlockB")
       (command "-insert" "Block2" "0,0" "" "" "")
    )
    ((tblsearch "BLOCK" "BlockC")
      (command "-insert" "Block3" "0,0" "" "" "")
    )
      (t nil)
  )
  (princ)
)

 

How do I run this check first and exit if any are true 

 

(("BlockA" "BlockB") ("BlockB" "BlockC") ("BlockA" "BlockC"))

 

Exit

 

(t nil)

 

Again, all these block names are example placeholders and are not the actual block names for the checks or the insert.

 

==== === ==== =====  ==== === ==== ===== ==== === ==== ===== 

==== === ==== =====  ==== === ==== ===== ==== === ==== ===== 

 

;;;;Does not work as is.. returns *Cancel*

 

(defun c:foo (/ a myblks)
  (setq
    myblks (mapcar
         '(lambda (x) (list x (strcat "Block" (itoa (- (ascii (substr x (strlen x))) 64)))))
         '("BlockA" "BlockB" "BlockC")
       )
  )
  ;; (("BlockA" "Block1") ("BlockB" "Block2") ("BlockC" "Block3")) 
  (foreach blk myblks
    (if    (and (tblsearch "BLOCK" blk) (set a (assoc blk myblks)))
      (command "-insert" (cadr a) "0,0" "" "" "")
    )
  )
  (princ)
)

 

==== === ==== =====  ==== === ==== ===== ==== === ==== ===== 

 

;;;;Does not work as is.. returns *Cancel*

 

(defun c:foo (/ a myblks)
  (setq
    myblks (mapcar
         '(lambda (x) (list x (strcat "Block" (itoa (- (ascii (substr x (strlen x))) 64)))))
         '("BlockA" "BlockB" "BlockC")
       )
  )
  ;; (("BlockA" "BlockB") ("BlockB" "BlockC") ("BlockA" "BlockC")) 
  (foreach blk myblks
    (if    (and (tblsearch "BLOCK" blk) (set a (assoc blk myblks)))
      (command "-insert" (cadr a) "0,0" "" "" "")
    )
  )
  (princ)
)

 

==== === ==== =====  ==== === ==== ===== ==== === ==== ===== 

 

;;; Parenthesis Mismatch [ 15ea ( ]   [ 18ea ) ]
;;;;Does not work as is..

 

(defun c:foo3 ()
  (setq myblks '("BlockA" "BlockB" "BlockC"))
  (foreach blk myblks
    (if (tblsearch "BLOCK" blk)
      (cond 
        (eq blk "BlockA")
          (command "-insert" "Block1" "0,0" "" "" "")
        )
        (eq blk "BlockB")
          (command "-insert" "Block2" "0,0" "" "" "")
        )
        (eq blk "BlockC")
          (command "-insert" "Block3" "0,0" "" "" "")
        )
      )
    )
  )
  (princ)
)

 

 

==== === ==== =====  ==== === ==== ===== ==== === ==== ===== 

 

;;;;Does not work as is.. for me error on load with a *Cancel*

 

(defun c:foo3 ()
  (setq myblks '("BlockA" "BlockB" "BlockC"))
  (foreach blk myblks
    (if (tblsearch "BLOCK" blk)
      (cond 
        (eq blk "BlockA")
          (command "-insert" "Block1" "0,0" "" "" "")
        )
        (eq blk "BlockB")
          (command "-insert" "Block2" "0,0" "" "" "")
        )
        (eq blk "BlockC")
          (command "-insert" "Block3" "0,0" "" "" "")
  )
  (princ)
)


 

I appreciate that you are hoping that I'm smarter than I really am... 😉

 

Thank you all so very much for all your input and assistance!

 

Link to comment
Share on other sites

Had a typo .. give this a try:
 

(defun c:foo (/ a myblks)
  (setq
    myblks (mapcar
	     '(lambda (x) (list x (strcat "Block" (itoa (- (ascii (substr x (strlen x))) 64)))))
	     '("BlockA" "BlockB" "BlockC")
	   )
  )
  ;; (("BlockA" "Block1") ("BlockB" "Block2") ("BlockC" "Block3")) 
  (foreach blk myblks
    (if	(and (tblsearch "BLOCK" (cadr blk)) (set a (assoc (car blk) myblks)))
      (command "-insert" (cadr a) "0,0" "" "" "")
    )
  )
  (princ)
)

 

Link to comment
Share on other sites

  • 3 weeks later...
Posted (edited)

Sorry for the long delay...

<ronjonp> Thank you for the response.

after testing multiple scenarios, your last code returns *Cancel* for me

 

This code is the only code that I've gotten to work

 

(defun c:foo ()
;;Steven P
  (cond 
    ((tblsearch "BLOCK" "BlockA")
      (command "-insert" "Block1" "0,0" "" "" "")
    )
    ((tblsearch "BLOCK" "BlockB")
       (command "-insert" "Block2" "0,0" "" "" "")
    )
    ((tblsearch "BLOCK" "BlockC")
      (command "-insert" "Block3" "0,0" "" "" "")
    )
      (t nil)
  )
  (princ)
)

 

this works too

 

(defun c:foo ()
;;mhupp/Steven P
  (setq myblks '("BlockA" "BlockB" "BlockC"))
  (foreach blk myblks
    (if (tblsearch "BLOCK" blk)
      (cond 
        ((eq blk "BlockA")
          (command "-insert" "Block1" "0,0" "" "" "")
        )
        ((eq blk "BlockB")
          (command "-insert" "Block2" "0,0" "" "" "")
        )
        ((eq blk "BlockC")
         (command "-insert" "Block3" "0,0" "" "" "")
        )
      )
    )
  )
  (princ)
)


If I could check for multiple inserts and exit if true, I'd be golden.

 

something along these lines [Not real code]

 

(if (BlockA & BlockB) or (BlockA & BlockC) or (BlockB & BlockC) are true <exit>


Sorry again for the delay in getting back.

 

I've attached a dummy drawing with all the blocks referenced contained within.
Block1 and BlockA go together

Block2 and BlockB go together

Block3 and BlockC go together


How I test is I copy 1 or 2 sets to a new drawing and test my routines...
 

foo.dwg

Edited by ILoveMadoka
Link to comment
Share on other sites

Posted (edited)

There is a song that says "Baby did a bad, bad thing..."

 

I went over to an ai website and asked some questions and it eventually returned this working code...
(Probably not the most efficient code but it is working in all my situations)

 

(defun c:foo(/ blockNames foundBlocks insertBlock)
  ;; Define the blocks to check
  (setq blockNames '("BLOCKA" "BLOCKB" "BLOCKC")
        foundBlocks '()
        insertBlock "")
  
  ;; Check for each block's presence in the drawing
  (foreach blk blockNames
    (if (tblsearch "BLOCK" blk)
      (setq foundBlocks (cons blk foundBlocks))
    )
  )

  ;; Determine action based on found blocks
  (cond
    ;; If more than one block is found
    ((> (length foundBlocks) 1)
     (princ "\nMore than one block found - Exiting...")
    )
    ;; If exactly one block is found
    ((= (length foundBlocks) 1)
     (setq insertBlock
           (cond
             ((equal (car foundBlocks) "BLOCKA") "Block1")
             ((equal (car foundBlocks) "BLOCKB") "Block2")
             ((equal (car foundBlocks) "BLOCKC") "Block3")
           )
     )
     ;; Insert the block at the origin (0,0)
     (if (tblsearch "BLOCK" insertBlock)
       (command "_.-INSERT" insertBlock '(0 0) "1" "1" "0")
       (princ (strcat "\nBlock \"" insertBlock "\" not found in the drawing."))
     )
    )
    ;; If no blocks are found
    (T
     (princ "\nNo blocks found.")
    )
  )

  (princ)
)

 

 

My success rate using ai has been about 10% or less in the past..
so I gave up trying to use that method..   I got lucky I suppose.

 

I still thank each and every one of you for your assistance.

 

Edited by ILoveMadoka
  • Like 1
Link to comment
Share on other sites

AI is a tool to use but you do need to be able to assess what it is telling you rather than blindly following it. Perhaps best used to get you around tricky parts of the code rather than the whole code?

Link to comment
Share on other sites

I haven't tried LISP, but some of the programming languages have IDE's and Code Editors that practically write your code for you, at least helping finish and autocomplete with syntax, etc.

 

I am guessing that's what AI is doing pretty much adapting written instructions to appropriate IDE and letting that finish it up.

 

Most AI programmers probably not knowledgeable in AutoLISP, VLISP so might be a learn as LISP gets asked and corrected would be my guess.

 

Looks like they aren't working for me at work as per the recent CoPilot thread.

  • Like 1
Link to comment
Share on other sites

Posted (edited)

Early on I couldn't get ai to write an autolisp routine that could draw a circle..

It would make up weird commands and stuff because it didn't know jack about lisp

ie: drawcircle as a command..

 

I'm glad it's learning...

 

I guess if Skynet is going to take over it has to learn lisp first...

 

Edited by ILoveMadoka
Link to comment
Share on other sites

I wish I had saved the conversation I had with ChatGPT about not knowing lisp...
It was kinda funny...

Link to comment
Share on other sites

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...