frostrap Posted May 19, 2008 Share Posted May 19, 2008 I've been looking but haven't found a solution to this one yet. This may be hard to explain, so I'm going to throw some code out there, and hopefully someone can help me out. Please ask questions and I'll clarify as needed. Essentially this code initiates the insertion of a block, but only predetermines the scale, leaving the insertion point and rotation up to the user to determine. I need the user to be able to visually rotate the block on screen before completing the insertion. Is there any way of accomplishing what the following code does, in vba without using the .sendcommand method (perhaps with an insertblock method)? ThisDrawing.SendCommand "-insert" & vbCr & thePath & vbCr & "S" & vbCr & theScale & vbCr I can send the rest of the Sub if you would like to see it. There are several reasons why I need to do this, I'll explain more as people ask... that way I wont have to write a larger book than I already have! Thanks for everything Joe Quote Link to comment Share on other sites More sharing options...
ASMI Posted May 20, 2008 Share Posted May 20, 2008 I think you cannot to do it without SendCommand (I can be wrong). Try something like this to complete your expression and continue of program execution: ThisDrawing.SendCommand "(command " & Chr(34) & "._-insert" & Chr(34) & vbCr & Chr(34) & thePath & _ Chr(34) & " pause" & vbCr & Chr(34) & "1" & Chr(34) & vbCr & Chr(34) & theScale & Chr(34) & _ vbCr & Chr(34) & " pause" & Chr(34) & ")" & vbCr Quote Link to comment Share on other sites More sharing options...
ska67can Posted May 20, 2008 Share Posted May 20, 2008 how about something like this: Dim oBlock As AcadBlockReference Dim Pt1 As Variant Dim iAngle As Double Pt1 = ThisDrawing.Utility.GetPoint(, "Select Basepoint: ") iAngle = ThisDrawing.Utility.GetAngle(Pt1, "Select Rotation Angle: ") Set oBlock = ThisDrawing.ModelSpace.InsertBlock(Pt1, thePath, 1#, 1#, 1#, iAngle) ska Quote Link to comment Share on other sites More sharing options...
ASMI Posted May 20, 2008 Share Posted May 20, 2008 > ska67can Read first post I need the user to be able to visually rotate the block on screen before completing the insertion. Quote Link to comment Share on other sites More sharing options...
LCE Posted May 20, 2008 Share Posted May 20, 2008 You could fudge it. Insert the block first, then use move to set the insertion point, and rotate with reference to set the angle... Then confirm it and it will keep the block, else delete it... Like I said, fudging it... Quote Link to comment Share on other sites More sharing options...
frostrap Posted May 21, 2008 Author Share Posted May 21, 2008 I think I'm going to end up fudging it as LCE suggests. ska, how does "._-insert" differ from "-insert"? Quote Link to comment Share on other sites More sharing options...
SEANT Posted May 21, 2008 Share Posted May 21, 2008 The “.” preceding a command will force Autocad to use its own core command. This feature is there because it is possible to redefine a command of a given name. As a matter of fact it may be just what’s required if the situation described here: http://www.cadtutor.net/forum/showthread.php?t=23403 is the problem at hand. Normally, employing that “SendCommand” configuration does not modify the FILEDIA variable; is it possible that the INSERT command has been redefined on your setup? Quote Link to comment Share on other sites More sharing options...
frostrap Posted May 21, 2008 Author Share Posted May 21, 2008 I've looked through the lisp files that could contain a redefinition of insert and also have looked at the command alias's, but didn't find anything. Actually, the reason I'm searching for alternatives to the insert command are not directly related to the mysterious filedia problem from the other post. There are two reasons that I was looking to not use sendcommand. One: I need the blocks being inserted to be inserted on a layer other than the current default layer. To accomplish this, I was temporarily changing the default layer to the insertion layer, inserting the block, then changing the default layer back to the original layer. Unfortunately, this isn't always working. If, after the insert command is issued, but before the block is inserted, the user tries to pan, AutoCAD resets the default layer to the original layer, away from the layer that I want the block to go on. To resolve this I will just change the block's layer after it's been inserted, rather than initially changing the layer that the block is being put on. Two: This VBA program is initiated by a small lisp routine. This allows the user to initialize the macro via the command line command "TTY". Once the user is done inserting the block they want, the VBA program closes. When the user hits enter (if TTY was the last command typed) AutoCAD should run the TTY command, and launch the block manager. Unfortunately, if I have issued a command (such as "._-insert") in the VBA code, AutoCAD will recognize that command as the last command instead of "TTY", so the user, expecting to relaunch the block manager, unintentionally launches the insert command. I have a workaround for this in my mind, but haven't tested it yet, and was hoping to get some more suggestions from the folks on here. That was a mouthful! Any other ideas? Quote Link to comment Share on other sites More sharing options...
LCE Posted May 21, 2008 Share Posted May 21, 2008 I would strongly advise that you look into the use of VB.NET, rather than VBA as it will help with a lot of what you have explained above. No need to run it from a lisp as the command is defined in the vb.net app. and you can call commands without sending them to the command line. So the last command would be your defined command, rather than any that you call from your app. Quote Link to comment Share on other sites More sharing options...
SEANT Posted May 21, 2008 Share Posted May 21, 2008 Using .NET is good advice – unfortunately 2004 predates that API. Is “dynamic feedback” actually that important? Sure, it would be nice but withholding that bit of eye candy to avoid SENDCOMMAND seems worth it. Something like this may give sufficient reference: Sub InsertWithReference() Dim varInsertPt As Variant Dim varInsertPtTran As Variant Dim entInsert As AcadBlockReference Dim dblOr(2) As Double Dim dblX(2) As Double Dim dblZ(2) As Double Dim varZ As Variant Dim varX As Variant Dim dblAngle As Double Dim entRay As AcadRay dblX(0) = 1# dblZ(2) = 1# With ThisDrawing varZ = .Utility.TranslateCoordinates(dblZ, acUCS, acWorld, 1) varInsertPt = .Utility.GetPoint(, "Insertion Point: ") varInsertPtTran = .Utility.TranslateCoordinates(varInsertPt, acWorld, acUCS, 0) varX = .Utility.TranslateCoordinates(dblX, acOCS, acUCS, 1, varZ) dblAngle = .Utility.AngleFromXAxis(dblOr, varX) varX(0) = varInsertPtTran(0) + 1 varX(1) = varInsertPtTran(1) varX(2) = varInsertPtTran(2) Set entInsert = .ModelSpace.InsertBlock(varInsertPt, "A", 1#, 1#, 1#, -dblAngle)'adjust block name as needed Set entRay = .ModelSpace.AddRay(varInsertPt, .Utility.TranslateCoordinates(varX, acUCS, acWorld, 0)) entRay.Highlight True varX = .Utility.GetPoint(varInsertPtTran, "Adjust angle: ") varInsertPtTran = .Utility.TranslateCoordinates(varInsertPt, acWorld, acOCS, 0, varZ) varX = .Utility.TranslateCoordinates(varX, acWorld, acOCS, 0, varZ) dblAngle = .Utility.AngleFromXAxis(varInsertPtTran, varX) entInsert.Rotation = dblAngle entRay.Delete End With End Sub Quote Link to comment Share on other sites More sharing options...
LCE Posted May 21, 2008 Share Posted May 21, 2008 Sorry, I missed that it was 04 being used. Quote Link to comment Share on other sites More sharing options...
Raggi_Thor Posted May 24, 2008 Share Posted May 24, 2008 I am having trouble updating a block from file without using SendCommand. Even if I supply if full filename in the InsertBlock method AutoCAd (2208) will use the local compy. So I have to do a "SendCommand blkname=blkaname" Quote Link to comment Share on other sites More sharing options...
SEANT Posted May 26, 2008 Share Posted May 26, 2008 I am having trouble updating a block from file without using SendCommand.Even if I supply if full filename in the InsertBlock method AutoCAd (2208) will use the local compy. So I have to do a "SendCommand blkname=blkaname" The general method shown below will update the geometry of a block. Extra steps would be required if attached Attributes are also modified. Make note of the line: Set ACDbx = ThisDrawing.Application.GetInterfaceObject("ObjectDBX.AxDbDocument.16") 'set to appropriate version in the attached code. Sub SetBlocks() 'Change as required Dim strPath As String Dim strBlockName As String Dim objBlock As AcadBlock strBlockName = "Tester" strPath = "C:\" BlockRedefine strBlockName, strPath End Sub Private Sub BlockRedefine(strBlockName As String, strPath As String) Dim strFullDef As String Dim objBlock As AcadBlock Dim entEnt As AcadEntity On Error GoTo BlockNotAvailable Set objBlock = ThisDrawing.Blocks.Item(strBlockName) On Error GoTo 0 For Each entEnt In objBlock entEnt.Delete Next strFullDef = strPath & strBlockName & ".dwg" DbxTransfer strFullDef, objBlock For Each entEnt In objBlock entEnt.Update Next For Each entEnt In ThisDrawing.ModelSpace entEnt.Update Next For Each entEnt In ThisDrawing.PaperSpace entEnt.Update Next BlockNotAvailable: End Sub Private Sub DbxTransfer(strFullFile As String, objBlock As AcadBlock) Dim entEntities() As Object Dim varReturn As Variant Dim ACDbx As AxDbDocument Dim intCount As Integer Set ACDbx = ThisDrawing.Application.GetInterfaceObject("ObjectDBX.AxDbDocument.16") 'set to appropriate version ACDbx.Open strFullFile intCount = ACDbx.ModelSpace.Count ReDim entEntities(intCount - 1) For intCount = 0 To ACDbx.ModelSpace.Count - 1 Set entEntities(intCount) = ACDbx.ModelSpace.Item(intCount) Next ACDbx.CopyObjects entEntities, objBlock End Sub Quote Link to comment Share on other sites More sharing options...
Raggi_Thor Posted May 27, 2008 Share Posted May 27, 2008 Thanks. Great :-) Quote Link to comment Share on other sites More sharing options...
frostrap Posted May 29, 2008 Author Share Posted May 29, 2008 One of the reasons that i want to be able to envoke the insert command without using a command is because I don't want autocad to recall "-insert" as the last command that was used. Since it looks like the only way to get dynamic feedback is by envoking the insert command, is there any way to effectively change what autocad recalls was the last command used? I don't think there's a way to do this using just VBA, but perhaps Lisp or Vlisp has some answer? Since I don't know C++ and there's no .Net API for r16, ARX options are probably out of the picture for the time being. Unless you think the switch from VBA to C++ is one that could be made without too much craziness. There must be a solution for this because I've seen this done by a program that already exists (i'm trying to reverse engineer portions of it). Thanks again. joe Quote Link to comment Share on other sites More sharing options...
SEANT Posted May 29, 2008 Share Posted May 29, 2008 I would imagine any of those other language options would accomplish the task more easily than VBA. Quite frankly, with Dynamic Feedback and Command Line interaction, you are dealing with two of VBA’s most celebrated shortcomings. The drawback to employing one of the other options is the overhead dealing with the mixed code base – if you plan on maintaining your existing VBA code. Not insurmountable, I understand, but no doubt a PITA. Quote Link to comment Share on other sites More sharing options...
frostrap Posted June 7, 2008 Author Share Posted June 7, 2008 Is there any way to do what I'm looking to do in VisualLisp? The program I'm using as a model to improve upon seems to be a compiled vlx file, and it is capable of handling dynamic insertions... there must be a way to do what I'm looking to do. Quote Link to comment Share on other sites More sharing options...
Raggi_Thor Posted June 9, 2008 Share Posted June 9, 2008 (command "-insert" "blockname=filename") I always mix the order of blockname and filename, but you have the method there. Quote Link to comment Share on other sites More sharing options...
frostrap Posted June 21, 2008 Author Share Posted June 21, 2008 Well, in order to solve a few issues, I ended up passing the filename/path, and a slew of other variables to a lisp routine via the "USER**" variables. That routine picks up where the VBA falls short and handles the ghosting and whatnot just great. I had to get a little tricky with the NOMUTT variable to get things to look right, but it seems to work like a charm. Am I right in assuming that vb.net or C++ would have been able to do the ghosting without scripting the .-insert command via Lisp? Thanks for all of your help! Joe Quote Link to comment Share on other sites More sharing options...
SEANT Posted June 22, 2008 Share Posted June 22, 2008 JIGGING is the .Net term for ghosting. Jigs allow .net the ability to display temporary graphics before commiting the elements to the drawing database. In the case of block insertion, I believe Autodesk.AutoCAD.EditorInput.DrawJig or Autodesk.AutoCAD.EditorInput.EntityJig would be the ticket. Quote Link to comment Share on other sites More sharing options...
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.