.NET

Reply
Distinguished Contributor
joshlund
Posts: 143
Registered: ‎07-07-2006
Message 1 of 7 (3,892 Views)

VB.NET: Inserting a file (block)

3892 Views, 6 Replies
01-19-2009 04:02 PM
Good evening,

Does anyone have a code snippet that shows how to insert a drawing (as a block) into the current drawing? I searched this forum for a few samples and only found partial functions, too little for me to turn into a working function or even understand what I should attempt to do.

I have a drawing on my hard drive and I want to insert it into my current drawing. It seems simple enough but I'm not getting it. Any suggestions?

Thanks,
Josh

Windows XP SP2
VS 2005 SP1
AutoCAD Civil 3D 2009 SP2
*Joe Sutphin
Message 2 of 7 (3,890 Views)

Re: VB.NET: Inserting a file (block)

01-20-2009 06:42 AM in reply to: joshlund

Perhaps this will help.

Joe
...

    <CommandMethod("IBFF")>
_
    Public Shared Sub
InsertBlockFromFile()
        'get an
editor object
        Dim ed As Editor =
Application.DocumentManager.MdiActiveDocument.Editor

 

        'ask for
block name from user
        Dim
BlockNameOptions As PromptStringOptions = New PromptStringOptions("Enter block
name")
        'no spaces allowed with
block names
       
BlockNameOptions.AllowSpaces =
False
        'get the
input
        Dim BlockNameResult As
PromptResult = ed.GetString(BlockNameOptions)

 

        'check
for valid input
        If
(BlockNameResult.Status = PromptStatus.OK)
Then
            'get
the working
database
           
Dim dwg As Database =
ed.Document.Database
           
'start a
transaction
           
Dim ta As Transaction = dwg.TransactionManager.StartTransaction

 


size=2>           
Try
               
'create temporary database to read in
block
               
Dim dbDwg As New
Database()
               
'read the file from
disk
               
dbDwg.ReadDwgFile("C:\Drawing2.dwg", IO.FileShare.Read, True,
"")
               
'insert it into the current
database
               
dwg.Insert(BlockNameResult.StringResult.ToString, dbDwg,
False)
               
'dispose of temporary database
object
               
dbDwg.Dispose()

 


size=2>               
'open the block table for
read
               
Dim BlockTable As BlockTable = ta.GetObject(dwg.BlockTableId,
OpenMode.ForRead)

 


size=2>               
'see if the block table record
exists
               
If (BlockTable.Has(BlockNameResult.StringResult) = True)
Then
                   
'prompt user for insertion
point
                   
Dim PromptPointOptions As PromptPointOptions = New PromptPointOptions("Select
insertion
point")
                   
'get user to select the insertion
point
                   
Dim PromptPointResult As PromptPointResult =
ed.GetPoint(PromptPointOptions)

 


size=2>                   
'user selected a valid
point
                   
If (PromptPointResult.Status = PromptStatus.OK)
Then
                       
'fix up the point to be a Point3D
object
                       
Dim Point3D As New Point3d(PromptPointResult.Value.X, PromptPointResult.Value.Y,
PromptPointResult.Value.Z)

 


size=2>                       
'insert the block at the insertion
point
                       
Dim BlockRef As BlockReference = New BlockReference(Point3D,
BlockTable.Item(BlockNameResult.StringResult))

 


size=2>                       
'add block reference to the current
space
                       
Dim CurrentSpace As BlockTableRecord = ta.GetObject(dwg.CurrentSpaceId,
OpenMode.ForWrite)

 


size=2>                       
'add the block reference to the current
space
                       
CurrentSpace.AppendEntity(BlockRef)

 


size=2>                       
'tell the
transaction
                       
ta.AddNewlyCreatedDBObject(BlockRef, True)

 


size=2>                       
'commit transaction to
database
                       
ta.Commit()

 


size=2>                   
End If

 


size=2>               
Else
                   
MsgBox("Block " & BlockNameResult.StringResult.ToString & " does not
exists")

 


size=2>               
End If

 


size=2>            Catch
ex As
Exception
               
MsgBox(ex.Message)

 


size=2>           
Finally

 


size=2>               
'always dispose of
transaction
               
ta.Dispose()

 


size=2>            End
Try
        End If
   
End Sub
<JoshLund> wrote in message
news:6107709@discussion.autodesk.com...
Good evening, Does anyone have a code
snippet that shows how to insert a drawing (as a block) into the current
drawing? I searched this forum for a few samples and only found partial
functions, too little for me to turn into a working function or even understand
what I should attempt to do. I have a drawing on my hard drive and I want to
insert it into my current drawing. It seems simple enough but I'm not getting
it. Any suggestions? Thanks, Josh Windows XP SP2 VS 2005 SP1 AutoCAD Civil 3D
2009 SP2
Distinguished Contributor
joshlund
Posts: 143
Registered: ‎07-07-2006
Message 3 of 7 (3,891 Views)

Re: VB.NET: Inserting a file (block)

01-20-2009 08:48 AM in reply to: joshlund
Joe,

Let me start out by saying thanks for such an excellent example. It is well commented and easy to follow.

When I first ran the code, it threw a FileNotFound exception. Not sure where "C:\Drawing2.dwg" was coming from I changed it to the name of the block I wanted to insert. This cleared up that exception. Not sure if that was the right thing to do as I encountered another problem a short time later.

'read the file from disk
'dbDwg.ReadDwgFile("C:\Drawing2.dwg", IO.FileShare.Read, True, "")

was changed to. . .

dbDwg.ReadDwgFile(BlockNameResult.StringResult.ToString, IO.FileShare.Read, True, "")


I ran it again and the following line threw an OutOfRange exception.

dwg.Insert(BlockNameResult.StringResult.ToString, dbDwg, False)

I tried a few things to fix this but can't seem to find the answer. Some things I tried: I changed BlockNameResult.StringResult.ToString to a static string, just to see if it would work. I tried specifying the block name with a full path and without a full path, thinking the path may have been causing the outof range exception.

The class file is attached as Class1.txt. Any suggestions?

Thanks,
Josh
*Tony Tanzillo
Message 4 of 7 (3,890 Views)

Re: VB.NET: Inserting a file (block)

01-20-2009 12:24 PM in reply to: joshlund
Sorry to say, but we can't call that an 'excellent' example.

Joe's code (assuming he actually wrote it, that is) converts the user's
coordinate into a Point3d. Problem is, it's
already a Point3d, making that pointless and unnecessary.

The code he posted also needlessly looks up the objectid of the
newly-inserted BlockTableRecord, when that is what is returned by the
Insert() method, whose result his code completely ignores.

So no, we can't call that an 'excellent' example.

My suggestion would be to focus on learning the language and the API. For
example, you call the 'ToString()' method on an object that is already a
string. If the object is already a string, you don't have to convert it to a
string. But it is the fact that you do not know that the object is already a
string, that suggests that you're trying to run before having learned to
walk, and that's the core problem you're faced with. No matter how good the
examples you find here are, they're not going to help you that much if you
don't understand the code, or how to modify/adapt them to your particular
situation.

If you are going to use VB.NET and the ObjectARX API, you have to learn to
use the programming language; the .NET framework, and the AutoCAD .NET API,
in that order.

The example below is in C#, but you can convert it to VB.NET using various
online translators or Reflector.

[code]

{code}

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.ApplicationServices;

using Acad = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof( Namespace1.InsertBlockFromFileExample ))]

namespace Namespace1
{
public static class InsertBlockFromFileExample
{
[CommandMethod("XINSERT")]
public static void InsertFromFileCommand()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.DefaultExt = ".dwg";
ofd.Filter = "Drawing Files (*.dwg)|*.dwg";
if( ofd.ShowDialog( Acad.MainWindow ) != DialogResult.OK )
return;
Document doc = Acad.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptPointOptions ppo = new PromptPointOptions( "\nInsertion
point: " );
PromptPointResult ppr = ed.GetPoint( ppo );
if( ppr.Status != PromptStatus.OK )
return;
using( Database xDb = new Database( false, true ) )
{
xDb.ReadDwgFile( ofd.FileName, FileShare.Read, true, null );
using( Transaction tr =
doc.TransactionManager.StartTransaction() )
{
string name =
SymbolUtilityServices.GetBlockNameFromInsertPathName( ofd.FileName );
ObjectId id = db.Insert( name, xDb, true );
if( id.IsNull )
{
ed.WriteMessage( "\nFailed to insert block" );
return;
}
BlockTableRecord currSpace = tr.GetObject( db.CurrentSpaceId,
OpenMode.ForWrite ) as BlockTableRecord;
BlockReference insert = new BlockReference( ppr.Value, id );
currSpace.AppendEntity( insert );
insert.SetDatabaseDefaults();
tr.AddNewlyCreatedDBObject( insert, true );
tr.Commit();
}
}
}
}
}


{code}

[/code]

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009
http://www.acadxtabs.com

Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm


wrote in message news:6108224@discussion.autodesk.com...
Joe, Let me start out by saying thanks for such an excellent example. It is
well commented and easy to follow. When I first ran the code, it threw a
FileNotFound exception. Not sure where "C:\Drawing2.dwg" was coming from I
changed it to the name of the block I wanted to insert. This cleared up that
exception. Not sure if that was the right thing to do as I encountered
another problem a short time later. 'read the file from disk
'dbDwg.ReadDwgFile("C:\Drawing2.dwg", IO.FileShare.Read, True, "") was
changed to. . . dbDwg.ReadDwgFile(BlockNameResult.StringResult.ToString,
IO.FileShare.Read, True, "") I ran it again and the following line threw an
OutOfRange exception. dwg.Insert(BlockNameResult.StringResult.ToString,
dbDwg, False) I tried a few things to fix this but can't seem to find the
answer. Some things I tried: I changed BlockNameResult.StringResult.ToString
to a static string, just to see if it would work. I tried specifying the
block name with a full path and without a full path, thinking the path may
have been causing the outof range exception. The class file is attached as
Class1.txt. Any suggestions? Thanks, Josh
*Roland Feletic
Message 5 of 7 (3,889 Views)

Re: VB.NET: Inserting a file (block)

01-21-2009 05:23 AM in reply to: joshlund
Thank you, Tony.
This code works really great, as allways. I hope you don't mind that I
changed the code a little bit that it works with annotative blocks, too.
Don't forget to set a reference to acmgdinternal.

[code]

{code}
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Internal;

using Acad = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof( RSNNAcadApp.Test.InsertBlock_Tanzillo ))]
namespace RSNNAcadApp.Test
{
class InsertBlock_Tanzillo
{
[CommandMethod("XINSERT")]
public static void InsertFromFileCommand()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.DefaultExt = ".dwg";
ofd.Filter = "Drawing Files (*.dwg)|*.dwg";
if (ofd.ShowDialog(Acad.MainWindow) != DialogResult.OK)
return;
Document doc = Acad.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptPointOptions ppo = new PromptPointOptions("\nEinsetzpunkt:
");
PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
return;
using (Database xDb = new Database(false, true))
{
xDb.ReadDwgFile(ofd.FileName, FileShare.Read, true, null);

using (Transaction tr =
doc.TransactionManager.StartTransaction())
{
string name =
SymbolUtilityServices.GetBlockNameFromInsertPathName(ofd.FileName);
ObjectId id = db.Insert(name, xDb, true);
if (id.IsNull)
{
ed.WriteMessage("\nFailed to insert block");
return;
}

//for inserting an annotative dwg
if (xDb.AnnotativeDwg)
{
using (BlockTableRecord btrAnnotative =
(BlockTableRecord)tr.GetObject(id, OpenMode.ForWrite))
{
btrAnnotative.Annotative =
AnnotativeStates.True;
}
}

BlockTableRecord currSpace =
tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
BlockReference insert = new BlockReference(ppr.Value,
id);
currSpace.AppendEntity(insert);
insert.SetDatabaseDefaults();

//for inserting an annotative dwg
if (xDb.AnnotativeDwg)
{
//Attach Current Annotation-Scale.
//If you don't add the content, the block and the
following attribute will not inserted correct.
ObjectContextManager ocm = db.ObjectContextManager;
ObjectContextCollection occ =
ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
ObjectContexts.AddContext(insert,
occ.CurrentContext);
}

tr.AddNewlyCreatedDBObject(insert, true);
tr.Commit();
}
}
}
}
}
{code}

[/code]
*Tony Tanzillo
Message 6 of 7 (3,887 Views)

Re: VB.NET: Inserting a file (block)

01-21-2009 12:43 PM in reply to: joshlund
Glad it worked for you, and thanks for posting
your enhancement. I'm sure others might find it useful.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009
http://www.acadxtabs.com

Introducing AcadXTabs 2010:
http://www.caddzone.com/acadxtabs/AcadXTabs2010.htm


"Roland Feletic" wrote in message
news:6108849@discussion.autodesk.com...
Thank you, Tony.
This code works really great, as allways. I hope you don't mind that I
changed the code a little bit that it works with annotative blocks, too.
Don't forget to set a reference to acmgdinternal.

[code]

{code}
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Internal;

using Acad = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof( RSNNAcadApp.Test.InsertBlock_Tanzillo ))]
namespace RSNNAcadApp.Test
{
class InsertBlock_Tanzillo
{
[CommandMethod("XINSERT")]
public static void InsertFromFileCommand()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.DefaultExt = ".dwg";
ofd.Filter = "Drawing Files (*.dwg)|*.dwg";
if (ofd.ShowDialog(Acad.MainWindow) != DialogResult.OK)
return;
Document doc = Acad.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptPointOptions ppo = new PromptPointOptions("\nEinsetzpunkt:
");
PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
return;
using (Database xDb = new Database(false, true))
{
xDb.ReadDwgFile(ofd.FileName, FileShare.Read, true, null);

using (Transaction tr =
doc.TransactionManager.StartTransaction())
{
string name =
SymbolUtilityServices.GetBlockNameFromInsertPathName(ofd.FileName);
ObjectId id = db.Insert(name, xDb, true);
if (id.IsNull)
{
ed.WriteMessage("\nFailed to insert block");
return;
}

//for inserting an annotative dwg
if (xDb.AnnotativeDwg)
{
using (BlockTableRecord btrAnnotative =
(BlockTableRecord)tr.GetObject(id, OpenMode.ForWrite))
{
btrAnnotative.Annotative =
AnnotativeStates.True;
}
}

BlockTableRecord currSpace =
tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
BlockReference insert = new BlockReference(ppr.Value,
id);
currSpace.AppendEntity(insert);
insert.SetDatabaseDefaults();

//for inserting an annotative dwg
if (xDb.AnnotativeDwg)
{
//Attach Current Annotation-Scale.
//If you don't add the content, the block and the
following attribute will not inserted correct.
ObjectContextManager ocm = db.ObjectContextManager;
ObjectContextCollection occ =
ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
ObjectContexts.AddContext(insert,
occ.CurrentContext);
}

tr.AddNewlyCreatedDBObject(insert, true);
tr.Commit();
}
}
}
}
}
{code}

[/code]
Contributor
eckdahlrd
Posts: 12
Registered: ‎11-13-2006
Message 7 of 7 (3,890 Views)

Re: VB.NET: Inserting a file (block)

05-11-2010 10:41 AM in reply to: joshlund
Tony, I appreciate you posting this code and providing the solution. I found it to be helpful to me, and really didn't have much pain in converting it to vb.net and getting it to fit into my existing class.

I'm hoping to be able to tweak it so that rather than using the file dialog, that it would use a specific file that is identified as part of another sub in an "IF....THEN" statement. I don't know if that's possible, but I guess I'll find out. :smileywink:

Thanks again. Very helpful.
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.