.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

the importing block from the external DWG file

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
sayidyeh
975 Views, 7 Replies

the importing block from the external DWG file

Where's my problem with the importing block from the external DWG file,I've already see the blog from 

http://through-the-interface.typepad.com/through_the_interface/2006/08/import_blocks_f.html,and change the part of the code,Now I want click one button so that the program can insert the  one of blocks in external DWG file. Where's my problem with the code? and how can i fix it ?and the filepath and blockname has been confirmed .I use the sidedatabase.and where's the problem?

 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
Dim destDB As Database = acDoc.Database
Dim acEditor As Editor = acDoc.Editor
Dim pPtRes As PromptPointResult
Dim pPtOpts As PromptPointOptions = New PromptPointOptions("")

pPtOpts.Message = vbLf & "insert the point:"
pPtRes = acEditor.GetPoint(pPtOpts)
Dim InsertPt As Point3d = pPtRes.Value

If pPtRes.Status = PromptStatus.Cancel Then
Exit Sub
End If

Dim FilePath As String = "D:\2RD\PMDS\PMDS\Resources\PFD.dwg"
Dim FileName As String = " PFD.dwg"
Dim BlockName As String = "0920101"
Dim sourceDb As New Database(True, True)
sourceDb.ReadDwgFile(FilePath, System.IO.FileShare.Read, True, "")
Dim blockId As New ObjectIdCollection()

Using (acDoc.LockDocument)
Dim sourcetm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = sourceDb.TransactionManager
Dim desttm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = destDB.TransactionManager

Dim sourcemyT As Transaction = sourcetm.StartTransaction()
Dim sourcebt As BlockTable = DirectCast(sourcetm.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, False), BlockTable)

For Each btrId As ObjectId In sourcebt
Dim sourcebtc As BlockTableRecord = DirectCast(sourcetm.GetObject((sourcebt(BlockTableRecord.ModelSpace)), OpenMode.ForRead, False), BlockTableRecord)
If sourcebtc.Name = BlockName Then
blockId.Add(btrId)
Dim mapping As New IdMapping()
sourceDb.WblockCloneObjects(blockId, destDB.BlockTableId, mapping, DuplicateRecordCloning.Replace, False)
Using destmyT As Transaction = desttm.StartTransaction()
Dim destbt As BlockTable = DirectCast(desttm.GetObject(destDB.BlockTableId, OpenMode.ForWrite, True), BlockTable)
Dim destbtc As BlockTableRecord = DirectCast(desttm.GetObject((destbt(BlockTableRecord.ModelSpace)), OpenMode.ForRead, False), BlockTableRecord)
Dim Block As BlockReference = New BlockReference(InsertPt, destbt(BlockName))
Block.ScaleFactors = New Scale3d(1, 1, 1)
Block.Rotation = 0
Dim ModelSpace As BlockTableRecord = desttm.GetObject(destDB.CurrentSpaceId, OpenMode.ForWrite)
ModelSpace.AppendEntity(Block)
destmyT.AddNewlyCreatedDBObject(Block, True)
destmyT.Commit()
End Using
ElseIf Not sourcebtc.IsAnonymous AndAlso Not sourcebtc.IsLayout Then
End If
sourcebtc.Dispose()
Next
Me.Close()
End Using


End Sub

 

 

7 REPLIES 7
Message 2 of 8
hgasty1001
in reply to: sayidyeh

Hi,

 

Why the documentlock?, try to separate distinct functionalities in distinct routines or subs: One for the import process, and one for the insert process, if the insert involve a modeless form or a tool palette you should lock the document (or send string to execute in order to Autocad take control of the locking procedure), but there is no need to lock if you are not using modeless or involve more than one document (a document it's not the same as a database).

I would program this in the following work flow:

 

1.- Import the blocks

Just declare a sub, or better, a function that returns the names of the imported blocks, with the Kean's code (translated properly to VB .NET)

2.-Insert the block

Declare a sub that can insert a block to the current document with some arguments like block name, layer, rotation, etc.

3.- Do your process

Either insert or import or both, now you have two reusable subs.

 

Gaston Nunez

 

 

 

 

Message 3 of 8
C_Witt
in reply to: sayidyeh

I didn't look at your code.. but here is what I use for importing a block from another drawing (i don't remember where i got it).

 

SourceFileName - Obvious (full file path)

TargetBlock - The arraylist has the "name" as the first value, the other values are for other programs.  You can change this to a string easy enough.

 

 

    Public Sub GSS_ImportBlock2Database(ByVal sourceFileName As String, ByVal TargetBlock As ArrayList)
        Dim dm As DocumentCollection = ApplicationServices.Application.DocumentManager
        Dim ed As Editor = dm.MdiActiveDocument.Editor
        Dim destDb As Database = dm.MdiActiveDocument.Database
        Dim sourceDb As New Database(False, True)

        Try
            sourceDb.ReadDwgFile(sourceFileName, System.IO.FileShare.Read, True, "")
            Dim blockIds As New ObjectIdCollection()
            Dim tm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = sourceDb.TransactionManager
            Using myT As Transaction = tm.StartTransaction()
                Dim bt As BlockTable = DirectCast(tm.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, False), BlockTable)
                For Each btrId As ObjectId In bt
                    Dim btr As BlockTableRecord = DirectCast(tm.GetObject(bt(TargetBlock(0)), OpenMode.ForRead), BlockTableRecord)
                    blockIds.Add(btr.ObjectId)
                    btr.Dispose()
                Next
            End Using
            Dim mapping As New IdMapping()
            sourceDb.WblockCloneObjects(blockIds, destDb.BlockTableId, mapping, DuplicateRecordCloning.Ignore, False)
        Catch

        End Try
        sourceDb.Dispose()
    End Sub

 

Then you can insert the block like any other.

Message 4 of 8
sayidyeh
in reply to: hgasty1001

Thank u very much ! I think I have a little more work to do ..Smiley Happy

Message 5 of 8
sayidyeh
in reply to: C_Witt

Thank u very much I've Already seen ur code ,and problely It's kean's code from his blog,and It can success,but not what I want.
Message 6 of 8
C_Witt
in reply to: sayidyeh

from your OP, you want "importing block from the external DWG file".  That is what the above code does..  So if that is not what you want, please clarify what you do want.

 

 

And you are correct, it was probably from Kean's site.

Message 7 of 8
C_Witt
in reply to: sayidyeh

If you are really need an all-in-one solution.. for importing and inserting.. 

 

Public Sub ImportInsert()
        Dim sourceFileName As String = "your path here"
        Dim TargetBlock As String = "your name here"

        Dim dm As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
        Dim ed As Editor = dm.MdiActiveDocument.Editor
        Dim destDb As Database = dm.MdiActiveDocument.Database
        Dim sourceDb As New Database(False, True)
        Try
            sourceDb.ReadDwgFile(sourceFileName, System.IO.FileShare.Read, True, "")
            Dim blockIds As New ObjectIdCollection()
            Dim tm As Autodesk.AutoCAD.DatabaseServices.TransactionManager = sourceDb.TransactionManager
            Using myT As Transaction = tm.StartTransaction()
                Dim bt As BlockTable = DirectCast(tm.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, False), BlockTable)
                Dim btr As BlockTableRecord = DirectCast(tm.GetObject(bt(TargetBlock), OpenMode.ForRead), BlockTableRecord)
                blockIds.Add(btr.ObjectId)
                btr.Dispose()
            End Using
            Dim mapping As New IdMapping()
            sourceDb.WblockCloneObjects(blockIds, destDb.BlockTableId, mapping, DuplicateRecordCloning.Ignore, False)

            Dim myDwg As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
            Using myTrans As Autodesk.AutoCAD.DatabaseServices.Transaction = myDwg.TransactionManager.StartTransaction
                'Open the database for Write
                Dim myBT As BlockTable = myDwg.Database.BlockTableId.GetObject(OpenMode.ForRead)
                Dim myBTR As BlockTableRecord
                myBTR = myBT(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)

                'Insert the Block
                Dim pPtRes As PromptPointResult
                Dim pPtOpts As PromptPointOptions = New PromptPointOptions("")

                pPtOpts.Message = vbLf & "insert the point:"
                pPtRes = ed.GetPoint(pPtOpts)
                Dim InsertPt As Point3d = pPtRes.Value

                If pPtRes.Status = PromptStatus.Cancel Then
                    Exit Sub
                End If

                Dim myBlockDef As BlockTableRecord = myBT(TargetBlock).GetObject(OpenMode.ForRead)
                Dim myBlockRef As New DatabaseServices.BlockReference(pPtRes.Value, myBT(TargetBlock))
                myBlockRef.ScaleFactors = New Scale3d(0)

                myBTR.AppendEntity(myBlockRef)
                myTrans.AddNewlyCreatedDBObject(myBlockRef, True)

                Dim myAttColl As DatabaseServices.AttributeCollection
                Dim myEnt As DatabaseServices.Entity
                Dim myBTREnum As BlockTableRecordEnumerator
                myAttColl = myBlockRef.AttributeCollection
                myBTREnum = myBlockDef.GetEnumerator
                While myBTREnum.MoveNext
                    myEnt = myBTREnum.Current.GetObject(OpenMode.ForWrite)
                    If TypeOf myEnt Is DatabaseServices.AttributeDefinition Then
                        Dim myAttDef As DatabaseServices.AttributeDefinition = myEnt
                        Dim myAttRef As New DatabaseServices.AttributeReference
                        myAttRef.SetAttributeFromBlock(myAttDef, myBlockRef.BlockTransform)
                        myAttColl.AppendAttribute(myAttRef)
                        myTrans.AddNewlyCreatedDBObject(myAttRef, True)
                    End If
                End While

                myTrans.Commit()
            End Using
        Catch
        End Try
        sourceDb.Dispose()
    End Sub

 

Message 8 of 8
sayidyeh
in reply to: C_Witt

thank u very much,I'v been successful to run the program,I use the regex MATCH to instead WblockCloneObjects before clone the blocks

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost