Set attribute value for windowed objects

I want to execute a command where I can do a crossing window and set (all included) attribute with tag BET1 to a defined value like ABCD, without further dialog.

Like:

Command
crossing window
enter

or crossing window
command

Howto, easiest?

Comments

  • You can do this via code. Maybe someone can translate this to Lisp

    import traceback
    from pyrx_imp import Ap, Db, Ed, Ge, Gi, Gs, Rx
    
    print("added command = changeatt")
    
    def PyRxCmd_changeatt():
        try:
            filter = [(Db.DxfCode.kDxfStart, "INSERT")]
            ps, ss = Ed.Editor.select(filter)
            refs = [Db.BlockReference(id) for id in ss.objectIds()]
            atts = [Db.AttributeReference(id) for ref in refs for id in ref.attributeIds()]
            for att in atts:
                if att.tag() == "BOXTYPE":
                    att.upgradeOpen()
                    att.setTextString("WOOHOO YES!")
        except Exception as err:
            traceback.print_exception(err)
    
    

  • Yep lisp exists, ok a question or 2, my way is a global function, select the attribute in a single block this returns Tagname & Blockname via code, so then ssget the blocks and change the correct attributes. Is this ok only one block name, if yes will post code done many times.

  • Mikael63
    edited November 5

    Name of block is always EPCBG1F0
    Tag is always BET1
    Value is always -XDA001
    Value is sometime hidden (other attribute in block is visible)

    New value -XDA002

    I need to mark those I want to change, some others need to be unchanged.

    The idea is to do this without filling forms, like in Find and Replace.

  • Sorry another question is it just add 1 to last number ? This can be done.

  • Well, this is what I need just now but for a more common usage, I think edit value in LISP is better.

    This is "one time job", but for many drawings.

  • Can you post a dwg please. Need to look at where block EPCBG1F0 is located Model, layouts etc or restrict changes some how. This may be a problem with multiple dwgs.

  • If you can figure out how to install python

    Here’s a sample sledge hammer approach, that will change every attribute in a folder of .DWGs

    https://github.com/CEXT-Dan/PyRx

    import traceback
    from pyrx_imp import Rx, Ge, Gs, Gi, Db, Ap, Ed
    
    import wx
    import os, pathlib
    
    def changeit(db : Db.Database, tagValue, textValue):
        ids = db.objectIds(Db.AttributeReference.desc())
        for att in [Db.AttributeReference(id) for id in ids]:
            if att.tag() == tagValue:
                att.upgradeOpen()
                att.setTextString(textValue)
    
    def openSideDrawing(path, tagValue,textValue):
        print("\nProcessing {} ".format(path))
        db = Db.Database(False, True)
        db.readDwgFile(path)
        db.closeInput(True)
        changeit(db,tagValue,textValue)
        db.saveAs(path)
                
    def PyRxCmd_doit():
        try:
            tagName = 'FGUIDE'
            textValue = 'WOOHOO YES!'
            dwgext = ".dwg".casefold()
    
            dlg = wx.DirDialog(None, "Choose input directory","",
                    wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST)
        
            if dlg.ShowModal() != wx.ID_OK:
                print("You Cancelled The Dialog!")
                return
    
            for fname in next(os.walk(dlg.GetPath()), (None, None, []))[2]:
                ext = pathlib.Path(fname).suffix.casefold()
                if ext != dwgext:
                    continue
                fpath = '{}\\{}'.format(dlg.GetPath(),fname)
                openSideDrawing(fpath, tagName,textValue)
            print("yay")
        except Exception as err:
            traceback.print_exception(err)
    

  • It is one dwg with many layer/sheets.

    I need (must) do the selection of objects, for each sheet, my self!

  • You don't need necessarily need a program to do this.

    You could select the blocks, then simply modify the attribute value from the Properties panel.

    Alternatively, you could use the FIND command to find and replace attribute values from selected blocks.

  • Jason Bourhill
    edited November 8

    Option to update the tag using LISP

    (defun C:BET1-update ( / sset newval tag oBlock att) 
     (princ "\nSelect blocks with attributes: ") ; prompt user
      (setq sset (ssget '((0 . "INSERT")(66 . 1)))) ; allow selection of only blocks with attributes
    (cond
    (sset ;If a selection has been created
    (if (not BET1val) (setq BET1val "-XDA002")) ; set default value
    (setq newval (getstring (strcat "\nNew value for BET1 <" BET1val ">: "))) ; prompt for new value
    (if (/= newval "") (setq BET1val newval)) ; save the new value if provided
    (setq tag "BET1") ; Attribute tag we want to update
    ; foreach block in our selection set
    (foreach oBlock (mapcar 'vlax-ename->vla-object (vle-selectionset->list sset))
    (foreach att (vlax-invoke oBlock 'getattributes) ; iterate through each of the blocks attributes
    (setq tagnm (strcase (vla-get-tagstring att))) ; retrieve the attributes tag name
    (cond
    ((= tagnm (strcase tag)) ;If the tag name matches the one we are looking for
    (vla-put-TextString att BET1val); update the tag with the new value
    )
    )
    )
    )
    )
    )
    (prin1)
    )

  • Yes, but that invokes more mouse clicks and keyboard usage.
    (I already do like that)

  • Thanks.

    Something is missing. I got a prompt saying "Select blocks with attributes:" but I got no chance to do that until the script stops.

  • I think the forum has mucked up the formatting. Try the attached

  • Big Thanks!
    Works even better than expected!