Phantom Block References

Phantom Block References

Anonymous
Not applicable
1,657 Views
12 Replies
Message 1 of 13

Phantom Block References

Anonymous
Not applicable

I have a routine that counts blocks and rights the results to a dialog box display. The odd part is that the routine counts block quantities that don't seem to exist in some cases. If I purge the drawing file prior to running the command, I get the correct counts, but if I don't purge I get extra quantities. At first I thought that it was some persistent record in the document database holding onto deleted entities. However I've tested each block reference for ".IsErased" before counting the reference but that doesn't seem to flag. Any suggestions on what might be going on? 

 

Thanks!

Michael Coffman

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

_gile
Consultant
Consultant

Hi,

 

Without seeing any code or example of drawing, it is impossible to do anything but hazardous speculation.
In order for us to help you, please post a code snippet showing how you count the blocks and an example drawing that causes the phenomenon you describe.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 13

Anonymous
Not applicable

Here's the code for the routine along with a sample drawing exhibiting this behavior. Specifically it's the FA_Speaker block. That block should have a count of 60 (confirmed with Select Similar and QSelect manual methods) but it's displaying a count of 68. After a purge the routine correctly counts 60. There are a handful of custom object classes referenced so you probably won't be able to run this code but hopefully it's enough to get an idea what's going on. Also, any recommendations on ways to improve the efficiency are appreciated. Thanks!

 

 

   Public Sub DeviceCount()
        Dim doc As Document = App.DocumentManager.MdiActiveDocument
        Dim strCurDir As String = Path.GetDirectoryName(doc.Name)
        Dim myOFD As New Win.OpenFileDialog
        With myOFD
            .Filter = "dwg files (*.dwg)|*.dwg|All files (*.*)|*.*"
            .FilterIndex = 1
            .InitialDirectory = strCurDir
            .Multiselect = True
            .Title = "Select .dwg Files to Query"
        End With

        If myOFD.ShowDialog = System.Windows.Forms.DialogResult.OK Then

            Dim lstDwgs As New List(Of DWGData)
            Dim lstBlockDataTotal As New List(Of BlockData)
            Dim blnAttCycle As Boolean = False

            For Each myFileName As String In myOFD.FileNames
                Dim myDwgData As New DWGData
                Dim lstBlockData As New List(Of BlockData)

                myDwgData.DwgName = myFileName

                Using myDB As New Database(False, True)
                    myDB.ReadDwgFile(myFileName, FileOpenMode.OpenForReadAndAllShare, True, "")
                    Using mytrans As Transaction = myDB.TransactionManager.StartTransaction
                        For Each myBlockName As String In GetTopLevelBlocks(myDB)
                            Dim blnBlockFound As Boolean = False
                            Dim blnTotalBlockFound As Boolean = False
                            For Each BRefID As ObjectId In GetBRefIDs(myDB, myBlockName)
                                Dim myBRef As BlockReference = BRefID.GetObject(DatabaseServices.OpenMode.ForWrite, False, True)
                                'Is the block on a layer that is useful to count.
                                If Left(myBRef.Layer.ToString, 2) = "F-" OrElse Left(myBRef.Layer.ToString, 2) = "FA-" And Left(myBRef.Layer.ToString, 6) <> "F-ANNO" OrElse Left(myBRef.Layer.ToString, 2) = "E-" Then

                                    'Evaluate block quantities at the individual file level.
                                    For Each myBlkData As BlockData In lstBlockData
                                        If myBlkData.BlockName = myBlockName Then
                                            myBlkData.BlockCount += 1
                                            Dim lstBlkAttributes As New List(Of AttData)
                                            lstBlkAttributes = myBlkData.AttributeList
                                            For Each myAtt As AttRef In GetAttributes(myDB, BRefID)
                                                Dim blnAttFound As Boolean = False
                                                For Each BlkAtt In lstBlkAttributes
                                                    If myAtt.attTag = BlkAtt.Tag AndAlso myAtt.attValue = BlkAtt.Value Then
                                                        BlkAtt.Count += 1
                                                        blnAttFound = True
                                                    End If
                                                Next
                                                If blnAttFound = False Then
                                                    Dim myAttData1 As New AttData
                                                    myAttData1.Tag = myAtt.attTag
                                                    myAttData1.Value = myAtt.attValue
                                                    myAttData1.Count = 1
                                                    lstBlkAttributes.Add(myAttData1)
                                                End If
                                            Next
                                            'Use dynamic sort for attributes
                                            Dim strSortList As String = "Tag, Value, Count"
                                            Dim AttCompare As DynamicComparer(Of AttData) = New DynamicComparer(Of AttData)(strSortList)
                                            lstBlkAttributes.Sort(AttCompare)
                                            ''lstBlkAttributes.Sort(AddressOf sortAttribute)
                                            myBlkData.AttributeList = lstBlkAttributes
                                            blnBlockFound = True
                                            Exit For
                                        End If
                                    Next

                                    'Evaluate block quantities for all files selected.
                                    For Each myBlkDataTotal As BlockData In lstBlockDataTotal
                                        If myBlkDataTotal.BlockName = myBlockName Then
                                            myBlkDataTotal.BlockCount += 1
                                            Dim lstBlkAttributeTotals As New List(Of AttData)
                                            lstBlkAttributeTotals = myBlkDataTotal.AttributeList
                                            For Each myAtt2 As AttRef In GetAttributes(myDB, BRefID)
                                                Dim blnAttFound2 As Boolean = False
                                                For Each BlkAtt2 As AttData In lstBlkAttributeTotals
                                                    If myAtt2.attTag = BlkAtt2.Tag AndAlso myAtt2.attValue = BlkAtt2.Value Then
                                                        BlkAtt2.Count += 1
                                                        blnAttFound2 = True
                                                    End If
                                                Next
                                                If blnAttFound2 = False Then
                                                    Dim myAttData2 As New AttData
                                                    myAttData2.Tag = myAtt2.attTag
                                                    myAttData2.Value = myAtt2.attValue
                                                    myAttData2.Count = 1
                                                    lstBlkAttributeTotals.Add(myAttData2)
                                                End If
                                            Next
                                            'Use dynamic sort for attributes
                                            Dim strSortList As String = "Tag, Value, Count"
                                            Dim AttCompare As DynamicComparer(Of AttData) = New DynamicComparer(Of AttData)(strSortList)
                                            lstBlkAttributeTotals.Sort(AttCompare)
                                            ''lstBlkAttributeTotals.Sort(AddressOf sortAttribute)
                                            myBlkDataTotal.AttributeList = lstBlkAttributeTotals
                                            blnTotalBlockFound = True
                                            Exit For
                                        End If
                                    Next

                                    If blnBlockFound = False Then
                                        Dim BlkData As New BlockData
                                        BlkData.BlockName = myBlockName
                                        BlkData.BlockCount = 1
                                        'Retrieve block attributes
                                        Dim lstAttributes As New List(Of AttData)
                                        For Each myAtt As AttRef In GetAttributes(myDB, BRefID)
                                            Dim blnAttFound As Boolean = False
                                            For Each BlkAtt As AttData In lstAttributes
                                                If myAtt.attTag = BlkAtt.Tag AndAlso myAtt.attValue = BlkAtt.Value Then
                                                    BlkAtt.Count += 1
                                                    blnAttFound = True
                                                End If
                                            Next
                                            If blnAttFound = False Then
                                                Dim myAttData2 As New AttData
                                                myAttData2.Tag = myAtt.attTag
                                                myAttData2.Value = myAtt.attValue
                                                myAttData2.Count = 1
                                                lstAttributes.Add(myAttData2)
                                            End If
                                        Next
                                        'Use dynamic sort for attributes
                                        Dim strSortList As String = "Tag, Value, Count"
                                        Dim AttCompare As DynamicComparer(Of AttData) = New DynamicComparer(Of AttData)(strSortList)
                                        lstAttributes.Sort(AttCompare)
                                        ''lstAttributes.Sort(AddressOf sortAttribute)
                                        BlkData.AttributeList = lstAttributes

                                        lstBlockData.Add(BlkData)
                                    End If

                                    If blnTotalBlockFound = False Then
                                        Dim BlkData2 As New BlockData
                                        BlkData2.BlockName = myBlockName
                                        BlkData2.BlockCount = 1
                                        'Retrieve block attributes
                                        Dim lstAttributes2 As New List(Of AttData)
                                        For Each myAtt2 As AttRef In GetAttributes(myDB, BRefID)
                                            Dim blnAttFound2 As Boolean = False
                                            For Each BlkAtt2 As AttData In lstAttributes2
                                                If myAtt2.attTag = BlkAtt2.Tag AndAlso myAtt2.attValue = BlkAtt2.Value Then
                                                    BlkAtt2.Count += 1
                                                    blnAttFound2 = True
                                                End If
                                            Next
                                            If blnAttFound2 = False Then
                                                Dim myAttData2 As New AttData
                                                myAttData2.Tag = myAtt2.attTag
                                                myAttData2.Value = myAtt2.attValue
                                                myAttData2.Count = 1
                                                lstAttributes2.Add(myAttData2)
                                            End If
                                        Next
                                        'Use dynamic sort for attributes
                                        Dim strSortList As String = "Tag, Value, Count"
                                        Dim AttCompare As DynamicComparer(Of AttData) = New DynamicComparer(Of AttData)(strSortList)
                                        lstAttributes2.Sort(AttCompare)
                                        ''lstAttributes2.Sort(AddressOf sortAttribute)
                                        BlkData2.AttributeList = lstAttributes2
                                        lstBlockDataTotal.Add(BlkData2)
                                    End If

                                End If
                            Next
                        Next
                        mytrans.Commit()
                    End Using
                End Using
                lstBlockData.Sort(AddressOf sortBlock)
                myDwgData.BlockList = lstBlockData
                lstDwgs.Add(myDwgData)
            Next

            'Add final "DWG" entry for total device summary.
            lstBlockDataTotal.Sort(AddressOf sortBlock)
            Dim myTotalDwgData As New DWGData
            myTotalDwgData.DwgName = "Total Device Counts"
            myTotalDwgData.BlockList = lstBlockDataTotal
            lstDwgs.Insert(0, myTotalDwgData)

            'XMLOutput(lstBlockData, lstFiles, Path.GetDirectoryName(lstFiles(0)))

            Dim frmDevCount As New frmDevCount(lstDwgs)
            App.ShowModelessDialog(frmDevCount)


        End If
    End Sub
    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(DatabaseServices.OpenMode.ForWrite)
            If myBT.Has(BlockName) = False Then
                Return Nothing
            End If
            Dim myBTR As BlockTableRecord = myBT(BlockName).GetObject(DatabaseServices.OpenMode.ForWrite)
            For Each myObjID As ObjectId In myBTR.GetBlockReferenceIds(True, True)
                If myObjID.IsEffectivelyErased = False Then
                    retOIDColl.Add(myObjID)
                End If
            Next
            Dim another As New ObjectIdCollection
            For Each childID As ObjectId In myBTR.GetAnonymousBlockIds
                Dim myChildBTR As BlockTableRecord = childID.GetObject(DatabaseServices.OpenMode.ForWrite)
                For Each myChildBRefID As ObjectId In myChildBTR.GetBlockReferenceIds(True, True)
                    retOIDColl.Add(myChildBRefID)
                Next
            Next
            myTrans.Commit()
        End Using
        Return retOIDColl
    End Function
0 Likes
Message 4 of 13

ActivistInvestor
Mentor
Mentor

Are you offering a price to the first one that correctly-guesses what the highlighted method does?

 

 

 For Each myBlockName As String In GetTopLevelBlocks(myDB)

 

If your code is coming up with a different answer before and after a purge, it means that your counting is flawed, It is most-likely because you are counting insertions of blocks contained in other blocks that are themselves, not inserted anywhere in the drawing.

 

 




@Anonymous wrote:

Here's the code for the routine along with a sample drawing exhibiting this behavior. Specifically it's the FA_Speaker block. That block should have a count of 60 (confirmed with Select Similar and QSelect manual methods) but it's displaying a count of 68. After a purge the routine correctly counts 60. There are a handful of custom object classes referenced so you probably won't be able to run this code but hopefully it's enough to get an idea what's going on. Also, any recommendations on ways to improve the efficiency are appreciated. Thanks!

 

 

Message 5 of 13

_gile
Consultant
Consultant

Hi,

 

You can easily avoid what describe @ActivistInvestor concerning nesting blocks by using a filtered selection set.

 

Here's a C# example (sorry, I don't use VB) to count inserted block references.

 

        [CommandMethod("BlockCount")]
        public void BlockCount()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var psr = ed.SelectAll(new SelectionFilter(new[] { new TypedValue(0, "INSERT") }));
            if (psr.Status != PromptStatus.OK)
                return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var count = psr.Value
                    .Cast<SelectedObject>()
                    .Select(so => (BlockReference)tr.GetObject(so.ObjectId, OpenMode.ForRead))
                    .GroupBy(br => ((BlockTableRecord)tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead)).Name)
                    .Select(g => new { Name = g.Key, Count = g.Count() });
                foreach (var item in count)
                {
                    ed.WriteMessage("\n{0}: {1}", item.Name, item.Count);
                }
                tr.Commit();
            }
        }

The output with your drawing:

 

KP3E: 1
ViewPortTitle: 2
NorthArrow: 2
ScaleBar: 2
X-FloorNotes: 2
X-Tblock: 2
SG_SheetBlock2013: 2
KP3W: 1
KEYNOTE: 27
ARROWHEAD: 6
FA_Speaker: 60
FA_IsolatorIDNet: 2
FA_AOM: 8
FA_Transponder: 1
FA_SmokeLED: 4
FA_ControlRelay: 12
FA_SmokeCO: 54
FA_Strobe: 5
FA_SpeakerStrobe: 15
FA_WSO: 1
FA_AIM: 13
FA_DamperFireSmoke: 6
FA_Smoke: 16
FA_DoorHolder: 3
LEVEL 04 FLOOR PLAN: 1


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 13

_gile
Consultant
Consultant

Oppss!..

 

Sorry I didn't attentively read you code. As you're using a side Database, you can't use a selection set.

Forgive my upper reply....



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 13

_gile
Consultant
Consultant

To avoid nested blocks, you can check if the block reference owner is a layout.

 

Here's a little C# example.

 

        [CommandMethod("CMD")]
        public void Cmd()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var ed = doc.Editor;

            var ofd = new System.Windows.Forms.OpenFileDialog()
            {
                Filter = "dwg files (*.dwg)|*.dwg",
                FilterIndex = 1,
                InitialDirectory = System.IO.Path.GetDirectoryName(doc.Name),
                Multiselect = true,
                Title = "Select .dwg Files to Query"
            };

            var result = ofd.ShowDialog();
            if (result != System.Windows.Forms.DialogResult.OK)
                return;
            foreach (string filename in ofd.FileNames)
            {
                ed.WriteMessage("\n\n" + filename);
                using (var db = new Database(false, true))
                {
                    db.ReadDwgFile(filename, FileOpenMode.OpenForReadAndAllShare, false, null);
                    using (var tr = db.TransactionManager.StartTransaction())
                    {
                        var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                        foreach (ObjectId btrId in bt)
                        {
                            var btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                            if (!(btr.IsAnonymous || btr.IsLayout || btr.IsDependent || btr.IsFromExternalReference || btr.IsFromOverlayReference))
                            {
                                int cnt = CountReferences(btr, tr);
                                if (cnt > 0)
                                    ed.WriteMessage("\n{0}: {1}", btr.Name, CountReferences(btr, tr));
                            }
                        }
                        tr.Commit();
                    }
                }
            }
        }

        private int CountReferences(BlockTableRecord btr, Transaction tr)
        {
            int cnt = CountReferencesInSpaces(btr, tr);
            if (btr.IsDynamicBlock)
                foreach (ObjectId btrId in btr.GetAnonymousBlockIds())
                {
                    var anonymousBtr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                    cnt += CountReferencesInSpaces(anonymousBtr, tr);
                }
            return cnt;
        }

        private int CountReferencesInSpaces(BlockTableRecord btr, Transaction tr)
        {
            int cnt = 0;
            foreach (ObjectId brId in btr.GetBlockReferenceIds(true, true))
            {
                var br = (BlockReference)tr.GetObject(brId, OpenMode.ForRead);
                var owner = (BlockTableRecord)tr.GetObject(br.OwnerId, OpenMode.ForRead);
                if (owner.IsLayout)
                    cnt++;
            }
            return cnt;
        }

Output with your file:

 

C:\Temp\SampleDrawing.dwg
SG_SheetBlock2013: 2
FA_SmokeCO: 54
FA_Speaker: 60
FA_AIM: 13
FA_DamperFireSmoke: 6
FA_ControlRelay: 12
FA_Smoke: 16
FA_SpeakerStrobe: 15
FA_Strobe: 5
FA_DoorHolder: 3
KEYNOTE: 27
KP3E: 1
FA_AOM: 8
ViewPortTitle: 2
ScaleBar: 2
NorthArrow: 2
KP3W: 1
FA_WSO: 1
FA_Transponder: 1
FA_SmokeLED: 4
ARROWHEAD: 6
FA_IsolatorIDNet: 2


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 8 of 13

_gile
Consultant
Consultant

Try to replace your GetBRefIds method with the following one.

 

C#

        public ObjectIdCollection GetBRefIDs(Database db, string blkName)
        {
            var ids = new ObjectIdCollection();
            using (var tr = db.TransactionManager.StartOpenCloseTransaction())
            {
                var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (!bt.Has(blkName))
                    return null;
                var btr = (BlockTableRecord)tr.GetObject(bt[blkName], OpenMode.ForRead);
                GetReferencesInSpaces(btr, tr, ids);
                if (btr.IsDynamicBlock)
                {
                    foreach (ObjectId btrId in btr.GetAnonymousBlockIds())
                    {
                        var anonymousBtr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
                        GetReferencesInSpaces(anonymousBtr, tr, ids);
                    }
                }
                tr.Commit();
            }
            return ids;
        }

        private void GetReferencesInSpaces(BlockTableRecord btr, Transaction tr, ObjectIdCollection ids)
        {
            foreach (ObjectId brId in btr.GetBlockReferenceIds(true, true))
            {
                var br = (BlockReference)tr.GetObject(brId, OpenMode.ForRead);
                var owner = (BlockTableRecord)tr.GetObject(br.OwnerId, OpenMode.ForRead);
                if (owner.IsLayout)
                    ids.Add(br.ObjectId);
            }
        }

VB (converted with telerik, not tested)

 

Public Function GetBRefIDs(ByVal db As Database, ByVal blkName As String) As ObjectIdCollection
    Dim ids = New ObjectIdCollection()
    Using tr = db.TransactionManager.StartOpenCloseTransaction()
        Dim bt = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
        If Not bt.Has(blkName) Then Return Nothing
        Dim btr = CType(tr.GetObject(bt(blkName), OpenMode.ForRead), BlockTableRecord)
        GetReferencesInSpaces(btr, tr, ids)
        If btr.IsDynamicBlock Then
            For Each btrId As ObjectId In btr.GetAnonymousBlockIds()
                Dim anonymousBtr = CType(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)
                GetReferencesInSpaces(anonymousBtr, tr, ids)
            Next
        End If

        tr.Commit()
    End Using

    Return ids
End Function

Private Sub GetReferencesInSpaces(ByVal btr As BlockTableRecord, ByVal tr As Transaction, ByVal ids As ObjectIdCollection)
    For Each brId As ObjectId In btr.GetBlockReferenceIds(True, True)
        Dim br = CType(tr.GetObject(brId, OpenMode.ForRead), BlockReference)
        Dim owner = CType(tr.GetObject(br.OwnerId, OpenMode.ForRead), BlockTableRecord)
        If owner.IsLayout Then ids.Add(br.ObjectId)
    Next
End Sub

'=======================================================
'Service provided by Telerik (www.telerik.com)
'Conversion powered by Refactoring Essentials.
'Twitter: @telerik
'Facebook: facebook.com/telerik
'=======================================================


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 9 of 13

Anonymous
Not applicable

GetTopLevelBlocks simply returns the names of the block definitions in the drawing file as a list of strings. It shouldn't have an impact on the issue at hand.

0 Likes
Message 10 of 13

ActivistInvestor
Mentor
Mentor
Accepted solution

@Anonymous wrote:

I have a routine that counts blocks and rights the results to a dialog box display. The odd part is that the routine counts block quantities that don't seem to exist in some cases. If I purge the drawing file prior to running the command, I get the correct counts, but if I don't purge I get extra quantities. At first I thought that it was some persistent record in the document database holding onto deleted entities. However I've tested each block reference for ".IsErased" before counting the reference but that doesn't seem to flag. Any suggestions on what might be going on? 

 

Thanks!

Michael Coffman


Your code is gathering block references that are nested within other blocks, which are not inserted into your drawing. Some of them are blocks that were created by COPY & PASTE or drag-and-drop, and they contain insertions of the blocks that your code is looking for.

 

Since the code is fairly complicated, a complete refactoring is probably in order, but that will require a lot of work on your part, and a lot of guidance as well.

 

So, the simplest way to solve the problem of the 'phantom' block reference is to modify your GetBRefIDs method to collect only block references in model space (because it's obvious that your code intends to deal only with blocks inserted into model space).

 

You also do not need to check IsEffectivelyErased because none of the blocks returned can be erased or have an erased owner.

 

Lastly, do not open objects for write if you do not intend to modify them.

 

This revised version will collect only blocks inserted directly into model space:

 

Public Function GetBRefIDs(ByVal DatabaseIn As Database, ByVal BlockName As String) As ObjectIdCollection
    Dim retOIDColl As ObjectIdCollection = New ObjectIdCollection()
    Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction()
        Dim myBT As BlockTable = CType(DatabaseIn.BlockTableId.GetObject(OpenMode.ForRead), BlockTable)
        If myBT.Has(BlockName) = False Then
            Return Nothing
        End If
        Dim modelSpace As ObjectId = SymbolUtilityServices.GetBlockModelSpaceId(DatabaseIn)
        Dim myBTR As BlockTableRecord = CType(myBT(BlockName).GetObject(OpenMode.ForRead), BlockTableRecord)
        For Each myObjID As ObjectId In myBTR.GetBlockReferenceIds(True, True)
            Dim blkref As BlockReference = CType(myTrans.GetObject(myObjID, OpenMode.ForRead), BlockReference)
            If blkref.BlockId = modelSpace Then 
                 retOIDColl.Add(myObjID)
            End If
        Next
        Dim another As ObjectIdCollection = New ObjectIdCollection()
        For Each childID As ObjectId In myBTR.GetAnonymousBlockIds()
            Dim myChildBTR As BlockTableRecord = CType(childID.GetObject(OpenMode.ForRead), BlockTableRecord)
            For Each myChildBRefID As ObjectId In myChildBTR.GetBlockReferenceIds(True, True)
                Dim blkref2 As BlockReference = CType(myTrans.GetObject(myChildBRefID, OpenMode.ForRead), BlockReference)
                If blkref2.BlockId = modelSpace Then 
                    retOIDColl.Add(myChildBRefID)
                End If
            Next
        Next

        myTrans.Commit()
    End Using

    Return retOIDColl
End Function
0 Likes
Message 11 of 13

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

GetTopLevelBlocks simply returns the names of the block definitions in the drawing file as a list of strings. It shouldn't have an impact on the issue at hand.


If we don't know what it does, then it does have an impact on the ability to diagnose the issue at hand.

 

 

0 Likes
Message 12 of 13

Anonymous
Not applicable

Thanks for the help! The overall project this is a part of is the culmination of about 10 years of efforts, during which I've learned a lot. There's much I would do differently now. Pretty much all of my code could be refactored into something much more efficient based on the lessons learned over the years, and I'm still learning (obviously). As for the openmode.forwrite, I'm aware that's not ideal for AutoCAD. However this code is also recompiled for use with another application (BricsCAD) that seems to require ForWrite to function correctly. Until I can figure out an alternative solution for that platform, ForWrite is a necessary evil at the moment. 

0 Likes
Message 13 of 13

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

Thanks for the help! The overall project this is a part of is the culmination of about 10 years of efforts, during which I've learned a lot. There's much I would do differently now. Pretty much all of my code could be refactored into something much more efficient based on the lessons learned over the years, and I'm still learning (obviously). As for the openmode.forwrite, I'm aware that's not ideal for AutoCAD. However this code is also recompiled for use with another application (BricsCAD) that seems to require ForWrite to function correctly. Until I can figure out an alternative solution for that platform, ForWrite is a necessary evil at the moment. 


Not necessarily.

 

Consider the following:

 

 

public static class Utils
{
   public static bool IsAutoCAD
   {
       get
       {
              // return a bool if the code is running on AutoCAD or not
       }
   }

   public static readonly OpenMode OpenForRead = IsAutoCAD ? OpenMode.ForRead : OpenMode.ForWrite;

}

 

 

With the above, instead of using OpenMode.ForWrite where BricsCAD requires it, but where OpenMode.ForRead is what should be used, use the Utils.OpenForRead, field rather than OpenMode.ForWrite.  On AutoCAD it will be assigned to OpenMode.ForRead, on anything else it'll be OpenMode.ForWrite.

0 Likes