For all files in folder, replace block from a identically named drawing

For all files in folder, replace block from a identically named drawing

Anonymous
Not applicable
2,827 Views
15 Replies
Message 1 of 16

For all files in folder, replace block from a identically named drawing

Anonymous
Not applicable

So basically I need some kind of script or VBA routine to do this:

 

For each drawing in folder 1 replace the same block from an identically named file located in folder 2.

Is this possible with any tool / script / routine?

0 Likes
2,828 Views
15 Replies
Replies (15)
Message 2 of 16

dlanorh
Advisor
Advisor

To the best of my knowledge, you can't replace blocks in drawing 1 with identically named blocks from drawing 2.

 

You can open drawing 2 delete everything then insert drawing 1, explode it and save as drawing 1. This could possibly be automated.

 

Or

 

You can open a new drawing, use LeeMac's steal lisp Here to steal the all the blocks from drawing 2, then insert drawing 1, explode it and save as drawing 1. Not sure if it is possible to integrate "steal.lsp" into an automatic process since it uses a DCL dialog interface.

 

I have yet to come across a lisp that has automated the whole proceedure, so if anyone else know of one I'll stand corrected.

I am not one of the robots you're looking for

0 Likes
Message 3 of 16

roland.r71
Collaborator
Collaborator

In theory... but it sounds like a very complex procedure.

First of all, you can not copy a block from one drawing to another, & definately not for redefining an existing block.

 

...but it slightly depends on what you are up to.

 

Is the name of the block known & always the same?

Or do you have to retrieve the block from drawing1 before you know what to get from drawing2?

Is it about the block, or about attribute values (or both) ?

etc.

 

A normal procedure would be to use wblock, to export the block from drawing2

& then redefine the block in drawing1 with that wblock. (& watch out for attribute changes, as you will lose values. To prevent that, read the values to variables before redefining (& attsync) so you can 'restore' the values afterwards.

 

It COULD be combined in an automated process.

However, if the blockname is not known, or not always the same, it becomes a hell of a procedure.

You would (at least) need to:

open drawing1, get the blockname.

Open drawing2 & wblock out the block by the same name. (& save any attrib values you need to a file)

Open drawing1 again (save any attrib values you wish to preserve) & redefine the block using the wblock file.

& set any attrib values 'copied' from drawing2 or 'preserved' from drawing1 (in case of changed tag names)

 

Unless you have hundreds of files and perfect lisp skills, doing it by hand might be faster as creating such routine.

 

"Simply" redefining the same block(s), with the same content, accross all drawings would be far easier.

0 Likes
Message 4 of 16

serag.hassouna
Advocate
Advocate

I've tried Wblock and CopyObjects methods in VBA (for Excel), however, both of them don't work!
I've made 2 trials:

  1. Fetch {block name,insertion point, Attributes Array} from drawing2, In drawing1 insert the block of the same name at the fetched insertion point, add it to a selection set, then apply Wblock, then delete the previously inserted block in drawing1.
    Result: Insertion works successfully, & WBlock doesn't work
  2. Fetch {block name, insertion point, Attributes Array} from drawing2, In drawing1 CopyObjects of the block, add them to a selection set, apply Wblock, then delete the copied objects.
    Result: The Program displays the number of entities within the selection set & they're reasonable, however, these objects don't appear within the drawing area itself when I leave them intentionally (by not deleting them), & as usual Wblock doesn't work.

____________________

Wblock is used like this

BaseDocument.Wblock TrgtFilepath, Block2Export

where BaseDocument is drawing1, TrgtFilepath is the path to drawing2, & Block2Export is the supplied selection set.

Message 5 of 16

serag.hassouna
Advocate
Advocate

The best I could accomplish until now is to copy "exploded" blocks from drawing1 to drawing2 onto their insertion points in drawing2.
Sadly, Wblock was useless with every attempt, CopyObjects doesn't affect block definition, and the block object (within AutoCAD's "documented" object model) doesn't expose any method to add multiple objects like the BEDIT command.

________________

Anyway, here's the reference files to the macro

macro references.PNG

 

And Here's the Code

Public FSO As New FileSystemObject
'The Fucntion ((ExplodeEX)) is written by Randal Rath
'The Source is from this URL:-
' https://forums.autodesk.com/t5/visual-basic-customization/explode-method-in-vba/m-p/336502#M28390
'This Function is used instead of the "Explode" method, that's because it doesn't work with blocks (undocumented issue)

Public Function ExplodeEX(oBlkRef As AcadBlockReference, _
bKeep As Boolean) As Variant
Dim objEnt As AcadEntity
Dim objMT As AcadMText
Dim objBlk As AcadBlock
Dim objDoc As AcadDocument
Dim objArray() As AcadEntity
Dim objSpace As AcadBlock
Dim intCnt As Integer
Dim varTemp As Variant
Dim varPnt As Variant
Dim dblScale As Double
Dim dblRot As Double
Dim dblMatrix(3, 3) As Double
On Error GoTo Err_Control
'What document is the reference in?
Set objDoc = oBlkRef.Document
'Model space or layout?
Set objSpace = objDoc.ObjectIdToObject(oBlkRef.OwnerID)
Set objBlk = objDoc.Blocks(oBlkRef.name)
varPnt = oBlkRef.InsertionPoint
dblScale = oBlkRef.XScaleFactor
dblRot = oBlkRef.Rotation
'Set the matrix for new objects transform
'*Note:
'This matrix uses only the X scale factor of the
'Block reference, many entities can not be scaled
'Non-uniformly!
dblMatrix(0, 0) = dblScale
dblMatrix(0, 1) = 0
dblMatrix(0, 2) = 0
dblMatrix(0, 3) = varPnt(0)
dblMatrix(1, 0) = 0
dblMatrix(1, 1) = dblScale
dblMatrix(1, 2) = 0
dblMatrix(1, 3) = varPnt(1)
dblMatrix(2, 0) = 0
dblMatrix(2, 1) = 0
dblMatrix(2, 2) = dblScale
dblMatrix(2, 3) = varPnt(2)
dblMatrix(3, 0) = 0
dblMatrix(3, 1) = 0
dblMatrix(3, 2) = 0
dblMatrix(3, 3) = 1
'Get all of the entities in the block
ReDim objArray(objBlk.Count - 1)
For Each objEnt In objBlk
Set objArray(intCnt) = objEnt
intCnt = intCnt + 1
Next objEnt
'Place them into the correct space
varTemp = objDoc.CopyObjects(objArray, objSpace)
'Transform & rotate
For intCnt = LBound(varTemp) To UBound(varTemp)
Set objEnt = varTemp(intCnt)
objEnt.TransformBy dblMatrix
objEnt.Rotate varPnt, dblRot
Next intCnt
'Keep the block reference?
If Not bKeep Then
oBlkRef.Delete
End If
'Return all of the new entities
ExplodeEX = varTemp
'Release memory
Set objDoc = Nothing
Set objBlk = Nothing
Set objSpace = Nothing
Exit_Here:
Exit Function
Err_Control:
MsgBox Err.Description
Resume Exit_Here
End Function

'The Subroutine BlockReplace is written by Serag Hassouna
'The Commented Codes belong to the unsuccessfull trials, they're left for reference
Sub BlockReplace()
    'Get the Application object
    Dim acad As AcadApplication
    Set acad = GetObject(, "AutoCAD.Application.20")
    
    'Get the Documents Collection
    Dim docs As AcadDocuments
    Set docs = acad.Documents

    'Get folders' directories
    Dim dir1 As String, dir2 As String
    '<<Replace these directories to the actual ones of folder 1 & folder 2>>
    dir1 = "C:\User\AutoCAD files\folder1"
    dir2 = "C:\User\AutoCAD files\folder2"
    
    Dim BaseFo As Folder, BaseFile As File, TrgtFile As File
    Set BaseFo = FSO.GetFolder(dir1)
    
    'Declare needed variables
    Dim BaseFilename As String, BaseFilepath As String, TrgtFilepath As String
    Dim BaseDocument As AcadDocument, TrgtDocument As AcadDocument
    Dim AllBlockRefs As AcadSelectionSet
    Dim gpcode(0) As Integer, datavalue(0) As Variant
    gpcode(0) = 0
    datavalue(0) = "INSERT"
    Dim GroupCode As Variant, dataCode As Variant
    GroupCode = gpcode
    dataCode = datavalue
    
    Dim BlockRef As AcadBlockReference, i As Integer, BRefName As String, BRefInsPnt As Variant
    Dim BlockAttrs As Variant, BRefInBase As AcadBlockReference
    Dim obj() As Variant 'As Object with CopyObjects method, As AcadEntity with single Blocks
    Dim TrgtObj() As Variant
    ' Dim objs() As Object
    ' Dim ssobjs As AcadSelectionSet
    Dim BCount As Integer
    Dim j As Integer
    
    'Iterate through the base folder, get the other file that's named the same
    'Make a selection set for all block reference objects within the target drawing
    'For every block reference, get its name, insertion point and attributes
    'The rest are ((trials to copy the block references from base drawing to target drawing))
    For Each BaseFile In BaseFo.Files
        BaseFilename = BaseFile.name
        BaseFilepath = dir1 & "\" & BaseFilename
        TrgtFilepath = dir2 & "\" & BaseFilename
        
        
        Set BaseDocument = docs.Open(BaseFilepath)
        Set TrgtDocument = docs.Open(TrgtFilepath)
        
        Set AllBlockRefs = TrgtDocument.SelectionSets.Add("allblockrefs")
        'Set ssobjs = BaseDocument.SelectionSets.Add("BlocksToDeliver")
        AllBlockRefs.Select acSelectionSetAll, , , GroupCode, dataCode
        BCount = AllBlockRefs.Count
        ReDim obj(0 To (BCount - 1)) As Variant 'Base objects to be copied, As Object with CopyObjects method
        'As AcadEntity with Wblock when they're single Blocks
        ReDim TrgtObj(0 To (BCount - 1)) As Variant
        
        'For every target blockref, insert a similar-named block within the base drawing
        For i = 0 To (BCount - 1)
            Set BlockRef = AllBlockRefs.Item(i)
            BRefName = BlockRef.name
            BRefInsPnt = BlockRef.InsertionPoint
            BlockAttrs = BlockRef.GetAttributes
            
            obj(i) = ExplodeEX(BaseDocument.ModelSpace.InsertBlock(BRefInsPnt, BRefName, 1, 1, 1, 0), False) 'Thanks Randal Rath
            ' "Set" keyword was used with obj(i) when its data type was Object & AcadEntity
            ' ssobjs.AddItems obj(i)
            ' BaseDocument.Wblock TrgtFilepath, ssobjs
            TrgtObj(i) = BaseDocument.CopyObjects(obj(i), TrgtDocument.ModelSpace) 'Works with Modelspace, not with any block definition
            'TrgtDocument.CopyObjects TrgtObj(i), TrgtDocument.Blocks.Item(BRefName) 'Doesn't Work
            ' ssobjs.Clear
            
            'Delete the objects resulted from the explosion process
            For j = LBound(obj(i)) To UBound(obj(i))
                obj(i)(j).Delete
            Next j
            
        Next i
        
        
        ' ReDim objs(0 To (BCount - 1)) As Object 'used with CopyObject
        ' objs = BaseDocument.CopyObjects(obj, TrgtDocument.ModelSpace)
        ' ssobjs.AddItems obj 'used with Wblock
        ' BaseDocument.Wblock TrgtFilepath, ssobjs
        
        'Delete blocks from target drawings [not used when incrementing with "Item" method to avoid
        'any indexing issues that could result from deletion]
        Dim elem As Variant 'any other data type declaration generates an error
        For Each elem In AllBlockRefs
            elem.Delete
        Next elem
        
        BaseDocument.Close False
        TrgtDocument.Close True
    Next BaseFile
    
    MsgBox "Finished" 'debug line
    
End Sub
Message 6 of 16

roland.r71
Collaborator
Collaborator

The only way I know to do this would be to use lisp, in a way most will tell you is impossible. By switching drawings from a lisp routine.

 

While drawing1 is open, let user select a block.

Check if no other drawings are open

If not, set SDI to 1 & LISPINIT to 0

Now use fileopen to open drawing2

( - Thanks to those 2 settings the lisp will not terminate at this point, but continue!  - )

Check for the block & wblock it to a temp folder

Use fileopen to open drawing1 again

& insert/redefine the block using the wblock dwg.

(& meanwhile mind the attribute tags!!!)

 

Apart from getting the blockname from drawing1, I've done this before.

Message 7 of 16

roland.r71
Collaborator
Collaborator

Proof of concept:

For this I used 1 DWG in a folder called: SET1

I made a copy in folder: SET2 and changed the block a bit.

I opened the first DWG (SET1) and loaded&executed the below routine.

 

It asks for a block, then opens the second dwg (SET2) exports the block by the same name using WBLOCK to the system TEMP folder. Then it reopens the first dwg (SET1) and -inserts (&redefines) the block.

 

When done, the block from SET1 will have been replaced by the block from SET2 (with the same name)

It checks if a block was selected & it checks if the block exists inside the second DWG (SET2), and it will delete the WBLOCK dwg inside the TEMP folder, to clean up. but that's about it. So, as I said: this is realy only just a "(quick 'n dirty) proof of concept".

 

(defun C:redef (/ *error* sdi lispinit attreq curDWG secDWG blk blkName blkDef)

   (defun *error* ( msg / )
(if attreq (setvar "ATTREQ") attreq) (if (= sdi 0) (setvar "SDI" 0)) (if (= lispinit 1)(setvar "LISPINIT" 1)) (if (or (= msg "Function cancelled") (= msg "quit / exit abort") ) (princ) (progn (princ (strcat "; error: " msg))(princ)) ) ) (setq sdi (getvar "SDI")) (setq lispinit (getvar "LISPINIT")) (if (= sdi 0)(setvar "SDI" 1)) (if (= lispinit 1)(setvar "LISPINIT" 0)) (setq curDWG (strcat (getvar "dwgprefix") (getvar "dwgname"))) (setq secDWG (strcat "c:/lisp/testDWG/set2/" (getvar "dwgname"))) ; change path! (setq blk (entsel "Select block to copy ")) (if (= (cdr (assoc 0 (entget (car blk)))) "INSERT") (progn (setq blkName (cdr (assoc 2 (entget (car blk))))) (setq blkDef (strcat (getvar "TEMPPREFIX") blkName ".dwg")) (command "QSAVE") (command "_.fileopen" secDWG) (if (ssget "X" (list (cons 2 blkName))) (command "-wblock" blkDef blkName) ) (command "QSAVE") (command "_.fileopen" curDWG) (if (findfile blkDef) (progn (setq attreq (getvar "ATTREQ")) (setvar "ATTREQ" 0) (command "-insert" (strcat blkName "=" blkDef) "0,0" "" "") (setvar "ATTREQ" attreq) (vl-file-delete blkdef) ) ) ) (prompt "\nPlease select a block") ) (if (= sdi 0)(setvar "SDI" 0)) (if (= lispinit 1)(setvar "LISPINIT" 1)) (princ) )
Message 8 of 16

roland.r71
Collaborator
Collaborator

 

   (defun *error* ( msg / )
(if attreq (setvar "ATTREQ") attreq)

I see I made a booboo, with my last minute adition...

Should of course be:

(if attreq (setvar "ATTREQ" attreq))

Message 9 of 16

serag.hassouna
Advocate
Advocate

@roland.r71 wrote:

The only way I know to do this would be to use lisp, in a way most will tell you is impossible. By switching drawings from a lisp routine.


Finally, I made it with VBA, though attributes needs a second look, but I do now have a working code that accomplish the rest.

This is thanks to the sincere help from you, @doaiena, and Randal Rath's old reply. 

Check out this code.

Public FSO As New FileSystemObject
'The Fucntion ((ExplodeEX)) is written by Randal Rath
'The Source is from this URL:-
' https://forums.autodesk.com/t5/visual-basic-customization/explode-method-in-vba/m-p/336502#M28390
'This Function is used instead of the "Explode" method, that's because it doesn't work with blocks (undocumented issue)

Public Function ExplodeEX(oBlkRef As AcadBlockReference, _
bKeep As Boolean) As Variant
Dim objEnt As AcadEntity
Dim objMT As AcadMText
Dim objBlk As AcadBlock
Dim objDoc As AcadDocument
Dim objArray() As AcadEntity
Dim objSpace As AcadBlock
Dim intCnt As Integer
Dim varTemp As Variant
Dim varPnt As Variant
Dim dblScale As Double
Dim dblRot As Double
Dim dblMatrix(3, 3) As Double
On Error GoTo Err_Control
'What document is the reference in?
Set objDoc = oBlkRef.Document
'Model space or layout?
Set objSpace = objDoc.ObjectIdToObject(oBlkRef.OwnerID)
Set objBlk = objDoc.Blocks(oBlkRef.name)
varPnt = oBlkRef.InsertionPoint
dblScale = oBlkRef.XScaleFactor
dblRot = oBlkRef.Rotation
'Set the matrix for new objects transform
'*Note:
'This matrix uses only the X scale factor of the
'Block reference, many entities can not be scaled
'Non-uniformly!
dblMatrix(0, 0) = dblScale
dblMatrix(0, 1) = 0
dblMatrix(0, 2) = 0
dblMatrix(0, 3) = varPnt(0)
dblMatrix(1, 0) = 0
dblMatrix(1, 1) = dblScale
dblMatrix(1, 2) = 0
dblMatrix(1, 3) = varPnt(1)
dblMatrix(2, 0) = 0
dblMatrix(2, 1) = 0
dblMatrix(2, 2) = dblScale
dblMatrix(2, 3) = varPnt(2)
dblMatrix(3, 0) = 0
dblMatrix(3, 1) = 0
dblMatrix(3, 2) = 0
dblMatrix(3, 3) = 1
'Get all of the entities in the block
ReDim objArray(objBlk.Count - 1)
For Each objEnt In objBlk
Set objArray(intCnt) = objEnt
intCnt = intCnt + 1
Next objEnt
'Place them into the correct space
varTemp = objDoc.CopyObjects(objArray, objSpace)
'Transform & rotate
For intCnt = LBound(varTemp) To UBound(varTemp)
Set objEnt = varTemp(intCnt)
objEnt.TransformBy dblMatrix
objEnt.Rotate varPnt, dblRot
Next intCnt
'Keep the block reference?
If Not bKeep Then
oBlkRef.Delete
End If
'Return all of the new entities
ExplodeEX = varTemp
'Release memory
Set objDoc = Nothing
Set objBlk = Nothing
Set objSpace = Nothing
Exit_Here:
Exit Function
Err_Control:
MsgBox Err.Description
Resume Exit_Here
End Function

'The Subroutine ((BlockReplace)) is written by Serag Hassouna
'The Commented Codes belong to the unsuccessfull trials, they're left for reference
Sub BlockReplace()
    'Get the Application object
    Dim acad As AcadApplication
    Set acad = GetObject(, "AutoCAD.Application.20")
    
    'Get the Documents Collection
    Dim docs As AcadDocuments
    Set docs = acad.Documents

    'Get folders' directories
    Dim dir1 As String, dir2 As String
    '<<Replace these directories to the actual ones of folder 1 & folder 2>>
    dir1 = "C:\User\AutoCAD files\folder1"
    dir2 = "C:\User\AutoCAD files\folder2"
    
    Dim BaseFo As Folder, BaseFile As File, TrgtFile As File
    Set BaseFo = FSO.GetFolder(dir1)
    
    'Declare needed variables
    Dim BaseFilename As String, BaseFilepath As String, TrgtFilepath As String
    Dim BaseDocument As AcadDocument, TrgtDocument As AcadDocument
    Dim AllBlockRefs As AcadSelectionSet
    Dim gpcode(0) As Integer, datavalue(0) As Variant
    gpcode(0) = 0
    datavalue(0) = "INSERT"
    Dim GroupCode As Variant, dataCode As Variant
    GroupCode = gpcode
    dataCode = datavalue
    
    'Variables for block references in target drawing
    Dim BlockRef As AcadBlockReference, BRefName As String, BRefInsPnt As Variant
    Dim BCount As Integer
    
    'Variables for the copied objects to the target drawing
    Dim obj() As Variant
    Dim TrgtObj() As Variant
    Dim ssTrgtObj As AcadSelectionSet, DefInsPnt As String
    
    'Variables for block definitions
    Dim BDefsStatus() As Variant, BDefStatus(0 To 1) As String, BDefSt As Variant 'is block definition modified?
    Dim BDefsCount As Integer
    
    'Variables for incrementation
    Dim i As Integer, j As Integer, k As Integer, m As Integer, m2 As Integer
    

    'Iterate through the base folder, get the other file that's named the same
    'Make a selection set for all block reference objects within the target drawing
    'For every block reference, get its name, insertion point and attributes
    'If the corespondant block definition isn't modified, modify it
    'by
    '  1- insert a block reference in the base drawing onto the corespondant insertion point of the
    '     the block reference with the target drawing.
    '  2- explode the newly inserted block reference in the base drawing.
    '  3- copy the explosion objects to the target drawing.
    '      [an attribute definition was inserted within a block definition in the base
    '      drawing & was successfully copied to the target drawing]
'Note that modification is done with the "-Block" command
'Finally, insert the modified block into its original insertion point in the target drawing. For Each BaseFile In BaseFo.Files BaseFilename = BaseFile.name If Right(BaseFilename, 4) = ".dwg" Then BaseFilepath = dir1 & "\" & BaseFilename TrgtFilepath = dir2 & "\" & BaseFilename Set BaseDocument = docs.Open(BaseFilepath) On Error GoTo NoMatchFile: Set TrgtDocument = docs.Open(TrgtFilepath) TrgtDocument.Activate TrgtDocument.SendCommand "(vl-load-com)" & vbCr 'Prepare for blocks redefinition Set AllBlockRefs = TrgtDocument.SelectionSets.Add("allblockrefs") Set ssTrgtObj = TrgtDocument.SelectionSets.Add("Block2Define") AllBlockRefs.Select acSelectionSetAll, , , GroupCode, dataCode BCount = AllBlockRefs.Count BDefsCount = BaseDocument.Blocks.Count ReDim obj(0 To (BCount - 1)) As Variant 'Base objects to be copied, As Object with CopyObjects method 'As AcadEntity with Wblock when they're single Blocks ReDim TrgtObj(0 To (BCount - 1)) As Variant ReDim idpairs(0 To (BCount - 1)) As Variant Dim TrgtObjs() As AcadEntity 'for "Block2Define" Selection Set ReDim BDefsStatus(0 To BDefsCount) As Variant On Error Resume Next 'Make the useless "Invalid procedure call or argument" error go away For m = 0 To BDefsCount BDefStatus(0) = BaseDocument.Blocks.Item(m).name BDefStatus(1) = "Not Modified" BDefsStatus(m) = BDefStatus Next m 'Define vlaSel->Sel (docks elements in an ActiveX sset to a new ordinary sset) 'vlaSel-> is written by Doaiena 'The replay URL that contains it is:- ' https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/convert-selection-set-s-vla-object-to-ordinary-selection-set/m-p/8216062#M373023 TrgtDocument.Activate TrgtDocument.SendCommand "(defun vlaSel->Sel ( vlaSel / sel )" & vbLf & _ "(setq sel (ssadd))" & vbLf & _ "(vlax-for obj vlaSel" & vbLf & _ "(ssadd (vlax-vla-object->ename obj) sel)" & vbLf & _ ")" & vbLf & _ "sel" & vbLf & _ ")" & vbCr 'For every target blockref, insert a similar-named block within the base drawing For i = 0 To (BCount - 1) Set BlockRef = AllBlockRefs.Item(i) BRefName = BlockRef.name BRefInsPnt = BlockRef.InsertionPoint DefInsPnt = BRefInsPnt(0) & "," & BRefInsPnt(1) & "," & BRefInsPnt(2) 'get the block definition modification status For m = 0 To BDefsCount If BRefName = BDefsStatus(m)(0) Then BDefSt = BDefsStatus(m)(1) m2 = m End If Next m 'if the block definition isn't modified, modify it and change its modification status If BDefSt = "Not Modified" Then BDefsStatus(m2)(1) = "Modified" obj(i) = ExplodeEX(BaseDocument.ModelSpace.InsertBlock(BRefInsPnt, BRefName, 1, 1, 1, 0), False) 'Thanks Randal Rath ' "Set" keyword was used with obj(i) when its data type was Object & AcadEntity TrgtObj(i) = BaseDocument.CopyObjects(obj(i), TrgtDocument.ModelSpace, idpairs(i)) 'Works with ModelSpace, not with any block definition ReDim TrgtObjs(LBound(TrgtObj(i)) To UBound(TrgtObj(i))) For k = LBound(TrgtObj(i)) To UBound(TrgtObj(i)) Set TrgtObjs(k) = TrgtObj(i)(k) Next k ssTrgtObj.AddItems TrgtObjs 'MsgBox ssTrgtObj.Count 'Selection Set works fine 'Delete the objects resulted from the explosion process For j = LBound(obj(i)) To UBound(obj(i)) obj(i)(j).Delete Next j 'Redefine block TrgtDocument.SendCommand "-Block" & vbCr & BRefName & vbCr & "y" & vbCr & DefInsPnt & vbCr & _ "(vlaSel->Sel (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) ""Block2Define""))" _ & vbCr & vbCr End If 'MsgBox CStr(idpairs(i)) 'debug line TrgtDocument.ModelSpace.InsertBlock BRefInsPnt, BRefName, 1, 1, 1, 0 ssTrgtObj.Clear Next i 'Delete blocks from target drawings [not used when incrementing with "Item" method to avoid 'any indexing issues that could result from deletion] Dim elem As Variant 'any other data type declaration generates an error For Each elem In AllBlockRefs elem.Delete Next elem BaseDocument.Close False TrgtDocument.Close True End If 'for dealing only with .dwg files Next BaseFile NoMatchFile: MsgBox "Base file " & BaseFilename & " has no target one." & vbLf & "Operation Terminated." BaseDocument.Close False Exit Sub End Sub
Message 10 of 16

serag.hassouna
Advocate
Advocate

This is a slightly modified code that uses the 2nd version of @doaiena's vlaSel->Sel function, and resolves a bug for the false alert of "target file absence".

 

Public FSO As New FileSystemObject
'The Fucntion ((ExplodeEX)) is written by Randal Rath
'The Source is from this URL:-
' https://forums.autodesk.com/t5/visual-basic-customization/explode-method-in-vba/m-p/336502#M28390
'This Function is used instead of the "Explode" method, that's because it doesn't work with blocks (undocumented issue)

Public Function ExplodeEX(oBlkRef As AcadBlockReference, _
bKeep As Boolean) As Variant
Dim objEnt As AcadEntity
Dim objMT As AcadMText
Dim objBlk As AcadBlock
Dim objDoc As AcadDocument
Dim objArray() As AcadEntity
Dim objSpace As AcadBlock
Dim intCnt As Integer
Dim varTemp As Variant
Dim varPnt As Variant
Dim dblScale As Double
Dim dblRot As Double
Dim dblMatrix(3, 3) As Double
On Error GoTo Err_Control
'What document is the reference in?
Set objDoc = oBlkRef.Document
'Model space or layout?
Set objSpace = objDoc.ObjectIdToObject(oBlkRef.OwnerID)
Set objBlk = objDoc.Blocks(oBlkRef.name)
varPnt = oBlkRef.InsertionPoint
dblScale = oBlkRef.XScaleFactor
dblRot = oBlkRef.Rotation
'Set the matrix for new objects transform
'*Note:
'This matrix uses only the X scale factor of the
'Block reference, many entities can not be scaled
'Non-uniformly!
dblMatrix(0, 0) = dblScale
dblMatrix(0, 1) = 0
dblMatrix(0, 2) = 0
dblMatrix(0, 3) = varPnt(0)
dblMatrix(1, 0) = 0
dblMatrix(1, 1) = dblScale
dblMatrix(1, 2) = 0
dblMatrix(1, 3) = varPnt(1)
dblMatrix(2, 0) = 0
dblMatrix(2, 1) = 0
dblMatrix(2, 2) = dblScale
dblMatrix(2, 3) = varPnt(2)
dblMatrix(3, 0) = 0
dblMatrix(3, 1) = 0
dblMatrix(3, 2) = 0
dblMatrix(3, 3) = 1
'Get all of the entities in the block
ReDim objArray(objBlk.Count - 1)
For Each objEnt In objBlk
Set objArray(intCnt) = objEnt
intCnt = intCnt + 1
Next objEnt
'Place them into the correct space
varTemp = objDoc.CopyObjects(objArray, objSpace)
'Transform & rotate
For intCnt = LBound(varTemp) To UBound(varTemp)
Set objEnt = varTemp(intCnt)
objEnt.TransformBy dblMatrix
objEnt.Rotate varPnt, dblRot
Next intCnt
'Keep the block reference?
If Not bKeep Then
oBlkRef.Delete
End If
'Return all of the new entities
ExplodeEX = varTemp
'Release memory
Set objDoc = Nothing
Set objBlk = Nothing
Set objSpace = Nothing
Exit_Here:
Exit Function
Err_Control:
MsgBox Err.Description
Resume Exit_Here
End Function

'The Subroutine ((BlockReplace)) is written by Serag Hassouna
'The Commented Codes belong to the unsuccessfull trials, they're left for reference
Sub BlockReplace()
    'Get the Application object
    Dim acad As AcadApplication
    Set acad = GetObject(, "AutoCAD.Application.20")
    
    'Get the Documents Collection
    Dim docs As AcadDocuments
    Set docs = acad.Documents

    'Get folders' directories
    Dim dir1 As String, dir2 As String
    '<<Replace these directories to the actual ones of folder 1 & folder 2>>
    dir1 = "C:\User\AutoCAD files\folder1"
    dir2 = "C:\User\AutoCAD files\folder2"
    
    Dim BaseFo As Folder, BaseFile As File, TrgtFile As File
    Set BaseFo = FSO.GetFolder(dir1)
    
    'Declare needed variables
    Dim BaseFilename As String, BaseFilepath As String, TrgtFilepath As String
    Dim BaseDocument As AcadDocument, TrgtDocument As AcadDocument
    Dim AllBlockRefs As AcadSelectionSet
    Dim gpcode(0) As Integer, datavalue(0) As Variant
    gpcode(0) = 0
    datavalue(0) = "INSERT"
    Dim GroupCode As Variant, dataCode As Variant
    GroupCode = gpcode
    dataCode = datavalue
    
    'Variables for block references in target drawing
    Dim BlockRef As AcadBlockReference, BRefName As String, BRefInsPnt As Variant
    Dim BCount As Integer
    
    'Variables for the copied objects to the target drawing
    Dim obj() As Variant
    Dim TrgtObj() As Variant
    Dim ssTrgtObj As AcadSelectionSet, DefInsPnt As String
    
    'Variables for block definitions
    Dim BDefsStatus() As Variant, BDefStatus(0 To 1) As String, BDefSt As Variant 'is block definition modified?
    Dim BDefsCount As Integer
    
    'Variables for incrementation
    Dim i As Integer, j As Integer, k As Integer, m As Integer, m2 As Integer
    

    'Iterate through the base folder, get the other file that's named the same
    'Make a selection set for all block reference objects within the target drawing
    'For every block reference, get its name, insertion point and attributes
    'If the corespondant block definition isn't modified, modify it
    'by
    '  1- insert a block reference in the base drawing onto the corespondant insertion point of the
    '     the block reference with the target drawing.
    '  2- explode the newly inserted block reference in the base drawing.
    '  3- copy the explosion objects to the target drawing.
    '      [an attribute definition was inserted within a block definition in the base
    '      drawing & was successfully copied to the target drawing]
    'Note that modification is done with the "-Block" command
    'Finally, insert the modified block into its original insertion point in the target drawing.
    For Each BaseFile In BaseFo.Files
        BaseFilename = BaseFile.name
        
        If Right(BaseFilename, 4) = ".dwg" Then
        
        BaseFilepath = dir1 & "\" & BaseFilename
        TrgtFilepath = dir2 & "\" & BaseFilename
        
        
        Set BaseDocument = docs.Open(BaseFilepath)
        On Error GoTo NoMatchFile:
        Set TrgtDocument = docs.Open(TrgtFilepath)
        TrgtDocument.Activate
        TrgtDocument.SendCommand "(vl-load-com)" & vbCr 'Prepare for blocks redefinition
        
        Set AllBlockRefs = TrgtDocument.SelectionSets.Add("allblockrefs")
        Set ssTrgtObj = TrgtDocument.SelectionSets.Add("Block2Define")
        AllBlockRefs.Select acSelectionSetAll, , , GroupCode, dataCode
        
        BCount = AllBlockRefs.Count
        BDefsCount = BaseDocument.Blocks.Count
        
        ReDim obj(0 To (BCount - 1)) As Variant 'Base objects to be copied, As Object with CopyObjects method
        'As AcadEntity with Wblock when they're single Blocks
        ReDim TrgtObj(0 To (BCount - 1)) As Variant
        ReDim idpairs(0 To (BCount - 1)) As Variant
        Dim TrgtObjs() As AcadEntity 'for "Block2Define" Selection Set
        ReDim BDefsStatus(0 To BDefsCount) As Variant
        
        On Error Resume Next 'Make the useless "Invalid procedure call or argument" error go away
        For m = 0 To BDefsCount
            BDefStatus(0) = BaseDocument.Blocks.Item(m).name
            BDefStatus(1) = "Not Modified"
            
            BDefsStatus(m) = BDefStatus
        Next m
        
        'Define vlaSel->Sel (docks elements in an ActiveX sset to a new ordinary sset)
        'vlaSel-> is written by Doaiena
        'The replay URL that contains it is:-
        ' https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/convert-selection-set-s-vla-object-to-ordinary-selection-set/m-p/8216368#M373026
            TrgtDocument.Activate
            
            TrgtDocument.SendCommand "(defun vlaSel->Sel (vlaSel / selName sel)" & vbLf & _
            "(setq selName (vla-get-name vlaSel))" & vbLf & _
            "(if (not *SS*)" & vbLf & _
            "(setq *SS* (cons (cons nil nil) *SS*))" & vbLf & _
            ")" & vbLf & _
            "(if (not (assoc selName *SS*))" & vbLf & _
            "(progn" & vbLf & _
            "(setq sel (ssadd))" & vbLf & _
            "(vlax-for obj vlaSel" & vbLf & _
            "(ssadd (vlax-vla-object->ename obj) sel)" & vbLf & _
            ")" & vbLf & _
            "(setq *SS* (cons (cons selName (eval sel)) *SS*))" & vbLf & _
            ")" & vbLf & _
            ")" & vbLf & _
            "(cdr (assoc selName *SS*))" & vbLf & _
            ")" & vbCr
        
        'For every target blockref, insert a similar-named block within the base drawing
        For i = 0 To (BCount - 1)
            Set BlockRef = AllBlockRefs.Item(i)
            BRefName = BlockRef.name
            BRefInsPnt = BlockRef.InsertionPoint
            DefInsPnt = BRefInsPnt(0) & "," & BRefInsPnt(1) & "," & BRefInsPnt(2)
            
            'get the block definition modification status
            For m = 0 To BDefsCount
                If BRefName = BDefsStatus(m)(0) Then
                    BDefSt = BDefsStatus(m)(1)
                    m2 = m
                End If
            Next m
            
            'if the block definition isn't modified, modify it and change its modification status
            If BDefSt = "Not Modified" Then
            
                BDefsStatus(m2)(1) = "Modified"
                
                obj(i) = ExplodeEX(BaseDocument.ModelSpace.InsertBlock(BRefInsPnt, BRefName, 1, 1, 1, 0), False) 'Thanks Randal Rath
                ' "Set" keyword was used with obj(i) when its data type was Object & AcadEntity

                TrgtObj(i) = BaseDocument.CopyObjects(obj(i), TrgtDocument.ModelSpace, idpairs(i)) 'Works with ModelSpace, not with any block definition
            
                ReDim TrgtObjs(LBound(TrgtObj(i)) To UBound(TrgtObj(i)))
                For k = LBound(TrgtObj(i)) To UBound(TrgtObj(i))
                    Set TrgtObjs(k) = TrgtObj(i)(k)
                Next k
            
                ssTrgtObj.AddItems TrgtObjs
                'MsgBox ssTrgtObj.Count 'Selection Set works fine
            
                'Delete the objects resulted from the explosion process
                For j = LBound(obj(i)) To UBound(obj(i))
                    obj(i)(j).Delete
                Next j
                
                'Redefine block
                TrgtDocument.SendCommand "-Block" & vbCr & BRefName & vbCr & "y" & vbCr & DefInsPnt & vbCr & _
                "(vlaSel->Sel (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) ""Block2Define""))" _
                & vbCr & vbCr
            
            End If
            
            'MsgBox CStr(idpairs(i)) 'debug line
            TrgtDocument.ModelSpace.InsertBlock BRefInsPnt, BRefName, 1, 1, 1, 0
            ssTrgtObj.Clear
            
            
        Next i
        
        'Delete blocks from target drawings [not used when incrementing with "Item" method to avoid
        'any indexing issues that could result from deletion]
        Dim elem As Variant 'any other data type declaration generates an error
        For Each elem In AllBlockRefs
            elem.Delete
        Next elem
        
        BaseDocument.Close False
        TrgtDocument.Close True
        
        End If 'for dealing only with .dwg files
    Next BaseFile
    
NoMatchFile:
  If Err.Number = -2145320924 Then
      MsgBox "Base file " & BaseFilename & " has no target one." & vbLf & "Operation Terminated."
      BaseDocument.Close False
  End If
  Exit Sub
End Sub
Message 11 of 16

serag.hassouna
Advocate
Advocate

As For a VBA routine, this is the last version that hasn't produced any bug yet as far as I know.
I've posted similar routines but both of them don't work totally as expected.

Public FSO As New FileSystemObject
'The Fucntion ((ExplodeEX)) is written by Randal Rath
'The Source is from this URL:-
' https://forums.autodesk.com/t5/visual-basic-customization/explode-method-in-vba/m-p/336502#M28390
'This Function is used instead of the "Explode" method, that's because it doesn't work with blocks (undocumented issue)

Public Function ExplodeEX(oBlkRef As AcadBlockReference, _
bKeep As Boolean) As Variant
Dim objEnt As AcadEntity
Dim objMT As AcadMText
Dim objBlk As AcadBlock
Dim objDoc As AcadDocument
Dim objArray() As AcadEntity
Dim objSpace As AcadBlock
Dim intCnt As Integer
Dim varTemp As Variant
Dim varPnt As Variant
Dim dblScale As Double
Dim dblRot As Double
Dim dblMatrix(3, 3) As Double
On Error GoTo Err_Control
'What document is the reference in?
Set objDoc = oBlkRef.Document
'Model space or layout?
Set objSpace = objDoc.ObjectIdToObject(oBlkRef.OwnerID)
Set objBlk = objDoc.Blocks(oBlkRef.name)
varPnt = oBlkRef.InsertionPoint
dblScale = oBlkRef.XScaleFactor
dblRot = oBlkRef.Rotation
'Set the matrix for new objects transform
'*Note:
'This matrix uses only the X scale factor of the
'Block reference, many entities can not be scaled
'Non-uniformly!
dblMatrix(0, 0) = dblScale
dblMatrix(0, 1) = 0
dblMatrix(0, 2) = 0
dblMatrix(0, 3) = varPnt(0)
dblMatrix(1, 0) = 0
dblMatrix(1, 1) = dblScale
dblMatrix(1, 2) = 0
dblMatrix(1, 3) = varPnt(1)
dblMatrix(2, 0) = 0
dblMatrix(2, 1) = 0
dblMatrix(2, 2) = dblScale
dblMatrix(2, 3) = varPnt(2)
dblMatrix(3, 0) = 0
dblMatrix(3, 1) = 0
dblMatrix(3, 2) = 0
dblMatrix(3, 3) = 1
'Get all of the entities in the block
ReDim objArray(objBlk.Count - 1)
For Each objEnt In objBlk
Set objArray(intCnt) = objEnt
intCnt = intCnt + 1
Next objEnt
'Place them into the correct space
varTemp = objDoc.CopyObjects(objArray, objSpace)
'Transform & rotate
For intCnt = LBound(varTemp) To UBound(varTemp)
Set objEnt = varTemp(intCnt)
objEnt.TransformBy dblMatrix
objEnt.Rotate varPnt, dblRot
Next intCnt
'Keep the block reference?
If Not bKeep Then
oBlkRef.Delete
End If
'Return all of the new entities
ExplodeEX = varTemp
'Release memory
Set objDoc = Nothing
Set objBlk = Nothing
Set objSpace = Nothing
Exit_Here:
Exit Function
Err_Control:
MsgBox Err.Description
Resume Exit_Here
End Function

'The Subroutine ((BlockReplace)) is written by Serag Hassouna
'The Commented Codes belong to the unsuccessfull trials, they're left for reference
Sub BlockReplace()
    'Get the Application object
    Dim acad As AcadApplication
    Set acad = GetObject(, "AutoCAD.Application.20")
    
    'Get the Documents Collection
    Dim docs As AcadDocuments
    Set docs = acad.Documents

    'Get folders' directories
    Dim dir1 As String, dir2 As String
    '<<Replace these directories to the actual ones of folder 1 & folder 2>>
    dir1 = "C:\User\AutoCAD files\folder1"
    dir2 = "C:\User\AutoCAD files\folder2"
    
    Dim BaseFo As Folder, BaseFile As File, TrgtFile As File
    Set BaseFo = FSO.GetFolder(dir1)
    
    'Declare needed variables
    Dim BaseFilename As String, BaseFilepath As String, TrgtFilepath As String
    Dim BaseDocument As AcadDocument, TrgtDocument As AcadDocument
    Dim AllBlockRefs As AcadSelectionSet
    Dim gpcode(0) As Integer, datavalue(0) As Variant
    gpcode(0) = 0
    datavalue(0) = "INSERT"
    Dim GroupCode As Variant, dataCode As Variant
    GroupCode = gpcode
    dataCode = datavalue
    
    'Variables for block references in target drawing
    Dim BlockRef As AcadBlockReference, BRefName As String, BRefInsPnt As Variant
    Dim BCount As Integer
    
    'Variables for the copied objects to the target drawing
    Dim obj() As Variant
    Dim TrgtObj() As Variant
    Dim ssTrgtObj As AcadSelectionSet, DefInsPnt As String
    
    'Variables for block definitions
    Dim BDefsStatus() As Variant, BDefStatus(0 To 1) As String, BDefSt As Variant 'is block definition modified?
    Dim BDefsCount As Integer
    
    'Variables for incrementation
    Dim i As Integer, j As Integer, k As Integer, m As Integer, m2 As Integer
    

    'Iterate through the base folder, get the other file that's named the same
    'Make a selection set for all block reference objects within the target drawing
    'For every block reference, get its name, insertion point and attributes
    'If the corespondant block definition isn't modified, modify it
    'by
    '  1- insert a block reference in the base drawing onto the corespondant insertion point of the
    '     the block reference with the target drawing.
    '  2- explode the newly inserted block reference in the base drawing.
    '  3- copy the explosion objects to the target drawing.
    '      [an attribute definition was inserted within a block definition in the base
    '      drawing & was successfully copied to the target drawing]
    'Note that modification is done with the "-Block" command
    'Finally, insert the modified block into its original insertion point in the target drawing.
    For Each BaseFile In BaseFo.Files
        BaseFilename = BaseFile.name
        
        If Right(BaseFilename, 4) = ".dwg" Then
        
        BaseFilepath = dir1 & "\" & BaseFilename
        TrgtFilepath = dir2 & "\" & BaseFilename
        
        
        Set BaseDocument = docs.Open(BaseFilepath)
        On Error GoTo NoMatchFile:
        Set TrgtDocument = docs.Open(TrgtFilepath)
        TrgtDocument.Activate
        TrgtDocument.SendCommand "(vl-load-com)" & vbCr 'Prepare for blocks redefinition
        
        Set AllBlockRefs = TrgtDocument.SelectionSets.Add("allblockrefs")
        Set ssTrgtObj = TrgtDocument.SelectionSets.Add("Block2Define")
        AllBlockRefs.Select acSelectionSetAll, , , GroupCode, dataCode
        
        BCount = AllBlockRefs.Count
        BDefsCount = BaseDocument.Blocks.Count
        
        ReDim obj(0 To (BCount - 1)) As Variant 'Base objects to be copied, As Object with CopyObjects method
        'As AcadEntity with Wblock when they're single Blocks
        ReDim TrgtObj(0 To (BCount - 1)) As Variant
        ReDim idpairs(0 To (BCount - 1)) As Variant
        Dim TrgtObjs() As AcadEntity 'for "Block2Define" Selection Set
        ReDim BDefsStatus(0 To BDefsCount) As Variant
        
        On Error Resume Next 'Make the useless "Invalid procedure call or argument" error go away
        For m = 0 To BDefsCount
            BDefStatus(0) = BaseDocument.Blocks.Item(m).name
            BDefStatus(1) = "Not Modified"
            
            BDefsStatus(m) = BDefStatus
        Next m
        
        'Define vlaSel->Sel (docks elements in an ActiveX sset to a new ordinary sset)
        'vlaSel-> is written by Doaiena
        'The replay URL that contains it is:-
        ' https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/convert-selection-set-s-vla-object-to-ordinary-selection-set/m-p/8216062#M373023
            TrgtDocument.Activate
            
            TrgtDocument.SendCommand "(defun vlaSel->Sel ( vlaSel / sel )" & vbLf & _
            "(setq sel (ssadd))" & vbLf & _
            "(vlax-for obj vlaSel" & vbLf & _
            "(ssadd (vlax-vla-object->ename obj) sel)" & vbLf & _
            ")" & vbLf & _
            "sel" & vbLf & _
            ")" & vbCr
        
        'For every target blockref, insert a similar-named block within the base drawing
        For i = 0 To (BCount - 1)
            Set BlockRef = AllBlockRefs.Item(i)
            BRefName = BlockRef.name
            BRefInsPnt = BlockRef.InsertionPoint
            DefInsPnt = BRefInsPnt(0) & "," & BRefInsPnt(1) & "," & BRefInsPnt(2)
            
            'get the block definition modification status
            For m = 0 To BDefsCount
                If BRefName = BDefsStatus(m)(0) Then
                    BDefSt = BDefsStatus(m)(1)
                    m2 = m
                End If
            Next m
            
            'if the block definition isn't modified, modify it and change its modification status
            If BDefSt = "Not Modified" Then
            
                BDefsStatus(m2)(1) = "Modified"
                
                obj(i) = ExplodeEX(BaseDocument.ModelSpace.InsertBlock(BRefInsPnt, BRefName, 1, 1, 1, 0), False) 'Thanks Randal Rath
                ' "Set" keyword was used with obj(i) when its data type was Object & AcadEntity

                TrgtObj(i) = BaseDocument.CopyObjects(obj(i), TrgtDocument.ModelSpace, idpairs(i)) 'Works with ModelSpace, not with any block definition
            
                ReDim TrgtObjs(LBound(TrgtObj(i)) To UBound(TrgtObj(i)))
                For k = LBound(TrgtObj(i)) To UBound(TrgtObj(i))
                    Set TrgtObjs(k) = TrgtObj(i)(k)
                Next k
            
                ssTrgtObj.AddItems TrgtObjs
                'MsgBox ssTrgtObj.Count 'Selection Set works fine
            
                'Delete the objects resulted from the explosion process
                For j = LBound(obj(i)) To UBound(obj(i))
                    obj(i)(j).Delete
                Next j
                
                'Redefine block
                TrgtDocument.SendCommand "-Block" & vbCr & BRefName & vbCr & "y" & vbCr & DefInsPnt & vbCr & _
                "(vlaSel->Sel (vla-item (vla-get-selectionsets (vla-get-activedocument (vlax-get-acad-object))) ""Block2Define""))" _
                & vbCr & vbCr
            
            End If
            
            'MsgBox CStr(idpairs(i)) 'debug line
            TrgtDocument.ModelSpace.InsertBlock BRefInsPnt, BRefName, 1, 1, 1, 0
            ssTrgtObj.Clear
            
            
        Next i
        
        'Delete blocks from target drawings [not used when incrementing with "Item" method to avoid
        'any indexing issues that could result from deletion]
        Dim elem As Variant 'any other data type declaration generates an error
        For Each elem In AllBlockRefs
            elem.Delete
        Next elem
        
        BaseDocument.Close False
        TrgtDocument.Close True
        
        End If 'for dealing only with .dwg files
    Next BaseFile
    
NoMatchFile:
  If Err.Number = -2145320924 Then
      MsgBox "Base file " & BaseFilename & " has no target one." & vbLf & "Operation Terminated."
      BaseDocument.Close False
  End If
  Exit Sub
End Sub

____________
Don't forget to add needed reference files.

macro references.PNG

Message 12 of 16

Anonymous
Not applicable

Sorry for getting back to this so late!

 

I would like to test this but I am having issues with references, here is all I could find: acad_2018-09-19_10-04-01.png

 

And I am getting User-Defined type not defined error when trying to run this!

Message 13 of 16

Anonymous
Not applicable

Ok I think I fixed the references, but now this throws me off:

It highlights the set acad = getobject line.

acad_2018-09-19_10-55-15.png

Message 14 of 16

serag.hassouna
Advocate
Advocate

Well, I'm using AutoCAD 2016, Can you tell me the version you're using ?
Also, try to remove the ".20" part from this line & run the code

Set acad = GetObject(, "AutoCAD.Application")

________
To specify the suitable text replacing "AutoCAD.Application.20" please refer to a file named acadauto.chm, search for it into your installation folder.

Here's where I've taken the text that worked for the version I'm using.

appid string.PNG

Message 15 of 16

jtm2020hyo
Collaborator
Collaborator

how did you solve this issue?
can you share your code?

0 Likes
Message 16 of 16

roland.r71
Collaborator
Collaborator

I might be wrong, as i'm (still) unfarmiliar with VBA, but the line adressed here seems odd...

 

Set acad = GetObject(, "AutoCAD.Application")

 

What is that comma (,) doing there?

 

Should it not be:

Set acad = GetObject("AutoCAD.Application")

 or

Set acad = GetObject("AutoCAD.Application.20")

 as with the example given form the AKN (& highlighted) ?

0 Likes