The total number of DWG files in the title block

The total number of DWG files in the title block

bigcarl5000kg
Advisor Advisor
3,464 Views
27 Replies
Message 1 of 28

The total number of DWG files in the title block

bigcarl5000kg
Advisor
Advisor

Hi everyone,

 

I have a corner stamp block "PageHeader" in each separate DWG drawing (per 1 sheet) with the existing attribute "TOTAL", in which I need to read the total number of related sheets in the same directory (all DWG files in the same directory) and write it in this attribute after creating all the drawings. I don't know in advance how many sheets there will be in total, because this is a manual creation.

 

Example:
1234-XXX-001_Sheet_1.dwg
1234-XXX-001_Sheet_2.dwg

...

...
1234-XXX-001_Sheet_12.dwg
1234-XXX-001_Sheet_13.dwg

 

Total amount of sheets: 13 -> write this value in 13 separate DWGs / each corner stamp block / each specified attribute

 

Is there a LISP that can do this? Does each file have to be opened separately for this or can it be done directly from any opened file for all other files?

 

Many thanks in advance and have a nice day

 

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Accepted solutions (4)
3,465 Views
27 Replies
Replies (27)
Message 2 of 28

hak_vz
Advisor
Advisor

@bigcarl5000kgAttach sample drawing with title block. Change of attribute value can be done on all drawings in single folder (or even its subfolders) without separately opening single file.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 3 of 28

bigcarl5000kg
Advisor
Advisor

@hak_vz,

 

here an example page header ... the change of attribute value is only in current (one) folder needed 👍. Sometimes several projects are open in parallel, which could cause unwanted changes.

 

Thank you

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 4 of 28

bigcarl5000kg
Advisor
Advisor

Sorry, here is the sample drawing...

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 5 of 28

pbejse
Mentor
Mentor

@bigcarl5000kg wrote:

Total amount of sheets: 13 -> write this value in 13 separate DWGs / each corner stamp block / each specified attribute


Are you saying the string value would include this string  "Total amount of sheets:" + the total?

 

0 Likes
Message 6 of 28

bigcarl5000kg
Advisor
Advisor

total amount of DWG files only, it is in my case also total amount of "sheets" as information in each drawing, because each DWG have one sheet only 😉 .... sorry for my english...

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 7 of 28

pbejse
Mentor
Mentor
Accepted solution

@bigcarl5000kg wrote:

total amount of DWG files only, it is in my case also total amount of "sheets" as information in each drawing, 


  • This program will modify ONLY files on the selected folder. [ un-opened ]
  • The "total" will be based on the number of .dwg files on the selected folder [ we can add a filter just in case there are rogue files on the selected folder. 
  • The file should have a attribute block named "PAGEHEADER" with a TAG name  "TOTAL"

 

(defun c:TNoS ( /  allfiles odbs v adoc odbx  AllDrawingFiles Total#Dwg Total_TAG); Total Number of Sheets
(setq	odbs "ObjectDBX.AxDbDocument"
	v    (substr (getvar 'acadver) 1 2)
	adoc (vla-get-activedocument (setq app (vlax-get-acad-object)))
  )
	
(setq f (acet-ui-pickdir "Select project Folder" (if f f (getvar 'dwgprefix))))
(setq AllDrawingFiles (vl-directory-files f "*.dwg"))
(setq Total#Dwg (length AllDrawingFiles))
  
(cond
    ((vl-catch-all-error-p
       (setq odbx (vl-catch-all-apply
		    'vla-getinterfaceobject
		    (list app
			  (if (< (atoi v) 16)
			    odbs
			    (strcat odbs "." v)
			  )
		    )
		  )
       )
     )
     (princ "\nObject DBX interface not created!")
    )
    ( AllDrawingFiles    
     (foreach dwg  AllDrawingFiles
       
       (if (vl-catch-all-error-p
	     (vl-catch-all-apply 'vla-open (list odbx (Strcat f "\\" dwg)))
	   )
	 (princ (strcase (strcat "\nError opening: " dwg)))
	 (progn
	   (princ (strcat "\nOpening: " dwg))
	   (vlax-for item (vla-get-layouts odbx)
		     (if (/= (vla-get-name item) "Model")
		       	(Vlax-for obj (vla-get-block item)
			  	(if (and
				  	(eq (vla-get-objectname obj) "AcDbBlockReference" ) 
					(eq (Strcase (vla-get-EffectiveName obj))  "PAGEHEADER")
				  	(setq Total_TAG (vl-some '(lambda (At)
						    (if (eq (vla-get-tagstring at) "TOTAL") at))
								(Vlax-invoke obj 'GetAttributes)))
				  	)
				  (vla-put-textstring  Total_TAG (itoa Total#Dwg))
				)
		       )
	     	)
	     )
	   (and Total_TAG (vla-saveas odbx (Vla-get-name odbx)))
	  )
	 )
       )
     )
    )
  (princ)
)

 

Command: Tnos

 

If the file is read-only. the message 

"Error opening: < Filename >"  on the command prompt

 

To make this work on files currently open will require additional coding.

 

HTH

Message 8 of 28

hak_vz
Advisor
Advisor

@pbejse  Nice work . I'll stop working on this. Also opted for ODBX but didn't have time to finish it.

 

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 9 of 28

bigcarl5000kg
Advisor
Advisor

Dear @pbejse - perfect solution 👍, it works extra-easy-super-clever, many thanks and also to @hak_vz, have a nice day

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 10 of 28

bigcarl5000kg
Advisor
Advisor

I have one problem - once a value is defined, it cannot be overwritten by additional invocation of the same command (eg after changing the number of data in the directory). 

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 11 of 28

pbejse
Mentor
Mentor

@bigcarl5000kg wrote:

I have one problem - once a value is defined, it cannot be overwritten by additional invocation of the same command (eg after changing the number of data in the directory). 


Not sure what you mean by that, the values will update as soon as you run the program again. Unless the files is currently opened by you or other users. Then that file will not be updated but the others will be.

We can modify the code to deal with that condtion or at least part of it. and also to work on the current dwg session.

 

Are you using Sheet Set by any chance? If not then you should, that would be the best way to keep track of the number of dwg details on a folder and use FIELDS to populate the attribute.

 

Let us know if you need help  putting that together.

 

 

 

0 Likes
Message 12 of 28

bigcarl5000kg
Advisor
Advisor

Hi @pbejse - many thanks, I have found one problem on my side, now it works ... have a nice day

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 13 of 28

hak_vz
Advisor
Advisor
Accepted solution

@bigcarl5000kg  Here you have another one.

 

 

(defun c:append_total_files_in_titleblock ( / find_all_file_paths getDBXDoc oVer include_subfolders dwg_files doc total)
	(defun find_all_file_paths (file_extension include_subfolders /  subFolderTree acad shell hwnd folder basefolder basefolderpath fso folder_list pathlist)	;
		;file_extension ".dwg" ".jpg"
		(defun subFolderTree (root_folder / subfolder)
			(setq subfolder (vlax-get root_folder 'Subfolders))
				(vlax-for sub subfolder
					(setq folder_list (cons (vlax-get sub 'Path) folder_list))
					(subFolderTree sub)
				)
			folder_list
		)
		(setq
			acad (vlax-get-acad-object)
			shell (vla-getinterfaceobject acad "Shell.Application")
			fso (vlax-create-object "Scripting.FileSystemObject") 
			hwnd (vl-catch-all-apply 'vla-get-hwnd (list  acad))
			folder  (vlax-invoke-method shell 'browseforfolder 
				(if (vl-catch-all-error-p hwnd) 0 hwnd) "Select folder:" 0 "")
		)
		(cond 
			((and folder)
				(setq basefolderpath (vlax-get-property (vlax-get-property folder 'Self) 'Path))
				(cond 
					((> (strlen basefolderpath ) 3)
						(setq folder_list nil)
						(cond 
							((and include_subfolders)
								(setq folder_list (append (list basefolderpath) (reverse (subFolderTree (vlax-invoke-method fso 'GetFolder basefolderpath)))))
							)
							(T (setq folder_list (list basefolderpath)))
						)
						(foreach item folder_list
							(vlax-for file (vlax-get (vlax-invoke-method fso 'GetFolder item) 'Files) 
								(cond 
									((wcmatch (strcase (vlax-get file 'Name) T) (strcat "*" file_extension))
										(setq pathlist (cons (strcat "" item "\\" (vlax-get file 'Name)) pathlist))
									)
								)
							)
						)
					)
					(T (alert (strcat "You can not search whole partition " basefolderpath)))
				)
			)
		)
		(vlax-release-object shell)
		(vlax-release-object fso)
		(cond 
			((not pathlist) (setq folder_list nil))
			((and pathlist)
				(setq folder_list nil)
				(reverse pathlist)
			)
		)
	)
	(defun getDBXDoc (dwg / app dbx oVer)
		(setq dbx
			(if (< (atoi (setq oVer (substr (getvar "acadver") 1 2))) 16)
				(vla-GetInterfaceObject (vlax-get-acad-object) "ObjectDBX.AxDbDocument")
				(vla-GetInterfaceObject (vlax-get-acad-object) (strcat "ObjectDBX.AxDbDocument." oVer))
			)
		)
		(cond 
			((and dbx) (vla-open dbx dwg)
				dbx
			)	
		)
	)	
	(initget 1 "Yes No")
	(setq include_subfolders (strcase(getkword "Include files in subfolders? (Yes or No) ")))
	(cond 
		((= include_subfolders "YES")
			(setq dwg_files (find_all_file_paths ".dwg" T))
		)
		((= include_subfolders "NO")
			(setq dwg_files (find_all_file_paths ".dwg" nil))
		)
	)
	(cond 
		((and dwg_files)
			  (foreach dwgfile dwg_files
					(cond 
						((and(setq doc (getDBXDoc dwgfile)))
					
							(vlax-for item (vla-get-layouts doc)
							 (if (/= (vla-get-name item) "Model")
									(vlax-for obj (vla-get-block item)
									(if (and
										(eq (vla-get-objectname obj) "AcDbBlockReference" ) 
										(eq (Strcase (vla-get-EffectiveName obj))  "PageHeader")
										(setq total(vl-some '(lambda (At)
												(if (eq (vla-get-tagstring at) "TOTAL") at))
													(Vlax-invoke obj 'GetAttributes)))
										)
									  (vla-put-textstring  total (itoa (length dwg_files)))
									)
								   )
								)
							)
							(and total (vla-saveas doc dwgfile))

						)
					)
					(vlax-release-object doc )
				)
				
		)
	)
	(princ "\nDone!")
	(princ)
)

 

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Message 14 of 28

bigcarl5000kg
Advisor
Advisor

Hi @hak_vz,

 

thank you very much, it works very good 👍

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 15 of 28

bigcarl5000kg
Advisor
Advisor

General question - it is possible to implement another version of the folder browser in LISP, eg similar to Windows explorer - it does not have to be exactly the same, it has the advantage of faster selection of the required directory (user favorites, entering the path to the server, ...)

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 16 of 28

hak_vz
Advisor
Advisor

Probably it can be done, but it's not easy.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 17 of 28

bigcarl5000kg
Advisor
Advisor

Ok, it's a question only, many thanks and have a nice weekend

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 18 of 28

pbejse
Mentor
Mentor
Accepted solution

@bigcarl5000kg wrote:

General question - it is possible to implement another version of the folder browser in LISP, eg similar to Windows explorer - it does not have to be exactly the same, it has the advantage of faster selection of the required directory (user favorites, entering the path to the server, ...)


One step closer is you can paste a path on the dialog

pbejse_1-1630689197390.png

 

(defun _getfolder ( m / sh f r)
    (setq sh (vla-getinterfaceobject
	       (vlax-get-acad-object)  "Shell.Application" )
	  f  (vlax-invoke-method sh 'browseforfolder 0 m 16)
    )
    (vlax-release-object sh)
    (if	f (vlax-get-property (vlax-get-property f 'self) 'path)
          )
  )
(setq f (_GETFOLDER "Select folder to process"))

 

HTH

 

 it is possible to implement another version of the folder browser 

This is actually easier to accomplish in .NET, wherein you can even drag files to your list from windows explorer 

 

Message 19 of 28

bigcarl5000kg
Advisor
Advisor

@pbejse @ Nice solution, many thank

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes
Message 20 of 28

bigcarl5000kg
Advisor
Advisor

Dear Masters,

 

I have now a problem, the LISP from @pbejse (see message no. 7) does not work in the Autocad 2026 (newly installed), but in Autocad 2024 it still works great.

 

In Autocad 2026, it will only generate this message:

Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended.

 

Has there been a change in Autocad 2026 that does not allow the code to be executed? I kindly ask for your help and thank you in advance.

 

 

+++ impossible immediately and miracles within 3 days +++
+++ the only constant is the change +++ stay tuned for more +++
+++ since 03/2023 is Advance Steel in maintenance mode, no further development +++
0 Likes