AVZ Posted July 11, 2013 Share Posted July 11, 2013 Hi I am new here and have a little problem. Ihave an AutoCAD dynamic block, it has a few attributes and a visibilityparameter that allows different switches to be displayed as part of the block.This block is used as part of a template that is used with a database softwarepackage. SQL queries are written in the block’s attributes, when the templateis selected from the database software the template is automatically populatedwith the information. TheSQL queries can only be written in the blocks attributes. I can add anotherattribute to the block and insert a SQL query to index to the correctvisibility number to show the right switch. What I need is aVBA routine to sense a change in and attribute and then changing the valueof the visibility parameter so the correct switch is displayed. I am not very familiar with the AutoCAD methods, properties and events, juststarted researching this week, in fact. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 11, 2013 Share Posted July 11, 2013 Welcome to CADTutor, and congrats on your first post! I know nothing of this 'database software package' that shall not be named, but presuming this software provides Command(s) for updating these AttributeReference(s)... You'll want to catch the ObjectIds for the modified AttributeReference Object(s) when the ObjectModified event is raised, and process the stored ObjectId[] (Collection) or List by hooking your 'database software package' Command's CommandCancelled, CommandEnded, or CommandFailed events, as one cannot modify an ObjectId's DBObject whilst it is open in the Database (and there is no such DBObject.ClosedInDatabase event). More information is needed. Cheers Quote Link to comment Share on other sites More sharing options...
AVZ Posted July 11, 2013 Author Share Posted July 11, 2013 Thank you for your quick response. Maybe I am a bit cryptic the database software package isAveva Instrumentation. It has an addition to AutoCAD allowing the selection ofthe blocks to add data links into the attribute fields. These attributes getpopulated with the information from the Aveva database when the drawing isopened and the text of the attributes on the drawing gets updated as well. For instancethe table for my block has the attributes: INSTRUMENT_DESCRIPTION,INSTRUMENT_RANGE, INSTRUMENT_TAG and CABLE# the text for these is changed fromthe data links with the text in the database and displayed on the drawing. Ihave added another attribute “SWPOS” where I can make a SQL query for the datalink to generate a value matching the visibility state for “Switch Type”. I will need to trap the Modified event then check if themodified object is the “SWPOS” attribute of one of my blocks if so put thatvalue into the visibility parameter to make the switch picture change. My problem is I don’t know to correctly call outthe path to access the correct properties. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 12, 2013 Share Posted July 12, 2013 (edited) Thanks for the additional information, but being unfamiliar with that software I still do not understand if a Command is used in order to populate/update said attributed block(s)? That said, and I neglected this in my earlier response, you'll also want to catch the Object prior to being Modified (implicitly storing the original value), so that when you catch the Modified Object you have something to compare against. I'd suggest you store both the ObjectId and the original value, so as to match corresponding resultant (modified) Objects. Also, it might be helpful to have a sample drawing on which to test... Obviously I do not have your supplementary software, but an assumed change in value should be sufficient for testing. I'm more interested in catching the appropriate Object (as I suspect you need to catch the BlockReference and not the AttributeReference as its a nested entity that can be culled from its owner, the BlockReference), and correctly changing visibility state accordingly. Cheers Edited July 12, 2013 by BlackBox Quote Link to comment Share on other sites More sharing options...
AVZ Posted July 12, 2013 Author Share Posted July 12, 2013 Thanks for the help. I have attached the block. I am thinking all I will need is to look for a change in the attribute “SWPOS” and then changing the visibility parameter “Switch Type” to that value. That way the changes of the other attributes will be done with the data links from the Aviva software. If I could put the data link in the “Switch Type” parameter Iwould just do that but that is not possible. Sample DI Block.dwg Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 12, 2013 Share Posted July 12, 2013 Thanks for posting the sample; I'll look into it during my lunch break... Again though, Command, or no Command? I am thinking all I will need is to look for a change in the attribute “SWPOS” and then changing the visibility parameter “Switch Type” to that value. That way the changes of the other attributes will be done with the data links from the Aviva software. Correct. Once a change in the "SWPOS" AttributeReference has been identified, we can change access the BlockReferece via the AttributeReference's OwnerId Property... And from there we can change the visibility state via DynamicBlockReferencePropertyCollection. Quote Link to comment Share on other sites More sharing options...
AVZ Posted July 12, 2013 Author Share Posted July 12, 2013 Thank you for your help but, I don't understand your question. The attributes are changed from the information the datalinks points to when the drawing is opened from the Aviva software. This is what the table of datalinks look like, you just drag and drop them into the form shown in my last post. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 12, 2013 Share Posted July 12, 2013 Thank you for your help but, I don't understand your question. Perhaps if I explained a bit more, it might make more sense.... Storing modified Object(s) is relatively easy process, comparing them to their prior value is a bit more complex, processing stored Object(s) after-the-fact is relatively easy to do... *IF* piggy-backing a CommandCancelled, CommandEnded, or CommandFailed event, as the stored Object(s) are closed in the Database at that time. One cannot make changes to an Object that is currently open in the Database, which is why we cannot modify the AttributeReference Object's Owner (the BlockReference), as it too is open in the Database (where the former is OpenMode.ForWrite via UpgradeOpen() Method, and the latter is OpenMode.ForRead). One can process the stored Object(s) even without a Command ending, etc. but that takes another leap in complexity (an ObjectOverrule), that I'd prefer to avoid unless needed. That said, having glanced at the drawing you posted, I think I have my answer to the question of if a Command is used to modify the attribute value... Since your SWPOS attribute is being modified manually, instead of being modified by some programmatic means (i.e., .NET, ObjectARX, etc.), the EATTEDIT Command is used... We'll piggy-back that. If, however, you instead change the SWPOS attribute value via Properties Palette, etc.. then the Command is _not_ used, and that ObjectOverrule I mentioned will in fact be necessary. I hope this makes (more?) sense to you now? Cheers Quote Link to comment Share on other sites More sharing options...
AVZ Posted July 19, 2013 Author Share Posted July 19, 2013 Hello, I apologize being gone for so long. I have tried tolook into and answer to your question and I cannot find it. I can only guessthat the attributes are updated programmatically when the drawings are beinggenerated and therefore it is commanded. What type of code is needed if that is the case? There is a VBA module loaded when AutoCAD is used to enterthe Aviva datalinks. I cannot see where it has anything to do with accessingthe database and retrieving the data fields. I have included the code with mypost. Thanks for the help. Code.txt Quote Link to comment Share on other sites More sharing options...
AVZ Posted September 26, 2013 Author Share Posted September 26, 2013 Well… I found a way to do what I wanted. It may not be a eloquentas a seasoned pro but, hey, it works. I have the following code in the ThisDrawing. Public LastID As Variant Dim NoRun As Boolean Private Sub AcadDocument_BeginCommand(ByVal CommandName As String) NoRun = True End Sub Private Sub AcadDocument_EndCommand(ByVal CommandName As String) NoRun = False End Sub Private Sub AcadDocument_BeginSave(ByVal FileName As String) NoRun = True End Sub Private Sub AcadDocument_EndSave(ByVal FileName As String) NoRun = False End Sub Private Sub AcadDocument_ObjectModified(ByVal Object As Object) If NoRun Then Exit Sub ' if there are othere activities do not call Sub ' If the Modified Object is a dynamic block then call the Sub If Object.ObjectName = "AcDbAttribute" And LastID <> Object.OwnerID32 Then ' Save the Owner ID so the Sub is only called once for the Block Modification LastID = Object.OwnerID32 Call ModifiedObject(Object, LastID) End If End Sub From theObjectModified event it will call a Sub in Module1. Option Explicit Public Sub ModifiedObject(ByVal Object As Object, LastID As Variant) Dim ParObj As AcadObject Dim obj As AcadObject Dim BlkRef As AcadBlockReference Dim varAttributes As Variant Dim DBRP As Variant Set obj = Object Set ParObj = ThisDrawing.ObjectIdToObject32(obj.OwnerID32) ' Check the object's parent type (Dynamic Block Reference) If ParObj.EntityName = "AcDbBlockReference" Then ' change object type to get Block Reference Attributes ' and test for the correct Dynamic Block Name Set BlkRef = ParObj If BlkRef.EffectiveName = "SW_INPUT" Then ' Get the attributes for the block reference varAttributes = BlkRef.GetAttributes ' If the Instrument Tag attribute hasn't changed leave the sub If varAttributes(0).TextString = "INSTRUMENT_TAG" Then Set obj = Nothing Set ParObj = Nothing Set BlkRef = Nothing LastID = "" Exit Sub End If varAttributes(4).TextString = "" ' Set the value of of the dynamic block attribute to ' the code for the switch type DBRP = BlkRef.GetDynamicBlockProperties DBRP(0).Value = GetSwitchType(varAttributes(0).TextString) End If End If ' Clean up before exiting the Sub Set obj = Nothing Set ParObj = Nothing Set BlkRef = Nothing End Sub Private Function GetSwitchType(ByVal TagName As String) As String Dim RetVal, Fst, Trd, WkStr As String WkStr = Left(TagName, 3) Fst = UCase(Left(WkStr, 1)) Trd = UCase(Right(WkStr, 1)) Debug.Print TagName & " = " & Fst & ", " & Trd Select Case Fst Case "P" ' Test for a Pressure Switch If Trd = "L" Then GetSwitchType = "A1" Else GetSwitchType = "A2" End If Case "T" ' Test for a Temperature Switch If Trd = "L" Then GetSwitchType = "B1" Else GetSwitchType = "B2" End If Case "L" ' Test for a Level Switch If Trd = "L" Then GetSwitchType = "C1" Else GetSwitchType = "C2" End If Case "F" ' Test for a Flow Switch If Trd = "L" Then GetSwitchType = "D1" Else GetSwitchType = "D2" End If Case "Z" ' Test for a Position Switch If Trd = "C" Then GetSwitchType = "E1" Else GetSwitchType = "E2" End If Case Else ' If the type doesn't match anything else use contacts If Trd = "L" Then GetSwitchType = "F1" Else GetSwitchType = "F2" End If End Select End Function 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.