Copy Pasting object from one drawing file to another

Copy Pasting object from one drawing file to another

Anonymous
Not applicable
9,890 Views
27 Replies
Message 1 of 28

Copy Pasting object from one drawing file to another

Anonymous
Not applicable

Hallo everyone! 

I have a problem regarding Autocad drawing with VBA coding. I am trying to copy paste an object (for ex. a circle) from one dwg file to another dwg file via VBA coding. I cant write the code for it. Is there any way to do it besides Wblock command specially when I want to copy paste objects from multiple dwg files?

 

Please help me...

0 Likes
Accepted solutions (2)
9,891 Views
27 Replies
Replies (27)
Message 21 of 28

Anonymous
Not applicable

So I looked in to SelectionSet.Select as you suggested, thanks. And I wrote up some code for what I'm trying to achieve (selecting all to then copy).


I've resolved errors and refined it to this point - looks good to me but I'm getting "automation error" on "Set ssetObj = ThisDrawing.SelectionSets.Add("SSET")"

Option Explicit

Public Sub CopyEntities()

    ''Set the source drawing
    Dim curDwg As AcadDocument
    Dim d As AcadDocument
    For Each d In AcadApplication.Documents
        If UCase(d.Name) = "DRAWING1.DWG" Then
            Set curDwg = d
            Exit For
        End If
    Next
    
    If curDwg Is Nothing Then
        MsgBox "Cannot find source drawing ""Drawing1.dwg"""
        Exit Sub
    End If
    
    Dim entities() As Object
    entities = SelectAll(curDwg)
 
    ''Open a new drawing
    Dim newDwg As AcadDocument
    Set newDwg = AcadApplication.Documents.Add()
    
    ''Copy entities from source drawing to new drawing
    curDwg.CopyObjects entities, newDwg.ModelSpace
    
End Sub

Private Function SelectAll()

Dim ThisDrawing As AcadDocument
Set ThisDrawing = AutoCAD.ActiveDocument

Dim mode As Integer
Dim ssetObj As AcadSelectionSet
Set ssetObj = ThisDrawing.SelectionSets.Add("SSET")

Dim FilterType As Integer
Dim FilterData As Variant
FilterType = 67
FilterData = 0

'object.Select Mode [, Point1] [, Point2] [, FilterType, FilterData]
ssetObj.Select acSelectionSetAll, , , FilterType, FilterData

End Function

 

Any thoughts on what's going wrong here? Cheers.

0 Likes
Message 22 of 28

norman.yuan
Mentor
Mentor

The error lies in your function SelectAll: there are a few things wrong:

 

1. Firstly, you did not declare what the Type the function returns, which is allowed while not being good practice, thus, the function would return Variant type. However, with this function you DID not actually return anything; that is, you need to hate a line of code before "End Function", something like

Private Function SelectAll()

    ... ...

   SelectAll = ....

End Function

 

So, your function returns an empty value of Variant type. Therefore, your main code, after the Function is called, even assume you do not have other error in SelectAll(), obviously will not work, because 

 

entities = SelectAll() 

 

get you nothing in the "entities" object array.

 

2. About the error you get at 

 

Set ssetObj = ThsiDrawing.SelectionSet.Add("SSET")

 

I bet when you run the code first time, this line works OK (but not the next line, as aforementioned), because the drawing already has a SelectionSet, names as "SSET" due to the previous run, thus the error. When creating a AcadSelectionSet, ALWAYS test if there is one with the same name allready exists; if yes, either re-use the existing one, or create with different name.

 

a. you can:

 

Dim ssetObj As AcadSelectionSet

Dim ss As AcadSelectionSet

For Each ss in ThisDrawing.SelectionSets

  if Ucase(ss.Name)="SSET" Then

    Set ssetObj=ss

    ssetObj.Clear

    Exit For

  End If

Next

 

If ssetObj Is Noting Then

  Set ssetObj = ThisDrawing.SelectioNSets.Add("SSET")

End If

... ...

 

b. you can also use error catching to make your code a bit simple, like this:

 

On Error Resume Next

Dim ssetObj As AcadSelectionSet

'' Set it to existing one

Set ssetObj = ThisDrawing.SelectionSet("SSET")

'' If no existing found, error is raised

If err.Number <> 0 Then

  Set ssetObj = ThisDrawing.SelectionSets.Add("SSET")

End If

On Error GoTo 0

... ...

 

3. Even you actually return the selectionset (ssetObj) with a line of code in end SelectionAll(), like

 

Private Function SelectAll()

   ...

  ssetObj,Select acSelectionSetAll......

  Set SelectAll= ssetObj

End Function

 

The code STILL DOES NOT work, because CopyFrom expect an AcadObject array, not an AcadSelectionSet. You MUST convert the AcadSelectionSet to object array.

 

4. If your code is meant to run with AutoCAD VBA, you DO NOT declear a variable "ThisDrawing", which is AutoCAD VBA' reserved object

 

Anyway, Following should be how the SelectAll() function look like (not tested, just off my head):

 

Private Function SelectAll() As Variant

 Dim mode As Integer
 Dim ssetObj As AcadSelectionSet
Dim ss As AcadSelectionSet
For Each ss In ThisDrawing.SelectionSets
If UCase(ss.Name)="SSET" Then
Set ssetObj = ss
ssetObj.Clear
Exit For
End If
Next
If ssetObj Is Nothing Then Set ssetObj = ThisDrawing.SelectionSets.Add("SSET") End If Dim FilterType As Integer Dim FilterData As Variant FilterType = 67 FilterData = 0 ssetObj.Select acSelectionSetAll, , , FilterType, FilterData

Dim ents() As AcadEntity
Dim i As Inetger
For Each ent in ssetObj
ReDim Preserve ents(i)
Set ents(i)=ent
i = i + 1
Next

SelectAll = ents End Function

 HTH

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 23 of 28

Anonymous
Not applicable

here are some little modifications to your proposal:

 

Option Explicit

Private Function SelectAll() As Variant

    On Error Resume Next
    ThisDrawing.SelectionSets.Add ("SSET")
    On Error GoTo 0

    With ThisDrawing.SelectionSets("SSET")
        .Clear
        
        Dim FilterType(0 To 0) As Integer
        Dim FilterData(0 To 0) As Variant
        FilterType(0) = 67
        FilterData(0) = 0
        .Select acSelectionSetAll, , , FilterType, FilterData
        
        ReDim ents(0 To .Count - 1)
        Dim i As Integer
        For i = 0 To .Count - 1
            Set ents(i) = .Item(i)
        Next
    End With
    
    SelectAll = ents

End Function

 

 

0 Likes
Message 24 of 28

Anonymous
Not applicable

Hi Norman. Thanks for all your advice. It's good to have the explanations to go with everything - really helps me get my head around it all and how it thinks. 

I didn't think I needed to declare ThisDrawing either, but if I don't I keep getting "variable not defined"! I spent ages trying to figure it out and declaring it as i have seems to be the only way to pass it through. 

0 Likes
Message 25 of 28

Ed__Jobe
Mentor
Mentor

@Anonymous wrote:

I didn't think I needed to declare ThisDrawing either, but if I don't I keep getting "variable not defined"! I spent ages trying to figure it out and declaring it as i have seems to be the only way to pass it through. 


Declaring ThisDrawing and AcadApplication is something that AutoCAD VBA does for you automatically. If you're using COM in another app, i.e. not in AutoCAD, then you have to manually dim ThisDrawing or any other document variable you wish to use.

 

Another thing that AutoCAD VBA does for you is reference the correct/current AutoCAD tlb. Again, if you are in another app's vba, you have to reference the tlb manually.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes
Message 26 of 28

Anonymous
Not applicable

Ok, sorry I misunderstood you. I am using excel VBA so that is why I need to declare it i guess. 

0 Likes
Message 27 of 28

Anonymous
Not applicable

I started by using your code to try and perform the copying functions after selecting all of the items from another sheet. I also added a reference from the autodesk knowledge market "About copying multiple objects" to try and see if by setting an array equal to each copied object, it would actually perform the entire operation. However, it still does not perform as intended. Below is the code in question. I know it is not good practice to make a function for the select all but I think that this condenses everything neatly and should still perform as intended. 

The error code I get is a run time error with an "object not in database" description

 

On Error Resume Next
ThisDrawing.SelectionSets.Add ("SSET")
On Error GoTo 0

ThisDrawing.SelectionSets("SSET").Clear
Dim FilterType(0 To 0) As Integer
Dim FilterData(0 To 0) As Variant
FilterType(0) = 67
FilterData(0) = 0

ThisDrawing.SelectionSets("SSET").Select acSelectionSetAll, , , FilterType, FilterData

ReDim ents(0 To ThisDrawing.SelectionSets("SSET").Count - 1) As Object

Dim i As Integer

For i = 0 To ThisDrawing.SelectionSets("SSET").Count - 1
Set ents(i) = ThisDrawing.SelectionSets("SSET").Item(i)

Next

''Open a new drawing
Dim newDwg As AcadDocument
Dim newDwgMSpace As AcadModelSpace

Set newDwg = Documents.Add()
Set newDwgMSpace = newDwg.ModelSpace

''Copy entities from source drawing to new drawing
Dim m As Integer
Dim copiedobjects As Variant

copiedobjects = curDwg.CopyObjects(ents, newDwgMSpace)

 

0 Likes
Message 28 of 28

Anonymous
Not applicable

I don't see where is curdwg defined and set in your code: you should post all your not working code

0 Likes