• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Active Contributor
    Posts: 33
    Registered: ‎11-06-2012
    Accepted Solution

    search and work with atribute block in current space

    142 Views, 2 Replies
    12-04-2012 05:08 PM

    Hi everybody,

    I want to search and replace value of block reference in layout1. But I do not want to replace that block in layout2 or layout3. Please tell me how can I do?

    Thanks,

    Please use plain text.
    Distinguished Contributor
    khoa.ho
    Posts: 131
    Registered: ‎09-15-2011

    Re: search and work with atribute block in current space

    12-04-2012 05:42 PM in reply to: xdbk07

    Hi,

    If you have a layout name (Layout1, Layout2…), you can get its block table record of this layout. Then search for all block references in this block table record. For each block reference, loop through each attribute reference in the attribute collection (use BlockReference.AttributeCollection), compare its attribute TextString with the search value. If it is equal, change it with the replace value.

    The following method will get the block table record ObjectId of a given layout name:

    public static ObjectId GetSpaceId(Database db, string layoutName)
    {
        using (Transaction trans = db.TransactionManager.StartTransaction())
        {
            var layoutDict = (DBDictionary)trans.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
            ObjectId layoutId = layoutDict.GetAt(layoutName);
            var layout = (Layout)trans.GetObject(layoutId, OpenMode.ForRead);
            return layout.BlockTableRecordId;
        }
    }

     

    -Khoa

    Please use plain text.
    Distinguished Contributor
    khoa.ho
    Posts: 131
    Registered: ‎09-15-2011

    Re: search and work with atribute block in current space

    12-04-2012 10:46 PM in reply to: xdbk07

    Here is the final working code (in C#). Use DeveloperFusion to convert to VB.NET. This code will find and replace only attributes of block references in a given layout name. If you don't specify layout name (empty string), it will find and replace block attribute values in the whole drawing database.

     

    [CommandMethod("FindReplaceAttributeValues")]
    public static void FindReplaceAttributeValues()
    {
        Document document = Application.DocumentManager.MdiActiveDocument;
        Database db = document.Database;
        Editor editor = document.Editor;
        
        editor.WriteMessage("Replace all found block attribute values.\n");
        PromptResult findResult = editor.GetString("Find text: ");
        PromptResult replaceResult = editor.GetString("Replace text: ");
        string findText = findResult.StringResult;
        string replaceText = replaceResult.StringResult;
        
        string layoutName = "Layout1"; // Target layout name to find block attributes
    
        FindReplaceAttributeValues(db, findText, replaceText, layoutName);
    }
    
    public static int FindReplaceAttributeValues(Database db, string findText, string replaceText, string layoutName = "")
    {
        int count = 0;
        if (string.IsNullOrEmpty(findText))
            return count;
        if (replaceText == null)
            replaceText = string.Empty;
        using (Transaction trans = db.TransactionManager.StartTransaction())
        {
            var blockTable = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
            foreach (ObjectId objectId in blockTable)
            {
                var btr = (BlockTableRecord)trans.GetObject(objectId, OpenMode.ForRead);
                if (btr.Name.StartsWith("*"))    // Search for Model and Paper spaces
                {
                    if (layoutName != "")
                    {
                        // Check layout for each block table record
                        if (btr.IsLayout)
                        {
                            var layout = (Layout)trans.GetObject(btr.LayoutId, OpenMode.ForRead);
                            if (!layout.LayoutName.Equals(layoutName, StringComparison.OrdinalIgnoreCase))
                                continue;    // skip the current loop, move to the next block table record
                        }
                    }
                    foreach (ObjectId id in btr)
                    {
                        var entity = trans.GetObject(id, OpenMode.ForRead);
                        if (entity is BlockReference)
                        {
                            var blockRef = (BlockReference)entity;
                            AttributeCollection attributeCollection = blockRef.AttributeCollection;
                            foreach (ObjectId attributeId in attributeCollection)
                            {
                                var attRef = (AttributeReference)trans.GetObject(attributeId, OpenMode.ForRead);
                                if (attRef.TextString.Equals(findText, StringComparison.OrdinalIgnoreCase))
                                {
                                    attRef.UpgradeOpen();
                                    attRef.TextString = replaceText;
                                    attRef.AdjustAlignment(HostApplicationServices.WorkingDatabase);
                                    attRef.DowngradeOpen();
                                    count++;
                                }
                            }
                        }
                    }
                }
            }
            trans.Commit();
        }
        return count;
    }

     

    -Khoa

     

    Please use plain text.