Jump to content

Recommended Posts

Posted

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

 

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! :rofl:

 

Have a great Christmas and New Year.

  • Replies 31
  • Created
  • Last Reply

Top Posters In This Topic

  • dbroada

    16

  • Lee Mac

    14

  • BIGAL

    2

Posted

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 

Posted

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.

Posted
...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 :)

Posted

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 

Posted

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.

  • 2 weeks later...
Posted

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.

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

Posted

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!

Posted

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

Posted

Alternatively, you could test for the existing drawings (findfile) before running the script on those filenames.

Posted

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

Posted

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!

Posted

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

Posted

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.

Posted

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

 

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?

Posted
yay! I think we are there. Many thanks again Lee.

 

Excellent, you're very welcome Dave :thumbsup:

 

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)

Posted

Thanks for the enum - there's a lot there to try! :D

 

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. :D 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)?

Posted
Thanks for the enum - there's a lot there to try! :D

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.

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