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