Jump to content

Inserting Block using VBA


voyagr12

Recommended Posts

I am trying to insert a block via vba from a "Master Block" drawing, into another drawing. This "Master Block" drawing has almost all of our blocks in it. I can insert a dwg file as a block with out any issues. But I am not sure where to start with inserting a particular block from the master block drawing into another drawing.

 

do i use the insertblock method?

 

thanks in advance.

Link to comment
Share on other sites

The general method would be to open the Block container file:

 

Dim objContainFile as AcadDocument

Set objContainFile = ThisDrawing.Application.Documents.Open (Path to document)

(or, if you’d prefer to open the document behind the scenes, AxDbDocument.Open with the appropriate ObjectDBX reference included in the VBA project)

 

With the container file now open a:

 

objContainFile.CopyObjects(Objects , Current Drawing)

 

where Objects are the required blocks and Current Drawing is the copied blocks new document.

Link to comment
Share on other sites

I apologize, but I think I am somewhat lost.

Here is some more information:

Wish to insert block into a drawing(Drawing1.dwg)

Block I wish to insert is named C01 in a drawing named block_drawing_civil in the following directory: C:\hfl_civil_blocks

 

So the code would be

 

 
Dim objContainFile as AcadDocument
Set objContainFile = AxDbDocument.Open("C:\hfl_civil_blocks\block_drawing_civil.dwg")

 

What do I do from here. Do I still use the insertblock method? How do I actually get the block from within one drawing to the other?

 

Thank you very much for the help.

Link to comment
Share on other sites

I apologize, but I think I am somewhat lost.

Here is some more information:

Wish to insert block into a drawing(Drawing1.dwg)

Block I wish to insert is named C01 in a drawing named block_drawing_civil in the following directory: C:\hfl_civil_blocks

 

 

Actually, I apologize. I glossed over a critical step or two in my original post. The example below shows how to deal with the parameters you've listed.

 

Option Explicit

Sub TestDwg2DwgBlkTrans() 'Change as required
Dim strPath As String
Dim strBlockName As String
Dim objBlock As AcadBlock
Dim entRef As AcadBlockReference
Dim dblPkPt() As Double
  strBlockName = "C01"
  strPath = "C:\hfl_civil_blocks\block_drawing_civil.dwg"
  On Error Resume Next
  Set objBlock = ThisDrawing.Blocks.Item(strBlockName)
  On Error GoTo 0
  If Not objBlock Is Nothing Then objBlock.Delete 'To reinitialize Block from container file
  DbxCopyBlock strBlockName, strPath 'Copy block into ThisDrawing
  dblPkPt = ThisDrawing.Utility.GetPoint(, "Pick insertion Point: ") 'Get insertion point for test insert
  Set entRef = ThisDrawing.ModelSpace.InsertBlock(dblPkPt, "C01", 1#, 1#, 1#, 0#) 'Test insert
End Sub

Sub DbxCopyBlock(strBlockName As String, strPath As String)
Dim strFullDef As String
Dim objBlock As AcadBlock
Dim colBlocks As AcadBlocks
Dim objArray(0) As Object
Dim ACDbx As Object
  Set ACDbx = GetAcDbxDoc()
  ACDbx.Open strPath
  Set colBlocks = ACDbx.Blocks
  Set objBlock = colBlocks.Item(strBlockName) 'Find appropriate block in container file's Blocks Collection
  Set objArray(0) = objBlock 'Create object array as required by the CopyObjects Method
  ACDbx.CopyObjects objArray, ThisDrawing.Blocks 'Copy to current drawing's Blocks Collection
  Set ACDbx = Nothing
End Sub

Function GetAcDbxDoc() As Object
Dim strAcadVersion As String
With ThisDrawing.Application
  strAcadVersion = Mid(.Version, 1, 2)
  If CInt(strAcadVersion) < 16 Then
      Set GetAcDbxDoc = .GetInterfaceObject("ObjectDBX.AxDbDocument")
  Else
      Set GetAcDbxDoc = .GetInterfaceObject("ObjectDBX.AxDbDocument." & strAcadVersion)
  End If
End With
End Function

Link to comment
Share on other sites

Thank you so much for you assistance.

I am having a slight issue with on line of code

 

Set GetAcDbxDoc = .GetInterfaceObject("ObjectDBX.AxDbDocument." & strAcadVersion)

 

It is telling me "object required" I am thinking it may have something to do with my references but I have the AutoCAD/ObjectDBX common 16.0 Type Library loaded. So not sure if there is another reference that I need, or maybe this isnt even the issue.

 

thanks again for you help.

Link to comment
Share on other sites

A couple of things:

 

I don’t use Civil 3d so I don’t have any direct way of testing.

 

I thought 2008 used ObjectDBX common 17.0, but I could be wrong. A double check would be to query the AutoCAD system variable ACADVER. If you type that at the command line, the whole number portion would be the number needed in strAcadVersion at the line:

 

Set GetAcDbxDoc = .GetInterfaceObject("ObjectDBX.AxDbDocument." & strAcadVersion)

It may make sense to just hardcode that in.

 

 

Another thing, unrelated to the objectDBX issue – the lines of code:

 

On Error Resume Next
Set objBlock = ThisDrawing.Blocks.Item(strBlockName)
On Error GoTo 0
If Not objBlock Is Nothing Then objBlock.Delete 'To reinitialize Block from container file

 

were for some initial testing and will need reworking for a routine designed for daily use.

Link to comment
Share on other sites

I have everything working great now. Thank you so much for you assistance. It is greatly appreciated.

 

But I have an additional question relating to this.

 

Is there a way for me to select which drawing session I would like to insert the block into. Could I have it insert it into the last accessed? I am sending this from an access database and at times we would have two or more sessions of autocad open. If this were the case, then I would like to be able to select the session and insert the block into this particular session I have selected, or made active. It appears that currently the program inserts the block into the session that was opened first.

 

Thanks

Link to comment
Share on other sites

Is there a way for me to select which drawing session I would like to insert the block into. Could I have it insert it into the last accessed? I am sending this from an access database and at times we would have two or more sessions of autocad open. If this were the case, then I would like to be able to select the session and insert the block into this particular session I have selected, or made active. It appears that currently the program inserts the block into the session that was opened first.

 

You say you are “sending this from an access database” so I assume you are employing GetObject() at some point (that would also explain why the very first AutoCAD session gets preferential treatment).

 

If that is true, is it possible to initiate your Access code through an AutoCAD VBA routine called from the target session? That would give you the opportunity to pass ThisDrawing.Application – which would conceivably be the correct instance – to the Access routine thus eliminating the need for GetObject.

Link to comment
Share on other sites

I wrote some code to open the access database from a session of AutoCAD but it didnt seem to fix my issue.

 

But I did not pass anything, all I did was opened the db from a session of AutoCAD that wasnt the first opened. unfortunately, when I attempted to send a block back to CAD it went to the first instance.

 

But I might be able to "Pass" the current drawing to access when I open it. (if I can figure out how). I will try and let you know.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...