Lisp (no function definition )

Lisp (no function definition )

brian_adams
Collaborator Collaborator
5,665 Views
9 Replies
Message 1 of 10

Lisp (no function definition )

brian_adams
Collaborator
Collaborator

Actually I a zero in lisp but I need to solve one small part of puzzle with the lisp code

code capturing of value from command line with VBA and there is a part of lisp expresion, doesn't works and I can't solve it.

more about problem is here

https://forums.autodesk.com/t5/visual-basic-customization/capturing-command-line-output-from-vba/m-p...

 

0 Likes
Accepted solutions (3)
5,666 Views
9 Replies
Replies (9)
Message 2 of 10

serag.hassouna
Advocate
Advocate
Accepted solution

As far as I know, there's no direct way to fetch values from the command line to a VBA variable.

But thanks to the Object Model of AutoCAD, this task can be achieved using an Xrecord and a dictionary as follows:

  1. Load the attached lisp file (fetchvar.lsp) to the drawing.
    ((There's an automated way to load lisp files from VBA))
    'Given that the document/drawing object is mydoc
    mydoc.SendCommand("(setq secureloadstate (getvar 'SECURELOAD))" & vbCr)
    mydoc.SendCommand("(setvar " & Chr(34) & "SECURELOAD" & Chr(34) & " 0)" & vbCr)
    Dim path2fetchvar As String
    path2fetchvar = "C:\User\AutoCADfiles\fetchvar.lsp" 'Replace with the actual path
    mydoc.SendCommand("(load " & Chr(34) & path2fetchvar & Chr(34) & ")" & vbCr)
    mydoc.SendCommand("(setvar " & Chr(34) & "SECURELOAD" & Chr(34) & " secureloadstate)" & vbCr)
  2. In the command line, if you'd like to store a value e.g. "15" to be fetched later in VBA, type 
    (fetchvar 15)

     

  3. Apply the following VBA function to fetch this value.
    Public Function FetchVar() As Variant
    ' create an instance to point to Autocad itself
    Dim mycad As AcadApplication
    Set mycad = GetObject(, "AutoCad.Application.20")
    
    'Get the "ActiveDocument" Object
    Dim mydoc As AcadDocument
    Set mydoc = mycad.ActiveDocument
    
    'Get the umbrella "Dictionaries" Collection, the dictionary and XRecord
    Dim Dicts As AcadDictionaries, VarDict As AcadDictionary, VarXRec As AcadXRecord
    Set Dicts = mydoc.Dictionaries
    Set VarDict = Dicts.Item("__TEMP-VAR-DICT__")
    Set VarXRec = VarDict.GetObject("__TEMP-VAR-XRECORD__")
    
    Dim DxfGrcd As Variant, Val As Variant
    DxfGrcd = Array()
    Val = Array()
    
    
    VarXRec.GetXRecordData DxfGrcd, Val
    ReDim Preserve DxfGrcd(0)
    ReDim Preserve Val(0)
    
    FetchVar = Val(0)
    End Function
    Note that "AutoCAD.Application.20" is the ProgID of my 2016 version, check the relevant ProgID of your AutoCAD version.
    2017 -> "AutoCAD.Application.21"
    2018 -> "AutoCAD.Application.22"

Finally, I recommend you to get a basic grasp of AutoLISP, this is due to the fact that AutoLISP expressions can be evaluated in the command line.

Message 3 of 10

serag.hassouna
Advocate
Advocate

To dissect the line

(setvar "USERS1" (c:MY_FUNCTION))
  1. setvar: this is an AutoLISP built-in function that sets an AutoCAD system variable to a specified value.
    AutoCAD system variables are built-in also, you can find a PDF list of them for version 2013, and lists for updated, new and obsolete commands and system variables for later versions.
  2. "USERS1": the name of the system variable, this system variable stores a string/text value.
  3. (c:MY_FUNCTION): a custom command called "MY_FUNCTION", you can replace it with the expression you need to evaluate instead (knowing ahead that it returns a string value), or simply, the text/string you want to store in "USERS1", e.g.
    (setvar "USERS1" "Hello World")
Message 4 of 10

serag.hassouna
Advocate
Advocate
Accepted solution

I'm sorry, the automated way to load an AutoLISP file in VBA would be

'Given that the document/drawing object is mydoc
'Chr(34) indicates a double quotation character mydoc.SendCommand "(setq secureloadstate (getvar 'SECURELOAD))" & vbCr mydoc.SendCommand "(setvar " & Chr(34) & "SECURELOAD" & Chr(34) & " 0)" & vbCr Dim path2fetchvar As String path2fetchvar = "C:\User\AutoCADfiles\fetchvar.lsp" 'Replace with the actual path mydoc.SendCommand "(load " & Chr(34) & path2fetchvar & Chr(34) & ")" & vbCr mydoc.SendCommand "(setvar " & Chr(34) & "SECURELOAD" & Chr(34) & " secureloadstate)" & vbCr

I guess I were more attached to the func(args) notation of function calls forgetting that VBA has its special one for subroutines (by omitting the parentheses).

Message 5 of 10

brian_adams
Collaborator
Collaborator

Thanks a lot for halping me. Alctually I have been meeted the wall with my issue till now. Seems you give me a hope

tryed run load lisp from VBA but   it error 424 object required.

What could be wrong?

 

 

0 Likes
Message 6 of 10

brian_adams
Collaborator
Collaborator

sorry, I GET WHAT IS WRONG 🙂

0 Likes
Message 7 of 10

brian_adams
Collaborator
Collaborator

God send you to me ! Thanks a lottttt!

But it cant't capture the string only numbers

 

 

0 Likes
Message 8 of 10

brian_adams
Collaborator
Collaborator

My Idea Is to fetch value of materialist command for Aec Object in Autocad Architecture
I made some macro that chois every Aec Obj (wall) and apply the "materiallist" command to it and so on till all Aec Obj will be listed
Then I opened excel and copy autocad history to it
Then run another macro to create propery set deffinition and property for Aec Obj, filter date from excel by ID and apply value to Aec Obj
This method has restriction with size of Autocad history ...so the list can't be enormose as I need and I want to avoid third-party applications
Just run single script for all tasks

so i need to fetch not only numbers but strings 

it is looks like now on the pictureprompt.JPG

 

 

0 Likes
Message 9 of 10

serag.hassouna
Advocate
Advocate
Accepted solution

Though I don't have AutoCAD Architecture but I think I've found another way to get what you ask for.

First of all, in Tools>References browse/search for the file C:\Windows\system32\FM20.DLL (named "Microsoft Forms 2.0 Object Library") and add it as a reference.

Then, the following steps should be applied with every AEC object.

  1. Apply the command MATRIALLIST to the AEC object in the way you do it.
  2. Invoke the command COPYHIST, this will copy the content of the command line history to the clipboard
    mydoc.SendCommand "COPYHIST" & vbCr
  3. Fetch the highlighted (in yellow) text using
    Function materialfetch() As String
    'Get the object that stores the clipboard text Dim DataObj As MSForms.DataObject Set DataObj = New MSForms.DataObject DataObj.GetFromClipboard Dim mytxt As String mytxt = DataObj.GetText(1)

    'Get the text portion from the end (the portion of the last invoked command). Dim startpos As Long, endpos As Long startpos = InStrRev(mytxt, "Standard") '((Standard)) is The first word endpos = InStrRev(mytxt, "m3") '((m3)) is The last word materialfetch = Mid(mytxt, startpos, endpos - startpos + 2) '2 = length of the last word End Function
    Repeat these 3 steps for every AEC object.
Message 10 of 10

brian_adams
Collaborator
Collaborator

It is unbelivable. works
I changed a bit solution with method of getting date
made Array of function materialfetch

materialfetch = Replace(mytxt, vbCrLf, "%", 1)

in sub

LArray = Split(materialfetch, "%", -1, 1)

 

and then then in SUb filter it with upper and lower ID ..it is more proper way. Thanks for you help..it is start of new era in ACA

0 Likes