Author Topic: Loop through layers and blocks to search for tags  (Read 2810 times)

0 Members and 1 Guest are viewing this topic.

Floris

  • Guest
Loop through layers and blocks to search for tags
« on: March 10, 2014, 06:18:47 AM »
Hi all,

I'm new to lisp programming so I was searching the internet for some examples for a project that I'm working on.
However I could not find anything related to this but found this awesome forum luckily :-)

I'm looking for a code snippet that helps me with the following:

I have drawings that needs to have specific (meta) tags in them for document control purposes.
However, these can be located in multiple layers and in multiple blocks.
So the thing I am looking for is a function that would do:
- Loop trough all the layers & blocks
- Within the blocks search for a predefined list of tag names.

When done, it should display:
- A list of tags that were found together with it's value and layername
- A list of tags that were not found within the drawing.

It would be a bonus if it could write this to an external textfile (CSV or similar).. but I would already be more than happy if I would have something to start with.

Hope that someone can help me out and point me into the right direction.

Thank you in advance,
Greetings,
Floris.








irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Loop through layers and blocks to search for tags
« Reply #1 on: March 10, 2014, 06:49:26 AM »
A few questions:
  • By the layer, do you mean the tag itself is on a Layer inside the block, or are you referring to the layer on which the block is inserted
  • What type of metadata? Is this only attributes, or things like XData as well?
  • Do you have a list of tag names / identifying codes which can be searched through? Or should all found simply form part of the output?
  • Is there only some layers (i.e. a list of them) or should any layer be used?
  • How do you wish your output data to be formatted? Each column showing the tag name as heading, or should several tag names be combined into one column? If the later, what should happen if there's 2 tags with the to-be-combined tag names?
For points 3 & 4, it might be easier to have Excel filter these for you. It's reasonably easy to save out to a CSV file from AutoLisp - about the same as printing to the text screen. So it's then quite easy in Excel to convert it to a table, from which you can sort/filter on any columns. With a bit more programming you could even export directly to Excel if you so wish, but note there are some issues between 32bit & 64bit installations when you try to do this.

You "might" be able to use the built-in DataExtract tool to accomplish this. I'd first attempt to use it than create a full on addon. Only if I find it cannot do exactly what I want would I start writing the code.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Floris

  • Guest
Re: Loop through layers and blocks to search for tags
« Reply #2 on: March 10, 2014, 07:23:22 AM »
Hi Irneb,

Sorry for being to vague in my description.

The value I am looking for is a certain ATTRIBUTE TAG within a BLOCK
No XData required here...

So it could have better written it as:
- Loop through all blocks
- Check against a predefined list of tags if present in block

So to come back at your questions:
(1) If attribute tag is found, add attribute to reported list of found attributes (with layer name) or write to cvs or other ascii file.
(2) Just attributes.. no XData stuff.
(3) Both ways would work for me.. but I have a list of tag-names available which should be present.
(4) ANY layer should be used.
(5) If written to file, then all tag names could be in same column. So in column format it would look something such as:
<TagName>,<Present_True/False>,<LayerName>

For me it would already help to see where to start.
Personally I am more used to VB.NET.. so I would already learn a lot by having such an example.
For instance, how to do multiple FOR EACH loops in lisp.
Probably when having some nice examples, then I'll write a quick lisp designer to make life easier for myself :-)

Thank you very much in advance,
greetings,
Floris.





irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Loop through layers and blocks to search for tags
« Reply #3 on: March 10, 2014, 08:39:12 AM »
Seeing as you're used to VBA, then going with the ActiveX stuff might be familiar:

Quickly, written ... untested
Code - Auto/Visual Lisp: [Select]
  1.  
  2. ;; Edit this list with your tag names
  3. (setq *MyAttribList* (mapcar 'strcase '("TagName1" "TagName2" "TagName3")))
  4.  
  5. ;; Export a single block reference's tags to the file
  6. (defun ExportBlockToCSV  (block csvFile / layer)
  7.   (setq layer (vlax-get block 'Layer)) ;Get the block insert's layer
  8.   (foreach attribute  (vlax-get block 'Attributes) ;Step through all attributes of the block
  9.     (if (member (strcase (vlax-get attribute 'TagString)) *MyAttribList*) ;Check attribute in list to export
  10.       (princ ;Then print to the file
  11.         ;; Concatenate the following strings
  12.         (strcat "\n\"" ;New line & start double quote to force string
  13.                 (vlax-get attribute 'TagString) ;Tag name
  14.                 "\",\"" ;End double quote, add comma and start double quote to force string
  15.                 (vlax-get attribute 'TextString) ;Tag value
  16.                 "\",\"" ;End double quote, add comma and start double quote to force string
  17.                 ;; Check if attribute is on layer 0
  18.                 (cond ((eq (vlax-get attribute 'Layer) "0") layer) ;If so, use block's layer
  19.                       (t (vlax-get attribute 'Layer))) ;Else use attribute's layer
  20.                 "\"") ;End with double quote
  21.         csvFile)))) ;Sent the print to the file
  22.  
  23. ;; Create the SaveTagsToCSV command
  24. (defun c:SaveTagsToCSV (/ fname file)
  25.   (if (and (setq fname (getfiled "Select a new CSV file" "" "csv" (+ 1 4))) ;Let user choose file
  26.            (setq file (open fname "w"))) ;Open the file
  27.     (progn ;Group the following statements into the if's then clause
  28.       (princ "\"TagName\",\"TagValue\",\"Layer\"" file) ;Write th title row in the file
  29.       ;; Step through all blok definitions including Model- & PaperSpace(s) to get even nested stuff
  30.         (vlax-for entity block-definition ;Step through everying inside the block definition
  31.           (if (eq (vla-get-ObjectName entity) "AcDbBlockReference") ;Check if current entity is a block insert
  32.             (ExportBlockToCSV entity file)))) ;Save it to the file
  33.       (close file)))
  34.   (princ)) ;Clean exit the command
Edit: forgot to close the file  :oops:
« Last Edit: March 10, 2014, 08:47:23 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Floris

  • Guest
Re: Loop through layers and blocks to search for tags
« Reply #4 on: March 10, 2014, 09:48:23 AM »
Hi Irneb,

Unfortunately I'm getting an "null function :error#9".
Probably because I'm using lisp in an IntelliCAD based program.
Let me check if there is a tool available to convert to regular lisp..

Greetings,
Floris.



irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Loop through layers and blocks to search for tags
« Reply #5 on: March 10, 2014, 09:59:20 AM »
It might be that the IntelliCAD product doesn't include the VisualLisp functions (those beginning with vl/vla/vlax). If this is the case, then you have to do this through the old methods (i.e. using the DXF data lists instead of ActiveX object properties/methods). There are a few threads showing something similar:
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.