New to VBA

Discussion in 'AutoCAD' started by jed648, Mar 23, 2005.

  1. jed648

    jed648 Guest

    While I have never posted to this group before, I have been lurking for a couple of years. I am comfortable with VLisp, including ActiveX extensions for VLisp. I write automation scripts for civil engineering, mostly having to do with aligning viewports, automated plotting and such. Most of our work is in 2D. The drafters have been well-versed in the advantages of command-line based drafting and I don't want to change the way they do their jobs (especially if it means a lot of work for me). Until recently, GUI applications slowed down production, and we have aliased most every standard-issue Autocad command to a three letter (or less) command line alternative.

    A couple of fairly new developments have made me rethink the use of VLisp, namely the inability to work with LDT points and the .NET API with Autocad 2005. I think it is finally time to learn how to write VBA applications for Autocad.

    All I would like to know is how to re-write the following simple VLisp functions in VBA. I cannot find any good examples in the VBA help or browsing through this newsgroup. I realize that these functions are extremely simple and don't require VBA or ActiveX, but I plan on building upon them in the future.

    Example #1:
    ; Register a command and print a message to the command console
    (defun C:Hello () (princ "\nHello World")(princ))

    Example #2:
    ; Enhance an existing command to reduce keystrokes and enforce standards
    (defun C:RL ()
    (setvar "clayer" "RL")
    (command "PLINE" pause "W" 1.0 1.0)
    (while (= (getvar "cmdnames") "PLINE") (command pause))
    (princ)
    )

    Example #3:
    ; Selection sets and viewports, ala VLisp
    (defun zoom-viewports ( / SS VP)
    (setq SS (ssget "X" (list (cons 0 "VIEWPORT")(cons -4 ">")(cons 69 1))))
    (while (and SS (> (sslength SS) 0))
    (setq VP (entget (ssname SS 0)))
    (ssdel (ssname SS 0) SS)
    (setvar "ctab" (cdr (assoc 410 VP)))
    (command "mspace")
    (setvar "cvport" (cdr (assoc 69 VP)))
    (command "ucs" "world" "plan" "current")
    (command "pspace")
    (command "regenall")
    ); end while
    )
     
    jed648, Mar 23, 2005
    #1
  2. Hi,

    Very quickly:

    Q1 - No change, except that you are setting up to call a VBA function.

    Q2 - VBA has a different way of drafting. You accumulate the data first
    then draw the object. This makes drawing a polyline awkward. For anything
    else, it's straight forward where the general principle is to create an
    object with a command like

    set oLine = ThisDrawing.ModelSpace.AddLine (Pt1, Pt2)

    then "if required" you change it properties with code like:

    With oLine
    .Layer = LayerName
    .Color = 1
    .Linetype = "CONTINUOUS"
    .Lineweight = 0.01
    End With

    Note that a GUI is not an essential part of using VBA - you can readily use
    code with no interface - or get command line data if you want.

    Q3 - I haven't time to answer, but as with the first two questions the full
    details and sample code are available from the help files.


    --

    Regards,


    Laurie Comerford
    www.cadapps.com.au
     
    Laurie Comerford, Mar 23, 2005
    #2
  3. jed648

    TomD Guest

    I'm interpreting Q1 and Q2 differently than Laurie, so bear with me (and
    possibly clarify the question.)

    For the first issue, the short answer is you can't do that with VBA. AFAIK,
    you cannot directly define commands as you can with lisp. If you search
    through this group you'll find various methods of defining commands via lisp
    which call VBA macros. Not elegant, but quite effective.

    As Laurie is trying to show, VBA doesn't work that way. You could use
    SendCommand to pass things to the command line, the way you are used to
    doing with lisp, but I think most regulars in this group would agree that it
    is not a good idea. You are much better off breaking yourself from the idea
    of passing things to the command line, when using VBA.

    As for selection sets and viewports, you probably won't initially like the
    way VBA handles selection sets. There are things I like/dislike about both
    languages handling of them. It is fairly simple to do the same type of
    thing with VBA, though. There aren't many good examples of selection set
    filtering for VBA, though there is enough that with your knowledge of lisp,
    you shouldn't have too much trouble adapting. The only thing that's tricky
    is the list setup, which would look something like:

    Dim vCod(0) as Integer, vVal(0) as Variant
    vCod(0) = 8
    vVal(0) = "MyLayerName"

    This would be the filter data required to select objects on layer
    "MyLayerName", which would be passed to one of the selection methods.
     
    TomD, Mar 23, 2005
    #3
  4. jed648

    jed648 Guest

    Tom,

    Thanks for your response, it was helpful, if not what I wanted to hear.

    I'd like to clarify the third example, slightly, since it seems I missed the point on that one.

    The most time-saving automation that we used in LISP has to do with the automation of paperspace layouts. Specifically, our drawings consist of literally one to two hundred layout tabs (ten to twenty kilometers of highway drawn at 1:1000 or 1:500 scale on 11x17 pages). It is mind-blowing to consider the amount of time that can be saved by enumerating all of the layouts and processing each layout automatically (inserting cross references, north arrows, title blocks, scaling and positioning viewports, etc.) Since the twist angle of a viewport is used to rotate the view, I need to be able to determine the twist angle of a viewport, it's position in paper space and the 'type' of layout based on the layout name in order to position north arrows. This is just one example of the type of automation that we use every day.

    Example #3 was intended to show just this. The two key issues are being able to retrieve the layout name and the CVPORT number for each viewport so I can activate it and check it against our standards, not iterating through a selection set (which I believe is possible using for each...next, or the equivalent of vlax-for). Perhaps this is not the most efficient way to do things in VBA, if there is a better way than this, please let me know.
     
    jed648, Mar 23, 2005
    #4
  5. jed648

    TomD Guest

    Example 3, IMO, is perfectly suited for automation with VBA. I think you'll
    find it MUCH easier to do this type of thing in VBA vs. lisp. It would look
    something like

    Dim oLayout as AcadLayout
    dim oEnt as AcadEntity
    For Each oLayout in Thisdrawing.Layouts
    'Code to process your viewports here, maybe something like
    For Each oEnt in oLayout
    If TypeOf oEnt is AcadPViewport
    '(I embarrasingly Have to admit I don't know the exact code required
    here)
    'If the above is exactly correct, it is purely dumb luck....right
    idea, though
    'Code here to do whatever with the viewport
    Next oEnt
    Next oEnt
    Next oLayout
     
    TomD, Mar 23, 2005
    #5
  6. All I would like to know is how to re-write the following simple VLisp
    Looking at your examples the first thing that jumped out at me was that they
    use the COMMAND function. In general, lisp code using COMMAND is *very*
    short compared to code written against other API's. If you're looking to
    find short comparable functions written using other API's, then prepare
    yourself for disappointment.
    ..NET and VBA are two different API's altogether. While .NET is capable of
    accessing the ActiveX API, 2005 introduced the managed .NET API which is a
    thin wrapper over the ARX API. VBA has no direct access to this API. If
    you're wanting to explore the .NET API then VBA *will not* help you.

    As a side note, the 2006 .NET API is greatly expanded over the 2005 version
    and covers almost all of the ARX API.
    This is not possible via the ActiveX API. You can only use the lisp, .NET,
    or the ARX API to do this.
    Although this code isn't showing it, I assume that this example is meant to
    show how a pline can be automatically placed on a layer without affecting
    the drawings current layer setting. For something this simple, lisp is prob
    ably the best tool for the job. To recreate this code verbatim in VBA or
    ..NET would be monumental ,or hacked to the point of "why bother".

    If you must go to an API other than lisp, you have to rethink the way you
    design code to make something like this work. We also autolayer a lot of
    entities placed in the drawing. Drawings open in the editor are monitored
    by objects whose singular purpose in life is to watch for entities added to
    them and pass them on to other objects. These objects ignore or modify the
    entities as needed.

    This approach is much different than the traditional lisp approach in your
    example and if you start trying to code VBA or .NET the same way that you
    did with lisp, then you will *hate* it. And rightly so. However, if you
    are able to make the jump to another way of thinking about and designing
    code, then I think you'll find that you never want to go back.
    I've had less than 12 hours of sleep combined over the past three nights and
    I wore out my one working brain cell deciphering this odd method of
    iterating over a selection set. I'm just not able to determine what the
    rest of the code is accomplishing :)

    However, if you're iterating over layouts and processing viewports then I
    wouldn't use a selection set at all in any API other than lisp. A
    description of the goal of this example would be very helpful, to me at
    least.
     
    Bobby C. Jones, Mar 23, 2005
    #6
  7. jed648

    jed648 Guest

    Thanks, Tom

    You have been very helpful. Your response was exactly the information that I needed to get started in the right direction.
     
    jed648, Mar 23, 2005
    #7
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.