Author Topic: VBASTMT in AutoCAD 64 Bit >=2010  (Read 6497 times)

0 Members and 1 Guest are viewing this topic.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1453
  • Marco
VBASTMT in AutoCAD 64 Bit >=2010
« on: February 12, 2013, 05:33:11 AM »
I posted this message several times years ago on severals groups
in the Autodesk Discussion but I have not had any response,
I try again now:

I am using from years a command "_.VBASTMT" to load a lisp in a
"not current" document, after loading the Lisp execute itself and
close the "non current" switching back to the "sending" document.

With this method I can batch load a function in several DWG and
avoid problems of the script files.

This is a sample:
Code: [Select]
(setq
  *AcadApp* (vlax-get-acad-object)
  *AcDrwgs* (vla-get-documents *AcadApp*)
  LspFil "C:\\Mylisp.lsp"
  OpnFlg :vlax-true ; (or :vlax-false)
  NewDoc (vl-catch-all-apply 'vlax-invoke-method (list *AcDrwgs* 'Open InpFil OpnFlg))
)
(vl-cmdf
  "_.VBASTMT"
  (strcat
    "documents.item(documents.count-1).sendcommand \"(load \"\""
    LspFil
    "\"\")\n\""
  )
)
So if I use VBASTMT in >= 2010 I need to load VBA
(x64VBAServer.exe on 64 bit) and *everything* runs 6-8x slower,
including AutoCAD commands! It is much true particularly if you
must use many commands inside of the Lisp function.
Then I need to close AutoCAD to restore previous speed.

%%

If I substitute (vl-cmdf "_.VBASTMT" ...) with (for example):
Code: [Select]
(vla-SendCommand NewDoc (strcat "(load \"" LspFil "\")\n"))
(vla-activate NewDoc)
Every thinks works but I need to switch manually every
document back to the "sending" document to continue.

Any workaround? (I know .NET is the answer...)
Is there an utility (.net) to replace (vl-cmdf "_.VBASTMT" ...)?

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: VBASTMT in AutoCAD 64 Bit >=2010
« Reply #1 on: February 12, 2013, 09:56:06 AM »
Yep, since Microsoft's in effect "discontinued" VBA, there's no 64 bit version thereof. So that separate install is loading a 32bit out-of-process service. Which in turn then passes messages back-n-forth between itself and the 64bit acad process. This is why it's so much slower.

There are 3 alternatives you could attempt:
  • Write some dotnet runner code which allows the doc to become active and then sendcommand to the document to call the lisp.
  • Generate a SCR file on the fly which would open the DWG, run your code and close the DWG, then repeat for the next.
  • Use some code appended to the s::startup defun-q to check if the newly opened DWG should form part of a "batch" lisp process. Similar to Tim's BatchWORX.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: VBASTMT in AutoCAD 64 Bit >=2010
« Reply #2 on: February 12, 2013, 10:03:38 AM »

Might be interesting what Autodesk decides to do with VBA now with VBA7
http://www.theswamp.org/index.php?topic=42048.msg471833#msg471833

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: VBASTMT in AutoCAD 64 Bit >=2010
« Reply #3 on: February 12, 2013, 10:21:56 AM »
If there isn't anything graphic involved, you might consider trying the core console along with the basic scripting suggested by irneb.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: VBASTMT in AutoCAD 64 Bit >=2010
« Reply #4 on: February 12, 2013, 10:27:17 AM »
Dunno! But for what it's worth, I can't understand why ADesk didn't integrate VSTA into ACad as they've done with Revit. That way users could have an integrated development environment for DotNet (C# / VB.Net) inside of ACad - much like VBA used to be. Not to mention it would open the DotNet stuff to a larger community - perhaps unwilling to go the VS-Express route and the not-to-minimal setup procedure to get your debugging working properly. The Revit's VSTA works quite well, at least as simple to use as VBA was in ACad - only you've got a near complete library to work on.

Anyhow, even if they "re"-incorporate VBA7, would they upgrade the ActiveX libs to match the DotNet stuff? I can't see them doing this, they've stagnated ActiveX as much as they have lisp. And if they don't upgrade ActiveX, then slapping on VBA7 isn't much more use than simply using the old VBA6. Though it might be faster, though MS's page is not clear on that - only stating that it's like a "bridge" between the 32bit ActiveX libs (or rather there called COM) and the 64 bit environment. If it's implemented as ADesk implemented the VBA6 addon, then the message passing would be as slow.

So for my money, they should rather organize a "decent" scripting / addon language. Either go with a "full" DotNet thing like VSTA. Or (if they don't want yet another issue with their Mac version) extend the ailing AutoLisp to a multithreaded lisp system and extend its built-in functionality to incorporate OO (preferably something like Common Lisp's CLOS + MOP) - that way it should be much less work to have the ObjectARX libs work directly inside it without needing to constantly upgrade the function catalogue. Actually it would be less work that generating the DotNet managed classes to map onto the ObjectARX libs as is the case now. But from past experience, ADesk don't always make the "best" or even "least-worst" decisions - so I'm not holding my breath.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1453
  • Marco
Re: VBASTMT in AutoCAD 64 Bit >=2010
« Reply #5 on: February 13, 2013, 12:56:32 PM »
First, thanks to those who answered me.
Currently I am using the script after many years that I had abandoned because they are difficult
to control in the event of problems and do not restore any modified variables or settings.
In Bricscad it is very simple: > vla-Open then load ..., see below:

Code: [Select]
(defun _SCR_WriteHeader (InpFil OutPtr OpnFlg)
  (write-line "_.OPEN" OutPtr)
  (prin1 (vl-string-translate "\\" "/" InpFil) OutPtr)
  (if OpnFlg
    (write-line " _Y" OutPtr)
    (write-line "" OutPtr)
  )
)
(defun _SCR_WriteFooter (OutPtr)
  (write-line (strcat "(if(=(getvar \"DBMOD\")0)(command \"_.CLOSE\")(command \"_.CLOSE\" \"_Y\"))") OutPtr)
)

(or #BCFlg (setq OutPtr (open (setq BatFil (strcat ExpTmp "Batch.scr")) "w")))

(foreach InpFil FlsLst
  (if #BCFlg ;Bricscad
    (progn
      (if (vl-catch-all-error-p (setq @AcDwg (vl-catch-all-apply 'vla-Open (list *AcDrwgs* InpFil OpnFlg))))
        (progn (alert (vl-catch-all-error-message @AcDwg)) (setq @AcDwg nil))
        (load "_SCR_BatchExe")
      )
    );Bricscad
    (progn
      (_SCR_WriteHeader InpFil OutPtr OpnFlg)
      (princ "(load \"_SCR_BatchExe\")\n" OutPtr)
      ...
      (_SCR_WriteFooter InpFil OutPtr) ; chiude il file
    )
  )
)

There are 3 alternatives you could attempt:
  • Write some dotnet runner code which allows the doc to become active and then sendcommand to the document to call the lisp.
    is not my case, my .NET is very poor, if there is any example, I'd like to know.
  • Generate a SCR file on the fly which would open the DWG, run your code and close the DWG, then repeat for the next.
    Yes, it is what I am doing but I do not like scripts.
  • Use some code appended to the s::startup defun-q to check if the newly opened DWG should form part of a "batch" lisp process. Similar to Tim's BatchWORX.
    I have read: http://www.opendcl.com/forum/index.php?topic=408.msg3860#msg3860 too
    > I do not like to write to much on registry, now I try to modify s::startup to see if I get a best result.

Thanks again.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1453
  • Marco
Re: VBASTMT in AutoCAD 64 Bit >=2010
« Reply #6 on: February 13, 2013, 01:04:46 PM »
... But from past experience, ADesk don't always make the "best" or even "least-worst" decisions - so I'm not holding my breath.
This is ONE of the reasons why other CAD as Bricscad are doing a great success!

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: VBASTMT in AutoCAD 64 Bit >=2010
« Reply #7 on: February 13, 2013, 02:56:47 PM »
Marc, I'd also not go for the DotNet option myself. You'd be tieing your code to ACad on Windows (only) - since the DotNet DLL would have to be loaded for you code to be run. Though nearly all the newest Batch Utilities go about it this way (or at least something similar - perhaps a separate EXE which sends messages to ACad). Samples of this type of thing (though they may have been implemented not through DotNet, but the principle is the same) is ScriptPro / AutoScript / EZScript / CadFX'x Batch Script Processor. There are even some which generate a BAT file which opens & closed acad with the new DWG and runs a script / lisp on each in turn - I class them under the same idea, though I find them inefficient in the extreme (even though they might take advantage of multi-cores you need lots of RAM to stop from crashing): http://forums.augi.com/showthread.php?77021-How-to-create-a-routine-to-batch-process-files-or-a-directory

The simplest method is still the scripting idea. Runs reasonably well, but you do have a temporary file and some command-calls. If you can live with that I'd stay with it - it's the least convoluted and problematic. You'll note that 90% of all lisp-only-batch programs follow this route. Samples include Lee's Script Writer / Kean Walmsley's / BatchLisp.

That is if you don't want to revert acad back to the old DOS single document interface by changing the SDI sysvar to 1. It has some issues, e.g. what about starting your code if there's already more than one document open? Anyhow, if this is set, then any open of a DWG closes the previous and sets the new as current - so your code can simply continue as per BC's idea. There are some lisp-only-batch programs doing this, but they're rare and usually quite old.

The s::startup routine needs some store of which DWGs to act on. I've noted in that other thread that I was thinking of the registry. But I now think that Tim's idea of having a file listing the DWGs is better - it might even work on other OS's (if you can get the vla/x stuff functioning of course). Very few lisp stuff go about it this way, since it's quite difficult - nearly as complex as making a DotNet runner for your code. Tim's is one of the only ones I've come across.

Kean Walmsley's 2nd version is a hybrid between the script & s::startup idea. Makes it a bit less complex.

Another thing you could try is using the VBScript's Sendkeys to swap over to the other DWG, and then start your lisp from there. But take note, SendKeys is very prone to errors as it does not wait for acad to become responsive and you could then easily send only half the lisp call (or rather acad doesn't pick up all of it) - causing an error. I'd only go with this as a very last resort.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1453
  • Marco
Re: VBASTMT in AutoCAD 64 Bit >=2010
« Reply #8 on: February 16, 2013, 06:00:26 AM »
Irneb,
thanks for your long and detailed reply and I apologize for the delay. I have looked at all the possibilities and I still have not found a solution. For the moment I will continue with the script (in AutoCAD) and hope that Autodesk decides to incorporate VBA7.
....
That is if you don't want to revert acad back to the old DOS single document interface by changing the SDI sysvar to 1. It has some issues, e.g. what about starting your code if there's already more than one document open? Anyhow, if this is set, then any open of a DWG closes the previous and sets the new as current - so your code can simply continue as per BC's idea. There are some lisp-only-batch programs doing this, but they're rare and usually quite old.
...
I just want to add that there are no problems with BC, if you open a file with vla-Open everything you do after that is done on that file as long the file will be closed and then control return to the starting  file (as with VBASTMT and sendcommand):
Code: [Select]
; previous version with VBA and no Script
(if (vl-catch-all-error-p (setq @AcDwg (vl-catch-all-apply 'vla-Open (list *AcDrwgs* InpFil OpnFlg))))
  (progn (alert (vl-catch-all-error-message @AcDwg)) (setq @AcDwg nil))
  (if #BCFlg  ;Bricscad
    (load "Ale_SCmd_BatchExe")
    (vl-cmdf "_.VBASTMT" "documents.item(documents.count-1).sendcommand \"(load \"\"Ale_SCmd_BatchExe\"\")\n\"")
  )
)

Grazie.
Marco