Autodesk Community Tips- ADNオープン
Autodesk Community Tipsではちょっとしたコツ、やり方、ショートカット、アドバイスやヒントを共有しています。
ソート順:
質問 AutoCAD .net APIで寸法拘束パラメータとユーザ定義パラメータをグループ化するグループフィルタを作成する方法はありますか。 回答 AutoCADのデータ構造として、グループフィルタはAssocNetworkのXData(拡張データ)にアプリケーション 名ACAD_NETWORK_GROUPSにて定義されます。グループフィルタの情報は、アプリケーションACAD_NETWORK_GROUPSの開始エントリ(1001,ACAD_NETWORK_GROUPS)に続いて、(1070,1)(1000, グループフィルタ名1)(1070,2)(1000, グループフィルタ名2)の形でデータを保持します。 ここで、Dxfグループ コード1070の値はグループフィルタの内部Idを、Dxfグループ コード1000の値はグループフィルタ名に対応します。   例えば拡張データの内容が(1001,ACAD_NETWORK_GROUPS)(1070,1)(1000, グループフィルタ1)(1070,2)(1000, グループフィルタ2)の場合、グループフィルタとして”グループフィルタ1”と”グループフィルタ2”が定義されており、それぞれの内部Idが1と2である状態となります。   グループフィルタ内のパラメータについては、上述の内部Idをパラメータ側から参照する形でAssocVariableのxDataに保存されている形となります。 AssocVariableのxDataにはアプリケーション名PARAMETER_GROUPSにて、(1001,PARAMETER_GROUPS)(1070,1)(1070,2)といった形でデータが保持されておりDxfグループコード1070の値が上述のグループフィルタのIdとなります。   このため、グループフィルタ(パラメータグループ)を新規作成する場合は、AssocNetworkのxDataに追加をする形となります。 また、既存のグループフィルタ内のパラメータを取得する場合には、AssocNetworkのxDataから対象のグループフィルタのIdを取得したのちに、各AssocVariableのxDataを参照して、PARAMETER_GROUPSアプリケーションに対象のグループフィルタのIdを持つデータがあるかを確認する形となります。   以下は新規のグループフィルタを作成するサンプルコードとなります。 [CommandMethod("AddFilterGroup")] public static void AddFilterGroup() { Document dc = Application.DocumentManager.MdiActiveDocument; Database db = dc.Database; Editor ed = dc.Editor; ObjectId networkId = AssocNetwork.GetInstanceFromObject(db.CurrentSpaceId, false, true, "ACAD_ASSOCNETWORK"); if (networkId == ObjectId.Null) return; const string APP_NAME = "ACAD_NETWORK_GROUPS"; PromptResult pr = ed.GetString("Type filter name to create."); string groupFilterName = pr.StringResult; using (Transaction tx = db.TransactionManager.StartTransaction()) { RegAppTable regTable = (RegAppTable)tx.GetObject(db.RegAppTableId, OpenMode.ForRead); if (!regTable.Has(APP_NAME)) { regTable.UpgradeOpen(); RegAppTableRecord app = new RegAppTableRecord(); app.Name = APP_NAME; regTable.Add(app); tx.AddNewlyCreatedDBObject(app, true); } using (AssocNetwork network = tx.GetObject(networkId, OpenMode.ForWrite, false) as AssocNetwork) { ResultBuffer rb = network.XData; if (rb != null) { IEnumerator enu = rb.GetEnumerator(); while (enu.MoveNext()) { TypedValue wk = (TypedValue)enu.Current; ed.WriteMessage("\n" + wk.TypeCode.ToString() + " = " + wk.Value.ToString()); } int nextIndex = 1; var wrapper = rb.Cast<TypedValue>(); //Find "ACAD_NETWORK_GROUPS" in xData if (0 != wrapper.Where<TypedValue>( tv => tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001).Count<TypedValue>()) { //if there is "ACAD_NETWORK_GROUPS" in xData, check duplication of filter. bool inTargetApp = false; if (0 != wrapper.Where(tv =>{ if (inTargetApp) { if (tv.TypeCode == 1000 && tv.Value.ToString() == groupFilterName) { return true; } else if (tv.TypeCode == 1001) { inTargetApp = false; } } else { if (tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001) { inTargetApp = true; } } return false; }).Count()) { //abort if there is same filter name. ed.WriteMessage("\nThe group fileter already exists."); tx.Abort(); return; } else { inTargetApp = false; nextIndex = wrapper.Max<TypedValue>(tv => { if (inTargetApp) { if (tv.TypeCode == 1070) { return Convert.ToInt32(tv.Value); } else if (tv.TypeCode == 1001) { inTargetApp = false; } } else { if (tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001) { inTargetApp = true; } } return 0; } ) + 1; rb = new ResultBuffer(); inTargetApp = false; bool added = false; foreach (var tv in wrapper) { if (inTargetApp) { //start of next application if (tv.TypeCode == 1001) { inTargetApp = false; added = true; rb.Add(new TypedValue(1070, nextIndex)); rb.Add(new TypedValue(1000, groupFilterName)); } rb.Add(tv); } else { rb.Add(tv); if (tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001) { inTargetApp = true; } } } if(!added) { rb.Add(new TypedValue(1070, nextIndex)); rb.Add(new TypedValue(1000, groupFilterName)); } } } else { //Add "ACAD_NETWORK_GROUPS" if not found. rb.Add(new TypedValue(1001, APP_NAME)); rb.Add(new TypedValue(1070, nextIndex)); rb.Add(new TypedValue(1000, groupFilterName)); } network.XData = rb; } else { network.XData = new ResultBuffer(new TypedValue(1001, APP_NAME), new TypedValue(1070, 1), new TypedValue(1000, groupFilterName)); } } tx.Commit(); } ed.Command("PARAMETERS"); }   また、以下は指定したパラメータグループに含まれているパラメータを確認するサンプルコードとなります。 [CommandMethod("GetFilterGroupParameters")] public static void GetFilterGroupParameters() { Document dc = Application.DocumentManager.MdiActiveDocument; Database db = dc.Database; Editor ed = dc.Editor; ObjectId networkId = AssocNetwork.GetInstanceFromObject(db.CurrentSpaceId, false, true, "ACAD_ASSOCNETWORK"); if (networkId == ObjectId.Null) return; const string APP_NAME = "ACAD_NETWORK_GROUPS"; PromptResult pr = ed.GetString("Type filter name to get parameters."); string groupFilterName = pr.StringResult; using (Transaction tx = db.TransactionManager.StartTransaction()) { RegAppTable regTable = (RegAppTable)tx.GetObject(db.RegAppTableId, OpenMode.ForRead); if (!regTable.Has(APP_NAME)) { ed.WriteMessage("\n There is no spcified parameter group."); return; } using (AssocNetwork network = tx.GetObject(networkId, OpenMode.ForWrite, false) as AssocNetwork) { ResultBuffer rb = network.XData; if (rb == null) { ed.WriteMessage("\n There is no spcified parameter group."); return; } IEnumerator enu = rb.GetEnumerator(); while (enu.MoveNext()) { TypedValue wk = (TypedValue)enu.Current; ed.WriteMessage("\n" + wk.TypeCode.ToString() + " = " + wk.Value.ToString()); } var wrapper = rb.Cast<TypedValue>(); bool inTargetApp = false; int targetIndex = 0; bool found = false; foreach(var tv in wrapper) if (inTargetApp) { if(tv.TypeCode == 1070) { targetIndex = Convert.ToInt32(tv.Value); } else if(tv.TypeCode == 1000 && tv.Value.ToString() == groupFilterName) { found = true; break; } } else { if (tv.Value.ToString() == APP_NAME && tv.TypeCode == 1001) { inTargetApp = true; } } } if (!found) { ed.WriteMessage("\n There is no spcified parameter group."); return; } //Now iterate though AssocActions to find variable which has targetIndex in it's xData. foreach (ObjectId actionId in network.GetActions) { if (actionId == ObjectId.Null) continue; DBObject obj = tx.GetObject(actionId, OpenMode.ForRead); if (actionId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(AssocVariable)))) { AssocVariable var = obj as AssocVariable; ed.WriteMessage("\n - AssocVariable " + var.Name + " = " + var.Expression); ResultBuffer pRb = var.XData; if (pRb != null) { var pWrapper = pRb.Cast<TypedValue>(); //loop thourough result buffer to find typedvalue with (1070, targetIndex). inTargetApp = false; foreach (var tv in pWrapper) { if (inTargetApp) { if (tv.TypeCode == 1070 && targetIndex == Convert.ToInt32(tv.Value)) { ed.WriteMessage(" is referenced by specified group."); } else if(tv.TypeCode == 1001) { inTargetApp = false; } } else { if (tv.Value.ToString() == "PARAMETER_GROUPS" && tv.TypeCode == 1001) { inTargetApp = true; } } } } } } } tx.Commit(); } }
記事全体を表示
質問 AutoCADの.net APIで寸法拘束の拘束フォームを変更する方法はありますか。 回答 残念ながら、AutoCADの.net APIには寸法拘束の拘束フォームを変更するAPIはありません。 一方でObjectARX C++のAPIには対応するAPIが存在するため、.netのプログラムからは、P/Invoke を用いることで.netから寸法拘束の拘束フォームを変更することが可能です。   寸法拘束の拘束フォームの変更には、ObjectARX C++の寸法線の基底クラスAcDbDimensionの、isConstraintDynamic()メソッドおよびsetConstraintDynamic(bool isDynamic)メソッドを使用します。   isConstraintDynamic()メソッドは、その戻り値で現在の拘束フォームの設定状態を確認することが出来ます(true:ダイナミック, false:注釈)。 また、setConstraintDynamic(bool isDynamic)メソッドは、引数に指定した値で拘束フォームの設定状態を変更することが可能です。   以下は、AutoCAD 2023でP/Invokeを用いて.net で作成したAutoCADのカスタムコマンドから、選択した寸法拘束の拘束フォームの設定を変更するサンプルコードとなります。 [CommandMethod("FlipConstraintsForm")] public void FlipConstraintsForm() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; var option = new PromptEntityOptions("\n" + "Select a dimension constraints."); PromptEntityResult result = ed.GetEntity(option); if (result.Status != PromptStatus.OK) return; ObjectId id = result.ObjectId; using (Transaction tx = db.TransactionManager.StartTransaction()) { Dimension dim = tx.GetObject(id, OpenMode.ForWrite) as Dimension; DatabaseExtensions.DatabaseExtensions.Dimension_FlipConstraintsForm(dim); tx.Commit(); } } //DatabaseExtensions.cs namespace DatabaseExtensions { public class DatabaseExtensions { private static class AcDbDimension { [DllImport("acdb24.dll", CallingConvention = CallingConvention.ThisCall, CharSet = CharSet.Unicode, EntryPoint = "?isConstraintDynamic@AcDbDimension@@QEBA_NXZ")] [return: MarshalAs(UnmanagedType.Bool)] public static extern Boolean isConstraintDynamic(IntPtr dimension); [DllImport("acdb24.dll", CallingConvention = CallingConvention.ThisCall, CharSet = CharSet.Unicode, EntryPoint = "?setConstraintDynamic@AcDbDimension@@QEAA?AW4ErrorStatus@Acad@@_N@Z")] public static extern ErrorStatus setConstraintDynamic(IntPtr dimension, [MarshalAs(UnmanagedType.Bool)] Boolean bDynamic); } public static void Dimension_FlipConstraintsForm(Dimension dim) { dim.UpgradeOpen(); bool isDynamic = AcDbDimension.isConstraintDynamic(dim.UnmanagedObject); AcDbDimension.setConstraintDynamic(dim.UnmanagedObject, !isDynamic); } } }   DllImportによりImportするdllファイル名は、対象のAutoCADのバージョンに依存して変わる点にご留意ください。   なお、P/Invokeを用いたAPIの実装方法についてはこちらの記事に開設がありますので、ご参照ください。
記事全体を表示
Issue Civil3DのImportSubassembly APIでSubassemblyComposerで作成したサブアセンブリが正しく挿入されmせん。API自体はエラーもなく実行できていますが、挿入したサブアセンブリには作成時に設定したパラメータも表示されず、また形状もSubassemblyComposerで作成したものではなく、「○」の状態となってしまう。 なお、対象のサブアセンブリはツールパレットには読み込まれており、GUIからは正しく図面に挿入することが出来ています。   Solution ImportSubassembly APIの不具合により、正しく挿入ができていない状況と思われます。   ImportSubassemblyの引数に指定しているatcファイルをテキストエディタで開き、ファイル内のDataTypeの記述を編集することでImportSubassembly にて配置をすることが可能となります。   DataType="long" → DataType="Long" DataType="double" → DataType="Double" DataType="bool" → DataType="Bool" DataType="string" → DataType="String"  
記事全体を表示
Issue 図面ファイルを開いた際に、その図面ファイルの DWG ファイル形式が表示されます。 この情報を AutoCAD .NET API で取得することは出来ますか?    Solution 図面ファイル形式は、Database.OriginalFileVersion プロパティで返される DwgVersion 値で取得することが出来ます。    次のコードは、その C# 使用例です。   [CommandMethod("MyCommand", CommandFlags.Modal)] public void MyCommand() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; Database db = Application.DocumentManager.MdiActiveDocument.Database; ed.WriteMessage("\nSaved DWG format:{0}", GetDwgFormat(db.OriginalFileVersion)); } private string GetDwgFormat(DwgVersion ver) { string dwgFormat = string.Empty; switch (ver) { case DwgVersion.AC1002: dwgFormat = "AutoCAD 2.5 形式"; break; case DwgVersion.AC1003: dwgFormat = "AutoCAD 2.6 形式"; break; case DwgVersion.AC1004: dwgFormat = "AutoCAD R9 形式"; break; case DwgVersion.AC1006: dwgFormat = "AutoCAD R10 形式"; break; case DwgVersion.AC1009: dwgFormat = "AutoCAD R11/R12 形式"; break; case DwgVersion.AC1012: dwgFormat = "AutoCAD R13 形式"; break; case DwgVersion.AC1014: dwgFormat = "AutoCAD R14 形式"; break; case DwgVersion.AC1015: dwgFormat = "AutoCAD 2000 形式"; break; case DwgVersion.AC1021: dwgFormat = "AutoCAD 2007 形式"; break; case DwgVersion.AC1024: dwgFormat = "AutoCAD 2010 形式"; break; case DwgVersion.AC1027: dwgFormat = "AutoCAD 2013 形式"; break; case DwgVersion.AC1032: dwgFormat = "AutoCAD 2018 形式"; break; case DwgVersion.AC1800: case DwgVersion.AC1800a: dwgFormat = "AutoCAD 2004 形式"; break; default: dwgFormat = "Unknown 形式"; break; } return dwgFormat; }    
記事全体を表示
Issue .NET API で開発したアドイン アプリのアセンブリを他のコンピューターで動作テストしようとしています。 一旦、アセンブリを共有サーバーにアップロードして他のコンピューターにダウンロードすると、そのアセンブリがロード出来ません。  具体的には System.IO.FileLoadException 例外エラーが表示されてロードできません。 どうすればいいでしょうか?     Solution .NET Framework のセキュリティ ポリシーにより、クラウド ストレージを含むネットワーク リソースからダウンロードしたアセンブリ ファイルは読み込みがブロックされています。 Windows エクスプローラーからアセンブリのプロパティ ダイアログを表示させると、「許可する」項(Windows バージョンによっては「ブロック解除」項)が表示されます。 この項目にチェックしてブロックを解除すると、NETLOAD 出来るようになります。 一度、NETLOAD 時に例外エラーが発生した場合には、次の NETLOAD 作業前に AutoCAD を再起動してください。(キャッシュされたアセンブリ情報をクリアする目的)
記事全体を表示
Issue AutoCAD .NET API:ダウンロードしたアセンブリが NETLOAD 出来ない - Autodesk Community の内容に沿ってブロック解除したアドイン アプリ アセンブリがロード出来ません。  なぜでしょうか?     Solution アセンブリ ファイルのブロックを解除しても改善が見られないようでしたら、SECURITYOPTIONS コマンドで [セキュリティ オプション] ダイアログの信頼できるパスにアセンブリ ファイルの配置パスをに追加してみてください。     セキュリティ オプションを変更したら、AutoCAD を再起動して、再度、NETLOAD してみてください。   ご参考: AutoCAD 2016 のセキュリティとアドインのデジタル署名 - Technology Perspective from Japan (typepad.com) アドイン ロード時の警告ダイアログ抑止 - Technology Perspective from Japan (typepad.com)
記事全体を表示
Issue MSPACE[モデル空間] コマンドや PSPACE[ペーパー空間] コマンド のように、レイアウト上に配置したビューポートの編集モードを変更するメソッドはありますか?     Solution Editor.SwitchToModelSpace メソッドと Editor.SwitchToPaperSpace メソッドがそれぞれ該当します。   Editor.SwitchToModelSpace メソッドは、現在のビューポートをモデル空間編集モードに切り替えます。同様に、Editor.SwitchToPaperSpace メソッドは、現在のビューポートをペーパー空間編集モードに切り替えます。   AutoCAD のオンラインヘルプ「AutoCAD 2024 Developer and ObjectARX ヘルプ | 浮動ビューポート(.NET) | Autodesk」も参考にしてください。
記事全体を表示
Issue 寸法が参照する画層が、同寸法の削除後も削除出来ません。     ただし、一度、図面を保存して開き直すと削除出来ます。 図面を開き直さなくても、この画層を削除したいのですが、AutoCAD .NET API で可能でしょうか?   Solution AutoCAD .NET API では、Database.ReclaimMemoryFromErasedObjects メソッドでメモリ上の図面データベースからオブジェクトを削除する方法を利用することが出来ます。   このメソッドは、元々、32 ビット環境で大規模図面を操作する際の消費メモリ低減を狙ったものですが、図面を保存して開き直さなくても、同じセッションで図面データベース内の削除フラグが付いたオブジェクトをメモリから削除することが可能です。 下記コード例では、対象の寸法オブジェクトの削除後に ReclaimMemoryFromErasedObjects メソッドで同オブジェクトをメモリ上から削除、その後、参照画層と寸法を表現していた匿名ブロックを削除している点にご注意ください。 後半の処理(下部の Using スコープ)がないと、AUDIT コマンドで図面破損が報告されてしまうので注意が必要です。 少し趣旨が異なりますが、ちょうど、LAYDEL[画層削除] コマンドが処理する内容と似ています。   Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptEntityOptions peo1 = new PromptEntityOptions("\n削除する寸法を選択:"); PromptEntityResult pent = ed.GetEntity(peo1); if (pent.Status != PromptStatus.OK) { return; } ObjectIdCollection erased = new ObjectIdCollection(); ObjectId layId = ObjectId.Null; ObjectId blkId = ObjectId.Null; using (Transaction tr = db.TransactionManager.StartTransaction()) { Dimension dim = (Dimension)tr.GetObject(pent.ObjectId, OpenMode.ForWrite); erased.Add(pent.ObjectId); layId = dim.LayerId; blkId = dim.DimBlockId; dim.Erase(); tr.Commit(); } db.ReclaimMemoryFromErasedObjects(erased); using (Transaction tr = db.TransactionManager.StartTransaction()) { LayerTableRecord lay = (LayerTableRecord)tr.GetObject(layId, OpenMode.ForWrite); lay.Erase(); BlockTableRecord blk = (BlockTableRecord)tr.GetObject(blkId, OpenMode.ForWrite); blk.Erase(); tr.Commit(); }  
記事全体を表示
Issue Database.CurrentSpaceId プロパティでアクティブなレイアウトのレイアウト(ペーパー空間)の BlockTableRecord を取得して、対応する Layout を得ています。   [CommandMethod("GetLayoutId", CommandFlags.NoTileMode | CommandFlags.Modal)] public void GetLayoutId() { Database acCurDb = Application.DocumentManager.MdiActiveDocument.Database; Editor acDocEd = Application.DocumentManager.MdiActiveDocument.Editor; using (Transaction acTr = acCurDb.TransactionManager.StartTransaction()) { ObjectId objId = acCurDb.CurrentSpaceId; BlockTableRecord oRec = (BlockTableRecord)acTr.GetObject(objId, OpenMode.ForRead); if (oRec.IsLayout) { Layout oLay = (Layout)acTr.GetObject(oRec.LayoutId, OpenMode.ForRead); acDocEd.WriteMessage("\nCurrent LayoutId:{0}, Tab Name:{1}", oLay.ObjectId.ToString(), oLay.LayoutName); } acTr.Commit(); } }   ただ、レイアウト上のビューポートでモデル空間がアクティブになっていると、モデル空間を表す BlockTableRecord に対するレイアウト名(モデル空間のタブ名「モデル」は英語の「Model」)が表示されてしまいます。      ビューポートでモデル空間がアクティブな状態でも、アクティブなレイアウトに対応する Layout を得ることは出来るでしょうか?   Solution Database.CurrentSpaceId プロパティは、アクティブな空間の ID を返すプロパティです。 アクティブなレイアウトタブに対応する BlockTableRecord の ID を得るためには、システム変数 CTAB を利用することが出来ます。   [CommandMethod("GetLayoutId2", CommandFlags.NoTileMode | CommandFlags.Modal)] public void GetLayoutId2() { Database acCurDb = Application.DocumentManager.MdiActiveDocument.Database; Editor acDocEd = Application.DocumentManager.MdiActiveDocument.Editor; string strLay = (string)Application.GetSystemVariable("CTAB"); using (Transaction acTr = acCurDb.TransactionManager.StartTransaction()) { BlockTable oTbl = (BlockTable)acTr.GetObject(acCurDb.BlockTableId, OpenMode.ForRead); Layout oLay; BlockTableRecord oRec; foreach (ObjectId objId in oTbl) { oRec = (BlockTableRecord)acTr.GetObject(objId, OpenMode.ForRead); if (oRec.IsLayout) { oLay = (Layout)acTr.GetObject(oRec.LayoutId, OpenMode.ForRead); if (oLay.LayoutName == strLay) acDocEd.WriteMessage("\nCurrent LayoutId:{0}, Tab Name:{1}", oLay.ObjectId.ToString(), strLay); } } acTr.Commit(); } }  
記事全体を表示
Issue 特定の作図コマンドの実行を抑止する目的で、CommandWillStart イベント ハンドラ内で Document.SendStringToExecute メソッドを使って ESC コード(C#:"\x1B"、VB.NET:Chr$(27) )を送信してコマンドの実行をキャンセルしています。   Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; doc.SendStringToExecute("\x1B\x1B", false, true, false);   他にコマンドの実行を抑止する方法はないでしょうか?   Solution ドキュメント ウィンドウに表示されている図面に作図をする場合、AutoCAD は内部的にドキュメントをロックします。   ドキュメント ロックはアプリケーション実行コンテキストで定義したコマンドの実装時に必要になる知識と言えますが、この仕組みをイベント ハンドラで取得、利用することが出来ます。   この場合、DocumentLockModeChanged イベント ハンドラで DocumentLockModeChangedEventArgs.Veto メソッドを呼び出すことで、作図コマンドの実行時にドキュメント ロックを拒否してコマンドの実行そのものを抑止することが出来ます。    次の C# コードは、LINE コマンドの実行を抑止する例です。   ... [CommandMethod("MyCommand", CommandFlags.Modal)] public void MyCommand() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; Application.DocumentManager.DocumentLockModeChanged += DocumentEvent_LockModeChanged_Handler; } private static void DocumentEvent_LockModeChanged_Handler(object sender, DocumentLockModeChangedEventArgs e) { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; if (e.GlobalCommandName == "LINE") { e.Veto(); ed.WriteMessage(string.Format("\n{0} command was vetoed\n", e.GlobalCommandName)); } } ...    
記事全体を表示
質問 AutoCAD Plant3D .net API でデータマネージャで表示されているガスケットのプロパティ情報を取得したい。 回答 ガスケット(≒ コネクタ)の場合、Connector.AllSubPartsからサブパーツ数を取得し、DataLinksManager.MakeAcPpObjectId()をsubIndexを指定してrowIdを取得後にDataLinksManager.GetAllProperties()を実行することでプロパティを取得することが可能となります。   以下は、選択したガスケットのプロパティ情報を取得するC#のサンプルコードとなります。 [CommandMethod("GetPipingProperties")] public void GetPipingProperties() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; PromptEntityResult res = ed.GetEntity("Pick Object obtain properties : "); if (res.Status == PromptStatus.OK) { ObjectId objectId = res.ObjectId; PlantProject currentProj = PlantApplication.CurrentProject; PipingProject pipingProj = (PipingProject)currentProj.ProjectParts["Piping"]; DataLinksManager dlm = pipingProj.DataLinksManager; int rowId = dlm.FindAcPpRowId(res.ObjectId); List<KeyValuePair<string, string>> properties; properties = dlm.GetAllProperties(rowId, true); for (int i = 0; i < properties.Count; i++) ed.WriteMessage("\nProperty name:" + properties[i].Key + " = " + properties[i].Value); Database trDatabase = objectId.Database; using (Transaction tr = trDatabase.TransactionManager.StartTransaction()) { Connector connector = tr.GetObject(objectId, OpenMode.ForRead, false, true) as Connector; if (connector != null) { SubPartCollection subPartCollection = connector.AllSubParts; int index = 1; foreach (object connectorSubPart in subPartCollection) { int acPcRowId = dlm.FindAcPpRowId(dlm.MakeAcPpObjectId(objectId, index)); List<KeyValuePair<string, string>> subProps = dlm.GetAllProperties(acPcRowId, true); if (subProps != null) { foreach(var subProp in subProps) ed.WriteMessage("\nProperty name:" + subProp.Key + " = " + subProp.Value); } index++; } } } } }
記事全体を表示
質問 AutoCAD .net APIで寸法補助線の開始、終了点と寸法線と寸法補助線の交差点の座標を取得したいのですが、方法はありますか。 回答 AutoCADの.net APIには、直接的に寸法補助線の開始・終了点や寸法線と寸法補助線の交差点の座標を取得するメソッドやプロパティはありません。このため、対象の寸法線の幾何情報から算出して取得する必要があります。 最も簡便な方法としては、対象の寸法線をExplodeにより分解し、分解して取得したオブジェクトの内容から計算をして取得する形となります。   以下は、平行寸法線に対して、寸法補助線の開始・終了点や寸法線と寸法補助線の交差点に点オブジェクトを作成するC#のサンプルコードです。  private static void makePoint(Point2d point, Transaction tx, BlockTableRecord acBlkTblRec) { DBPoint acPoint = new DBPoint(new Point3d(point.X, point.Y, 0)); acPoint.SetDatabaseDefaults(); acBlkTblRec.AppendEntity(acPoint); tx.AddNewlyCreatedDBObject(acPoint, true); } [CommandMethod("GetPointsOnAlignedDimension")] public static void GetPointsOnAlignedDimension() { Document dc = Application.DocumentManager.MdiActiveDocument; Database db = dc.Database; Editor ed = dc.Editor; PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "\nSelect an Aligned Dimension:"; pso.SingleOnly = true; pso.SinglePickInSpace = true; PromptSelectionResult psr = ed.GetSelection(pso); if (psr.Status != PromptStatus.OK) return; SelectionSet ss = psr.Value; SelectedObject so = ss[0]; if (!so.ObjectId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AlignedDimension)))) { ed.WriteMessage("\nSelected entity is not Aligned Dimension..."); return; } ObjectId id = so.ObjectId; using (Transaction tx = db.TransactionManager.StartTransaction()) { try { // Open the Block table for read BlockTable acBlkTbl = tx.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; // Open the Block table record Model space for write BlockTableRecord acBlkTblRec = tx.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; AlignedDimension dim = tx.GetObject(id, OpenMode.ForRead) as AlignedDimension; DBObjectCollection col = new DBObjectCollection(); dim.Explode(col); Point3d dimLoc = dim.DimLinePoint; Point3d xPt1 = dim.XLine1Point; Point3d xPt2 = dim.XLine2Point; Line2d entityLine = new Line2d(new Point2d(xPt1.X, xPt1.Y), new Point2d(xPt2.X, xPt2.Y)); Line2d dimensionLine = new Line2d(new Point2d(dimLoc.X, dimLoc.Y), entityLine.Direction); Line2d lineStargingFromPt1 = entityLine.GetPerpendicularLine(new Point2d(xPt1.X, xPt1.Y)); Line2d lineStargingFromPt2 = entityLine.GetPerpendicularLine(new Point2d(xPt2.X, xPt2.Y)); Point2d interSection1 = lineStargingFromPt1.IntersectWith(dimensionLine).First(); Point2d interSection2 = lineStargingFromPt2.IntersectWith(dimensionLine).First(); makePoint(interSection1, tx, acBlkTblRec); makePoint(interSection2, tx, acBlkTblRec); foreach(DBObject dbObj in col) { Line line = dbObj as Line; if (line == null) { continue; } Point2d startPt = new Point2d(line.StartPoint.X, line.StartPoint.Y); Point2d endPt = new Point2d(line.EndPoint.X, line.EndPoint.Y); if (lineStargingFromPt1.IsOn(startPt) && lineStargingFromPt1.IsOn(endPt)) { makePoint(startPt, tx, acBlkTblRec); makePoint(endPt, tx, acBlkTblRec); } else if (lineStargingFromPt2.IsOn(startPt) && lineStargingFromPt2.IsOn(endPt)) { makePoint(startPt, tx, acBlkTblRec); makePoint(endPt, tx, acBlkTblRec); } } db.Pdmode = 34; db.Pdsize = 1; tx.Commit(); } catch (System.Exception e) { tx.Abort(); ed.WriteMessage(e.Message); } } }   平行寸法線以外の場合にも、Explodeしたオブジェクトから各寸法線の特徴に合わせて幾何計算を行うことで取得が可能です。
記事全体を表示
質問 InventorのAPIを使って、Inventorのコマンドを実行する方法はありますか。   回答 Inventorの各コマンド(カスタムコマンドを含む)はCommandManagerオブジェクトからControlDefinition オブジェクトとして取得することが出来ます。 取得したControlDefinition オブジェクトのExecuteメソッドを実行することで、コマンドを実行することが可能です。   以下は"Vaultステータスを更新"コマンドを実行するサンプルコードとなります。 ' Get the CommandManager object. Dim oCommandMgr As CommandManager = ThisApplication.CommandManager ' Get control definition. Dim oControlDef As ControlDefinition = oCommandMgr.ControlDefinitions.Item("VaultRefresh") ' Execute the command. Call oControlDef.Execute   ControlDefinitions.Itemメソッドに指定する引数は、取得するコマンドの名称となります。   コマンドの名称の取得方法としては、以下の2つの方法があります。   1.以下のサンプルコード(VBA)を実行し、出力されるファイル内から取得する Sub PrintCommandNames() ' Get the CommandManager object. Dim oCommandMgr As CommandManager Set oCommandMgr = ThisApplication.CommandManager ' Get the collection of control definitions. Dim oControlDefs As ControlDefinitions Set oControlDefs = oCommandMgr.ControlDefinitions ' Open the file and print out a header line. Dim oControlDef As ControlDefinition Open "C:\temp\CommandNames.txt" For Output As #1 Print #1, Tab(10); "Command Name"; Tab(75); _ "Description"; vbNewLine ' Iterate through the controls and write out the name. For Each oControlDef In oControlDefs Print #1, oControlDef.InternalName; Tab(55); _ oControlDef.DescriptionText Next ' Close the file. Close #1 End Sub   2.Inventor SDKに付属のEventWatcherを使用し、Inventorでコマンドを実行してコマンド名を取得する   EventWatcherは、Inventorに付属のInventor SDKをインストールすると以下のフォルダにあります。 C:\Program Files\Autodesk\<Inventor Version>\SDK\DeveloperTools\Tools\EventWatcher\bin\Release   EventoWatcherを起動し、左側のリストから「UserInputEvents.OnActivateCommand」をチェックされた状態で、InventorでAPIから実行したいコマンドを実行すると、実行されたコマンド名がウィンドウに表示されます。 取得したコマンド名をControlDefinitions.Itemメソッドの引数に指定することで、対象のコマンドを取得することが出来ます。     なお、コマンド実行時にダイアログが表示されるタイプのコマンド(例:押し出し コマンド)の場合、ダイアログ内で指定するパラメータ(押し出しコマンドの場合、押し出し方向や距離 等)の指定についてはコマンドの機能となり、コマンドを実行するAPIから制御(指定)することが出来ません。   このようなタイプのコマンドの場合、APIからユーザの入力なしに実行したい場合は、InventorのAPIを用いて処理を作成する必要があります(もちろん処理には、希望の処理に対応するInventorのAPIが公開されている必要があります)。  
記事全体を表示
質問 Inventor iLogicで現在開いているファイルがVaultに登録されているかを知る方法はありますか。 回答 Inventor iLogicからVaultのAPIを用いて、Vaultのチェックイン状態を確認することが可能です。   Vaultでのチェックイン状態を知るためには、対象のファイルのVualtのフォルダ構造のパス情報を用いてDocumentService.FindLatestFilesByPaths()メソッドを利用します。     以下は、現在Inventorで開いているファイルおよびその参照ファイルがVaultに登録されているかを確認し、Vaultに登録されていない場合は、iLogicのログにファイルのパスを出力するサンプルコードとなります。   なお、サンプルコードではわかりやすさを優先して、1ファイルずつDocumentService.FindLatestFilesByPaths()メソッドを実行していますが、 DocumentService.FindLatestFilesByPaths()メソッドには複数のパス情報を配列として指定可能なため、パフォーマンスを考慮した場合には、まとめて実行することをお勧めいたします。     ◆iLogicのファイルヘッダ AddReference "Autodesk.Connectivity.WebServices.dll" Imports AWS = Autodesk.Connectivity.WebServices AddReference "Autodesk.DataManagement.Client.Framework.Vault.dll" Imports VDF = Autodesk.DataManagement.Client.Framework AddReference "Connectivity.Application.VaultBase.dll" Imports VB = Connectivity.Application.VaultBase AddReference "Autodesk.DataManagement.Client.Framework"   ・ iLogicソース  Sub Main() Dim conn As VDF.Vault.Currency.Connections.Connection conn = VB.ConnectionManager.Instance.Connection If conn Is Nothing Then MessageBox.Show("Vaultにログインしていません。") Return End If Dim rootFolder As String rootFolder = conn .WorkingFoldersManager.GetWorkingFolder("$/").FullPath For Each doc As Inventor.Document In ThisDoc.Document.AllReferencedDocuments If (FindFileInVault(doc.FullFileName, rootFolder, conn)) Then Else Logger.Trace("{0} is not checked in to Vault ", doc.FullFileName) End If Next End Sub Public Function FindFileInVault(localfilePath As String, workingfolder As String, conn As VDF.Vault.Currency.Connections.Connection) As Boolean Dim VaultPath As String = localfilePath.Replace(workingfolder, "$/") VaultPath = VaultPath.Replace("\", "/") Dim VaultPaths() As String = New String() {VaultPath} Dim wsFiels() As AWS.File = conn.WebServiceManager.DocumentService.FindLatestFilesByPaths(VaultPaths) If wsFiels(0).Id <> -1 Then Return True End If Logger.Trace("localfilePath is {0}", localfilePath) Logger.Trace("VaultPath={0}, id={1}", VaultPath, wsFiels(0).Id) Return False End Function  
記事全体を表示
質問 AutoCAD .net API でパレットを作成しました。パレットには、テキストボックスを配置したカスタムコントロールを配置しています。パレットを表示しテキストボックスに値を入力している途中で、マウスカーソルをパレットから外すと、フォーカスがテキストボックスから外れ、以後のキー入力はAutoCADのコマンド入力として処理されてしまいます。 パレットからマウスカーソルを外してもフォーカスが外れないようにすることはできますか。   回答 PaletteSetを継承したクラスを作成し、KeepFocusメソッドをオーバライドして、フォーカスを外したくない場合には戻り値falseを戻すように実装することで実現が可能です。   以下は、テキストボックス(textBox1)を配置したユーザコントロール(UserControl1)をパレットに配置し、textBox1にフォーカスがある場合は、コントロールからフォーカスを外さない処理をKeepFocusメソッドに記述したサンプルコードとなります。   public class MyPalettSet : PaletteSet { private UserControl1 uctl1 = new UserControl1(); public MyPalettSet(string name) : base(name) { this.Style = PaletteSetStyles.ShowTabForSingle | PaletteSetStyles.ShowPropertiesMenu | PaletteSetStyles.ShowAutoHideButton | PaletteSetStyles.ShowCloseButton; this.MinimumSize = new System.Drawing.Size(400, 100); this.Add("uctl", uctl1); this.Visible = true; this.Size = new System.Drawing.Size(400, 100); this.DockEnabled = DockSides.None; } public override bool KeepFocus { get { return uctl1.Controls["textBox1"] != null ? uctl1.Controls["textBox1"].Focused : false; } } }
記事全体を表示
Issue AutoCAD のダイナミック ブロックについて、VBA でどの程度操作ができるかわかりません。 モデル空間などに配置されているダイナミック ブロックのパラメータの状態を取得したり、パラメータの値を更新して、形状や表示状態を変更することはできますか?   Solution ダイナミックブロックとして配置されているブロック参照からは、ある程度の情報を取得したり、その値を変化させることができます。ただし、現在のバージョンでは一部制限があるため、すべての情報の制御や、パラメータ間の関連付けを得ることができません。   ブロック参照からダイナミックブロック固有の情報にアクセスするには、AcadBlockReference オブジェクトの GetDynamicBlockProperties メソッドを使用して、パラメータ情報を含むコレクションを取得します。このコレクションには、DynamicBlockReferenceProperty オブジェクトがパラメータ(アクションとの組み合わせ)数分含まれます。   DynamicBlockReferenceProperty オブジェクトを取得した後は、このオブジェクトが持つプロパティを使って、パラメータ別の情報にアクセスできます。つまり、ダイナミック ブロック参照の現在の設定値を得ることが可能です。   なお、パラメータによっては、ルックアップ テーブルや可視テーブルなど、リスト化された情報も存在します。このような場面では、パラメータを表す DynamicBlockReferenceProperty.Value プロパティは配列として返されます。これをチェックすれば、その内容を AllowedValues プロパティから閲覧することもできます。   添付のコードは、ダイナミックブロックの情報を取得する例です。   Dim nDataIndex As Long Dim vDataInfo As Variant Dim oData As AcadDynamicBlockReferenceProperty Dim nListIndex As Long Dim vListInfo As Variant Dim nRound As Integer Dim oEnt As AcadEntity Dim oBlkRef As AcadBlockReference nRound = ThisDrawing.GetVariable("LUPREC") For Each pEnt In ThisDrawing.ModelSpace If pEnt.ObjectName = "AcDbBlockReference" Then Set oBlkRef = pEnt If oBlkRef.IsDynamicBlock Then ThisDrawing.Utility.Prompt vbCrLf & "***** ダイナミックブロック - " ThisDrawing.Utility.Prompt oBlkRef.EffectiveName & " : " & oBlkRef.Name nCtrlIndex = 1 For nDataIndex = LBound(oBlkRef.GetDynamicBlockProperties) To UBound(oBlkRef.GetDynamicBlockProperties) Set oData = oBlkRef.GetDynamicBlockProperties(nDataIndex) If oData.show Then ' パラメータ名ラベル ThisDrawing.Utility.Prompt vbCrLf & oData.PropertyName & " : " ' パラメータが配列か確認 vDataInfo = oData.Value If IsArray(vDataInfo) Then ' 座標データの場合 ThisDrawing.Utility.Prompt Round(vDataInfo(0), nRound) & "," & Round(vDataInfo(1), nRound) & "," & Round(vDataInfo(2), nRound) Else ' リスト要素か確認 vListInfo = oData.AllowedValues If UBound(vListInfo) > 0 Then ' リスト要素の場合 For nListIndex = LBound(vListInfo) To UBound(vListInfo) If VarType(vDataInfo) = vbDouble Then ThisDrawing.Utility.Prompt vbCrLf & vbTab & CStr(Round(vListInfo(nListIndex), nRound)) Else ThisDrawing.Utility.Prompt vbCrLf & vbTab & vListInfo(nListIndex) End If Next nListIndex If VarType(vDataInfo) = vbDouble Then ThisDrawing.Utility.Prompt vbCrLf & vbTab & "現在値 : " & CStr(Round(vDataInfo, nRound)) Else ThisDrawing.Utility.Prompt vbCrLf & vbTab & "現在値 : " & vDataInfo End If Else ' 通常データの場合 If VarType(vDataInfo) = vbDouble Then ThisDrawing.Utility.Prompt Round(vDataInfo, nRound) Else ThisDrawing.Utility.Prompt vDataInfo End If End If End If End If ThisDrawing.Utility.Prompt vbCrLf Next End If End If Next
記事全体を表示
Issue 複数の 3D ソリッドの底面を XY 平面(Z 座標値 0.0)に一斉に揃えることは出来ますか?   Solution 選択した 3D ソリッドの底辺を Z=0.0 に位置合わせするコードを作成する場合、オブジェクト(Solid3d)の境界ボックス座標を Entity.GeometricExtents プロパティで取得してから、Extents3d.MinPoint.Z で現在の底面の Z 値を取得、次に、XY 平面(Z 値 0.0)からのベクトル(Vector3d)からマトリックス(Matrix3d)を作成後、同マトリックスを反転して、Z 値 0.0 の移動させることで、底面の位置合わせを行うことが出来ます。次の例は、その C# コードとなります。 ご参考:オブジェクトを移動する(.NET) | Autodesk   Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; Database db = Application.DocumentManager.MdiActiveDocument.Database; Document doc = Application.DocumentManager.MdiActiveDocument; using (Transaction tr = db.TransactionManager.StartTransaction()) { PromptSelectionResult psr = doc.Editor.GetSelection(); SelectionSet sset = psr.Value; if (psr.Status == PromptStatus.OK) { Entity ent = null; Extents3d ext; foreach (SelectedObject so in sset) { ent = (Entity)tr.GetObject(so.ObjectId, OpenMode.ForWrite); if(ent.GetRXClass().Name == "AcDb3dSolid") { Solid3d sol = (Solid3d)ent; ext = sol.GeometricExtents; ed.WriteMessage("\nSolid3d Z value = {0}", ext.MinPoint.Z); Point3d pt = new Point3d(0, 0, 0); Vector3d vec = pt.GetVectorTo(new Point3d(0.0, 0.0, ext.MinPoint.Z)); sol.TransformBy(Matrix3d.Displacement(vec).Inverse()); } } } tr.Commit(); }
記事全体を表示
Issue 選択セットで条件に合った複数のオブジェクトを取得する際、特定の座標を持つ要素を条件に設定するにはどうしたらいいでしょうか?   Solution 選択セットのフィルタリングで座標を扱う際には、オンラインヘルプ 概要 - 選択セットのフィルタ リストでの関係テスト(AutoLISP) で触れられている、カンマ区切りで関係演算子を利用する方法を利用することが出来ます。   点グループ コードの場合、X、Y、Z に対するテストを結合して単一の文字列にできます。このとき、各演算子をカンマで区切ります(たとえば、">,>,*")。文字列から演算子を省略すると、すべてを選択する演算子 "*" とみなされます(たとえば、"=,<>" では Z がチェックされません)。 次のコードは、円オブジェクトの中心のX 座標が 123.45 以上123.46 以下で、Y 座標が 500.0、Z 座標値を無視するフィルタリングを指定した C# コードの例です。 Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; TypedValue[] typeAry = new TypedValue[9]; typeAry.SetValue(new TypedValue((int)DxfCode.Operator, "<and"), 0); typeAry.SetValue(new TypedValue((int)DxfCode.Start, "CIRCLE"), 1); typeAry.SetValue(new TypedValue((int)DxfCode.Operator, "<and"), 2); typeAry.SetValue(new TypedValue((int)DxfCode.Operator, ">=,=,*"), 3); typeAry.SetValue(new TypedValue((int)DxfCode.XCoordinate, new Point3d(123.45, 500.0, 0.0)), 4); typeAry.SetValue(new TypedValue((int)DxfCode.Operator, "<=,=,*"), 5); typeAry.SetValue(new TypedValue((int)DxfCode.XCoordinate, new Point3d(123.46, 500.0, 0.0)), 6); typeAry.SetValue(new TypedValue((int)DxfCode.Operator, "and>"), 7); typeAry.SetValue(new TypedValue((int)DxfCode.Operator, "and>"), 8); SelectionFilter filter = new SelectionFilter(typeAry); PromptSelectionResult psr = ed.SelectAll(filter); if (psr.Status == PromptStatus.OK) { SelectionSet sset = psr.Value; ed.WriteMessage("\nNumber of objects selected : {0}", sset.Count.ToString()); ObjectIdCollection objIds = new ObjectIdCollection(sset.GetObjectIds()); using (Transaction tr = db.TransactionManager.StartTransaction()) { Entity ent; foreach (ObjectId objId in objIds) { ent = (Entity)tr.GetObject(objId, OpenMode.ForRead); ent.Highlight(); } tr.Commit(); } } else { Application.ShowAlertDialog("\nNumber of objects selected: 0"); }  
記事全体を表示
現象 C#のコンソールアプリケーションで、Inventor Apprentice Server のApprenticeServerDocument.Thumbnailプロパティにアクセスするとエラーが発生します。 回避方法はありますか。   解決策 C#のコンソールApplicationの場合、Main関数に[STAThread]属性を付加しSTAで動作するように指定することで、Thumbnailプロパティにアクセスできるようになります。   [STAThread] static void Main(string[] args) {   なお、VB.netの場合コンソールアプリケーションはデフォルトでSTAで動作する設定のため、[STAThread]属性を付加する必要はありません。 また、C#の場合でもWindows フォームアプリケーションの場合も[STAThread]属性を付加する必要はありません。
記事全体を表示
Issue オンラインヘルプ「レイアウトをパブリッシュする(.NET) 」の例では、PublishExecute メソッドを利用して DSD ファイルを使ったバッチ印刷の方法を説明しています。ただし、この例では "DWG to PDF.PC3" を指定してプロッタ環境設定をオーバーライド(上書き)しています。 印刷対象のレイアウトに設定されたページ設定を利用してバッチ印刷する方法はありますか?   Solution PublishDsd メソッドで、定義済みのページ設定(印刷デバイスと設定)を使用してレイアウトを印刷、または、/ファイル出力することが出来ます。この場合、また、DsdData.SheetType の値を SheetType.OriginalDevice に指定することで、プロッタ環境設定(.pc3)を指定せずに連続印刷をおこなうことが可能です。 次のコードは、その C# 例です。 Try Dim collection As DsdEntryCollection = New DsdEntryCollection() Dim entry As DsdEntry entry = New DsdEntry() entry.Layout = "レイアウト1" entry.DwgName = "c:\Temp\Drawing1.dwg" entry.Nps = "Setup1" entry.Title = "Sheet1" collection.Add(entry) entry = New DsdEntry() entry.Layout = "レイアウト1" entry.DwgName = "c:\Temp\Drawing2.dwg" entry.Nps = "Setup1" entry.Title = "Sheet2" collection.Add(entry) Dim dsd As DsdData = New DsdData() dsd.SetDsdEntryCollection(collection) dsd.ProjectPath = "c:\Temp\" dsd.LogFilePath = "c:\Temp\logdwf.log" dsd.SheetType = SheetType.OriginalDevice dsd.NoOfCopies = 1 dsd.SheetSetName = "PublisherSet" dsd.WriteDsd("c:\Temp\publisher.dsd") Dim nbSheets As Integer = collection.Count Using progressDlg As PlotProgressDialog = New PlotProgressDialog(False, nbSheets, True) progressDlg.UpperPlotProgressRange = 100 progressDlg.LowerPlotProgressRange = 0 progressDlg.UpperSheetProgressRange = 100 progressDlg.LowerSheetProgressRange = 0 progressDlg.IsVisible = True Autodesk.AutoCAD.ApplicationServices.Application.SetSystemVariable("BACKGROUNDPLOT", 0) Dim publisher As Autodesk.AutoCAD.Publishing.Publisher = Autodesk.AutoCAD.ApplicationServices.Application.Publisher publisher.PublishDsd("c:\Temp\publisher.dsd", progressDlg) progressDlg.Destroy() End Using Catch ex As Autodesk.AutoCAD.Runtime.Exception MsgBox(ex.Message) End Try End Sub なお、PublishDsd メソッドを使用して DSD ファイルをパブリッシュする前に、BACKGROUNDPLOT システム変数を 0 に設定する必要があります。
記事全体を表示