I am new to autocad VBA and I am facing this problem:
When user clicks "Done" button on userform, program loads a predefined drawing and then inserts block from SADD1000S.dwg. Above command works fine when I click "Done" for the first time, but when I click "Done" again, program throws runtime error.
Private Sub CommandButton4_Click()
Application.Documents.Open ("C:\Users\Admin\Desktop\BACK UP\VBA\Final\set")
Dim objBlockRef As AcadBlockReference
Dim varInsertionPoint(0 To 2) As Double
Dim dblX As Double
Dim dblY As Double
Dim dblZ As Double
Dim dblRotation As Double
dblX = 1
dblY = 1
dblZ = 1
dblRotation = 0
varInsertionPoint(0) = 256
varInsertionPoint(1) = 256
varInsertionPoint(2) = 0
Set objBlockRef = ThisDrawing.ModelSpace.InsertBlock(varInsertionPoint, "C:\Users\Admin\Desktop\BACK UP\VBA\Final\SADD1000S.dwg", dblX, dblY, dblZ, dblRotation)
End Sub
Can anyone suggest what might the problem be?
Solved! Go to Solution.
Solved by Alfred.NESWADBA. Go to Solution.
Hi,
what have you tried from my suggestions >>>here<<<?
- alfred -
I guess it's because the "Application.Documents.Open" method is always called for the same file, so that after its first calling subsequent files are opened in "readonly" mode which shouldn't allow you any document modifications, like a block insertion is.
if you need to insert blocks in the same document you'll have to check whether the file of interest is already open and, if not, open it. otherwise set it as the ActiveDocument
my advice was to check and, if necessary, open the desired file. this because Autocad VBA online Help says "In-process clients (VBA macros) may notice that objects are not destroyed until the subroutine is exited. However, references to destroyed objects are not recommended at all, even in the in-process code"
so try this
Private Sub CommandButton4_Click() Dim DwgFullName As String DwgFullName = "C:\Users\Admin\Desktop\BACK UP\VBA\Final\set.dwg" If ActiveDocument.FullName <> DwgFullName Then Application.Documents.Open (DwgFullName) Dim objBlockRef As AcadBlockReference Dim varInsertionPoint(0 To 2) As Double Dim dblX As Double Dim dblY As Double Dim dblZ As Double Dim dblRotation As Double dblX = 1 dblY = 1 dblZ = 1 dblRotation = 0 varInsertionPoint(0) = 256 varInsertionPoint(1) = 256 varInsertionPoint(2) = 0 Set objBlockRef = ThisDrawing.ModelSpace.InsertBlock(varInsertionPoint, "C:\Users\Admin\Desktop\BACK UP\VBA\Final\SADD1000S.dwg", dblX, dblY, dblZ, dblRotation) End Sub
since i'm getting no errors with that code snippet I suggested you'd better post your entire code (calling sub, and userform code) and the files involved (both "set" and "SADD1000S") so that I could have a thorough look at them
and specify your autocad version
Hi,
>> in above code when I remove "Application.Documents.Open ("C:\Users\Admin\Desktop\BACK UP\VBA\Final\set")" it works fine
So the line with "...Insert..." basically works without issues, that's what had to be proofed first.
Now the next step is to verify the state of "ThisDrawing." used in that line. Try to change the following lines to:
Dim tAcadDoc as AcadDocument
Set tAcadDoc = Application.Documents.Open ("C:\Users\Admin\Desktop\BACK UP\VBA\Final\set")
'...your code lines
Set objBlockRef = ThisDrawing.ModelSpace.InsertBlock(varInsertionPoint, "C:\Users\Admin\Desktop\BACK UP\VBA\Final\SADD1000S.dwg", dblX,dblY, dblZ, dblRotation)
Set objBlockRef = tAcadDoc.ModelSpace.InsertBlock(varInsertionPoint, "C:\Users\Admin\Desktop\BACK UP\VBA\Final\SADD1000S.dwg", dblX, dblY, dblZ, dblRotation)
Let's know if it works in that way!
HTH, - alfred -
@Alfred
I'm quite sure it's a "readonly" file issue
so it shouldn't matter if referencing it via ThisDrawing or a specific document object. we have only to care not to re-open it if already open since this would result in a readonly file with the same name.
what's strange is that I had no problems with the last sub I posted while cynide123 still have.
so it will be of some interest have a look at its code and files
attacted the project file (stripped from original program, but the problem still persists)
"set" and "sadd1000s" files
Clicking "Done" in userform1 once does the job, second time runtime error occurs.
Hi,
I ran your code, three clicks, no error/no exception. Additionaly info: I'm running 2014
As RICVBA already mentioned ... there is no close built in, so the drawing "SET.DWG" is then 3 times opened (two of them as "read-only".
One additional try (don't know where I have read that, but there was a difference): put the string with the filename into a variable and not directly into the insert-statement.
Dim tFileName as String
tFileName = "C:\Users\Admin\Desktop\BACK UP\VBA\Final\SADD1000S.dwg"
Set objBlockRef = tAcadDoc.ModelSpace.InsertBlock(varInsertionPoint, tFilename, dblX, dblY, dblZ, dblRotation)
Maybe it is a help for your system.
Also look to the servicepacks for your AutoCAD >>>click<<<
- alfred -
//Hello my name is Dario //'m from Brazil //can someone help me? //insert a block, and in the sequel want the data of this block, //and then delete this block //as the example in the main code, just below .. //I have these questions that are commented no Main method >>??????? //Main method //=================================================================================================== [CommandMethod("Blockk")] public void blockk() { Document doc = Host.ApplicationServices.Application.DocumentManager.MdiActiveDocument; string[] data = new string[3]; data[0] = "data 1"; data[1] = "data 2"; data[2] = "data 3"; BlockReference db = InsertBlockFromFile_(doc, @"C:\wbc\orienta.dwg", new Point3d(50, 50, 50), Math.PI * 0.25, "wbc_insert", data, 30, 30, 1, 7, true, null, "wbcd"); //??????? return..>>> Example //??????? db.insertionPoint //??????? db.angle //??????? db.handle //??????? db.Xproprierts //??????? db.Atrib //??????? db.erase } //Complementary methods //=============================================================================================================================== public static BlockReference InsertBlockFromFile_(Document doc, string DrawingFile, Point3d Pinsert, double Angle, string Layer, string[] DadosExtendidos = null, double escalax = 1.0, double escalay = 1.0, double escalaz = 1.0, short ColorLayer = 7, bool ModelSpace = true, string[] Atributos = null, string RegAplicacao = "wbc") { if (!System.IO.File.Exists(DrawingFile)) { MessageBox.Show("Drawing not found\n" + DrawingFile); return null; } string sourceFileName = DrawingFile; string Blockname = System.IO.Path.GetFileNameWithoutExtension(sourceFileName); try { using (Transaction tr = doc.TransactionManager.StartTransaction()) { Database db = new Database(false, false); db.ReadDwgFile(DrawingFile, System.IO.FileShare.Read, true, null); ObjectId BlkId = doc.Database.Insert(Blockname, db, true); // ISL: Small fix, use correct block name tr.Commit(); } } catch (IOException ioe) { MessageBox.Show(ioe.Message); return null; } return AddBlockTest_(doc, Blockname, Pinsert, Angle, Layer, DadosExtendidos, escalax, escalay, escalaz, ColorLayer, Atributos, RegAplicacao); } private static BlockReference AddBlockTest_(Document doc, string blockName, Point3d Pinsert, double Angle, string Layer, string[] DadosExtendidos = null, double escalax = 1.0, double escalay = 1.0, double escalaz = 1.0, short ColorLayer = 7, string[] Atributos = null, string Regaplicacao = "wbc") { Database db = doc.Database; using (Transaction myT = db.TransactionManager.StartTransaction()) { //Get the block definition "Check". BlockTable bt = db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable; BlockTableRecord blockDef = bt[blockName].GetObject(OpenMode.ForRead) as BlockTableRecord; BlockTableRecord ms = (BlockTableRecord)myT.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); //Create new BlockReference, and link it to our block definition using (BlockReference blockRef = new BlockReference(Pinsert, blockDef.ObjectId)) { blockRef.Rotation = Angle; blockRef.ScaleFactors = new Scale3d(escalax, escalay, escalaz); //Add the block reference to modelspace ms.AppendEntity(blockRef); myT.AddNewlyCreatedDBObject(blockRef, true); SetXData_(blockRef, Regaplicacao , DadosExtendidos, doc); CreatLayer_(Layer, doc, ColorLayer); blockRef.Layer = Layer; } //Our work here is done myT.Commit(); } return null; } static public void SetXData_(Entity bref, string nome, string[] data, Document doc, string VersaoEquipamento = "Without Version") { Database db = doc.Database; using (Transaction tr = doc.TransactionManager.StartTransaction()) { AddRegAppTableRecord_(nome, doc); ResultBuffer rb = new ResultBuffer(); rb.Add(new TypedValue(1001, nome)); for (int i = 0; i < data.Length; i++) { rb.Add(new TypedValue(1000, data[i])); } rb.Add(new TypedValue(1000, VersaoEquipamento)); DateTime Wdata = DateTime.Now; Wdata.ToShortDateString(); rb.Add(new TypedValue(1000, Wdata.ToString())); rb.Add(new TypedValue(1000, VariaveisGlobais.Wusuario + "_" + VariaveisGlobais.NumeroSerie)); bref.XData = rb; tr.Commit(); } } public static void CreatLayer_(string sLayerName, Document doc, short CorCamada = 7) { Document acDoc = doc; Database acCurDb = acDoc.Database; // Start a transaction using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Open the Layer table for read LayerTable acLyrTbl; acLyrTbl = acTrans.GetObject(acCurDb.LayerTableId, OpenMode.ForRead) as LayerTable; if (acLyrTbl.Has(sLayerName) == false) { Platform.DatabaseServices.LayerTableRecord acLyrTblRec = new LayerTableRecord(); // Assign the layer the ACI color 1 and a name acLyrTblRec.Color = Platform.Colors.Color.FromColorIndex(Platform.Colors.ColorMethod.ByAci, CorCamada); acLyrTblRec.Name = sLayerName; // Upgrade the Layer table for write acLyrTbl.UpgradeOpen(); // Append the new layer to the Layer table and the transaction acLyrTbl.Add(acLyrTblRec); acTrans.AddNewlyCreatedDBObject(acLyrTblRec, true); } acTrans.Commit(); } } public static void AddRegAppTableRecord_(string regAppName, Document doc) { using (Transaction tr = doc.TransactionManager.StartTransaction()) { RegAppTable rat = (RegAppTable)tr.GetObject(doc.Database.RegAppTableId, OpenMode.ForRead, false); if (!rat.Has(regAppName)) { rat.UpgradeOpen(); RegAppTableRecord ratr = new RegAppTableRecord(); ratr.Name = regAppName; rat.Add(ratr); tr.AddNewlyCreatedDBObject(ratr, true); } tr.Commit(); } }