« July 2007 | Main | September 2007 »
"Creating an Installer" webcast recording available for download
The recording of the latest in the AutoCAD Development Masterclass series, "Creating an Installer" held on August 16, has been posted here. The supporting MSI template used in the session is available from here.
The next in the series, "10 easy ways to crash your AutoCAD addin", is scheduled for Thursday September 27. You can go here to register (like all in this series, this session is free for all to attend).
August 31, 2007 in AutoCAD, Training | Permalink | Comments (3) | TrackBack
Autodesk University 2007 Developer Track
As mentioned some time ago, my team has been working with members of our Engineering teams to put together a comprehensive "Developer" track for AU 2007. We have 52 sessions devoted to developers or people customizing our products, in addition to a further 96 sessions in the "Customization and Programming" track. This adds up to host of great content for developers at this year's Autodesk University.
Below are the details of the various sessions in the "Developer" track. I've marked the course IDs of sessions that have already sold out in red and the guest speakers from Engineering in italics. There are three panel discussions where you can come along and get your development-oriented questions answered by experts from DevTech and Engineering. The sessions are filling up quickly (including the ones I'm presenting, thankfully :-) so please sign up soon.
I've created a "Through the Interface" group in AU Online (go to the Network tab). For those of you attending AU, please join the group. I'm looking forward to meeting many of you at AU!
Before I sign off, a quick reminder about our DevCamps... we have our AEC DevCamp next week and our Manufacturing DevCamp later in September. There is still time to sign up (depending on when you're reading this, of course :-).
Platforms (AutoCAD, RealDWG, AutoCAD OEM, DWF) DE105-2
AutoCAD® APIs: The Right Tools for the Job
Fenton Webb DE111-2
AutoCAD® .NET Basics, Part I
Stephen Preston DE115-2
AutoCAD® .NET Basics, Part II
Stephen Preston DE201-2
AutoCAD® .NET: Tell Me About It!
Stephen Preston DE205-2
AutoCAD® .NET Show and Tell
Gopinath Taget DE211-2
The Best of Both Worlds: .NET and LISP Can Coexist
Wayne Brill DE215-2
Ask the Experts: ObjectARX® and AutoCAD® .NET Panel Discussion
Panel of experts DE219-2
Data, Data, Everywhere: Storing Your Custom Data in a .DWG
Davis Augustine DE305-2
Everything You Wanted to Know About Custom Entities but Were Too Afraid to Ask
Fenton Webb DE311-2
Signed, Sealed, and Delivered: Writing an Installer for Your AutoCAD® Application
Fenton Webb DE315-2
Ten Ways to Crash Your AutoCAD® Add-In
Gopinath Taget DE319-2
There's More to .DWG Than AutoCAD®
Kean Walmsley DE401-2
Enriching Your DWF™
Kean Walmsley AEC (Architecture, Engineering & Construction) DE105-1
The ABCs of Programming in Revit® Architecture, Revit® Structure, and Revit® MEP
Jeremy Tammik DE111-1
The Autodesk® Revit® SDK Sample Smörgåsbord
Jeremy Tammik DE115-1
Ten Steps for Enhancing Your Autodesk® Revit® Add-In
Jeremy Tammik DE201-1
Create Your Own Bidirectional Revit® Structure Stress Analysis Integration Link
Jeremy Tammik DE205-1
Reinforce Your Design: Revit® Structure API for Rebar and Detailing
Jeremy Tammik DE211-1
AutoCAD® Architecture and AutoCAD® MEP .NET Programming: A Beginner’s Guide
Kevin Vandecar DE215-1
An In-Depth Look at AutoCAD® Architecture .NET Programming
Kevin Vandecar DE219-1
Using the AEC Details Framework in AutoCAD® Architecture
Mikako Harada DE305-1
A Closer Look at the Revit® Database with the Revit API
Mikako Harada DE311-1
An In-Depth Look at AutoCAD® MEP .NET Programming
Steve Milligan DE315-1
Answers to Your API Questions: Experts Talk About Revit® and AutoCAD® Architecture & MEP APIs
Panel of experts DE401-1
Into the Vortex: A Whirlwind Overview of Programming with Autodesk® 3ds Max®, Part I
Jean-Francois Yelle DE405-1
Into the Vortex: A Whirlwind Overview of Programming with Autodesk® 3ds Max®, Part II
Jean-Francois Yelle Manufacturing DE105-4
Turbo Charge Autodesk® Inventor™ with Its API
Wayne Brill DE111-4
Batch Those Autodesk® Inventor™ Drawings!
Wayne Brill DE115-4
Autodesk® Inventor™ Part APIs: Customizing the Building Blocks of Autodesk Inventor Models
Wayne Brill DE201-4
Autodesk® Inventor™ Assembly APIs: Bolt Together Inventor Models Automatically!
Wayne Brill DE205-4
Taking the Step from VBA to Autodesk® Inventor™ Add-Ins
Brian Ekins DE211-4
Industrial Strength Add-Ins: Creating Commands in Autodesk® Inventor™
Brian Ekins DE215-4
Autodesk® Inventor™ API: The Cutting Edge
Brian Ekins DE219-4
Hardball with the Autodesk® Inventor™ API
Brian Ekins DE305-4
An Introduction to the Autodesk® Vault API
Doug Redmond DE311-4
Digital Matchmaking: Using the Autodesk® Productstream® API to Integrate with Other Systems
Doug Redmond DE315-4
Introducing the AutoCAD® Mechanical API
Wayne Brill DE319-4
Introducing the AutoCAD® Electrical API
Nate Holt DE401-4
Ask the Experts About Manufacturing APIs
Panel of experts Geospatial DE105-3
Taking Geospatial Data Access to the Next Level with the FDO API
Dongjin Xing DE111-3
Getting Started with Autodesk MapGuide® Enterprise API Programming
Dongjin Xing DE115-3
Be Smart: Manage Those Resources with Autodesk MapGuide® Enterprise
Dongjin Xing DE201-3
Seek and You Shall Find: Query and Selection Through the Autodesk MapGuide® Enterprise API
Dongjin Xing DE205-3
Editing Data Online with the Autodesk MapGuide® Enterprise API
Dongjin Xing DE211-3
You Can Develop AutoCAD® Civil 3D® Applications, Too!
Partha Sarkar DE215-3
Come Up for Air: Learn to Surface with the AutoCAD® Civil 3D® API
Partha Sarkar DE219-3
Get Aligned with the AutoCAD® Civil 3D® API and Raise Your Profile
Partha Sarkar DE305-3
Design Your Own Custom AutoCAD® Civil 3D® Subassemblies Using .NET
Partha Sarkar DE311-3
AutoCAD® Map 3D API: Present and Future
Dongjin Xing DE315-3
Working with the AutoCAD® Map 3D Geospatial Platform API
Dongjin Xing DE319-3
Autodesk® Topobase™ API: Optimizing Spatial Data Access and Management
Partha Sarkar DE401-3
Taking a Closer Look at the Autodesk® Topobase™ API
Partha Sarkar
August 30, 2007 in Training | Permalink | Comments (2) | TrackBack
Updating an Excel spreadsheet from a linked AutoCAD table using .NET
In the last post we saw some code to update an AutoCAD table linked to an Excel spreadsheet. In this post we go the other way, updating an Excel spreadsheet from a linked AutoCAD table.
Here's the C# code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
namespace LinkToExcel
{
public class Commands
{
[CommandMethod("T2S")]
static public void UpdateSpreadsheetFromTable()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions opt =
new PromptEntityOptions(
"\nSelect table with spreadsheet to update: "
);
opt.SetRejectMessage(
"\nEntity is not a table."
);
opt.AddAllowedClass(typeof(Table), false);
PromptEntityResult per =
ed.GetEntity(opt);
if (per.Status != PromptStatus.OK)
return;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
try
{
DBObject obj =
tr.GetObject(
per.ObjectId,
OpenMode.ForRead
);
Table tb = (Table)obj;
// It should always be a table
// but we'll check, just in case
if (tb != null)
{
// The table must be open for write
tb.UpgradeOpen();
// Update the data link from the table
tb.UpdateDataLink(
UpdateDirection.DataToSource,
UpdateOption.ForceFullSourceUpdate
);
// And the spreadsheet from the data link
ObjectId dlId = tb.GetDataLink(0, 0);
DataLink dl =
(DataLink)tr.GetObject(
dlId,
OpenMode.ForWrite
);
dl.Update(
UpdateDirection.DataToSource,
UpdateOption.ForceFullSourceUpdate
);
}
tr.Commit();
ed.WriteMessage(
"\nUpdated the spreadsheet from the table."
);
}
catch (Exception ex)
{
ed.WriteMessage(
"\nException: {0}",
ex.Message
);
}
}
}
}
}
Tables with linked spreadsheets are locked by default and display this glyph when you hover over them:
. Before you run the code you will need to unlock the table by right-clicking the cell(s) you wish to edit:
One point to note is that the code will work even if the spreadsheet is open in Excel, but the contents will not be updated automatically - you have to close and reopen the file to see the results. And you will probably see this dialog come up twice:
For the best (most logical) results, the T2S command should really be run when the spreadsheet is not open in Excel. I expect it's possible to determine whether a spreadsheet is open in Excel from using standard file access functions in .NET (requesting exclusive access, to see whether it's possible to get it), but that's being left as an exercise for the reader (or for another day, at least :-).
For your convenience, here's a source file containing the code from the last three posts (command implementations for TFS, S2T and T2S).
August 27, 2007 in AutoCAD, AutoCAD .NET, Excel, Tables | Permalink | Comments (0) | TrackBack
Updating an AutoCAD table linked to an Excel spreadsheet using .NET
Thanks to Viru Aithal, from DevTech India, for providing the code for this post (I converted the C# code below from some C++ he had sent to a developer).
In the last post we showed how to create a table linked to an Excel spreadsheet using .NET in AutoCAD 2008. AutoCAD does a great job of looking for changes in the Excel spreadsheet, and asking whether you want to update the linked table:
There may be times, however, when you want to force the update programmatically, whether from the spreadsheet to the table ot vice-versa. In this post we'll show the code to update the table from the spreadsheet, and in the next post we'll see some code to update the spreadsheet from the table (should it have been unlocked and edited).
Here's the C# code:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace LinkToExcel
{
public class Commands
{
[CommandMethod("S2T")]
static public void UpdateTableFromSpreadsheet()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions opt =
new PromptEntityOptions(
"\nSelect table to update: "
);
opt.SetRejectMessage(
"\nEntity is not a table."
);
opt.AddAllowedClass(typeof(Table), false);
PromptEntityResult per =
ed.GetEntity(opt);
if (per.Status != PromptStatus.OK)
return;
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
try
{
DBObject obj =
tr.GetObject(
per.ObjectId,
OpenMode.ForRead
);
Table tb = (Table)obj;
// It should always be a table
// but we'll check, just in case
if (tb != null)
{
// The table must be open for write
tb.UpgradeOpen();
// Update the data link from the spreadsheet
ObjectId dlId = tb.GetDataLink(0, 0);
DataLink dl =
(DataLink)tr.GetObject(
dlId,
OpenMode.ForWrite
);
dl.Update(
UpdateDirection.SourceToData,
UpdateOption.None
);
// And the table from the data link
tb.UpdateDataLink(
UpdateDirection.SourceToData,
UpdateOption.None
);
}
tr.Commit();
ed.WriteMessage(
"\nUpdated the table from the spreadsheet."
);
}
catch (Exception ex)
{
ed.WriteMessage(
"\nException: {0}",
ex.Message
);
}
}
}
}
}
When you run the S2T (for Spreadsheet-to-Table) command, you will be prompted to select a table. The code retrieves the link information from the table and then requests the data link to pull down new data from the spreadsheet before updating the table. Next time we'll look at the code for T2S...
August 24, 2007 in AutoCAD, AutoCAD .NET, Excel, Tables | Permalink | Comments (4) | TrackBack
Creating an AutoCAD table linked to an Excel spreadsheet using .NET
In the last post I promised to tackle this issue, and so here we are again. :-)
Note: the code in this post relies on enhanced table functionality introduced in AutoCAD 2008, so please don't get frustrated trying to make this work in previous versions.
The following C# code follows on from yesterday's, taking the spreadsheet selected by the user and linking it to a newly-created table in the active AutoCAD drawing. I haven't bothered with line numbering in the below code, as it follows on almost exactly from the code shown last time (aside from renaming the namespace, the command and the function, as well as adding a string constant at the top of the function implementation).
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
namespace LinkToExcel
{
public class Commands
{
[CommandMethod("TFS")]
static public void TableFromSpreadsheet()
{
// Hardcoding the string
// Could also select for it
const string dlName =
"Import table from Excel demo";
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
OpenFileDialog ofd =
new OpenFileDialog(
"Select Excel spreadsheet to link",
null,
"xls; xlsx",
"ExcelFileToLink",
OpenFileDialog.OpenFileDialogFlags.
DoNotTransferRemoteFiles
);
System.Windows.Forms.DialogResult dr =
ofd.ShowDialog();
if (dr != System.Windows.Forms.DialogResult.OK)
return;
ed.WriteMessage(
"\nFile selected was \"{0}\".",
ofd.Filename
);
PromptPointResult ppr =
ed.GetPoint(
"\nEnter table insertion point: "
);
if (ppr.Status != PromptStatus.OK)
return;
// Remove the Data Link, if it exists already
DataLinkManager dlm = db.DataLinkManager;
ObjectId dlId = dlm.GetDataLink(dlName);
if (dlId != ObjectId.Null)
{
dlm.RemoveDataLink(dlId);
}
// Create and add the Data Link
DataLink dl = new DataLink();
dl.DataAdapterId = "AcExcel";
dl.Name = dlName;
dl.Description =
"Excel fun with Through the Interface";
dl.ConnectionString = ofd.Filename;
dl.DataLinkOption =
DataLinkOption.PersistCache;
dl.UpdateOption |=
(int)UpdateOption.AllowSourceUpdate;
dlId = dlm.AddDataLink(dl);
Transaction tr =
doc.TransactionManager.StartTransaction();
using (tr)
{
tr.AddNewlyCreatedDBObject(dl, true);
BlockTable bt =
(BlockTable)tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
Table tb = new Table();
tb.TableStyle = db.Tablestyle;
tb.Position = ppr.Value;
tb.SetDataLink(0, 0, dlId, true);
tb.GenerateLayout();
BlockTableRecord btr =
(BlockTableRecord)tr.GetObject(
db.CurrentSpaceId,
OpenMode.ForWrite
);
btr.AppendEntity(tb);
tr.AddNewlyCreatedDBObject(tb, true);
tr.Commit();
}
// Force a regen to display the table
ed.Regen();
}
}
}
Here's what happens when you run the TFS command and select your favourite XLS for linking (I used mass-balance.xls from AutoCAD 2008's Sample\Mechanical Sample folder):
At this stage I haven't focused at all on formating - this is just coming in "as is", without any adjustment of cell alignments, column widths or row heights.
I chose to hardcode the name of the Data Link we use for the spreadsheet. You can run the DATALINK command to check on it, after the command has executed:
It doesn't seem to be an issue if you repeat the command and bring in a different spreadsheet using the same link - the link appears to continue (although I haven't performed exhaustive testing). If it does prove to be a problem it should be simple enough to create a unique Data Link per spreadsheet imported (or even per time the command is run).
August 22, 2007 in AutoCAD, AutoCAD .NET, Excel, Tables | Permalink | Comments (0) | TrackBack
Using AutoCAD's file selection dialog from .NET
Today I started putting together some code showing how to link an Excel sheet to an AutoCAD table (watch this space - there should be something posted later this week). As I was working through it I decided enough was enough, and rather than - yet again - using the command-line to get the name of the file, I'd use the opportunity to demonstrate how to make use of AutoCAD's standard file selection dialog in your applications.
At which point I decided to cut the original post short, as I didn't want this useful (but quite short) topic to get swamped by the broader one.
Here's the C# code that asks the user to select an Excel spreadsheet:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
namespace OpenFiles
{
public class Commands
{
[CommandMethod("SS")]
static public void SelectSpreadsheet()
{
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
OpenFileDialog ofd =
new OpenFileDialog(
"Select Excel spreadsheet to link",
null,
"xls; xlsx",
"ExcelFileToLink",
OpenFileDialog.OpenFileDialogFlags.DoNotTransferRemoteFiles
);
System.Windows.Forms.DialogResult dr =
ofd.ShowDialog();
if (dr != System.Windows.Forms.DialogResult.OK)
return;
ed.WriteMessage(
"\nFile selected was \"{0}\".",
ofd.Filename
);
}
}
}
A few notes on the arguments to the OpenFileDialog constructor:
- The first string is the one shown in the title bar (see below)
- You can pass in a default filename in the second argument, but in our case it isn't appropriate
- You can provide multiple file extensions upon which to filter in the third argument, separated by semi-colons
- The fourth argument is an internal identifier used to store data about the dialog, such as size, position and last navigated path (this data will be picked up automatically the next time the identifier is used)
- The fifth argument is for flags: we're choosing not to copy remote files locally if selected via a URL, in this case
If we were opting to allow multiple file selection (passing AllowMultiple as an additional flag to the fifth argument), then we would access the files returned using ofd.GetFileNames() to access an array of strings.
Here's the dialog we see when we run the SS command:
August 21, 2007 in AutoCAD, AutoCAD .NET, User interface | Permalink | Comments (11) | TrackBack
CommandComplete bonus tool
Most members of my team (DevTech) have a background in software development, having developed code professionally in previous jobs. People often join DevTech because they enjoy the variety and flexibility the role brings as well as the direct communication we have with the Autodesk development community.
That said, we still like to hone our coding skills - some of this we get from fielding questions we receive from ADN members but it's also helpful to work on the odd software project. Back in the day - during my stint living in India - DevTech was part of Autodesk Consulting and so members of the team were often involved in developing code for customers. These days our mandate is clearer, to focus on providing services through the Autodesk Developer Network.
The majority of the software projects we currently work on are samples for publication, whether as DevNotes on the ADN site or as samples we ship with the ObjectARX SDK. During the last year or so we've been running an internal initiative called "DevTech Labs", through which we develop customer-oriented features and bonus tools for posting to Autodesk Labs.
The first fruit of these labours is now available: the CommandComplete bonus tool. Sreekar Devatha, a member of the DevTech team based in India, was the primary developer on this project. I think he's done a great job on this very useful tool. :-)
This post from Scott Sheppard lists some of the feedback we've received to date. There's also further feedback received by email and the discussion group that we'll take into account when working on an update to this tool.
August 17, 2007 in AutoCAD, Commands | Permalink | Comments (0) | TrackBack
Purging registered application names from a folder of AutoCAD drawings using .NET
In the last post we looked at some code to programmatically purge Registered Application names from the drawing currently active in AutoCAD. In this post we take the "batching" code first used in this previous post and apply it to this problem.
What we end up with is an additional command called PF which asks the user to specify a folder and then purges the RegApps from the DWGs in that folder, saving those files that end up being modified with the "_purged" suffix.
One point to note is the use of the Database.RetainOriginalThumbnailBitmap property: as we're not making any graphical changes it's fairly safe to set this to true, which retains the pervious thumbnail bitmap, rather than it being blank in the new drawing. If you were to set it to true after graphical changes nothing especially serious would happen, but it could be confusing for users if the preview differed substantially from the DWG contents.
Here's the C# code with the additional lines in red:
1 using Autodesk.AutoCAD.ApplicationServices;
2 using Autodesk.AutoCAD.DatabaseServices;
3 using Autodesk.AutoCAD.EditorInput;
4 using Autodesk.AutoCAD.Runtime;
5 using System.IO;
6 using System;
7
8 namespace Purger
9 {
10 public class Commands
11 {
12 [CommandMethod("PF")]
13 public void PurgeFiles()
14 {
15 Document doc =
16 Application.DocumentManager.MdiActiveDocument;
17 Editor ed = doc.Editor;
18
19 PromptResult pr =
20 ed.GetString(
21 "\nEnter folder containing DWGs to process: "
22 );
23 if (pr.Status != PromptStatus.OK)
24 return;
25 string pathName = pr.StringResult;
26
27 string[] fileNames =
28 Directory.GetFiles(pathName, "*.dwg");
29
30 // We'll use some counters to keep track
31 // of how the processing is going
32
33 int processed = 0, saved = 0, problem = 0;
34
35 foreach (string fileName in fileNames)
36 {
37 if (fileName.EndsWith(
38 ".dwg",
39 StringComparison.CurrentCultureIgnoreCase
40 )
41 )
42 {
43 string outputName =
44 fileName.Substring(
45 0,
46 fileName.Length - 4) +
47 "_purged.dwg";
48 Database db = new Database(false, true);
49 using (db)
50 {
51 try
52 {
53 ed.WriteMessage(
54 "\n\nProcessing file: " + fileName
55 );
56
57 db.ReadDwgFile(
58 fileName,
59 FileShare.ReadWrite,
60 false,
61 ""
62 );
63
64 db.RetainOriginalThumbnailBitmap = true;
65
66 int objectsPurged =
67 PurgeDatabase(db);
68
69 // Display the results
70
71 ed.WriteMessage(
72 "\nPurged {0} object{1}",
73 objectsPurged,
74 objectsPurged == 1 ? "" : "s"
75 );
76
77 // Only save if we changed something
78
79 if (objectsPurged > 0)
80 {
81 ed.WriteMessage(
82 "\nSaving to file: {0}", outputName
83 );
84
85 db.SaveAs(
86 outputName,
87 DwgVersion.Current
88 );
89 saved++;
90 }
91 processed++;
92 }
93 catch (System.Exception ex)
94 {
95 ed.WriteMessage(
96 "\nProblem processing file: {0} - \"{1}\"",
97 fileName,
98 ex.Message
99 );
100 problem++;
101 }
102 }
103 }
104 }
105 ed.WriteMessage(
106 "\n\nSuccessfully processed {0} files," +
107 " of which {1} had objects to purge" +
108 " and an additional {2} had errors " +
109 "during reading/processing.",
110 processed,
111 saved,
112 problem
113 );
114 }
115
116 [CommandMethod("PC")]
117 public void PurgeCurrentDocument()
118 {
119 Document doc =
120 Application.DocumentManager.MdiActiveDocument;
121 Database db = doc.Database;
122 Editor ed = doc.Editor;
123
124 int count =
125 PurgeDatabase(db);
126
127 ed.WriteMessage(
128 "\nPurged {0} object{1} from " +
129 "the current database.",
130 count,
131 count == 1 ? "" : "s"
132 );
133 }
134
135 private static int PurgeDatabase(Database db)
136 {
137 int idCount = 0;
138
139 Transaction tr =
140 db.TransactionManager.StartTransaction();
141 using (tr)
142 {
143 // Create the list of objects to "purge"
144
145 ObjectIdCollection idsToPurge =
146 new ObjectIdCollection();
147
148 // Add all the Registered Application names
149
150 RegAppTable rat =
151 (RegAppTable)tr.GetObject(
152 db.RegAppTableId,
153 OpenMode.ForRead
154 );
155
156 foreach (ObjectId raId in rat)
157 {
158 if (raId.IsValid)
159 {
160 idsToPurge.Add(raId);
161 }
162 }
163
164 // Call the Purge function to filter the list
165
166 db.Purge(idsToPurge);
167
168 Document doc =
169 Application.DocumentManager.MdiActiveDocument;
170 Editor ed = doc.Editor;
171
172 ed.WriteMessage(
173 "\nRegistered applications being purged: "
174 );
175
176 // Erase each of the objects we've been
177 // allowed to
178
179 foreach (ObjectId id in idsToPurge)
180 {
181 DBObject obj =
182 tr.GetObject(id, OpenMode.ForWrite);
183
184 // Let's just add to me "debug" code
185 // to list the registered applications
186 // we're erasing
187
188 RegAppTableRecord ratr =
189 obj as RegAppTableRecord;
190 if (ratr != null)
191 {
192 ed.WriteMessage(
193 "\"{0}\" ",
194 ratr.Name
195 );
196 }
197
198 obj.Erase();
199 }
200
201 // Return the number of objects erased
202 // (i.e. purged)
203
204 idCount = idsToPurge.Count;
205 tr.Commit();
206 }
207 return idCount;
208 }
209 }
210 }
You can download the source file from here.
August 15, 2007 in AutoCAD, AutoCAD .NET, Batch processing, Drawing structure, Purge | Permalink | Comments (10) | TrackBack
Purging registered application names in the current AutoCAD drawing using .NET
Purging can seriously reduce the size of AutoCAD drawings by removing unnecessary symbol table and dictionary entries. The PURGE command in AutoCAD allows you to safely purge these non-graphical objects (layers, linetypes, block definitions, etc.).
Since AutoCAD 2005 (if I recall correctly), PURGE also supports the removal of Registered Application names. Applications that make use of Extended Entity Data (XData) must register unique application names in drawings. A few applications have, in the past, created many more names than they required, and as these RegApp names get copied from drawing to drawing (when they get XRefed, for instance), they ended spreading from DWG file to

Atom





