Help in Customizing Lisp Code

Help in Customizing Lisp Code

clerigoaaron
Contributor Contributor
3,404 Views
38 Replies
Message 1 of 39

Help in Customizing Lisp Code

clerigoaaron
Contributor
Contributor

I have a Lisp code from a community member that compiles different pipe dxfs into 1 single file. It also inserts the pipes drawing number and pipe number as it is compiling. The data is extracted from an excel spread sheet and is cross referenced with the dxfs file name (also the drawing number). This Lisp only works if the data in the excel starts at Column A row 2. How can I change the code for it work even if the data starts at column B row 26? Thank you. Please see the code and excel below.

clerigoaaron_1-1727786421903.png

(Defun c:MakeThisHAppen ( /  _Entnext ExtractFromXls el moveAll fileName XL-App Workbooks exData f textObj moveAll)
(defun _Entnext ( e )
    (if (setq e (entnext e)) (cons e (_Entnext e)))
  )  
(defun ExtractFromXls (st app col / ncol val dataCollection)
      (repeat col
	(setq ncol (cons col ncol))
	(setq col (1- col))
      )
       (while
	 (vl-every 'eval
		   (setq val 
			  (mapcar '(lambda (i / cv)
				     (if (Setq cv (vlax-get-property (vlax-get (vlax-get app "ActiveSheet") 'Cells) 'Item st i))
                  			(vlax-variant-value
					  (vlax-get-property
					    (vlax-variant-value cv)
					    'Value
					  )
					)
				       )
				     ) ncol)
			  
		   	)
		   )
	 (setq dataCollection (cons (mapcar 'vl-princ-to-string val) dataCollection))
	 (setq st (1+ st))
	 )
      dataCollection
       )
			     
(if (and
      		(setq  Directory (acet-ui-pickdir
				 "Select Project Folder" (if Directory Directory (getvar 'dwgprefix))))
      		(setq moveAll (ssadd)
		       dxfFiles (vl-directory-files directory "*.dxf" 1))
		(setq fileName (getfiled "Excel Spreadsheet File"
                                   (if fileName fileName (getvar 'dwgprefix))"XLSX;XLS" 16 ))
        	(setq XL-App    (vlax-get-or-create-object "Excel.Application"))      		
      		(Setq Workbooks (vlax-invoke-method (vlax-get-property XL-App 'WorkBooks)
                                    'Open  fileName ))
      		(setq exData (extractfromxls 1 XL-App 2))
      		
      )
  (progn
	(foreach fname dxfFiles	  
	  (if (Setq f (Assoc (strcase (vl-filename-base  fname)) exData))
		(progn
		  (setq el (entlast))
		  (command "_DXFIN" (strcat directory "\\" fname) '(0.0 0.0 0.0))
		  (if (null el)(and (setq el (entnext)) (ssadd el moveAll)))
		  (mapcar '(lambda ( x ) (ssadd x moveAll)) (_Entnext el))		  
		  (foreach strdata (list
				     '((0.0 0.0 0.0) 12 "Proj-123")
				     (list '(0.0 -30.00 0.0) 12
				       (strcat "Dwg no: " (vl-filename-base fname)
				       )
				     )
				     (list '(0.0 -45.0 0.0) 12 (strcat "Pipe no: " (Cadr f))
				     )
				   )
		  (setq textObj (entmakex (list (cons 0 "TEXT")
					    (cons 10 (car strdata))
					    (cons 40 (cadr strdata))
					    (cons 1 (caddr strdata))
				      )
			    )
		  )
		    
		    (ssadd textObj moveAll))		    
		    (command "_move" moveAll "" "_non" "0,0,0" "0,500,0")
		    )
	    (princ (Strcat "\n" (vl-filename-base  fname) " Not found on source list"))
	    )
		)
		
  		(vlax-invoke-method Workbooks 'close  fileName )
	    	(vlax-release-object XL-App)
		(vlax-release-object Workbooks)
    )
	    		
  (Vl-some '(lambda (l)
	      (if (null (eval (Car l)))(print (cadr l))))
	   		'((Directory "No folder selected/Cancelled by user")
			  (dxfFiles "No DXF files found on selected folder")
			  (fileName "No xls:x;sx file found on selected folder / Cancelled by user")
			  (XL-App "Excel application not found")
			  )
		)	   
  )
  (princ)
  )
0 Likes
3,405 Views
38 Replies
Replies (38)
Message 21 of 39

pbejse
Mentor
Mentor

@clerigoaaron wrote:

Thats because is your code @pbejse I've been trying to study it for a while now but its so hard because I am starting from the basics


Any chance you can post the link of the original topic?

 

0 Likes
Message 22 of 39

clerigoaaron
Contributor
Contributor
0 Likes
Message 23 of 39

ec-cad
Collaborator
Collaborator

OOPS,

The fname is a 'list,, so we need to pull out just the 1st element of the list.

Try this instead.

(if (member (strcase (car fname)) exData)

 

ECCAD

0 Likes
Message 24 of 39

pbejse
Mentor
Mentor

Let me see if I understand the task, you want an option where the user will the define the start column and row number ? 

It feels odd that if you hardcode a specific row, and why 26? what is the data currently on row 2 to 25? in the furture will it be another row / column number?

 

0 Likes
Message 25 of 39

clerigoaaron
Contributor
Contributor

@pbejse That is definitely possible. We get orders from different customers and they sometimes have different way of presenting their data. The excel data actually comes with the pipes dimension, material, thickness etc. The arrangement of data in excel differs

0 Likes
Message 26 of 39

Sea-Haven
Mentor
Mentor

That is why I suggested selecting the range in excel that is to be used. The issue of the columns being in a different order is a completely different issue, but could be addressed. But easier would be move the columns in Excel to correct order.

0 Likes
Message 27 of 39

clerigoaaron
Contributor
Contributor

@ec-cad trying this gave this error and immediately terminated it. 4L is the first pipe in the data.

IMG_20241009_091215.jpg

0 Likes
Message 28 of 39

pbejse
Mentor
Mentor

@clerigoaaron wrote:

@pbejse That is definitely possible. We get orders from different customers and they sometimes have different way of presenting their data. The excel data actually comes with the pipes dimension, material, thickness etc. The arrangement of data in excel differs


I do understand that there are different sources, but why start from a particular row? why not put up a condition that ignores invalid data instead of guessing what row or column the valid data starts. 

 

Would you mind post at least 3 different excel file from different customers. you can strip confidential information from those files before posting it here.

 

0 Likes
Message 29 of 39

ec-cad
Collaborator
Collaborator

Yes, that fix wasn't any good.

Seems that exData (might have an entry like) (11.0 10.0), and won't match.

I added a loop to catch that condition (Attached Lisp). Back to square 1.

Give it a whirl. A test module shows that it picks up (all) the .dxf's and should process them.

-------------- use latest version on Message 36 ----------------

 

ECCAD

Message 30 of 39

clerigoaaron
Contributor
Contributor

@pbejse To be honest I didnt think of that. My plan was to tweek the code everytime I use it since I have to change the project number every time anyways. But here are sample files. For some reason the drawing numbers are set to general and pipe numbers are set to text. Not sure if that changes things.

IMG_20241010_111150.jpg

IMG_20241010_111128.jpg

IMG_20241010_110651.jpg

 

0 Likes
Message 31 of 39

CLL_PBE
Contributor
Contributor

Been trying to extract the values off the columns and rows from an image file but no joy @clerigoaaron  🙂

0 Likes
Message 32 of 39

clerigoaaron
Contributor
Contributor

@CLL_PBE Sorry. Files are on work computer and work computer cannot access this site. I will try to gain permission to send files to personal email but prospects look bleak

0 Likes
Message 33 of 39

ec-cad
Collaborator
Collaborator

You could set it up to ask for the Project, and Excel Col/Row with a few questions up top:

(setq Project (getstring 1 "\nProject ?"))

(setq startcol (strcase (getstring "\nStarting Column ? e.g. A or D")))

(setq startrow (getint "\nStarting Row ? e.g. 26"))

Then put the Project string in output text.

And, calculate the Column #:

(setq colx (- (ascii startcol) 65)); A=0, B=1, C=2 etc.

Then, make this line: (setq exData (extractfromxls startrow XL-App 2 colx))

 

Did you check out my latest Lisp  Message 29 ?

 

ECCAD

 

Message 34 of 39

Sea-Haven
Mentor
Mentor

@ec-cad You can click on a cell in Excel and get its address from CAD, the issue is that, to which I could not find an answer for, was to make Excel the current program, so to get around this I do an (alert "Please select cell in Excel press ok when done") the alert halts the lisp program so you can jump into Excel and pick a cell, when you press OK back in cad the next line in the code gets "current cell selected" from excel. So would know C26 etc.

 

 

(alert "Please select cell in Excel press ok when done")

(setq cell (vlax-get-property myxl 'Selection))
(setq address (vlax-get cell 'address))
; or for numbers
(setq row (vlax-get cell 'row))
(setq column (vlax-get cell 'column))

 

 

 

Message 35 of 39

clerigoaaron
Contributor
Contributor

@ec-cad I have skimmed through it but have not actually tested it. Will try soon. Work has just been so hectic recently. 

0 Likes
Message 36 of 39

ec-cad
Collaborator
Collaborator

OK,

Here's the Lisp with all the changes applied.

Tested, and finalized 10-12-2024.

Works for me 🙂

 

 

ECCAD

0 Likes
Message 37 of 39

clerigoaaron
Contributor
Contributor

@ec-cad Tested on a few project. No problems so far all pipes are accounted for. Still not sure why the previous code skipped some pipes but this one works great. thank you

Will keep testing a few more project to be sure.

0 Likes
Message 38 of 39

ec-cad
Collaborator
Collaborator

OK, the latest Lisp should be working just fine.

The basic issue with the original code (which was working also for 'most' .dxf's), was

that when Excel cells values were extracted, based on how the cell was formatted,

it would send back a  (number) e.g. 24 as a string "24.0" or intact as "24" ,

The "24.0" would not match the base filename of the .dxf file 24.dxf in the dxflist, and 

therefore, report it could not find it. Same with the job that stopped at 10, data was 10.0.

So, I fixed that condition by adding a little loop that strips ".0" from the Excel data, making

"24.0" into "24" - which would match.

With that change in the Lisp, it won't matter what 'format' those cells are.

 

Cheers

ECCAD

0 Likes
Message 39 of 39

Sea-Haven
Mentor
Mentor

This may have been helpful I think it was Gile or Pbe.

 

; if needed
(setq ExcelValue
(cond
((= (type ExcelValue) 'INT) (itoa ExcelValue))
((= (type ExcelValue) 'REAL) (rtos ExcelValue 2 2))
((= (type ExcelValue) 'STR) (vl-string-trim " " ExcelValue))
((/= (type ExcelValue) 'STR) "")
)
)
0 Likes