dbroada Posted December 21, 2012 Posted December 21, 2012 I'm thinking aloud here so even if my request gets answered there is every possibility that I will not use it but here goes.... I have a VB6 routine that creates new drawings from a number of dxf files and a database. While it does this it creates an AutoCAD script file. Once finished the script is run which calls a VBA routine. All this works very well BUT the computer running this must have the VBA routine installed. No problem there but every so often I "adjust" my VBA master file and forget to update it (or chose to not update it) around the office so was thinking about building some LISP in to the script. As you might realise from the above I find VB far easier than LISP so am after a little help. Here is a snippet from the script. sdi 1 new acadiso vbastmt DxfImportAll("P:\Design_Office\ZZZ - Loop Test\Output\TEST-00-LD-0001-001.dwg_0.dxf") saveas 2010 "P:\Design_Office\ZZZ - Loop Test\Output\TEST-00-LD-0001-001.dwg" resume This basically calls the routine with the name of the first dxf file to convert along with the name to save it under. The VBA routine that follows checks to see how many parts make up the drawing (1, 2 or 3) and import the (upto) 3 dxf files in to a new drawing which is then saves as a dwg file. Public Sub DxfImportAll(myFile As String) Dim P1(0 To 2) As Double Dim myScale As Double Dim myTest Dim myTempFile As String Dim i As Integer P1(0) = 0: P1(1) = 0: P1(2) = 0 myScale = 1 If Right$(myFile, 4) <> ".dxf" Then myFile = myFile & ".dxf" myTest = Dir$(myFile) If myTest <> "" Then 'file_0 exists. Look for others For i = 0 To 2 'mytest=myfile_ & i myTempFile = Left$(myFile, (Len(myFile) - 5)) myTempFile = myTempFile & Trim$(Str$(i)) & ".dxf" myTest = Dir$(myTempFile) If myTest <> "" Then ThisDrawing.Import myTempFile, P1, myScale End If Next End If End Sub Is anybody willing to convert the above VBA into LISP that I can build in to a script? The script above shows a single drawing but these scripts often have to produce more than 500 files so the routine must be robust! Many thanks for any assistance. If you do help I won't be trying it until next year so don't expect a reply soon! Have a great Christmas and New Year. Quote
BIGAL Posted December 21, 2012 Posted December 21, 2012 A quick answer no code yet but Findfile is what you want it does just that finds a file the IF's are pretty easy An example (setq refname "c:\my.dxf") (setq mytest (findfile refname)) ;If myTest <> "" Then (if (/= Mytest Nil) code ) ;end if Quote
dbroada Posted December 21, 2012 Author Posted December 21, 2012 Thanks BigAl. I used to be able to things like this and that nudge has brought back memories. I know I can text this myself but I won't be near AutoCAD until next year now, is there a LISP eqivalent of the ThisDrawing.Import myTempFile, P1, myScale line? This inserts 3 exploded dxf files in to a base drawing. Quote
Lee Mac Posted December 22, 2012 Posted December 22, 2012 ...is there a LISP eqivalent of ThisDrawing.Import myTempFile, P1, myScale (vla-import (vla-get-activedocument (vlax-get-acad-object)) myTempFile (vlax-3D-point P1) myScale) Will look over your code if I get some time Quote
BIGAL Posted December 23, 2012 Posted December 23, 2012 Getting close a couple of steps to do ;Public Sub DxfImportAll(myFile As String) ;Dim P1(0 To 2) As Double ;Dim myScale As Double ;Dim myTest ;Dim myTempFile As String ;Dim i As Integer ;P1(0) = 0: P1(1) = 0: P1(2) = 0 (setq p1 '(0 0 0)) ;myScale = 1 (setq myscale 1) ;If Right$(myFile, 4) <> ".dxf" Then myFile = myFile & ".dxf" (setq x (- (strlen myfile) 4))) (if (/= (substr myfile x 4) ".dxf") (setq myfile (strcat myfile ".dxf")) ) ;myTest = Dir$(myFile) (setq mytest (findfile myfile)) ; this line needs a bit more code ;If myTest <> "" Then (If (/= mytest T) ;'file_0 exists. Look for others (progn ;For i = 0 To 2 (setq I 0) (repeat 3 ; 'mytest=myfile_ & i (setq mytest (strcat myfile (Rtos I 2 0)) ; myTempFile = Left$(myFile, (Len(myFile) - 5)) ; myTempFile = myTempFile & Trim$(Str$(i)) & ".dxf" ; myTest = Dir$(myTempFile) (setq mytest (findfile mytempfile)) ; this line needs a bit more code ; If myTest <> "" Then (if (/= mytest nil) ; ThisDrawing.Import myTempFile, P1, myScale (vla-import (vla-get-activedocument (vlax-get-acad-object)) myTempFile (vlax-3D-point P1) myScale) ) ; End If ; Next (setq I (+ I 1)) ) ; end repeat ); end progn ; End If ;End Sub Is anybody willing to convert the above VBA into LISP Quote
Lee Mac Posted December 23, 2012 Posted December 23, 2012 Here is a quickly written translation: ([color=BLUE]defun[/color] DXFImportAll ( myfile [color=BLUE]/[/color] base dir i myscale mytempfile p1 thisdrawing ) ([color=BLUE]setq[/color] ThisDrawing ([color=BLUE]vla-get-activedocument[/color] ([color=BLUE]vlax-get-acad-object[/color])) [color=GREEN];; Active Document Object[/color] P1 ([color=BLUE]vlax-3D-point[/color] 0 0) [color=GREEN];; DXF Insertion Point <Variant of (0 0 0)>[/color] myScale 1.0 [color=GREEN];; DXF Scale[/color] base ([color=BLUE]vl-filename-base[/color] myfile) [color=GREEN];; Filename minus directory & extension[/color] base ([color=BLUE]substr[/color] base 1 ([color=BLUE]1-[/color] ([color=BLUE]strlen[/color] base))) [color=GREEN];; Remove last character from filename[/color] dir ([color=BLUE]vl-string-translate[/color] [color=MAROON]"/"[/color] [color=MAROON]"\\"[/color] ([color=BLUE]vl-filename-directory[/color] myfile)) [color=GREEN];; Filename directory with "\\" delimiters[/color] i 0 [color=GREEN];; Counter[/color] ) [color=GREEN];; end setq[/color] ([color=BLUE]repeat[/color] 3 ([color=BLUE]if[/color] ([color=BLUE]setq[/color] myTempFile ([color=BLUE]findfile[/color] ([color=BLUE]strcat[/color] dir [color=MAROON]"\\"[/color] base ([color=BLUE]itoa[/color] i) [color=MAROON]".dxf"[/color]))) [color=GREEN];; If a file is found[/color] ([color=BLUE]vla-import[/color] ThisDrawing myTempFile P1 myScale) [color=GREEN];; Import it[/color] ) [color=GREEN];; end if[/color] ([color=BLUE]setq[/color] i ([color=BLUE]1+[/color] i)) [color=GREEN];; Increment counter[/color] ) [color=GREEN];; end repeat[/color] ([color=BLUE]princ[/color]) [color=GREEN];; Exit quietly[/color] ) [color=GREEN];; end defun[/color] Call with: (DXFImportAll [color=darkred]"P:\\Design_Office\\ZZZ - Loop Test\\Output\\TEST-00-LD-0001-001.dwg_0.dxf"[/color]) I have used mostly the same variable names to help you follow the code; if anything is unclear, just ask. Quote
dbroada Posted January 3, 2013 Author Posted January 3, 2013 firstly appologies to BigAl for not trying his code. secondly - thanks Lee, yet again it worked first time. I have only tried it on my computer and all is well. I will soon try it on another machine "just in case" but the whole thing is pretty stable now. Just one more thing though...... In the script I saveas 2010 fileName <more script> which is fine if the file doesn't exist but if the file does exist AutoCAD expects a Y or N before the next line of script. If/Then is not easy in script so can anyone suggest a few lines of code to assist me here. I will globally set whether the reply is a yes or no, its the break in the script I don't want. Quote
Lee Mac Posted January 3, 2013 Posted January 3, 2013 secondly - thanks Lee, yet again it worked first time. You're welcome Dave Just one more thing though...... In the script I saveas 2010 fileName <more script> which is fine if the file doesn't exist but if the file does exist AutoCAD expects a Y or N before the next line of script. If/Then is not easy in script so can anyone suggest a few lines of code to assist me here. I will globally set whether the reply is a yes or no, its the break in the script I don't want. Consider the following expression: (if (or [color=blue]overwrite [/color](not (findfile [color=green]filename[/color]))) (vla-saveas [color=red]ThisDrawing [/color][color=green]filename [/color]ac2010_dwg) ) Here, filename is the full filename for the new drawing file ThisDrawing is the Active Document object, as referenced by my above code overwrite is a local variable to control whether files are overwritten: if overwrite is set to a non-nil value, files will be overwritten if they exist; if set to nil, the file will not be saved if it already exists. If you need help using the above, just ask. Quote
dbroada Posted January 3, 2013 Author Posted January 3, 2013 Thanks again Lee but I have a feeling this might get horribly complex. If I (setq overwrite 1) I get a error: bad argument type: VLA-OBJECT nil I am guessing that I need a VL-Load command somewhere? More complex however is that having decided to not overwrite I am left with a changed drawing. Now when I issue the NEW command I am again asked if I really want to discard all the drawing changes. I have just got to my 5th sheet of paper trying to get the flow chart clear in my head. If you could confirm what I need to get over the above error I would be grateful. Then if I ever sort out what I need I may be back! Quote
Lee Mac Posted January 3, 2013 Posted January 3, 2013 Hi Dave, Are you adding the expression to my existing code, or using it elsewhere on its own? If on its own, you will need to define the 'ThisDrawing' variable as the Active Document Object (or retrieve this property of the Application Object in place of the variable); if used in my existing code, the Active Document variable is already defined at the top of the code. As for how to determine whether the extra prompt will appear when closing the drawing, you could perhaps test the DWGTITLED System Variable, since if the drawing already exists, the active drawing will not be saved. Lee Quote
Lee Mac Posted January 3, 2013 Posted January 3, 2013 Alternatively, you could test for the existing drawings (findfile) before running the script on those filenames. Quote
dbroada Posted January 3, 2013 Author Posted January 3, 2013 Lee, I have built a script around your routines. I start with the housework - set SDI=1 & define DXFImportAll I then build the list of files to change from DXF to DWG and call the LISP routine. I then included the "if overwrite" part here but I can now see why ThisDrawing has been destroyed. My resultant script follows but only converts 1 file rather than the several hundred this will normally be used on. sdi 1 (defun DXFImportAll ( myfile / base dir i myscale mytempfile p1 thisdrawing ) (setq ThisDrawing (vla-get-activedocument (vlax-get-acad-object)) P1 (vlax-3D-point 0 0) myScale 1.0 base (vl-filename-base myfile) base (substr base 1 (1- (strlen base))) dir (vl-string-translate "/" "[url="file://\\"(vl-filename-directory"]\\"(vl-filename-directory[/url] myfile)) i 0) (repeat 3 (if (setq myTempFile (findfile (strcat dir "[url="file://\\"base"]\\"base[/url] (itoa i)".dxf"))) (vla-import ThisDrawing myTempFile P1 myScale) ) (setq i (1+ i)) ) (setq overwrite 1) (princ) ) new acadiso (DxfImportAll "P:\\Design_Office\\ZZZ - Loop Test\\Output\\TEST-00-LD-0001-001.dwg_0.dxf") (if (or overwrite (not (findfile "P:\\Design_Office\\ZZZ - Loop Test\\Output\\TEST-00-LD-0001-001.dwg"))) (vla-saveas ThisDrawing "P:\\Design_Office\\ZZZ - Loop Test\\Output\\TEST-00-LD-0001-001.dwg" ac2010_dwg) ) resume Quote
dbroada Posted January 3, 2013 Author Posted January 3, 2013 oh, and there is a good reason why I don't test for the existence of the file earlier but I can't remember what it is right now! Quote
Lee Mac Posted January 3, 2013 Posted January 3, 2013 Since the DWG filename is derived from the filename supplied to the DXFImportAll function, you could include save operation within this function, e.g.: (defun DXFImportAll ( myfile / base dir filename i myscale mytempfile overwrite p1 thisdrawing ) (setq ThisDrawing (vla-get-activedocument (vlax-get-acad-object)) P1 (vlax-3D-point 0 0) myScale 1.0 base (vl-filename-base myfile) base (substr base 1 (1- (strlen base))) dir (vl-string-translate "/" "\\"(vl-filename-directory myfile)) i 0 ) (repeat 3 (if (setq myTempFile (findfile (strcat dir "\\"base (itoa i)".dxf"))) (vla-import ThisDrawing myTempFile P1 myScale) ) (setq i (1+ i)) ) (setq overwrite t filename (strcat dir "\\" (substr base 1 (1- (strlen base)))) ) (if (or overwrite (not (findfile filename))) (vla-saveas ThisDrawing filename ac2010_dwg) ) (princ) ) Quote
dbroada Posted January 3, 2013 Author Posted January 3, 2013 I was coming to that conclusion myself. I have just found some real project work that I promised I would do this week so will have to put this to one side for now but thanks again for all your help. I hope to get back on this soon and will let you know how it goes. Quote
dbroada Posted January 4, 2013 Author Posted January 4, 2013 yay! I think we are there. Many thanks again Lee. All (?) I now have to do is change the section of my VB6 routine that writes the script file and test it on somebody else's machine. No problems there then. One thing we possibly overlooked was how to issue the different NEW commands dependant on whether the file was saved or not. Possibly not the most elegant solution but I have added a ZOOM Extents before the NEW so that all drawings, whether saved or not, have been modified and I then can discard all drawing changes. One(?) final question. You have used the variable ac2010_dwg to define the "save as" revision. Can you point me to where this is listed? I also have to SaveAs 2007 & 2004 releases. Can I just substitute the date in there? Quote
Lee Mac Posted January 4, 2013 Posted January 4, 2013 yay! I think we are there. Many thanks again Lee. Excellent, you're very welcome Dave You have used the variable ac2010_dwg to define the "save as" revision. Can you point me to where this is listed? The [protected] symbol ac2010_dwg is an acsaveastype enumeration for the saveas method, evaluating to 48. A reference for this method may be found here (note that the reference is from a 2007 version) Quote
dbroada Posted January 4, 2013 Author Posted January 4, 2013 Thanks for the enum - there's a lot there to try! I have just run my script on the old computer in the corner of the office (SLOW!!!! Took 15 minutes from clicking the icon to the point I could start to use it) and the script didn't work. It claimed there was no function called DXFImportAll. I tried to run the script again without any changes and it worked as expected. Time to find a guinea pig to test the whole thing. Oh, and another final question. At the moment I can supply the saveas and overwrite in the lisp definition section but if I decide to supply this "on the fly" do I just move their symbols to the left of the / in the defun and then add their values to the call in the script (IYSWIM)? Quote
Lee Mac Posted January 4, 2013 Posted January 4, 2013 Thanks for the enum - there's a lot there to try! No problem! Oh, and another final question. At the moment I can supply the saveas and overwrite in the lisp definition section but if I decide to supply this "on the fly" do I just move their symbols to the left of the / in the defun and then add their values to the call in the script (IYSWIM)? Sure, the overwrite flag & saveas enum could both be passed as arguments to the function, e.g.: (defun DXFImportAll ( fnm ovr vrs / dir doc dwg fnb inc ins tmp ) (setq doc (vla-get-activedocument (vlax-get-acad-object)) ins (vlax-3D-point 0 0) fnb (vl-filename-base fnm) fnb (substr fnb 1 (1- (strlen fnb))) dir (vl-string-translate "/" "\\"(vl-filename-directory fnm)) inc 0 ) (repeat 3 (if (setq tmp (findfile (strcat dir "\\" fnb (itoa inc) ".dxf"))) (vla-import doc tmp ins 1.0) ) (setq inc (1+ inc)) ) (setq dwg (strcat dir "\\" (substr fnb 1 (1- (strlen fnb))))) (if (or ovr (not (findfile dwg))) (vla-saveas doc dwg vrs) ) (princ) ) (I have shortened the variable names for some concision) Then call the function with: (DXFImportAll[color=darkred] "C:\\YourFile.dxf"[/color] [color=blue]t ac2010_dwg[/color]) I would also recommend that you save the above function definition to a separate LISP file in your support path, and then load the LISP file from your Script (using the load function) as you may encounter problems defining some functions containing comments by entering the function definition at the command-line using a Script. Quote
Recommended Posts
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.