Jump to content

Programmatically change blocks visibility parameter when an attribute is changed.


AVZ

Recommended Posts

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.

Link to comment
Share on other sites

Welcome to CADTutor, and congrats on your first post! :beer:

 

 

 

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

Link to comment
Share on other sites

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. Block Table.JPGFor 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.

Link to comment
Share on other sites

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 by BlackBox
Link to comment
Share on other sites

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. :(

Aveva Block.jpg

Sample DI Block.dwg

Link to comment
Share on other sites

Thanks for posting the sample; I'll look into it during my lunch break... Again though, Command, or no Command? :unsure:

 

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.

Link to comment
Share on other sites

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.Datalinks.jpg

pencil.png

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

  • 2 months later...

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

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...