The method I use (may not be the best way) is to:
get existing block references
delete existing block definition
create new block definition
assign new block definition to existing block references
insert new block reference
Heres the code:
Public Sub Insert()
Dim strBlock As String = "Your Block/DWG Name"
Dim strBlockPath As String = "Your Path to Block/DWG"
Dim objDB As Database = HostApplicationServices.WorkingDatabase
Dim objTrans As Transaction = objDB.TransactionManager.StartTransaction
Dim objBlockDefId As ObjectId = GetTableRecordId(objDB.BlockTableId, strBlock) 'Function Defined Below
Dim objBlockDef As BlockTableRecord
Dim objBlockRefs2Update As New ObjectIdCollection
'If BlockDef Exists Get All Block References To Be Updated And Then Delete BlockDef
If objBlockDefId <> ObjectId.Null Then
objBlockDef = CType(objTrans.GetObject(objBlockDefId, DatabaseServices.OpenMode.ForWrite, False), BlockTableRecord)
objBlockRefs2Update = objBlockDef.GetBlockReferenceIds(True, False)
objBlockDef.Erase()
End If
'Create New BlockDef From DWG
Dim objBlockDefDB As Database = New Database
objBlockDefDB.ReadDwgFile(strBlockPath, IO.FileShare.ReadWrite, False, "")
objBlockDefId = objDB.Insert(strBlock, objBlockDefDB, True)
objBlockDefDB.Dispose()
'Update Block References With New BlockDef
For Each objBlockRef2UpdateId As ObjectId In objBlockRefs2Update
Dim objBlockRef2Update As BlockReference = CType(objTrans.GetObject(objBlockRef2UpdateId, DatabaseServices.OpenMode.ForWrite, False), BlockReference)
objBlockRef2Update.BlockTableRecord = objBlockDefId
Next objBlockRef2UpdateId
objTrans.Commit()
objTrans.Dispose()
'Insert Block Reference At 0,0,0
objTrans = objDB.TransactionManager.StartTransaction
Dim objBlockRef As BlockReference = New BlockReference(New Point3d(0, 0, 0), objBlockDefId)
Dim objBT As BlockTable = CType(objTrans.GetObject(objDB.BlockTableId, DatabaseServices.OpenMode.ForWrite, False), BlockTable)
Dim objBTR As BlockTableRecord = CType(objTrans.GetObject(objBT(BlockTableRecord.ModelSpace), DatabaseServices.OpenMode.ForWrite, False), BlockTableRecord)
objBTR.AppendEntity(objBlockRef)
objTrans.AddNewlyCreatedDBObject(objBlockRef, True)
objTrans.Commit()
objTrans.Dispose()
End Sub
' This is a workaround for getting a non-erased SymbolTableRecord, when there are also erased ones with the same name
Public Function GetTableRecordId(ByVal objTableId As ObjectId, ByVal strName As String) As ObjectId
GetTableRecordId = ObjectId.Null
Dim objDB As Database = objTableId.Database
Dim objTrans As Transaction = objDB.TransactionManager.StartTransaction
Dim objTable As SymbolTable = CType(objTrans.GetObject(objTableId, DatabaseServices.OpenMode.ForRead, False), SymbolTable)
If objTable.Has(strName) Then
Dim objID As ObjectId
objID = objTable(strName)
If objID.IsErased Then
For Each objID In objTable
If Not objID.IsErased Then
Dim objSTR As SymbolTableRecord = CType(objTrans.GetObject(objID, DatabaseServices.OpenMode.ForRead, False), SymbolTableRecord)
If String.Compare(objSTR.Name, strName, True) = 0 Then
GetTableRecordId = objID
Exit For
End If
End If
Next
Else
GetTableRecordId = objID
End If
End If
objTrans.Commit()
objTrans.Dispose()
End Function