pythonautocadbricscadzwcad

pyautocad loop through attributes


I have many blocks which have attributes. I'm trying to search through attributes in WEE specific value and when I find it, I would like to change the NDT to some value.

Name Att Value Att
WEE A011
NDT (Null)
for Atributi in acad.ActiveDocument.ModelSpace:
    name = Atributi.EntityName
    if name == 'AcDbBlockReference':
        isciAtribute = Atributi.HasAttributes
        if isciAtribute and Atributi.Name == blokZvar:
#            print(Atributi.Name) 
           
            for att in Atributi.GetAttributes():
                 if att.TagString == 'WEE' and att.TextString == 'A011':
                     storedID = att.ObjectID
            for atb in Atributi.GetAttributes():
                 if atb.ObjectID == storedID:
                     atb.TagString == 'NDT'
                     atb.TextString = '*'
                     atb.Update()
#                         print(" {}: {}".format(atb.TagString, atb.TextString))

I'm trying a new way to get to the result via ObjectID of the finded block, but now I got error name 'storedID' is not defined

Please advise how to solve this issue.

I have tried to change value in WEE and have succeed there but I just can't change another attribute value inside the same block, based on the previous value.


Solution

  • The issue lies here:

                for att in Atributi.GetAttributes():
                     if att.TagString == 'WEE' and att.TextString == 'A011':
                         if att.TagString == 'NDT':
    

    Consider that att.TagString cannnot be equal to both WEE and NDT at the same time, and so the test expression for the second if statement can never be validated, since, for it to be reached att.TagString has to be equal to WEE.

    Instead, one possible solution would be to iterate over the set of attributes and use two separate if statements (or rather, an if elif):

    1. if att.TagString == 'WEE' and att.TextString == 'A011' then set a boolean 'flag' variable to true, so that we know later on that the condition has been met.

    2. else if att.TagString == 'NDT' then set assign the attribute reference object to a separate variable, so that we can operate on it outside of the loop.

    Since we cannot rely on the order in which the attribute references will be encountered within the loop, we cannot exit the loop if only one of these conditions is met, and so they must be evaluated separately.

    Then, outside of the loop, you can test the flag variable, and if true, modify the value of the attribute assigned by the second if statement.

    For example:

    for Atributi in acad.ActiveDocument.ModelSpace:
        name = Atributi.EntityName
        if name == 'AcDbBlockReference':
            if Atributi.HasAttributes and Atributi.Name == blokZvar:
                flg = False
                for att in Atributi.GetAttributes():
                     if att.TagString == 'WEE' and att.TextString == 'A011':
                        flg = True
                     elif att.TagString == 'NDT':
                        atb = att
                if flg and atb:
                    atb.TextString = '*'
                    atb.Update()