Author Topic: Delete blocks  (Read 3609 times)

0 Members and 1 Guest are viewing this topic.

krkec

  • Guest
Delete blocks
« on: March 15, 2012, 10:00:18 AM »
Hi

I am trying to create program to delete blocks from selected drawings. 

I always get fatal error. Can anybody tell me why, I will go crazy????

Lblokova is listbox for selecting blocks for deleting.

Code: [Select]
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.ApplicationServices.Application
Imports Autodesk.AutoCAD.LayerManager
Imports Autodesk.AutoCAD.Windows

Public Class BlokoviForm
    Dim mojofdbl As Array
    Dim mojofd2 As Array
    Dim mojofddxr As Array
    Dim mojofdxr As String
    Dim check1 As Integer

    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

    Function potrazixref(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.IsFromExternalReference = True Then
                    myList.Add(myBTR.Name)

                End If
            Next
        End Using
        Return myList
    End Function

    Private Sub Odaberiblok_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Odaberiblok.Click
        If RadioButton1.Checked = True Then
            Dim myOFD As New OpenFileDialog("Select DWG", "", "dwg", "Select DWG", _
            OpenFileDialog.OpenFileDialogFlags.AllowMultiple)
            If myOFD.ShowDialog = System.Windows.Forms.DialogResult.OK Then
                mojofdbl = myOFD.GetFilenames
                For Each myFileName As String In mojofdbl
                    'Debug.Print("***EXPORT FOR " & myFileName)
                    Dim 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)
                            'Debug.WriteLine(myBlockName)
                            If Lblokova.Items.IndexOf(myBlockName) < 0 Then
                                Lblokova.Items.Add(myBlockName)
                            End If

                            'If Lblokova.FindString("myBlockName") Then  Else Lblokova.Items.Add(myBlockName)
                        Next
                    End Using
                    myDB.Dispose()
                Next
            End If
            'Lblokova = Lblokova.Distinct().ToList()
        Else
            Dim myOFD As New OpenFileDialog("Select Folder", "", "", "Select Folder", _
OpenFileDialog.OpenFileDialogFlags.AllowFoldersOnly)
            If myOFD.ShowDialog = System.Windows.Forms.DialogResult.OK Then
                Dim myDIO As New IO.DirectoryInfo(myOFD.Filename)
                For Each myFileInfo As IO.FileInfo In myDIO.GetFiles("*.dwg", _
IO.SearchOption.AllDirectories)
                    mojofdbl = myDIO.GetFiles("*.dwg", _
IO.SearchOption.AllDirectories)
                    'Debug.Print("***EXPORT FOR " & myFileName)
                    Dim myDB As New Database(False, True)
                    myDB.ReadDwgFile(myFileInfo.FullName, FileOpenMode.OpenForReadAndAllShare, True, "")
                    Using mytrans As Transaction = myDB.TransactionManager.StartTransaction
                        For Each myBlockName As String In GetTopLevelBlocks(myDB)
                            'Debug.WriteLine(myBlockName)
                            If Lblokova.Items.IndexOf(myBlockName) < 0 Then
                                Lblokova.Items.Add(myBlockName)
                            End If

                            'If Lblokova.FindString("myBlockName") Then  Else Lblokova.Items.Add(myBlockName)
                        Next
                    End Using
                    myDB.Dispose()
                Next

            End If
        End If
    End Sub


    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles brisiblokove.Click

        If Lblokova.Items.Count > 0 Then
            For i As Integer = 0 To Lblokova.SelectedItems.Count - 1
                Dim imebloka As String = (Lblokova.SelectedItems(i).ToString)


                ' MsgBox(Lblokova.Items(i).ToString)
                '-------------------------------------------------------------------------------
                For Each myFileName As System.IO.FileInfo In mojofdbl

                    Dim myDB As New Database(False, True)

                    myDB.ReadDwgFile(myFileName.ToString, FileOpenMode.OpenForReadAndAllShare, True, "")
                    Using mytrans As Transaction = myDB.TransactionManager.StartTransaction
                        For Each myBlockName As String In GetTopLevelBlocks(myDB)
                            Using myBt As BlockTable = mytrans.GetObject(myDB.BlockTableId, OpenMode.ForRead)
                                If myBt.Has(myBlockName) And myBlockName = imebloka Then
                                    Dim btrId As ObjectId = myBt(myBlockName)

                                    Dim myBtr As BlockTableRecord = mytrans.GetObject(btrId, OpenMode.ForRead)
                                    Dim blkIds As ObjectIdCollection = myBtr.GetBlockReferenceIds(True, True)

                                    For Each blkID As ObjectId In blkIds
                                        Using bref As BlockReference = mytrans.GetObject(blkID, OpenMode.ForWrite)
                                            bref.Erase()
                                        End Using
                                    Next

                                    ' ' Now delete the block record itself
                                    myBtr.UpgradeOpen()
                                    myBtr.Erase()

                                End If
                            End Using

                        Next
                        mytrans.Commit()
                    End Using ' ' transaction
                    myDB.SaveAs(myFileName.ToString, DwgVersion.Current) '<-- 2009

                Next ' ' myFileName

                '----------------------------------------------------------------------------------------------------

                Lblokova.Items.Remove(Lblokova.SelectedItems(i))
            Next
        Else
            Label1.Visible = True
        End If
    End Sub


End Class

Jeff H

  • Needs a day job
  • Posts: 6151
Re: Delete blocks
« Reply #1 on: March 15, 2012, 12:07:17 PM »
When you step through code which line causes crash?

krkec

  • Guest
Re: Delete blocks
« Reply #2 on: March 15, 2012, 12:59:28 PM »
I dont know, how i find that???

this is output log:

'acad.exe' (Managed): Loaded 'C:\inp_krkc\x86\inp_krkc.dll', Symbols loaded.
'acad.exe' (Managed): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualBasic\8.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'acad.exe' (Managed): Loaded 'C:\Program Files\AutoCAD Civil 3D 2010\AcDialogToolTips.dll'
'acad.exe' (Managed): Loaded 'C:\Program Files\AutoCAD Civil 3D 2010\en-US\AcDialogToolTips.resources.dll'
'acad.exe' (Managed): Loaded 'C:\Windows\assembly\GAC_MSIL\UIAutomationProvider\3.0.0.0__31bf3856ad364e35\UIAutomationProvider.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'acad.exe' (Managed): Loaded 'C:\Windows\assembly\GAC_MSIL\Accessibility\2.0.0.0__b03f5f7f11d50a3a\Accessibility.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
System.Windows.Media.Animation Warning: 6 : Unable to perform action because the specified Storyboard was never applied to this object for interactive control.; Action='Stop'; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='3336177'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; TargetElement='Autodesk.Internal.Windows.ToolTip: Up one level (Alt+2)'; TargetElement.HashCode='30025596'; TargetElement.Type='Autodesk.Internal.Windows.ToolTip'
System.Windows.Media.Animation Warning: 6 : Unable to perform action because the specified Storyboard was never applied to this object for interactive control.; Action='Stop'; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='3336177'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; TargetElement='Autodesk.Internal.Windows.ToolTip: Show files on your desktop'; TargetElement.HashCode='30025596'; TargetElement.Type='Autodesk.Internal.Windows.ToolTip'
System.Windows.Media.Animation Warning: 6 : Unable to perform action because the specified Storyboard was never applied to this object for interactive control.; Action='Stop'; Storyboard='System.Windows.Media.Animation.Storyboard'; Storyboard.HashCode='3336177'; Storyboard.Type='System.Windows.Media.Animation.Storyboard'; TargetElement='Autodesk.Internal.Windows.ToolTip: Open'; TargetElement.HashCode='30025596'; TargetElement.Type='Autodesk.Internal.Windows.ToolTip'
A first chance exception of type 'System.InvalidCastException' occurred in inp_krkc.dll
The program '[7968] acad.exe: Managed' has exited with code 1 (0x1).

TheMaster

  • Guest
Re: Delete blocks
« Reply #3 on: March 17, 2012, 12:47:47 AM »
Hi

I am trying to create program to delete blocks from selected drawings. 

I always get fatal error. Can anybody tell me why, I will go crazy????



I can't tell you what exactly is causing the InvalidCastException error you're
getting, but i did notice that you don't dispose the Database in one of your
methods, and that can cause problems. Even where you do call Dispose()
on the Database, the call isn't wrapped in a Finally, so it may never happen
if an exception is thrown before that line is reached.

You should wrap all use of 'Dim myDB As New Database(...)' into a  'Using'
block just like you do with Transactions, and then you don't need to call
myDb.Dispose(), and that will guarantee the Database gets disposed no
matter what.

e.g.,

Code: [Select]

  Using myDB As Database = New Database(False, True)
     ' use myDB here
  End Using


krkec

  • Guest
Re: Delete blocks
« Reply #4 on: March 17, 2012, 03:50:02 PM »
I tried with using but i still get fatal error. I tried catch error and i get this "unable to cast object of type 'system.string to type 'system.io.fileinfo" - this is probably because ReadDwgFile but I don't know why.

TheMaster

  • Guest
Re: Delete blocks
« Reply #5 on: March 17, 2012, 05:04:59 PM »
I tried with using but i still get fatal error. I tried catch error and i get this "unable to cast object of type 'system.string to type 'system.io.fileinfo" - this is probably because ReadDwgFile but I don't know why.

You should have no problem finding the problem. The debugger will break when the error happens, at the line of code where the exception is raised. The error suggests that you are passing a string to some function that is expecting a System.IO.Fileinfo object.

krkec

  • Guest
Re: Delete blocks
« Reply #6 on: March 17, 2012, 05:40:23 PM »
Problem is in this line but i dont know why : myDB.ReadDwgFile(myFileName1.ToString, FileOpenMode.OpenForReadAndAllShare, True, "") where i want to convert myFileName1 to string. any suggestions?

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Delete blocks
« Reply #7 on: March 17, 2012, 06:31:32 PM »

Looks like you have changed the code since you posted it.
The statement you quote as the exception cause does not exist in your code.

you may want to fix that.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Delete blocks
« Reply #8 on: March 17, 2012, 06:44:25 PM »

Perhaps you could add a breakpoint at the offending line in the IDE so that the debugger stops at that statement.
Then use the Locals pane to check the type of your variables.

Step through the code  ...
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

krkec

  • Guest
Re: Delete blocks
« Reply #9 on: March 18, 2012, 03:08:31 AM »
I check variables and everything is fine. Problem is somewhere between this two line:
Code - vb.net: [Select]
  1. 1             For Each myFileName1 As System.IO.FileInfo In mojofdbl
  2.  
  3. 2                        Using myDB As New Database(False, True)

i added brake point at this two lines, and program reaches first line, but error comes before second.

this is full code:
Code - vb.net: [Select]
  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports Autodesk.AutoCAD
  3. Imports Autodesk.AutoCAD.DatabaseServices
  4. Imports Autodesk.AutoCAD.EditorInput
  5. Imports Autodesk.AutoCAD.Geometry
  6. Imports Autodesk.AutoCAD.ApplicationServices
  7. Imports Autodesk.AutoCAD.ApplicationServices.Application
  8. Imports Autodesk.AutoCAD.LayerManager
  9. Imports Autodesk.AutoCAD.Windows
  10.  
  11. Public Class BlokoviForm
  12.     Dim mojofdbl As Array
  13.     Dim mojofd2 As Array
  14.     Dim mojofddxr As Array
  15.     Dim mojofdxr As String
  16.     Dim check1 As Integer
  17.  
  18.     Function GetTopLevelBlocks(ByVal DatabaseIn As Database) As List(Of String)
  19.         Dim myList As New List(Of String)
  20.         Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction
  21.             Dim myBT As BlockTable = DatabaseIn.BlockTableId.GetObject(OpenMode.ForRead)
  22.             For Each myBTRid As ObjectId In myBT
  23.                 Dim myBTR As BlockTableRecord = myBTRid.GetObject(OpenMode.ForRead)
  24.                 If myBTR.IsAnonymous = False And myBTR.IsLayout = False And _
  25.     myBTR.IsFromExternalReference = False And _
  26.     myBTR.IsDependent = False Then
  27.                     myList.Add(myBTR.Name)
  28.                 End If
  29.             Next
  30.         End Using
  31.         Return myList
  32.     End Function
  33.  
  34.     Function potrazixref(ByVal DatabaseIn As Database) As List(Of String)
  35.         Dim myList As New List(Of String)
  36.         Using myTrans As Transaction = DatabaseIn.TransactionManager.StartTransaction
  37.             Dim myBT As BlockTable = DatabaseIn.BlockTableId.GetObject(OpenMode.ForRead)
  38.             For Each myBTRid As ObjectId In myBT
  39.                 Dim myBTR As BlockTableRecord = myBTRid.GetObject(OpenMode.ForRead)
  40.                 If myBTR.IsFromExternalReference = True Then
  41.                     myList.Add(myBTR.Name)
  42.  
  43.                 End If
  44.             Next
  45.         End Using
  46.         Return myList
  47.     End Function
  48.  
  49.     Private Sub Odaberiblok_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Odaberiblok.Click
  50.         If RadioButton1.Checked = True Then
  51.             Dim myOFD As New OpenFileDialog("Select DWG", "", "dwg", "Select DWG", _
  52.             OpenFileDialog.OpenFileDialogFlags.AllowMultiple)
  53.             If myOFD.ShowDialog = System.Windows.Forms.DialogResult.OK Then
  54.                 mojofdbl = myOFD.GetFilenames
  55.                 For Each myFileName As String In mojofdbl
  56.                     'Debug.Print("***EXPORT FOR " & myFileName)
  57.                     Using myDB As New Database(False, True)
  58.                         myDB.ReadDwgFile(myFileName, FileOpenMode.OpenForReadAndAllShare, True, "")
  59.                         Using mytrans As Transaction = myDB.TransactionManager.StartTransaction
  60.                             For Each myBlockName As String In GetTopLevelBlocks(myDB)
  61.                                 'Debug.WriteLine(myBlockName)
  62.                                 If Lblokova.Items.IndexOf(myBlockName) < 0 Then
  63.                                     Lblokova.Items.Add(myBlockName)
  64.                                 End If
  65.  
  66.                                 'If Lblokova.FindString("myBlockName") Then  Else Lblokova.Items.Add(myBlockName)
  67.                             Next
  68.                         End Using
  69.  
  70.                     End Using
  71.                 Next
  72.             End If
  73.             'Lblokova = Lblokova.Distinct().ToList()
  74.         Else
  75.             Dim myOFD As New OpenFileDialog("Select Folder", "", "", "Select Folder", _
  76. OpenFileDialog.OpenFileDialogFlags.AllowFoldersOnly)
  77.             If myOFD.ShowDialog = System.Windows.Forms.DialogResult.OK Then
  78.                 Dim myDIO As New IO.DirectoryInfo(myOFD.Filename)
  79.                 For Each myFileInfo As IO.FileInfo In myDIO.GetFiles("*.dwg", _
  80. IO.SearchOption.AllDirectories)
  81.                     mojofdbl = myDIO.GetFiles("*.dwg", _
  82. IO.SearchOption.AllDirectories)
  83.                     'Debug.Print("***EXPORT FOR " & myFileName)
  84.                     Using myDB As New Database(False, True)
  85.                         myDB.ReadDwgFile(myFileInfo.FullName, FileOpenMode.OpenForReadAndAllShare, True, "")
  86.                         Using mytrans As Transaction = myDB.TransactionManager.StartTransaction
  87.                             For Each myBlockName As String In GetTopLevelBlocks(myDB)
  88.                                 'Debug.WriteLine(myBlockName)
  89.                                 If Lblokova.Items.IndexOf(myBlockName) < 0 Then
  90.                                     Lblokova.Items.Add(myBlockName)
  91.                                 End If
  92.  
  93.                                 'If Lblokova.FindString("myBlockName") Then  Else Lblokova.Items.Add(myBlockName)
  94.                             Next
  95.                         End Using
  96.  
  97.                     End Using
  98.                 Next
  99.  
  100.             End If
  101.         End If
  102.     End Sub
  103.  
  104.  
  105.     Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles brisiblokove.Click
  106.         Try
  107.             If Lblokova.Items.Count > 0 Then
  108.                 For i As Integer = 0 To Lblokova.SelectedItems.Count - 1
  109.                     Dim imebloka As String = (Lblokova.SelectedItems(i).ToString)
  110.  
  111.  
  112.                     ' MsgBox(Lblokova.Items(i).ToString)
  113.                     '-------------------------------------------------------------------------------
  114.                     For Each myFileName1 As System.IO.FileInfo In mojofdbl
  115.  
  116.                         Using myDB As New Database(False, True)
  117.                             myDB.ReadDwgFile(myFileName1.ToString, FileOpenMode.OpenForReadAndAllShare, True, "")
  118.                             Using mytrans As Transaction = myDB.TransactionManager.StartTransaction
  119.                                 For Each myBlockName As String In GetTopLevelBlocks(myDB)
  120.                                     Using myBt As BlockTable = mytrans.GetObject(myDB.BlockTableId, OpenMode.ForRead)
  121.                                         If myBt.Has(myBlockName) And myBlockName = imebloka Then
  122.                                             Dim btrId As ObjectId = myBt(myBlockName)
  123.  
  124.                                             Dim myBtr As BlockTableRecord = mytrans.GetObject(btrId, OpenMode.ForRead)
  125.                                             Dim blkIds As ObjectIdCollection = myBtr.GetBlockReferenceIds(True, True)
  126.  
  127.                                             For Each blkID As ObjectId In blkIds
  128.                                                 Using bref As BlockReference = mytrans.GetObject(blkID, OpenMode.ForWrite)
  129.                                                     bref.Erase()
  130.                                                 End Using
  131.                                             Next
  132.  
  133.                                             ' ' Now delete the block record itself
  134.                                             myBtr.UpgradeOpen()
  135.                                             myBtr.Erase()
  136.  
  137.                                         End If
  138.                                     End Using
  139.  
  140.                                 Next
  141.                                 mytrans.Commit()
  142.                             End Using ' ' transaction
  143.                             myDB.SaveAs(myFileName1.ToString, DwgVersion.Current) '<-- 2009
  144.                         End Using
  145.                         'End Using
  146.                     Next ' ' myFileName
  147.  
  148.                     '----------------------------------------------------------------------------------------------------
  149.  
  150.                     Lblokova.Items.Remove(Lblokova.SelectedItems(i))
  151.                 Next
  152.             Else
  153.                 Label1.Visible = True
  154.             End If
  155.         Catch ex As System.Exception
  156.             ' MsgBox("Greska se pojavila" & vbCr & ex.Message & ex.InnerException.ToString & ex.Source)
  157.             MsgBox("Greska se pojavila" & vbCr & ex.Message)
  158.         Finally
  159.         End Try
  160.     End Sub
  161.  
  162.  
  163. End Class
  164.  
  165.  
  166.  
  167.  

please help


kdub:edited for formatting=vbnet
« Last Edit: March 18, 2012, 05:59:19 AM by Kerry »

n.yuan

  • Bull Frog
  • Posts: 348
Re: Delete blocks
« Reply #10 on: March 18, 2012, 10:28:07 AM »
There are at least 2 obvious errors in your code:

1. Private Sub Odaberiblok_Click(...) event handler

If RadioButton1.Checked = True Then

    ''In this part, mojofdb1 is an ARRAY of string, returned by OpenFileDialog.GetFiles()

Else

    ''In this part,
    myDIO As New IO.DirectoryInfo(....)
    creates a WRONG DirectoryInfo object, because you pass in a file path/name, rather than a folder path/name. So, following For Each... loop may not build mojofdb1 array at all, unless you do have a folder name like "C:\....\xxx.dwg\"

End If

Also, since you did not declare mojofdb1 as a strong typed variable (just as Array), if the Then part of the If... statement, you fill it with strings, in the ELSE part, you fill it with FileInfo. And, in the later code (where you got error), you expect it as FileInfo.

I'd bet you only tested with the RadioButton1 always being checked. In this case, the mojofdb1 is an array of strings. So, when you code

For Each myFileName1 As System.IO.FileInfo in mojofdb1
...
Next

runs, you got exception, because a string (a file's path/name) from mojofdb1 cannot be a FileInfo object.

If you turned "Option Strict" on (VB.NET set it off by default. That is one thing I do not like VB.NET and choose C# instead), your mistake would have been caught during code building easily.

As you can see, your trouble is hardly because of AutoCAD programming.
« Last Edit: March 18, 2012, 12:26:00 PM by n.yuan »