Jump to content

Search for an item in a list


harilalmn

Recommended Posts

I want to search a string in a list of strings. How is that possible?

 

Before adding another item to the list I have to verify if it is already added in the list. I am here so far..

 

(defun checklist (blst bname)
 (setq h (length blst))
 (repeat h
   (if
     (eq h (nth j blst))

 

If it is equal the function should return 1.

Else if the bname is not there in the list, the function should return 0.

How is it done?

Link to comment
Share on other sites

Well...

Could anyone tell me where I am going wrong in the code below? It is written to prompt the count of each block. I know the BCOUNT command. It is a similar attempt to learn codding.

 

(vl-load-com)
(defun c:cntblk(/ allblocks n i blklst blkobj blkobjname)
 (setq allblocks (ssget "_X" (List (cons 0 "INSERT"))))
 (setq n (sslength allblocks))
 (setq i 1)
 (setq blklst (ssadd))
 (repeat n
   (setq blkobj (ssname allblocks i))
   (setq blkobjname (getEffectiveName blkobj))

   (if (not (eq (member blkobjname blklst) nil))
    (ssadd blkobj blklst)
   )

   (setq i (1+ i))
 )
)
(setq j (length blklst))
(setq i 0)
(textscr)
(repeat j
 (setq ss(ssget "_X" (list (cons 0 "INSERT")(cons 2 (nth i blklst)))))
 (setq cnt (sslength ss))
 (prompt (strcat "\n" (nth i blklst) "-----------------" (itoa cnt)))
 (setq i (1+ i))
)

(defun getEffectiveName (ent)
 (setq obj (vlax-ename->vla-object ent))
 (vlax-get obj "EffectiveName")
)

Link to comment
Share on other sites

Ok... I know I made a mistake in my previous code at;

 

(setq blklst (ssadd))

 

by trying to create a blank list by ssadd :oops:

 

But could someone correct the one below?

 

 

(vl-load-com)
(defun c:cntblk(/ allblocks n i blklst blkobj blkobjname)
 (setq allblocks (ssget "_X" (List (cons 0 "INSERT"))))
 (setq n (sslength allblocks))
 (setq i 1)
 (repeat n
   (setq blkobj (ssname allblocks i))
   (setq blkobjname (getEffectiveName blkobj))

   (if
(eq (member blkobjname blklst) nil)
       (if
  (not (eq blklst nil))
  (setq blklst (list blklst blkobjname))
  (setq blklst (list blkobjname))
)
   )

   (setq i (1+ i))
 )
)
(setq j (length blklst))
(setq i 0)
(textscr)
(repeat j
 (setq ss(ssget "_X" (list (cons 0 "INSERT")(cons 2 (nth i blklst)))))
 (setq cnt (sslength ss))
 (prompt (strcat "\n" (nth i blklst) "-----------------" (itoa cnt)))
 (setq i (1+ i))
)

(defun getEffectiveName (ent)
 (setq obj (vlax-ename->vla-object ent))
 (vlax-get obj "EffectiveName")
)

Link to comment
Share on other sites

blklst variable is not a list

 

oops.. you posted another one.. hang on

 

Are you trying to create a selection set or a list of blocknames?

 

(defun c:cntblk(/ allblocks n i blklst blkobj blkobjname)
 (setq allblocks (ssget "_X" (List (cons 0 "INSERT"))))
 (setq n (sslength allblocks))
 (setq i [color=sienna]0[/color])
 (repeat n
   (setq blkobj (ssname allblocks i))
   (setq blkobjname (getEffectiveName blkobj))
   (if [color=sienna](not (member blkobjname blklst))[/color]
     [color=sienna](setq blklst (cons blkobjname blklst))[/color])
(setq i (1+ i))
 )
[color=sienna] blklst    [/color]
)

 

 

with ssadd you're creating a selection set and not a list

with cons/append/list//vl-list* you can create a list

Edited by pBe
Link to comment
Share on other sites

pBe,

However, that just dumps the list on the command window. I was trying to count the instances of block and prompt something like;

 

Block1 --------------------- 10

Block2 --------------------- 15

Block3 --------------------- 8

Block4 --------------------- 6

Block5 --------------------- 12

Link to comment
Share on other sites

Here is a quick fix for your code:

 

(vl-load-com)

(defun c:cntblk ( / allblocks blklst blkobj blkobjname i n ss )

[color=red]    (if[/color] (setq allblocks (ssget "_X" (list (cons 0 "INSERT"))))
[color=red]        (progn[/color]
           (setq n (sslength allblocks))
           (setq i [color=red]0[/color])
           (repeat n
               (setq blkobj (ssname allblocks i))
               (setq blkobjname (getEffectiveName blkobj))
   [color=red]            (if (not (member blkobjname blklst))
                   (setq blklst (cons blkobjname blklst))
               )[/color]
               (setq i (1+ i))
           )
           (textscr)
[color=red]            (foreach blk blklst
               (if (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 blk))))
                   (prompt (strcat "\n" blk "-----------------" (itoa (sslength ss))))
               )
           )[/color]
[color=red]        )
   )[/color]
   (princ)
)

(defun getEffectiveName ( ent / [color=red]obj [/color])
 (setq obj (vlax-ename->vla-object ent))
 (vlax-get obj "EffectiveName")
)

 

But this is not a very good way to perform the count, since Dynamic Blocks which have changed Visibility State (and hence become anonymous) will be excluded when you collect the selection set. Also, this way, you are effectively counting the blocks twice, since you have already iterated through the selection set to get the block list.

 

Consider this code:

 

(defun c:cntblk ( / allblocks blockentity blocklist blockname counter item )

   (if (setq AllBlocks (ssget "_X" '((0 . "INSERT"))))
       (progn
           (setq counter 0)
           (repeat (sslength AllBlocks)
               (setq blockentity (ssname AllBlocks counter)
                     blockname   (GetEffectiveName (vlax-ename->vla-object blockentity))
               )
               (if (setq item (assoc blockname blocklist))
                   (setq blocklist (subst (cons blockname (1+ (cdr item))) item blocklist))
                   (setq blocklist (cons  (cons blockname 1) blocklist))
               )
               (setq counter (1+ counter))
           )
           (foreach blk blocklist
               (princ (strcat "\n" (car blk) " ----------------- " (itoa (cdr blk))))
           )
       )
   )
   (princ)
)


(defun GetEffectiveName ( obj )
   (if (vlax-property-available-p obj 'effectivename)
       (vla-get-effectivename obj)
       (vla-get-name obj)
   )
)

 

I have tried to keep the structure of the program as close to your original code as possible, so that it is easier for you to learn from. I would strongly recommend that you carefully study both of the above solutions, and ask any questions you may have about the code I have used.

Link to comment
Share on other sites

Lee's is right. even with the selection filter, dynamic blocks effective name wont be selected and there's no point in selecting the objects twice

t

too late for this anyway... with the initial run you can compose the list of all block name and make the count from that list

 

(defun c:cntblk(/ allblocks n i  blklst blkobj blkobjname)
 (setq allblocks (ssget "_X" (List (cons 0 "INSERT"))))
 (setq n (sslength allblocks))
 (setq i 0)
 (repeat n
   (setq blkobj (ssname allblocks i))
   (setq blkobjname (getEffectiveName blkobj))
     (setq blklst (cons blkobjname blklst))
(setq i (1+ i))
 )
 (while (setq a (car blklst))
        (prompt (strcat "\n" a "-----------------"
 (itoa (- (length blklst) (length (setq blklst (vl-remove a blklst)))))
                      ))
        )
     (princ)
)

 

as Lee stated, its as close to your original code as possible

Edited by pBe
Link to comment
Share on other sites

 

I dont know how to express my gratitude to you Lee...

If you don't mistake that you are flattered , I am very much impressed of your enthusiasm, and willingness to spend your precious time to help the learning folks...

I downloaded your Block Counter from http://lee-mac.com/blockcounter.html

It is awsome...!!! Great job... And hope that you would cheer up to know that, that routine is helping a lot of people around the globe.

Thanks a lot...!!!

 

--

 

Thanks for your efforts too pBe....

I could learn a lot from these codes...

Thanks a lot...

Link to comment
Share on other sites

I dont know how to express my gratitude to you Lee...

If you don't mistake that you are flattered , I am very much impressed of your enthusiasm, and willingness to spend your precious time to help the learning folks...

I downloaded your Block Counter from http://lee-mac.com/blockcounter.html

It is awsome...!!! Great job... And hope that you would cheer up to know that, that routine is helping a lot of people around the globe.

Thanks a lot...!!!

 

Thanks harilalmn, glad it helps :beer: Its nice to know that my programs are being put to good use around the world, as I have very much enjoyed writing them :)

Link to comment
Share on other sites

Lee, While you're in the helping mood.

 

I wrote a quick one 3 days or so ago:

 

(defun c:scx  (/ ent Xnme clrs lst)
     (vl-load-com)
     (setq ent (ssget "_+.:S:E" '((0 . "INSERT"))))
     (setq ent (entget (ssname ent 0)))
     (if (= 4
            (logand 4
                    (cdr (assoc 70
                                (tblsearch
                                      "BLOCK"
                                      (setq Xnme (cdr (assoc 2 ent))))))))
           (progn
                 (setq clrs (acad_truecolordlg
                                  '(420 . 8882055)
                                  nil))
                 (command "_Layer" "_Color")
                 (while (> (getvar "cmdactive") 0)
                       (if (> (length clrs) 1)
                             (command
                                   "TrueColor"
                                   (progn
                                         (setq lst  (vl-princ-to-string
                                                          (LM:TRUE->RGB
                                                                (cdr (cadr clrs)))))
                                         (setq lst  (vl-string-translate
                                                          " "
                                                          ","
                                                          lst))
                                         (vl-symbol-name
                                               (car (read lst)))
                                         )
                                   (strcat Xnme "*")
                                   ""
                                   )
                             (command
                                   (cdr (car clrs))
                                   (strcat Xnme "*")
                                   "")
                             )
                       )
                 )
           (princ "\nNObject Selected Not an Xref:")
           )
     (princ)
     ) 

 

It changes the layer color of an Xref to a lighter shade (or whatever the user picks)

 

Then earlier today, one my guys asked waht if we want it to revert to its orignal color? Told them before you invoke this routine use layer state to save the layer info. Thinking its easier that way. BUT for an existing drawing with Xref layers already screened what now? Told them to Detach and re-attached the XREF again. I was thinking maybe its easy enough to do it via lisp thru ODBX retrieving the layer info from the source file. or use your steal from drawing routine.

 

Is there an easier way to go about it other than that?

 

EDIT:oops forgot to include your sub-routine Lee (LM:True->RGB) which incidentally until now cant figure out how you came up with those numbers :)

Edited by pBe
Link to comment
Share on other sites

Then earlier today, one my guys asked waht if we want it to revert to its orignal color? I was thinking maybe its easy enough to do it via lisp thru ODBX retrieving the layer info from the source file. or use your steal from drawing routine.

 

I would use ObjectDBX to interface with the XRef Source file, then change the layer colours of the XRef dependent layers in the Active Drawing to match those present in the Source file.

 

This sounded like an interesting program to write, so I couldn't resist coding it - see attached.

 

EDIT:oops forgot to include your sub-routine Lee (LM:True->RGB) which incidentally until now cant figure out how you came up with those numbers :)

 

You may find my posts in this thread of interest :)

ResetXRefLayers.lsp

Link to comment
Share on other sites

This sounded like an interesting program to write, so I couldn't resist coding it - see attached.

 

cool beans..

Thank you Lee, I'll take a look later, but only right after i try to wirte one myself.. :lol:

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