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

Insert Block C# (eventually would like to put block on specific layer)

27 REPLIES 27
Reply
Message 1 of 28
joelkarr
1965 Views, 27 Replies

Insert Block C# (eventually would like to put block on specific layer)

I am trying to use C# to insert a block into an AutoCAD drawing at point 0,0

when I run the code I get "(2126748928)Temperature Switch - Imperial inserted" in the command line but can not see a block at point 0,0

any ideas on to why this code doesn't work? Does the fact that it is a dynamic block effect the code?

Thanks in advance



using System;

using Autodesk.AutoCAD;

using Autodesk.AutoCAD.Runtime;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using System.Collections.Generic;
using System.IO;


namespace BlockImport
{

public class BlockImportClass
{

[CommandMethod("BI")]
public void InsertBlock()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
try
{

//Test block name and point (final version will use user input)
string nameOfBlock = "Temperature Switch - Imperial";
Autodesk.AutoCAD.Geometry.Point3d pos = new Point3d(0, 0, 0);
// Get the current working database
Transaction tr = db.TransactionManager.StartTransaction();
// Then open the block table and check the
// block definition exists
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
if (!bt.Has(nameOfBlock))
{
ed.WriteMessage("\nBlock not found.");
}
else
{
ObjectId bdId = bt[nameOfBlock];
Point3d pt = new Point3d(0, 0, 0);
// Create the block reference
BlockReference br = new BlockReference(pt, bdId);
//Add block reference to model space table
BlockTableRecord btrms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
btrms.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
//Graphics Flush so block will be visible
doc.TransactionManager.QueueForGraphicsFlush();
ed.WriteMessage(bdId + nameOfBlock + " inserted");
}


//Clean up transaction

tr.Commit();
tr.Dispose();
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
ed.WriteMessage("\nError during copy: " + ex.Message);
}
}

}

}
27 REPLIES 27
Message 21 of 28
JamieVJohnson
in reply to: joelkarr

Tony,



Your a programmer I can definitely see that. However, as a proficient professional of logic, you seem to assume too many things. Proficient programmers should never leave their code up to assumtions for the processor. This is why most people use option explicit.



With that said, the assumtion that everybody will see your statements the same way your first in this long chain of retorts. Just realize that other people took many proper english classes too. Some of us even got the equivelent of an A in these classes. Therefore, its a shame that you keep redirecting people to go back and read the original statement in your posts. They did, you just did not write them properly to eliminate all possible assumptions, otherwise there would not be any confusion.



Later dude,



jvj
Message 22 of 28
joelkarr
in reply to: joelkarr

Since my initial post got so many answers I thought I would go for the extra bonus and ask this question.



Now that I have a block inserted I would like to have it inserted on a specific layer. I have set up a microsoft access database to be used to store which layer each block should be inserted.



It all works great until I get a block that needs to be inserted on a layer that does not yet exist. I am guessing that I need to add a new layer and its properties to the LayerTable but got a little caught up when I tried to use the same idea as I did for adding a block to the block table.



So for the bonus points. Can anyone submit sample code in C# or another language for adding a layer to the layerTable?



Here is my quick attempt. I am reading a database to get the values for all the properties. I still need to convert from string into ACAD properties but I thought I would see what everyone though.



public void createLayer(string layerName, string layerColor, string layerLineType, string layerDescription, bool blnPlot)

{

Document doc = Application.DocumentManager.MdiActiveDocument;



Database db = doc.Database;

// For multiple layers should I be adding all newly created layers to an object collection and then adding that collection to the LayerTable all at once?

// ObjectIdCollection layersIds = new ObjectIdCollection();



using (Transaction tr = db.TransactionManager.StartTransaction())

{



try

{



LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);



LayerTableRecord ltr = new LayerTableRecord();



//Set Layer Properties

//Still need to work out converting from string to appropriate acad prop. Color, linetype, plot

ltr.Name = layerName;

ltr.Color = layerColor;

ltr.LinetypeObjectId = layerLineType;

ltr.PlotStyleName = blnPlot;

ltr.Description = layerDescription;



//add newly created layer back to layerTable

lt.Add(ltr);



tr.Commit();



}



catch

{



tr.Abort();



}

}
Message 23 of 28
Anonymous
in reply to: joelkarr


If you're going to label someone's statements 'not
correct'

be prepared to back that up.

 

Your essentially like the guy that showed up at the gun
fight

with no bullets.


 

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000
through 2009

href="http://www.acadxtabs.com">http://www.acadxtabs.com

 


 

 


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
Tony,



Your
a programmer I can definitely see that. However, as a proficient professional
of logic, you seem to assume too many things. Proficient programmers should
never leave their code up to assumtions for the processor. This is why most
people use option explicit.



With that said, the assumtion that
everybody will see your statements the same way your first in this long chain
of retorts. Just realize that other people took many proper english classes
too. Some of us even got the equivelent of an A in these classes. Therefore,
its a shame that you keep redirecting people to go back and read the original
statement in your posts. They did, you just did not write them properly to
eliminate all possible assumptions, otherwise there would not be any
confusion.



Later
dude,



jvj
Message 24 of 28
Anonymous
in reply to: joelkarr


No time to write samples, but just a quick look at
your

code (which isn't easy with this forum software),
shows

that you're not calling AddNewlyCreatedDbObject()
on

the transaction, after you add the layer to the
table.

 

There may be other things as well.


 

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000
through 2009

href="http://www.acadxtabs.com">http://www.acadxtabs.com

 


 

 


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
Since
my initial post got so many answers I thought I would go for the extra bonus
and ask this question.



Now that I have a block inserted I would
like to have it inserted on a specific layer. I have set up a microsoft access
database to be used to store which layer each block should be
inserted.



It all works great until I get a block that needs to
be inserted on a layer that does not yet exist. I am guessing that I need to
add a new layer and its properties to the LayerTable but got a little caught
up when I tried to use the same idea as I did for adding a block to the block
table.



So for the bonus points. Can anyone submit sample code
in C# or another language for adding a layer to the
layerTable?



Here is my quick attempt. I am reading a database
to get the values for all the properties. I still need to convert from string
into ACAD properties but I thought I would see what everyone
though.



public void createLayer(string layerName, string
layerColor, string layerLineType, string layerDescription, bool
blnPlot)

{

Document doc =
Application.DocumentManager.MdiActiveDocument;



Database db =
doc.Database;

// For multiple layers should I be adding all newly
created layers to an object collection and then adding that collection to the
LayerTable all at once?

// ObjectIdCollection layersIds = new
ObjectIdCollection();



using (Transaction tr =
db.TransactionManager.StartTransaction())

{



try

{



LayerTable
lt = (LayerTable)tr.GetObject(db.LayerTableId,
OpenMode.ForRead);



LayerTableRecord ltr = new
LayerTableRecord();



//Set Layer Properties

//Still need
to work out converting from string to appropriate acad prop. Color, linetype,
plot

ltr.Name = layerName;

ltr.Color =
layerColor;

ltr.LinetypeObjectId =
layerLineType;

ltr.PlotStyleName = blnPlot;

ltr.Description =
layerDescription;



//add newly created layer back to
layerTable

lt.Add(ltr);



tr.Commit();



}



catch

{



tr.Abort();



}

}
Message 25 of 28
JamieVJohnson
in reply to: joelkarr

Wow Tony, that gun statement was totally irrelavent!! Cute though.



Word.



This is some VB.Net code for your layer problem:




Public Overridable Function SetLayer(ByVal strLayerName As String, ByVal sngColor As Single) As LayerTableRecord 'find it or create it



If strLayerName = "" Then Return Nothing



Dim ltr As LayerTableRecord



ltr = FindLayer(strLayerName)



If ltr IsNot Nothing Then Return ltr



Using trans As Transaction = db.TransactionManager.StartTransaction



Dim lt As LayerTable = trans.GetObject(db.LayerTableId, OpenMode.ForWrite, True, True)



ltr = New LayerTableRecord



ltr.Name = strLayerName



ltr.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, sngColor)



lt.Add(ltr)



trans.AddNewlyCreatedDBObject(ltr, True)



trans.Commit()



End Using



Return ltr



End Function



Public Overridable Function FindLayer(ByVal strLayerName As String) As LayerTableRecord



If strLayerName = "" Then Return Nothing



Dim ltr As LayerTableRecord = Nothing



Using trans As Transaction = db.TransactionManager.StartTransaction



Dim lt As LayerTable = trans.GetObject(db.LayerTableId, OpenMode.ForWrite, True, True)



For Each oid As ObjectId In lt



ltr = trans.GetObject(oid, OpenMode.ForRead, True, True)



If ltr.Name = strLayerName Then



Return ltr



End If



Next



End Using



Return Nothing



End Function



Hope this helps,



jvj

Message 26 of 28
Anonymous
in reply to: joelkarr


A simple fix for this is to post some code where
you say 'using' does not work... This will

show that you knew what 'using' is for and teach us
something at the same time - which

is alway nice!

 

 


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
Wow
Tony, that gun statement was totally irrelavent!! Cute
though.



Word.



This is some VB.Net code for your
layer problem:





Public Overridable Function SetLayer(ByVal strLayerName As String,
ByVal sngColor As Single) As LayerTableRecord 'find it or create
it




If strLayerName = "" Then Return Nothing




Dim ltr As LayerTableRecord




ltr = FindLayer(strLayerName)




If ltr IsNot Nothing Then Return ltr




Using trans As Transaction =
db.TransactionManager.StartTransaction




Dim lt As LayerTable = trans.GetObject(db.LayerTableId,
OpenMode.ForWrite, True, True)




ltr = New LayerTableRecord




ltr.Name = strLayerName




ltr.Color =
Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci,
sngColor)




lt.Add(ltr)




trans.AddNewlyCreatedDBObject(ltr, True)




trans.Commit()




End Using




Return ltr




End Function




Public Overridable Function FindLayer(ByVal strLayerName As String) As
LayerTableRecord




If strLayerName = "" Then Return Nothing




Dim ltr As LayerTableRecord = Nothing




Using trans As Transaction =
db.TransactionManager.StartTransaction




Dim lt As LayerTable = trans.GetObject(db.LayerTableId,
OpenMode.ForWrite, True, True)




For Each oid As ObjectId In lt




ltr = trans.GetObject(oid, OpenMode.ForRead, True, True)




If ltr.Name = strLayerName Then




Return ltr




End If




Next




End Using




Return Nothing




End Function



Hope this
helps,



jvj

Message 27 of 28
BKSpurgeon
in reply to: Anonymous

HI folks, 

 

I came across this interesting thread from a while ago, which raises an important point:

 

(i) when employing transactions utlising the using(......) statement :if an exception is thrown, will the transaction still get disposed? 

 

 

using( Transaction tr = database.TransactionManager.StartTransaction)

{

        // code goes here

       // exception is thrown here

 

 

}

 

 

Will the transaction be disposed of at all?

 

 

 

 

 

 

 

 

 

 

Message 28 of 28
phliberato
in reply to: BKSpurgeon

Yes, but it is a good idea handle the exception inside this code block.

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