Hickoz_bro Posted May 16, 2011 Posted May 16, 2011 Hi all, I'm new to VBA in AutoCAD I've played with Inventor VBA a bit, but the API appears to be drastically different. I need to manipulate existing splines on a drawing by joining them together via VBA. To achieve this manually, the user would use the command SPLINEDIT and go from there. What is the equivalent, or how do I access the command in VBA? Any suggestions would be greatly appreciated. Thanks and Regards Quote
SEANT Posted May 17, 2011 Posted May 17, 2011 There isn’t much spline related functionality exposed via the ActiveX API in vanilla AutoCAD. I think a “ThisDrawing.SendCommand” targeting SPLINEDIT is the most viable option. AutoLisp, .NET, and ARX are much better equipped for spline manipulation. Quote
Hickoz_bro Posted May 17, 2011 Author Posted May 17, 2011 ActiveX? Forgive my ignorance, but I'm using VBA, how is that related to ActiveX API? Either way I had started along the path of "ThisDrawing.SendCommand" expecting that would be the case, but I'm finding it really difficult to call on a selection set that I've defined earlier. I have a selection set (called SSetTemp) and it contains one single spline. How do I call that into the "SendCommand"? Once I've started the "SendCommand" I can't call my VBA object SSetTemp, and I can't figure out how to recall the selection set from command line. Thanks for your help. Quote
SEANT Posted May 17, 2011 Posted May 17, 2011 The ActiveX (or COM) is just the name of the interface used to expose various bits of functionality to VBA. The “various bits”, unfortunately, aren’t all that plentiful. Here was a way to use a SelectOnScreen call. I’m not sure how useful that “Previous” method would be with other (more automated) selection modes. http://www.cadtutor.net/forum/showthread.php?19349 Quote
Hickoz_bro Posted May 17, 2011 Author Posted May 17, 2011 Thanks for that. Do you have any reference information regarding splines etc in LISP? The piece of code I'm trying to write, in essence, will combine multiple splines (arranged end to end) into single splines, creating a loop. however there are many loops on the page. My plan was to do something like this: for each spline on thisdoc.modelspace splinedit.join (All) next spline (excuse the home made syntax) So, in VBA I can easily do a "for each" but I can't do a splinedit. In LISP, I don't know how to do a 'for each' or a splinedit. So, If you have info on 'for each' or 'splinedit' in LISP, I'd greatly appreciate it. Quote
SEANT Posted May 17, 2011 Posted May 17, 2011 Sadly, it is not that easy in VBA. Lisp has a much better connection with the AutoCAD command line so, conceivably, would make the SPLINEDIT implementation easier. I don’t know enough autolisp to make an attempt, though. Perhaps a post should be made in the AutoLISP, Visual LISP & DCL section to entice one of the guru’s there to take a look. Quote
Hickoz_bro Posted May 17, 2011 Author Posted May 17, 2011 No worries.. I'll give the SendCommand another go (just found something that might be useful) then I'll take a look at the LISP threads. Thanks again for your help. Quote
Hickoz_bro Posted May 17, 2011 Author Posted May 17, 2011 Okay... Getting warmer... How do I cancel the active command OR (preferably) get the prompt displayed in the command line? Quote
BlackBox Posted May 17, 2011 Posted May 17, 2011 Do you have any reference information regarding splines etc in LISP? From AutoCAD open the Visual LISP Integrated Developement Environment using the VLIDE command. Then hit F1 to open the Developer Documentation - two sources: DXF Reference > ENTITIES > SPLINE ActiveX and VBA Reference > Object Model > Document > ModelSpace > Spline The latter being similar to the VBAIDE's Object Browser. The piece of code I'm trying to write, in essence, will combine multiple splines (arranged end to end) into single splines, creating a loop. however there are many loops on the page. My plan was to do something like this: for each spline on thisdoc.modelspace splinedit.join (All) next spline (excuse the home made syntax) So, in VBA I can easily do a "for each" but I can't do a splinedit. In LISP, I don't know how to do a 'for each' or a splinedit. So, If you have info on 'for each' or 'splinedit' in LISP, I'd greatly appreciate it. Sadly, it is not that easy in VBA. Lisp has a much better connection with the AutoCAD command line so, conceivably, would make the SPLINEDIT implementation easier. I don’t know enough autolisp to make an attempt, though. Perhaps a post should be made in the AutoLISP, Visual LISP & DCL section to entice one of the guru’s there to take a look. Nawww... Occasionally we make house calls. :wink: (^^ Yeah, right... I'm no Guru, but I think I can help ^^) Perhaps this will help accomplish the task at hand: (defun JoinSplines ( / ss) ;; Example function call: (JoinSplines) (while (/= nil (setq ss (ssget '((0 . "SPLINE"))))) (command "._join" (ssname ss 0) ss "")) (princ)) The problem being that this will only work with a co-located group of splines. More specifically... if one were, for example, to have two groups of splines and you selected all of them, only the group first selected would join (hence the included while loop, which will permit the user to do this task for each co-located group). If you have an alternative example using either VBA, or VB.NET I *might* be able to port it to Auto/Visual LISP for you, as most of my development is done with ActiveX COM API via Visual LISP. I just don't work with Splines enough to know of a better way at the moment. Hope this helps! Quote
BlackBox Posted May 17, 2011 Posted May 17, 2011 Okay... Getting warmer... How do I cancel the active command OR (preferably) get the prompt displayed in the command line? Not sure how to cancel from VBA . I would imagine there's an exit, or quit method, no? Sub Prompt(Message As String) Member of AutoCAD.AcadUtility Posts a prompt to the command line Quote
Hickoz_bro Posted May 17, 2011 Author Posted May 17, 2011 Thanks guys, I greatly appreciate this. Below is the code I've written so far. If you run through for one loop of the FOR loop, it works fine (check the numeral '5' on the attached example.dwg before and after you run the code), but when you run through a second time I get a catastrophic failure at line "SET ADDITEM(0) = SSET (X1)" and I'm not sure why. If you re-run through the first loop again, you'll error immediately after "THISDRAWING.SENDCOMMAND" because the selected spline is a closed loop. Sub JoinSplines() Dim SSet As AcadSelectionSet Dim oSSetGroup As AcadGroup Dim sGRName As String Dim FilterType(0) As Integer Dim FilterData(0) As Variant Dim X1 As Integer Dim AddItem() As AcadEntity On Error Resume Next If ThisDrawing.SelectionSets.Item("SSet") Is Nothing Then Set SSet = ThisDrawing.SelectionSets.Add("SSet") Else ThisDrawing.SelectionSets.Item("SSet").Clear Set SSet = ThisDrawing.SelectionSets("SSet") End If On Error GoTo 0 Err.Clear FilterType(0) = 0 FilterData(0) = "Spline" SSet.Select acSelectionSetAll, , , FilterType, FilterData ReDim AddItem(0) As AcadEntity For X1 = 1 To SSet.Count Set oSSetGroup = ThisDrawing.Groups.Add("SG") sGRName = oSSetGroup.Name [color="red"] ''CATASTROPHIC FAILURE HERE[/color] Set AddItem(0) = SSet(X1) oSSetGroup.AppendItems AddItem [color="red"]'''NEED TO END ANY, AND ALL EXISTING COMMANDS BEFORE PROCEEDING[/color] On Error Resume Next ThisDrawing.SendCommand "splinedit" + vbCr + "G" + vbCr + sGRName + vbCr + "J" + vbCr + _ "all" + vbCr + vbCr + vbCr If Not Err Is Nothing Then ThisDrawing.SendCommand "!(command)" & vbCr [color="red"]'''NEED TO END CURRENT COMMAND HERE.[/color] Err.Clear End If On Error GoTo 0 oSSetGroup.Delete ReDim AddItem(X1) As AcadEntity Next End Sub The code sample you posted, RenderMan, works well if the loop contains only splines, but the code I've posted above works for loops containing loops, lines and arcs like the attached file (example.dwg). The code will process text loops like this almost exclusively. Once it's done joining splines, it will join any remaining polylines. Thanks again. Example.dwg Quote
SEANT Posted May 17, 2011 Posted May 17, 2011 AutoCAD 2012 can use the standard JOIN command (i.e., not through SPLINEDIT) to join both splines and non splines into one large composite (See returned sample). So, depending on what the end result needs to be, perhaps this variation on your posted code would do. I can’t test it myself because my install of AutoCAD 2012 is 64 bit, with which VBA does not play nice. Sub JoinSplines() ' This example adds objects to a selection set by prompting the user ' to select ones to add. ' Create the selection set Dim ssetObj As AcadSelectionSet On Error Resume Next ThisDrawing.SelectionSets.Item("TEST_SSET").Delete On Error GoTo 0 Set ssetObj = ThisDrawing.SelectionSets.Add("TEST_SSET") Dim mode As Integer Dim pointsArray(0 To 11) As Double mode = acSelectionSetCrossingPolygon 'I just hardcoded a rectangle size to fit. May want to use extmin and extmax pointsArray(0) = 0#: pointsArray(1) = 0#: pointsArray(2) = 0# pointsArray(3) = 950#: pointsArray(4) = 0#: pointsArray(5) = 0# pointsArray(6) = 950#: pointsArray(7) = 420#: pointsArray( = 0# pointsArray(9) = 0#: pointsArray(10) = 420#: pointsArray(11) = 0# ssetObj.SelectByPolygon mode, pointsArray ThisDrawing.SendCommand "JOIN" & vbCr & "Previous" & vbCr & vbCr End Sub Example_2012.dwg Quote
Hickoz_bro Posted May 18, 2011 Author Posted May 18, 2011 Oh damn... that would be helpful... unfortunately we won't be rolling out 2012 here for quite some time (if at all). Either way... I think I got it sorted... Sub JoinSplinesOnDWG() Dim SSet As AcadSelectionSet Dim oSSetGroup As AcadGroup Dim sGRName As String Dim FilterType(0) As Integer Dim FilterData(0) As Variant Dim X1 As Integer Dim SplCountLive As Integer Dim AddItem() As AcadEntity Dim acadDoc As AcadDocument Set acadDoc = ThisDrawing On Error Resume Next If ThisDrawing.SelectionSets.Item("SSet") Is Nothing Then Set SSet = ThisDrawing.SelectionSets.Add("SSet") Else ThisDrawing.SelectionSets.Item("SSet").Clear Set SSet = ThisDrawing.SelectionSets("SSet") End If On Error GoTo 0 Err.Clear FilterType(0) = 0 FilterData(0) = "Spline" ReDim AddItem(0) As AcadEntity SSet.Select acSelectionSetAll, , , FilterType, FilterData SplCountLive = SSet.Count X1 = 0 Do Until X1 = SplCountLive X1 = X1 + 1 Set oSSetGroup = ThisDrawing.Groups.Add("SG") sGRName = oSSetGroup.Name Set AddItem(0) = SSet(X1) oSSetGroup.AppendItems AddItem On Error Resume Next If AddItem(0).Closed = False Then ThisDrawing.SendCommand "splinedit" + vbCr + "G" + vbCr + sGRName + vbCr + "J" + vbCr + _ "all" + vbCr + vbCr + vbCr End If If Not Err = 0 Then ThisDrawing.SendCommand "!(command)" & vbCr Err.Clear End If On Error GoTo 0 oSSetGroup.Delete SSet.Clear SSet.Select acSelectionSetAll, , , FilterType, FilterData SplCountLive = SSet.Count Loop End Sub Next question... I found a good site yesterday explaining how to use multiple filters in your selection sets... But I can't find it again... Here's what I've got... Dim FilterType(1) As Integer Dim FilterData(1) As Variant FilterType(0) = 0 FilterData(0) = "Arc" FilterType(1) = 0 FilterData(1) = "Line" SSet.Select acSelectionSetAll, , , FilterType, FilterData Unfortunately, this returns 0 items... but if I run either filter type separately, then I get plenty of objects returned... What have I missed? Quote
Hickoz_bro Posted May 18, 2011 Author Posted May 18, 2011 Found it... http://www.kxcad.net/autodesk/autocad/Autodesk_AutoCAD_ActiveX_and_VBA_Developer_Guide/ws1a9193826455f5ff1a32d8d10ebc6b7ccc-6c11.htm Quote
SEANT Posted May 18, 2011 Posted May 18, 2011 For that particular data type items can be strung together. Does this work any different: Dim FilterType(0) As Integer Dim FilterData(0) As Variant FilterType(0) = 0 FilterData(0) = "Arc,Line" SSet.Select acSelectionSetAll, , , FilterType, FilterData Quote
Hickoz_bro Posted May 18, 2011 Author Posted May 18, 2011 Oh damn... that simple... I'll have to give that a shot tomorrow at work. I got the method mentioned on that kxcad.net website to work.. so it's all good... now when I run both bits of code, it joins all splines together, then all lines and arcs together as polylines... Next episode, we hatch and export... then add the whole lot to the Inventor code I wrote earlier. Thanks heaps for your help. Quote
Recommended Posts
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.