Author Topic: Erase and Replace Multiple Blocks  (Read 304 times)

0 Members and 1 Guest are viewing this topic.

Conveyor1

  • Mosquito
  • Posts: 8
Erase and Replace Multiple Blocks
« on: June 12, 2018, 07:08:27 AM »
Morning,

 

I am trying to write some code to look at a block to see if it has been improperly modified and, if yes, delete it and reinsert the block correctly.

 

Currently, the code is able to find the modified blocks and it is able to delete and rebuild it.  However, if more then 1 block is found in the drawing, I am getting an error "Object Reference not set to and instance of an Object" in the bold line of code on the second pass.

Code:

Code - vb.net: [Select]
  1. Public Sub Drawing_Check() ' In Testing
  2.  
  3. Dim myblocks As ArrayList = GetTopLevelBlocks()
  4. Dim myBlockName As String
  5. Dim myTransMan As DatabaseServices.TransactionManager
  6. Dim myTrans As DatabaseServices.Transaction
  7. Dim myDB As DatabaseServices.Database
  8. Dim mydwg As Document = ApplicationServices.Application.DocumentManager.MdiActiveDocument
  9. myDB = mydwg.Database
  10. myTransMan = myDB.TransactionManager
  11. myTrans = myTransMan.StartTransaction
  12.  
  13. For Each myBlockName In myblocks
  14. Dim myObjIDs As DatabaseServices.ObjectIdCollection
  15. Dim myObjID As DatabaseServices.ObjectId
  16. Dim myBlockRef As DatabaseServices.BlockReference
  17. myObjIDs = PopulateOIDC(myBlockName)
  18.  
  19. For Each myObjID In myObjIDs
  20. myBlockRef = myObjID.GetObject(DatabaseServices.OpenMode.ForRead)
  21. Dim mybtr As DatabaseServices.BlockTableRecord = myBlockRef.DynamicBlockTableRecord.GetObject(OpenMode.ForRead)
  22. If mybtr.Name = "GENERAL BLOCK" Then
  23. ' Check If Rotated
  24. If myBlockRef.Rotation > Math.PI / 2 Or myBlockRef.Rotation > Math.PI * 3 / 2 Then
  25. 'Read Attributes
  26. Dim Temp_1 As String = Class1_Obj.ReadAttributeValue(myObjID, "Attribute_1")
  27. Dim Temp_2 As String = Class1_Obj.ReadAttributeValue(myObjID, "Attribute_2")
  28. 'Read Dynamic
  29. Dim Temp_3 As String = Class1_Obj.ReadDynamicValue(myObjID, "Dynamic_1")
  30. Dim Insertion_Point As Point3d = myBlockRef.Position
  31. Dim New_Insertion_Point As Point3d = Insertion_Point.Add(New Vector3d(Math.Cos(myBlockRef.Rotation) * Temp_3, Math.Sin(myBlockRef.Rotation) * Temp_3, 0))
  32.  
  33. Call RepopulatetoForm(myObjID) ' Records Block Related Items
  34.  
  35. myBlockRef.UpgradeOpen() ' Open Block Reference for Write
  36. myBlockRef.Erase(True) ' Erase the Incorrect Block
  37. myTrans.Commit()
  38. myTrans.Dispose()
  39. 'myTransMan.Dispose()
  40.  
  41. Call Class1_Obj.InsertConveyorBlock() ' Redraws a New Block
  42.  
  43. End If
  44. End If
  45. Next
  46. Next
  47. ' End Transactions
  48. myTrans.Dispose()
  49. myTransMan.Dispose()
  50.  
  51. End Sub


Please let me know your thoughts.

MickD

  • Gator
  • Posts: 3137
  • I don't need a job, I need Money!!
Re: Erase and Replace Multiple Blocks
« Reply #1 on: June 12, 2018, 07:22:52 AM »
I only quickly looked at your code but you should only need to redefine your block 'definition' and all 'references' (the ones in the drawing) will be updated accordingly keeping their orientations etc. This may be the reason for your error also, the old references may have already been updated when you updated the first block(?)

<edit> just noticed they could be dynamic blocks so what I said may not be relevant??
"A language that doesn’t have everything is actually easier to program in than some that do."

        — Dennis M. Ritchie

Conveyor1

  • Mosquito
  • Posts: 8
Re: Erase and Replace Multiple Blocks
« Reply #2 on: June 12, 2018, 07:39:09 AM »
Morning,

I thought that was happening when the code came around the second time with the "For Each myObjID In myObjIDs" loop.  But I could be misunderstanding.

When I test this, I have three blocks in the DWG and two are incorrect.  When the code runs, I do have (3) objectId's in the my myObjIDs.  And when it errors, the myObjID is set to the next object ID and not the one that was erased and replaced in the previous pass.

And yes, they are dynamic blocks.

Please let me know your thoughts.

MickD

  • Gator
  • Posts: 3137
  • I don't need a job, I need Money!!
Re: Erase and Replace Multiple Blocks
« Reply #3 on: June 13, 2018, 03:12:24 AM »
To be honest, I was only making a quick observation that you may be trying to edit each individual block 'reference' rather than editing the block 'definition' which would update all block references when it was updated (all references refer to a definition but I'm unclear on how this may work with dynamic blocks).

I did notice however that you're disposing of the transaction twice in the code you posted:


myTrans.Commit()
myTrans.Dispose()
'myTransMan.Dispose()
 
Call Class1_Obj.InsertConveyorBlock() ' Redraws a New Block
 
End If
End If
Next
Next
' End Transactions
myTrans.Dispose()


only commit and dispose of your transaction once you have completed all of your work (i.e. your loop iterations in this case). If you have to commit due to other circumstances then create a new nested transaction in the loop and be sure to commit and dispose before the next loop.
"A language that doesn’t have everything is actually easier to program in than some that do."

        — Dennis M. Ritchie

MexicanCustard

  • Swamp Rat
  • Posts: 702
Re: Erase and Replace Multiple Blocks
« Reply #4 on: June 13, 2018, 07:08:42 AM »
To be honest, I was only making a quick observation that you may be trying to edit each individual block 'reference' rather than editing the block 'definition' which would update all block references when it was updated (all references refer to a definition but I'm unclear on how this may work with dynamic blocks).

I did notice however that you're disposing of the transaction twice in the code you posted:


myTrans.Commit()
myTrans.Dispose()
'myTransMan.Dispose()
 
Call Class1_Obj.InsertConveyorBlock() ' Redraws a New Block
 
End If
End If
Next
Next
' End Transactions
myTrans.Dispose()


only commit and dispose of your transaction once you have completed all of your work (i.e. your loop iterations in this case). If you have to commit due to other circumstances then create a new nested transaction in the loop and be sure to commit and dispose before the next loop.

Better yet, put your transaction in a using statement and let the system dispose of it.
Revit 2019, AMEP 2019 64bit Win 10

WILL HATCH

  • Bull Frog
  • Posts: 448
Re: Erase and Replace Multiple Blocks
« Reply #5 on: June 18, 2018, 06:16:04 PM »
I noticed that you start your transaction outside of your loop, yet you commit and dispose of it inside your inner loop.

Conveyor1

  • Mosquito
  • Posts: 8
Re: Erase and Replace Multiple Blocks
« Reply #6 on: June 18, 2018, 06:54:34 PM »
You are correct.  That was the issue.

Thank you for the help.

WILL HATCH

  • Bull Frog
  • Posts: 448
Re: Erase and Replace Multiple Blocks
« Reply #7 on: June 18, 2018, 07:17:39 PM »
Awesome, cheers