How to recognize a Field in an Attribute Value?

How to recognize a Field in an Attribute Value?

Anonymous
Not applicable
2,855 Views
12 Replies
Message 1 of 13

How to recognize a Field in an Attribute Value?

Anonymous
Not applicable

Hello,

I'm writing code in VB.NET and I've hit a bit of a wall.

I wrote an app which will read from a text file and populate attributes in blocks with the value in the text file.

It works fine; replaces all attribute values correctly with the values in the text file.

But...

I need to have it ignore attributes which already contain a field; as in NOT overwrite attribute values which contain a field.

 

So...

How do I recognize whether an attribute contains a field?

 

For each block reference in the drawing I've collected and cycle through Attribute References one-by-one and query the attTag so that I'm updating the correct attribute.  I just need to conditionally state that if the AttRef.attValue contains a field it should be ignored.

 

How do I do that?

 

Here's the relevant code:

 

'See if it has attributes and if one of the attributes is ENTITY_CODE and another is CEID or CE!_CODE
'And collect the Entity Code value
For Each myAttRef As AttRef In GetAttributes(BRefID)
If myAttRef.attTag.ToString = "ENTITY_CODE" Then
myEC = 1
myECValue = myAttRef.attValue.ToString
End If
If myAttRef.attTag.ToString = "CEID" Or myAttRef.attTag.ToString = "CE!_CODE" Then
myCEID = 1
End If

'''''''''''''''''''''''''''''''''''
'If myAttRef.Value contains a field then ignore and go on to next

'End If
''''''''''''''''''''''''''''''''''''

Next

 

Thank you for any direction you can offer.

 

Erik

 

0 Likes
Accepted solutions (1)
2,856 Views
12 Replies
Replies (12)
Message 2 of 13

Alexander.Rivilis
Mentor
Mentor

You can check value of myAttRef.HasFields in order to understand myAttrRef has field(s) or no.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 3 of 13

Anonymous
Not applicable

Thank you for the reply.

 

I found that solution in my many Google searches.  Unfortunately .HasFields isn't available as an option; as in myAttRef.HasFields isn't valid input.  Maybe I'm trying to search that property wrong.  Do I need a special reference to use .HasFields?  I have AcCoreMgd.dll, AcDbMgd.dll and AcMgd.dll loaded as references among some others system references. 

 

The AutoCAD .NET Developer's Guide doesn't make any mention of .HasFields.

 

That seems to be exactly what I need, but I haven't found a way to make it work. 

 

Suggestions?

 

Erik

 

0 Likes
Message 4 of 13

Alexander.Rivilis
Mentor
Mentor

AttributeReference class is derived from DBObject class. DBObject class has property HasFields:

 

2016-09-22_18-24-04.png

 

 P.S.: What is a class AttRef in your's code? There is no such class in AutoCAD .NET API. Maybe it is a AttributeReference  class?

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 5 of 13

Alexander.Rivilis
Mentor
Mentor

@Anonymous wrote:
...Do I need a special reference to use .HasFields?...

 


No. You have to reference to AcDbMgd.dll and this enough to use HasFields property.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 6 of 13

Alexander.Rivilis
Mentor
Mentor

Sample code which check HasFields property and video of using this code:

 

Imports System
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
<Assembly: CommandClass(GetType(VBTestHasFields.MyCommands))> 
Namespace VBTestHasFields
    Public Class MyCommands
        <CommandMethod("TestFields")> _
        Public Sub MyCommand()
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
            Dim prOpt As PromptNestedEntityOptions =
                New PromptNestedEntityOptions("Select entity: ")
            Dim prRes As PromptEntityResult = ed.GetNestedEntity(prOpt)
            If prRes.Status = PromptStatus.OK Then
                Dim tr As Transaction = doc.TransactionManager.StartTransaction
                Using (tr)
                    Dim ent As Entity = tr.GetObject(prRes.ObjectId, OpenMode.ForRead)
                    If ent.HasFields Then
                        ed.WriteMessage(vbNewLine + "Entity has fields")
                    Else
                        ed.WriteMessage(vbNewLine + "Entity has NOT fields")
                    End If
                    tr.Commit()
                End Using
            End If
        End Sub
    End Class
End Namespace

 

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 7 of 13

Anonymous
Not applicable

Thank you for all the great help.  I really appreciate it.  I'm trying to wrap my head around how to use it...

 

The code you provided prompts for a block and then queries the block for fields (that's what I interpret)

 

However, the Attribute Reference is already in focus but is apparently not a database object because the .HasField property isn't an option.

 

I'll attach a jpg of the code I'm using. It does the following:

- Cycles through each block definition in the drawing

- Cycles through each block reference in each block definition 

- For each block reference, it gathers a list of attributes in the block

- For each attribute in the block it gathers some information such as the tag and the value of the attribute.

It is at this point that I need to determine whether the attribute reference currently in focus for the current block reference has a field in its value.

 

So I'm already drilled down into a specific block reference and specific attribute reference in that block reference.  This is where I need to ask about a field, not at the block reference or higher at the block name level.

 

I might be getting turned around as to what is a database object and what is not.  I would expect an attribute in a block to be a database object, but maybe not. 

 

I'm attaching a jpg of the relevant portion of the code I'm using because the formatting is visible (as opposed to pasting the code here).  Maybe that's helpful. 

 

I'm so close.  I have the attribute in hand and I just need to ask it if it contains a field. 

 

If I'm not being clear with my inquiry, my apologies.  I'm doing the best I can 🙂

 

Erik

0 Likes
Message 8 of 13

Alexander.Rivilis
Mentor
Mentor

1. Do not post jpg-file of code but post full code.

2. There is no AttRef class in AutoCAD .NET API. What is a AttRef class?

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 9 of 13

Anonymous
Not applicable

Sorry, I'll paste the code in below. 

 

Regarding the AttRef, it is defined in a Structure contained in the code.  The GetAttributes() function uses the AttRef. 

 

Like a lot of folks, I'm working with code which is pieced together from other apps, gathered from Google searches, with help provided by experts and all done over time by multiple users.  I'm trying to update it's function by having it NOT update attribute values IF the attribute value already contains a field.  If the attribute value contains just text, it updates, but it should leave fields alone.  So, that's my task and what I'm working with.

 

Here's the code.  I don't know how to paste it into this reply in its own box which preserves its formatting etc.  So here goes:

I'm not pasting in the code from the form.  All it does is prompt the user to browse to and select a drawing for all of this to work on.

 

 

Public Sub CEID()

Dim myForm2 As New Form2

Application.ShowModalDialog(myForm2)

myForm2.Close()

Dim ReadPath As String

ReadPath = myForm2.OpenFileDialog2.FileName.ToString

 

If ReadPath = "OpenFileDialog1" Then

Exit Sub

End If

MsgBox("You chose:" & vbCr & ReadPath & vbCr & "I'll now update CEID attributes...")

Dim myDb As Database = HostApplicationServices.WorkingDatabase

Dim myEd As Editor = DocumentManager.MdiActiveDocument.Editor

Dim myDocument As Document = Application.DocumentManager.MdiActiveDocument

'For each block name in drawing

For Each myBlockName As String In GetTopLevelBlocks(myDb)

'For each instance of each block name in the drawing

For Each BRefID As ObjectId In GetBRefIDs(myDb, myBlockName)

Dim myEC As Integer = 0

Dim myECValue As String = ""

Dim myCEID As Integer = 0

Dim myCEIDValue As String = ""

Dim myField As Integer = 0

If Not myBlockName = "EB" And Not myBlockName = "_DATME" Then

Using myTrans As Transaction = myDocument.TransactionManager.StartTransaction

Dim retList As New List(Of AttRef)

retList = GetAttributes(BRefID)

'Only perform on tool blocks, based on layer assignment A-EQPM-FIXD-*

Dim ent As Entity = CType(myTrans.GetObject(BRefID, OpenMode.ForRead), Entity)

Dim myLayer As String = ent.Layer().ToString

If myLayer.Contains("A-EQPM-FIXD") Then

'See if it has attributes and if one of the attributes is ENTITY_CODE and another is CEID or CE!_CODE

'And collect the Entity Code value

For Each myAttRef As AttRef In GetAttributes(BRefID)

If myAttRef.attTag.ToString = "ENTITY_CODE" Then

myEC = 1

myECValue = myAttRef.attValue.ToString

End If

If myAttRef.attTag.ToString = "CEID" Or myAttRef.attTag.ToString = "CE!_CODE" Then

myCEID = 1

End If

'''''''''''''''''''''''''''''''''''''''''''

If myAttRef.HasField = False Then

'Update the attribute value

End If

'''''''''''''''''''''''''''''''''''

 

Next

'If the block has both an Entity Code and a FLEX attribute...

If myEC = 1 And myCEID = 1 Then

'Look for myECValue in the text file and gather the FLEX value

Dim myFSR As New IO.StreamReader(ReadPath)

Using dl As DocumentLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument()

While myFSR.EndOfStream = False

Dim txtLine As String = myFSR.ReadLine

Dim txtLineParts() As String = txtLine.Split(",")

If txtLineParts(0) = myECValue Then

System.Windows.Forms.Application.DoEvents()

myEd.WriteMessage(" Updating: " & myECValue & vbCrLf)

myCEIDValue = txtLineParts(1)

For Each myAttRefID In retList

Select Case myAttRefID.attTag.ToUpper

Case "CEID"

UpdateAttributeValue(BRefID, myAttRefID.attTag, myCEIDValue)

Case "CE!_CODE"

UpdateAttributeValue(BRefID, myAttRefID.attTag, myCEIDValue)

End Select

Next

End If

End While

End Using

End If

'If the block has an Entity Code but no FLEX attribute, flag it to the user...

If myEC = 1 And myCEID = 0 Then

MsgBox("This tool: " & myECValue & " has no CEID or CE!_CODE attribute.")

End If

End If

myTrans.Commit()

End Using

End If

Next

Next

'Announce completion

System.Windows.Forms.Application.DoEvents()

myEd.WriteMessage("Done!")

End Sub

Function GetTopLevelBlocks(ByVal DatabaseIn As Database) As List(Of String)

Dim myList As New List(Of String)

Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction

Dim myBT As BlockTable = DatabaseIn.BlockTableId.GetObject(OpenMode.ForRead)

For Each myBTRid As ObjectId In myBT

Dim myBTR As BlockTableRecord = myBTRid.GetObject(OpenMode.ForRead)

If myBTR.IsAnonymous = False And myBTR.IsLayout = False And _

myBTR.IsFromExternalReference = False And _

myBTR.IsDependent = False Then

myList.Add(myBTR.Name)

End If

Next

End Using

Return myList

End Function

Public Function GetBRefIDs(ByVal DatabaseIn As Database, ByVal BlockName As String) As ObjectIdCollection

Dim retOIDColl As New ObjectIdCollection

Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction

Dim myBT As BlockTable = DatabaseIn.BlockTableId.GetObject(OpenMode.ForRead)

If myBT.Has(BlockName) = False Then

Return Nothing

End If

Dim myBTR As BlockTableRecord = myBT(BlockName).GetObject(OpenMode.ForRead)

For Each myObjID As ObjectId In myBTR.GetBlockReferenceIds(True, True)

retOIDColl.Add(myObjID)

Next

Dim another As New ObjectIdCollection

For Each childID As ObjectId In myBTR.GetAnonymousBlockIds

Dim myChildBTR As BlockTableRecord = childID.GetObject(OpenMode.ForRead)

For Each myChildBRefID As ObjectId In myChildBTR.GetBlockReferenceIds(True, True)

retOIDColl.Add(myChildBRefID)

Next

Next

End Using

Return retOIDColl

End Function

Structure AttRef

Dim attTag As String

Dim attValue As String

Dim attHandle As String

End Structure

Function GetAttributes(ByVal BRefID As ObjectId) As List(Of AttRef)

Dim retList As New List(Of AttRef)

Using myTrans As Transaction = BRefID.Database.TransactionManager.StartTransaction

Dim myBRef As BlockReference = BRefID.GetObject(OpenMode.ForRead)

If myBRef.AttributeCollection Is Nothing Then

Return retList

Else

For Each myAttRefID As ObjectId In myBRef.AttributeCollection

Dim myAttRef As AttributeReference = myAttRefID.GetObject(OpenMode.ForRead)

Dim myRetAttRef As New AttRef

myRetAttRef.attTag = myAttRef.Tag

myRetAttRef.attValue = myAttRef.TextString

myRetAttRef.attHandle = myAttRef.Handle.ToString

retList.Add(myRetAttRef)

Next

End If

End Using

Return retList

End Function

 

Sub UpdateAttributeValue(ByVal BlockID As ObjectId, ByVal AttributeTag As String, _

ByVal AttributeValue As String)

Using myTrans As Transaction = BlockID.Database.TransactionManager.StartTransaction

Dim myBRef As BlockReference = BlockID.GetObject(OpenMode.ForRead)

Dim myAttCollection As AttributeCollection = myBRef.AttributeCollection

For Each myAttRefID As ObjectId In myAttCollection

Dim myAttRef As AttributeReference = myAttRefID.GetObject(OpenMode.ForWrite)

If myAttRef.Tag.Equals(AttributeTag, StringComparison.OrdinalIgnoreCase) = True Then

myAttRef.TextString = AttributeValue

Exit For

End If

Next

myTrans.Commit()

End Using

End Sub

0 Likes
Message 10 of 13

Alexander.Rivilis
Mentor
Mentor

@Anonymous wrote:
....

- For each attribute in the block it gathers some information such as the tag and the value of the attribute.


Exactly at this point in yours function GetAttributes you have gather also information about fields in attribute using HasFields property of AttributeReference. Your have to add new member to yours class AttRef with this information.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 11 of 13

Alexander.Rivilis
Mentor
Mentor
Accepted solution

Changed code:

 

 

 

 

Public Sub CEID()
  Dim myForm2 As New Form2
  Application.ShowModalDialog(myForm2)
  myForm2.Close()
  Dim ReadPath As String
  ReadPath = myForm2.OpenFileDialog2.FileName.ToString
  If ReadPath = "OpenFileDialog1" Then
    Exit Sub
  End If

  MsgBox("You chose:" & vbCr & ReadPath & vbCr & "I'll now update CEID attributes...")

  Dim myDb As Database = HostApplicationServices.WorkingDatabase
  Dim myEd As Editor = DocumentManager.MdiActiveDocument.Editor
  Dim myDocument As Document = Application.DocumentManager.MdiActiveDocument
  'For each block name in drawing
  For Each myBlockName As String In GetTopLevelBlocks(myDb)
    'For each instance of each block name in the drawing
    For Each BRefID As ObjectId In GetBRefIDs(myDb, myBlockName)
      Dim myEC As Integer = 0
      Dim myECValue As String = ""
      Dim myCEID As Integer = 0
      Dim myCEIDValue As String = ""
      Dim myField As Integer = 0
      If Not myBlockName = "EB" And Not myBlockName = "_DATME" Then
        Using myTrans As Transaction = myDocument.TransactionManager.StartTransaction
          Dim retList As New List(Of AttRef)
          retList = GetAttributes(BRefID)
          'Only perform on tool blocks, based on layer assignment A-EQPM-FIXD-*
          Dim ent As Entity = CType(myTrans.GetObject(BRefID, OpenMode.ForRead), Entity)
          Dim myLayer As String = ent.Layer().ToString
          If myLayer.Contains("A-EQPM-FIXD") Then
            'See if it has attributes and if one of the attributes is ENTITY_CODE and another is CEID or CE!_CODE
            'And collect the Entity Code value
            For Each myAttRef As AttRef In retList ' GetAttributes(BRefID)
              If myAttRef.attTag.ToString = "ENTITY_CODE" Then
                myEC = 1
                myECValue = myAttRef.attValue.ToString
              End If
              If myAttRef.attTag.ToString = "CEID" Or myAttRef.attTag.ToString = "CE!_CODE" Then
                myCEID = 1
              End If

              '''''''''''''''''''''''''''''''''''''''''''

              If myAttRef.HasFields = False Then '<------- Changed by Alexander Rivilis
                'Update the attribute value
              End If

              '''''''''''''''''''''''''''''''''''
            Next

            'If the block has both an Entity Code and a FLEX attribute...

            If myEC = 1 And myCEID = 1 Then

              'Look for myECValue in the text file and gather the FLEX value

              Dim myFSR As New IO.StreamReader(ReadPath)

              Using dl As DocumentLock = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.LockDocument()

                While myFSR.EndOfStream = False

                  Dim txtLine As String = myFSR.ReadLine

                  Dim txtLineParts() As String = txtLine.Split(",")

                  If txtLineParts(0) = myECValue Then

                    System.Windows.Forms.Application.DoEvents()

                    myEd.WriteMessage(" Updating: " & myECValue & vbCrLf)

                    myCEIDValue = txtLineParts(1)

                    For Each myAttRefID In retList

                      Select Case myAttRefID.attTag.ToUpper

                        Case "CEID"

                          UpdateAttributeValue(BRefID, myAttRefID.attTag, myCEIDValue)

                        Case "CE!_CODE"

                          UpdateAttributeValue(BRefID, myAttRefID.attTag, myCEIDValue)

                      End Select

                    Next

                  End If

                End While

              End Using

            End If

            'If the block has an Entity Code but no FLEX attribute, flag it to the user...

            If myEC = 1 And myCEID = 0 Then

              MsgBox("This tool: " & myECValue & " has no CEID or CE!_CODE attribute.")

            End If

          End If

          myTrans.Commit()

        End Using

      End If

    Next

  Next

  'Announce completion

  System.Windows.Forms.Application.DoEvents()

  myEd.WriteMessage("Done!")

End Sub

Function GetTopLevelBlocks(ByVal DatabaseIn As Database) As List(Of String)

  Dim myList As New List(Of String)

  Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction

    Dim myBT As BlockTable = DatabaseIn.BlockTableId.GetObject(OpenMode.ForRead)

    For Each myBTRid As ObjectId In myBT

      Dim myBTR As BlockTableRecord = myBTRid.GetObject(OpenMode.ForRead)

      If myBTR.IsAnonymous = False And myBTR.IsLayout = False And _
      myBTR.IsFromExternalReference = False And _
      myBTR.IsDependent = False Then

        myList.Add(myBTR.Name)

      End If

    Next

  End Using

  Return myList

End Function

Public Function GetBRefIDs(ByVal DatabaseIn As Database, ByVal BlockName As String) As ObjectIdCollection

  Dim retOIDColl As New ObjectIdCollection

  Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction

    Dim myBT As BlockTable = DatabaseIn.BlockTableId.GetObject(OpenMode.ForRead)

    If myBT.Has(BlockName) = False Then

      Return Nothing

    End If

    Dim myBTR As BlockTableRecord = myBT(BlockName).GetObject(OpenMode.ForRead)

    For Each myObjID As ObjectId In myBTR.GetBlockReferenceIds(True, True)

      retOIDColl.Add(myObjID)

    Next

    Dim another As New ObjectIdCollection

    For Each childID As ObjectId In myBTR.GetAnonymousBlockIds

      Dim myChildBTR As BlockTableRecord = childID.GetObject(OpenMode.ForRead)

      For Each myChildBRefID As ObjectId In myChildBTR.GetBlockReferenceIds(True, True)

        retOIDColl.Add(myChildBRefID)

      Next

    Next

  End Using

  Return retOIDColl

End Function

Structure AttRef
  Dim attTag As String
  Dim attValue As String
  Dim attHandle As String
  Dim HasFields As Boolean '<------- Added by Alexander Rivilis
End Structure

Function GetAttributes(ByVal BRefID As ObjectId) As List(Of AttRef)
  Dim retList As New List(Of AttRef)
  Using myTrans As Transaction = BRefID.Database.TransactionManager.StartTransaction
    Dim myBRef As BlockReference = BRefID.GetObject(OpenMode.ForRead)
    If myBRef.AttributeCollection Is Nothing Then
      myTrans.Commit()
      Return retList
    Else
      For Each myAttRefID As ObjectId In myBRef.AttributeCollection
        Dim myAttRef As AttributeReference = myAttRefID.GetObject(OpenMode.ForRead)
        Dim myRetAttRef As New AttRef
        myRetAttRef.attTag = myAttRef.Tag
        myRetAttRef.attValue = myAttRef.TextString
        myRetAttRef.attHandle = myAttRef.Handle.ToString
        myRetAttRef.HasFields = myAttRef.HasFields '<------- Added by Alexander Rivilis
        retList.Add(myRetAttRef)
      Next
    End If
  myTrans.Commit() End Using Return retList End Function Sub UpdateAttributeValue(ByVal BlockID As ObjectId, ByVal AttributeTag As String, ByVal AttributeValue As String) Using myTrans As Transaction = BlockID.Database.TransactionManager.StartTransaction Dim myBRef As BlockReference = BlockID.GetObject(OpenMode.ForRead) Dim myAttCollection As AttributeCollection = myBRef.AttributeCollection For Each myAttRefID As ObjectId In myAttCollection Dim myAttRef As AttributeReference = myAttRefID.GetObject(OpenMode.ForWrite) If myAttRef.Tag.Equals(AttributeTag, StringComparison.OrdinalIgnoreCase) = True Then myAttRef.TextString = AttributeValue Exit For End If Next myTrans.Commit() End Using End Sub

 

P.S.: For inserting code in post use this button:

 

 2016-09-24_1-12-29.png

 

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 12 of 13

Anonymous
Not applicable

This looks so promising!  I need to leave for the weekend, but I'll implement Monday and can't wait to see if I can make it work.

Thank you so much.  Have a great weekend.

 

Erik

 

0 Likes
Message 13 of 13

Anonymous
Not applicable

This worked perfectly.  What you essentially pointed out to me is that I need to define and ask for the HasFields property back in the Structure and GetAttributes function.  I wish I'd thought of that, and it seems so obvious now that you led me in that direction. 

Thank you for taking the time to work with me on this.  I'm learning from you experts every time I embark on a coding project. 

 

With gratitude,

 

Erik

0 Likes