Kean Walmsley

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Twitter Updates

    follow me on Twitter



    « Developing Autodesk Civil 3D applications with .NET | Main | Cancelling an active command in AutoCAD »

    August 11, 2006

    TrackBack

    TrackBack URL for this entry:
    http://www.typepad.com/services/trackback/6a00d83452464869e200d83435c19b53ef

    Listed below are links to weblogs that reference Techniques for calling AutoCAD commands programmatically:

    Comments

    Isn't this what the labs demonstrate? :) Just wondering about the target group of people of this blog.

    Hi Stephan,

    Thanks for your comment, but I'm not sure what you mean...

    1) Which labs?
    2) Do you mean this specific entry or the blog as a whole?

    Regards,

    Kean

    Hi, Kean!
    Additional methods:
    1) int acedPostCommand(char const *cmd);
    2) PostMessage() to commandline window - useful in order cancel active command from external application: http://www.autocad.ru/cgi-bin/f1/board.cgi?t=26850Nn#20060506023520

    Hi Alexander,

    Thanks - these two are also definitely worth mentioning, and - as I'm sure you're aware - both are useful for cancelling running commands that have paused for user input.

    Please keep the comments coming! :-)

    Kean

    Thanks for the helpful information.

    As one that has been using acedCommand() and acedCmd() via P/Invoke for some time with great success, I don't think its entirely fair to discourage the use of these APIs from registered command handlers, only because the specifics relating command level nesting were left out.

    Perhaps a better strategy would be to get into those specifics, to help readers understand the limitations and caveats of the use of these APIs.

    For most practicle purposes, where the need is to execute a built-in AutoCAD command like PEDIT or what have you, and where there is little or no potential that others will attempt to script the registered command via the same API or the LISP (command) function, there is little danger that the command depth nesting limit will be reached.

    But there are also other issues relating to the use of acedCommand() which wasn't covered in your article, that can also result in problems when that API is improperly used from the handler of a registered command. Namely, any command which is scripted via calls to acedCommand(), must be exited before the handler that calls acedCommand() exits. Failing to do that usually results in a fatal condition.

    Another somewhat obscure issue relating to the use of all the various asynchronous methods you covered, is that their use can often corrupt or disable undo and/or redo, and prevent the user from redoing an operation that've undone. This usually occurs when attempting to use one of the asynchronous methods to execute commands that involve user interaction via the command line.

    The files below provide convienent wrappers for acedCmd(), that allow those whose needs are relatively simple to avoid the hideous issues that plague all of the asynchronous forms of command execution, and thanks for covering some of the issues relating to the use of acedCommand from registered command handlers.

    http://www.caddzone.com/CommandLine.cs
    http://www.caddzone.com/CommandLine.vb

    Kean,

    Sorry for the double post, I mistakenly posted this comment in the wrong topic earlier.

    Anyway to repeat the question: Is there a way to send a command from VBA to command line, such that you call a lisp interface exposed through ARX which takes some input parameters too?

    For example: I have a function written in ARX that is exposed through LISP. So you can type on command line (doSomethingWithThisFunction selectionset name)

    where:
    doSomethingWithThisFunction is the name of function exposed through LISP interface from ARX

    selectionset is an AutoCAD selectionset

    name is just a string

    Problem is when I use ThisDrawing.SendCommand () from VBA it treates the LISP function and its arguments as three separate commands

    To sum it up I need to be able to call a command line function from VBA, such that the function also takes some parameters.

    Is that possible?

    Thanks

    Vector,

    This is altogether possible: you just need to format the SendCommand() string appropriately. Make sure you use an opening parenthesis and pass the quotes for the string (and probably an apostrophe before the variable name containing the selection set).

    The other option is to expose your function as a command that gets the selection set (which you would now pass with an exclamation mark: "!") and the string using acedSsGet() and acedGetString().

    Regards,

    Kean

    Kean,

    I tired using send command using the following syntax in VBA

    Dim objNewSS As Object

    objNewSS.SelectOnScreen

    Dim tagNum As String
    tagNum = "UDE-121"

    strincom = "(at_UserDefinedFromSelSetAndTag 'objNewSS tagNum)" & vbCr

    ThisDrawing.SendCommand strincom

    When I do that I get the following error on the command line.

    "; error: invalid data type or data overflow: OBJNEWSS"

    Remember that this function is working perfectly from LISP when I do the following

    (setq OBJ_SS (ssget) ; pick objects one at a time
    NDX 0
    )
    (if OBJ_SS
    ;; if there is a selection set, do...
    (progn
    (while (< NDX (sslength OBJ_SS))
    (setq OBJ (ssname OBJ_SS NDX)
    NDX (+ NDX 1)
    )
    (setq tagnum "UDE-121")
    (at_UserDefinedFromSelSetAndTag OBJ_SS tagnum)
    )
    )
    ;; otherwise, no selection set
    (progn
    (alert "Nothing selected.\nExiting.")
    (exit)
    )

    Could it be that the send command can only process data of type string and has no clue what a selection set type, or an object type means? Any help would be appreciated.

    Thanks,
    Vector

    Vector,

    Your problem is that you're trying to pass VBA-defined variables by name through LISP to ObjectARX. Unlike with LISP symbols, VBA variable names are not exposed to AutoCAD itself - neither LISP or ObjectARX will understand them.

    For the string argument, this is easy - just change your code to this:

    strincom = "(at_UserDefinedFromSelSetAndTag """ + tagNum + """)" & vbCr

    For the selection set, it's trickier. The simplest is probably to use acedSsGet("P") from your ObjectARX application to pick up the most recent selection set. Otherwise it gets very diffidult (another option would be to use COM client code in your ObjectARX app to query the contents of a named selection set in VBA).

    Speaking of named selection sets - I assume you've simplified out a line such as this from your code:

    Set objNewSS = ThisDrawing.SelectionSets.Add("SS")

    Regards,

    Kean

    Kean,

    I tried another approach. It worked partially

    Set objNewSS = ThisDrawing.SelectionSets.Add("SS")

    Then used
    strincom = "(at_UserDefinedFromSelSetAndTag objNewSS.Name tagNum)" & vbCr

    ThisDrawing.SendCommand strincom

    This worked and I could get access to "SS" name entity in ARX. However, when I tried to get selection set in the ARX, using the resbuf filter, it fails to get the selection set. For example

    struct resbuf rb;

    rb.restype = 0; // Entity name filter
    rb.resval.rstring = EName; //Ename is coming
    //fromVBA properly
    rb.rbnext = NULL;

    if (ads_ssget("_X",NULL, NULL, &rb, selSet) == RTNORM)
    {
    The check fails and the code won't execute here
    ---
    ---
    ---
    }

    Now what?!?! Any Ideas?

    Vector,

    That's why I didn't suggest it: the "SS" name doesn't correspond to a symbol that's accessible from LISP or ObjectARX (that I can tell). Your best bet is to omit the argument altogether and rely on the previous selection, as I suggested (hopefully that's an option for you). Otherwise things get messy.

    Kean

    Kean,

    I tried another approach and it solved my problem. I am posting it here for the benefit of other users.

    VBA doesn't expose a handle for the AcadSelectionset object, that's true. This is kind of a sticky area that makes for some messy code. There are a couple of other options, but they basically require doing most of it in lisp, either having code execute from the lisp environment, or running lisp from vba.

    In the lisp you can access the activex SS. For example, in VBA create your
    SS and name it "SSforLisp". Then in lisp:

    (vl-load-com)
    (setq ss-vba (vla-item
    (vla-get-selectionsets
    (vla-get-activedocument
    (vlax-get-acad-object)))
    "SSforLisp"));; gets the ActiveX SS
    (setq ss-lisp (ssadd));;creates a new ename-based ss
    (vlax-for ent ss-vba
    (ssadd (vlax-vla-object->ename ent) ss-lisp)
    );;add each object's ename to the ename-ss

    Thanks,
    Vector

    Vector,

    Great - glad you found a solution!

    This is basically the approach I meant when I said "(another option would be to use COM client code in your ObjectARX app to query the contents of a named selection set in VBA)."

    My assumption was that you were working in C++, but this is essentially the same technique from LISP.

    Kean

    Hi
    I am try to create a selection select in vb and then use the sendcommand function to run a autocad command and pick the selectionset created in vb as the previous selectionset.
    I do not seem to be able to get the selectionset created in vb to be the previous set. Do you have any ideas how to do it for pass a selectionset from vb to a command with the send command.

    Sub Example_SelectwithVB()
    ' This example adds objects to a selectionset with vb

    On Error Resume Next

    'SSetColl.Item("CURRENT").Delete
    ThisDrawing.SelectionSets.Item("TEST_SSET").Delete


    ' Create the selection set
    Dim ssetObj As AcadSelectionSet
    Set ssetObj = ThisDrawing.SelectionSets.Add("TEST_SSET")

    ' Add objects to a selection set by prompting user to select on the screen
    'ssetObj.SelectOnScreen


    ' Iterate through the model space collection.
    ' Collect the objects found into an array of objects
    ' to be added to the selection set.
    ReDim ssobjs(0 To ThisDrawing.ModelSpace.Count - 1) As AcadEntity
    Dim I As Integer
    For I = 0 To ThisDrawing.ModelSpace.Count - 1
    Set ssobjs(I) = ThisDrawing.ModelSpace.Item(I)
    Next

    ' Add the array of objects to the selection set
    ssetObj.AddItems ssobjs

    ssetObj.Update


    ThisDrawing.Regen acActiveViewport

    MsgBox "A new SelectionSet called " & ssetObj.Name & " has been added to the SelectionSets collection.", vbInformation, "SelectionSets Example"

    'Once the selectionset has been created in the previous code in vb it becomes the previous
    'selectionset at the command line and can be accessed with the select p enter enter series
    'of commands

    ThisDrawing.SendCommand "AecIsolateObjects" + vbCr
    ThisDrawing.SendCommand "P" + vbCr + vbCr

    End Sub

    Regards

    Justin

    Hmm... SelectOnScreen will modify the previous selection set (as it's using AutoCAD's selection process), but selection sets created programmatically do not.

    In this case, I'd suggest either using SelectOnScreen (which is probably not what you need), or sending a much more complex text string to the command lines, one that contains a LISP command using (ssget "X") to select the various entities you want and save the selection set in a LISP variable. You should then be able to plug this into AecIsolateObjects using "!ss".

    hi there

    I have been scripting by using VBA for sometime. is there any other language(s) other than lisp. how about CSharp ? it it possible to write a code and use with Autocad as we do with VBA?

    thanks

    hi kean

    I am facing problem with VBA System when ever i am
    opening a cad drawing there is message is coming
    "VBA System... execution error execution error.

    please find some solution


    thanks
    awes

    Hi Awes,

    Sorry - it's not clear to me what the problem is. I suggest posting a more detailed description to the AutoCAD Visual Basic Customization Discussion Group.

    Regards,

    Kean

    hi kean

    regarding "VBA System... execution error execution error.
    I think it's a computer virus that is stored in the macros of a vba project. if we open a drawing that contains this virus, a virus can become active and be transmitted to your computer.
    from that point on, every drawing file you save can become infected with the virus. when other users open the infected drawing file, the virus can also be transmitted to their computers. so when ever we open any drawing file this execution error comes before starting the drawing and then it's normal. I want to remove this message, i tried antivirus but it's not detacting. please find some solution and advice.

    This sounds unlikely - I've never come across an AutoCAD VBA virus (but there's a first time for everything, I suppose).

    This isn't really the right place to get help on this: I suggest contacting your reseller, or otherwise someone on the discussion group I mentioned in my last comment.

    Kean

    Has anyone successfully been able to replicate and port this to VB.NET and been able to run it on Vista? Been struggling for hours without being able to send a WM_COPYDATA using SendCommand with a COPYDATASTRUCT to AutoCAD. Any ideas or samples would be highly appreciated.

    Thanks!

    dear kean.
    I found you as a professional programmer so I believe thats a good idea to consult with you. I am going to filter the points of the dwg file using selectionsets and select function. the problem is that i am going to filter them by symbol ( as an example select those points which have symbol tree. but i find no groupcode to filter it. I have got no Idea how to do it. I will really be grateful if you give me a hint.

    by the way i forgot to mention i am using vba

    Shahin - please post your questions to the discussion groups, or via the ADN website, if you're a member. I don't have the luxury of spending time providing specialised support for people, unless it's very much related to a post of mine.

    Kean

    How can i call superhatch command with all input paramters using vb.net? I just don't want to prompt the dialog boxes of superhatch to get inputs from user. I want to provide it programmatically.
    For eg: similar to this
    doc.SendCommand("_superhatch par1,par2.....")

    For rectangle, its :
    doc.SendCommand("_rec 10,10 20,20")

    But dont know the fromat to pass parameters for superhatch.
    Can anybody help me on this?

    Thanks,
    Sandip

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search