お知らせ
2025 年 4 月 26 日(土)から 4 月 28 日(月)まで、オートデスク コミュニティは閲覧専用となります。更新作業が完了次第、本バナーは表示されなくなります。ご迷惑をおかけいたしますが、何卒ご了承ください。
Announcements
We are currently migrating data within this board to improve the community. During this process, posting, replying, editing and other features are temporarily disabled. We sincerely apologize for any inconvenience caused and appreciate your understanding. Thank you for your patience and support.
Autodesk Community Tips- ADNオープン
Autodesk Community Tipsではちょっとしたコツ、やり方、ショートカット、アドバイスやヒントを共有しています。
ソート順:
Issue 選択したオブジェクトが自動調整配列複写の要素かどうか判定して、自動調整配列複写であった場合に分解する実装するには、どのようなコードを記述すればいいでしょうか?     Solution 自動調整配列複写の対象となっているオブジェクト一式は、匿名ブロック(Anonymous Block)として自動調整フレームワークで管理、維持されています。   自動調整配列複写の判定には、AssocArray.IsAssociativeArray メソッドを利用することが出来ます。 同様に、分解には AssocArray.Explode メソッドを利用することが出来ます。   次のコードは、選択したオブジェクトが自動調整配列複写の構成要素だった場合に、トップレベルの調整配列複写を分解する C# 例です。   Database db = HostApplicationServices.WorkingDatabase; Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; PromptEntityResult pent = ed.GetEntity("\nオブジェクトを選択:"); if (pent.Status != PromptStatus.OK) { return; } using (Transaction tr = db.TransactionManager.StartTransaction()) { if (AssocArray.IsAssociativeArray(pent.ObjectId)) { ed.WriteMessage("\n自動調整配列です"); AssocArray ary = AssocArray.GetAssociativeArray(pent.ObjectId); var param = ary.GetParameters(); if (param as AssocArrayPathParameters != null) ed.WriteMessage("\n - パス"); if (param as AssocArrayPolarParameters != null) ed.WriteMessage("\n - 円形状"); if (param as AssocArrayRectangularParameters != null) ed.WriteMessage("\n - 矩形状"); AssocArray.Explode(pent.ObjectId); } else ed.WriteMessage("\n自動調整配列ではありません"); tr.Commit(); }   EXPLODE コマンドで自動調整配列複写を分解する場合には、次のようなコードで AssocArray.Explode メソッドを代替することが出来ます。いずれの場合も、自動調整フレームワークが構成要素オブジェクトを保持しているため、すべてのオブジェクトを指定する必要はありません。   var sset = SelectionSet.FromObjectIds(new ObjectId[] { pent.ObjectId }); ed.Command("EXPLODE", sset);    
記事全体を表示
Issue 選択したオブジェクトが自動調整配列複写の要素かどうか判定して、自動調整配列複写であった場合に分解する実装するには、どのようなコードを記述すればいいでしょうか?       Solution 自動調整配列複写の対象となっているオブジェクト一式は、匿名ブロック(Anonymous Block)として自動調整フレームワークで管理、維持されています。   自動調整配列複写の判定には、AcDbAssocArrayActionBody::isAssociativeArray() メンバー関数を利用することが出来ます。同様に、分解には AcDbAssocArrayActionBody::explode() メンバー関数 を利用することが出来ます。   次のコードは、選択したオブジェクトが自動調整配列複写の構成要素だった場合に、トップレベルの調整配列複写を分解する例です。   ads_name ename; ads_point pt; int stat = acedEntSel(_T("\nオブジェクトを選択 : "), ename, pt); if (stat != RTNORM) return; AcDbEntity* pEnt; AcDbObjectId objId; acdbGetObjectId(objId, ename); Acad::ErrorStatus err = acdbOpenAcDbEntity(pEnt, objId, AcDb::kForRead); if (err != Acad::eOk) return; if (AcDbAssocArrayActionBody::isAssociativeArray(pEnt)) { acutPrintf(_T("\n自動調整配列です")); AcDbObjectId actId = AcDbAssocArrayActionBody::getControllingActionBody(pEnt, NULL); AcDbAssocArrayActionBody* pAryAct = NULL; err = acdbOpenAcDbObject((AcDbObject*&)pAryAct, actId, AcDb::kForWrite); if (err != Acad::eOk) { pEnt->close(); return; } if (AcDbAssocArrayPathParameters::cast(pAryAct->parameters())) acutPrintf(_T("\n - パス")); if (AcDbAssocArrayPolarParameters::cast(pAryAct->parameters())) acutPrintf(_T("\n - 円形状")); if (AcDbAssocArrayRectangularParameters::cast(pAryAct->parameters())) acutPrintf(_T("\n - 矩形状")); AcDbObjectIdArray newIds; pAryAct->explode(pEnt, newIds); pAryAct->close(); } else acutPrintf(_T("\n自動調整配列ではありません")); pEnt->close(); return;   EXPLODE コマンドで自動調整配列複写を分解する場合には、次のようなコードで AcDbAssocArrayActionBody::explode()  メンバー関数を代替することが出来ます。いずれの場合も、自動調整フレームワークが構成要素オブジェクトを保持しているため、すべてのオブジェクトを指定する必要はありません。   ads_name sset; acedSSAdd(NULL, NULL, sset); acedSSAdd(ename, sset, sset); acedCommandS(RTSTR, _T("EXPLODE"), RTPICKS, sset);      
記事全体を表示
AutoCAD .NET APIリファレンスに記載の様に、PromptSelectionOptions.SingleOnlyは、AutoCAD ObjectARXでのacedSSGet()での”:S”モードの設定に相当します。また、 PromptSelectionOptions.SinglePickInSpaceは、":A"モードに相当します。   ObjectARXでのacedSSGetでは、”:S"モードは、単一のエンティティの選択が許容される状態となりますが、窓選択については有効な状態のままとなります。   また、”:A"モードについては、aecdSSGetのリファレンスでは「This mode option causes acedSSGet() to perform single pick selection in space on entities that implement a subselection filter.」との説明がありますが、これは例えばテーブルの様な、エンティティ内にサブエンティティがあるようなエンティティにおいて、テーブルのセル内の文字のクリックを、テーブル自身の選択とするオプション設定となります。
記事全体を表示
Issue 寸法を分解すると寸法値にあたる文字が MText オブジェクトとして分解されます。 この MText オブジェクトについて、MText.Contents プロパティから寸法値の文字を取得すると、寸法値にないコードが返される場合があります。   例:\A1;57,{\H0.7x;\S66^;}   このコードはどのようなものでしょうか?   Solution このコードは、マルチテキストの整形するために用意された「書式コード」と呼ばれるコードで、AutoCAD のオンラインヘルプ ページで内容を確認することが出来ます。 AutoCAD 2024 ヘルプ | 他のテキスト エディタの書式コード リファレンス | Autodesk AutoCAD .NET API で MText オブジェクトの文字列の内容を確認する場合には、Contents プロパティが書式コード付きの内容を、Text プロパティが書式コードを削除した内容を返すので、用途に応じてプロパティを使い分けることが出来ます。   Database db = HostApplicationServices.WorkingDatabase; Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; PromptEntityOptions peo = new PromptEntityOptions("\nMText オブジェクトを選択:"); peo.SetRejectMessage("\nMText オブジェクトではありません."); peo.AddAllowedClass(typeof(MText), true); PromptEntityResult pent = ed.GetEntity(peo); if (pent.Status != PromptStatus.OK) { return; } using (Transaction tr = db.TransactionManager.StartTransaction()) { Entity ent = tr.GetObject(pent.ObjectId, OpenMode.ForRead) as Entity; ed.WriteMessage("\nObject Type : " + ent.GetType().ToString()); MText mtext = (MText)ent; ed.WriteMessage("\n\tMText Text : {0}", mtext.Text); ed.WriteMessage("\n\tMText Contents : {0}", mtext.Contents); tr.Commit(); }   寸法オブジェクトを分解せずに、AutoCAD .NET API :分解せずに寸法文字の情報を取得するには? (autodesk.co.jp) の方法も利用することが可能です。 
記事全体を表示
現象 AutoCAD 2025のAccoreconsole.exe でSystem.Data.OleDbを参照するプラグインのカスタムコマンドを実行すると、Accoreconsole.exeが異常終了するAutoCAD 2025のAccoreconsole.exe でSystem.Data.OleDbを参照するプラグインのカスタムコマンドを実行すると、Accoreconsole.exeが異常終了してしまいます。   なお、プラグインはAutoCAD 2025に合わせて.net 8を利用するように移植済みです。 また、System.Data.OleDbはVisual Studio のNugetパッケージマネージャから 9.0.2をプロジェクトにインストールして使用しています。 診断 AutoCAD インストールフォルダ配下のSystem.Data.OleDb.dllのバージョンと、プラグインプロジェクトのNugetでインストールしているSystem.Data.OleDb.dllのバージョンの差異に起因してAccoreconsole.exeが異常終了している状況です。   AutoCAD 2024以前は、.NET FrameworkのAppDomain機能を用いてプラグインは分離された実行空間にロード・実行されていました。AutoCADが利用するアセンブリとは異なるバージョンのアセンブリをプラグインが参照している場合でも問題なく実行することが出来ておりました。 一方で、AutoCAD 2025では、従来の.NET Frameworkから、.NET Core(.NET 8)にサポートプラットフォームが変更されましたが、この.NET CoreではAppDomain機能がサポートされておらず、すべてのプラグインとその参照アセンブリは同じ実行空間にロードされます。このため、AutoCADとプラグイン、または異なるプラグイン間でバージョンの異なる同じアセンブリを参照している場合、競合が発生して異常終了等の予期せぬ事態が発生することがあります(参照アセンブリによっては異常終了せず動作する場合もあります)。   解決策 System.Data.OleDbに特化した解決方法としては、プラグインが参照するSystem.Data.OleDbのライブラリをAutoCADのインストールフォルダ配下の者とすることで、問題を解消することが可能です。 以下、手順となります。 1.VisualStudio のプロジェクトからSystem.Data.OleDbのNugetパッケージを削除する 2.代わりに、VisualStudio のプロジェクトの参照設定で、AutoCADのインストールフォルダ(acad.exeおよびaccoreconsole.exeがあるフォルダ)配下のSystem.Data.OleDb.dllを参照ファイルに追加をする。   また、System.Data.OleDbに特化しない一般的な解決方法としては、.NET Coreが提供するAssemblyLoadContext機能を用いて、カスタム処理を異なる空間で実行することにより、参照するアセンブリのバージョン違いによる干渉を防ぐ方法となります。 AssemblyLoadContext機能については、Microsoft社の提供するマテリアル「System.Runtime.Loader.AssemblyLoadContext について」をご参照ください。
記事全体を表示
質問 InventorのVBA環境で、VBAの「ツール」-「参照設定」から利用するライブラリの参照設定が行えます。 VBAを実行するクライアント端末が複数あり、各端末でライラリファイルの参照設定をすることが手間なので、ライブラリの参照設定を出力して配布することは可能でしょうか? 回答 Inventorの設定ファイルには、VBAでの参照設定を編集する機能はありません。また、InventorのAPI にも直接的に参照設定を編集する機能はありません。   一方で、InventorのAPIで、Microsoft社が提供するVBA開発環境のVBProjectオブジェクトを取得するAPIが公開されているため、VBProjectオブジェクトのReferences.AddFromFile()メソッド等を利用することで、プログラムコードから参照設定を行うことが可能です。   以下は、"Adbe Acrobat 10 Type Library”への参照を追加する場合のサンプルコードとなります。 Dim app As Application Set app = ThisApplication Dim VBProject As Object Set VBProject = app.VBAProjects.Item(1).VBProject Const RefFile As String = "<path to acrobat.tlb file>" VBProject.References.AddFromFile RefFile
記事全体を表示
質問 Vaultクライアントで、プロジェクトエクスプローラ($)配下の、あるフォルダに対してローカル作業フォルダを規定値から別のフォルダに変更するを設定しました。 その後、Vault APIで対象のフォルダのローカル作業フォルダのパスを取得すると、変更したフォルダパスではなく、規定値のフォルダパスが取得されている状況です。 Vault クライアントで変更したフォルダパスを取得する方法はありますか。 回答  Vaultのローカル作業フォルダの設定を規定値から変更した場合、変更した設定は以下のファイルに保存されます(*****部は、実行環境により変化します)。   C:\Users\<Windows ログインユーザ>\AppData\Roaming\Autodesk\VaultCommon\Servers\Services_Security_******\<接続先サーバ名>\Vaults\<ボルト名>\Objects\WorkingFolders.xml     ファイルパスに<Windowsログインユーザ>、<接続先サーバ名>、<ボルト名>が含まれているため、カスタムアプリケーションからVaultに接続する際に、これらのどれかが異なる場合には、異なるローカル作業フォルダの設定が読み込まれます(ファイルが存在しない場合は、既定のパスとなります)。   ローカル作業フォルダの設定を規定値から変更したVaultクライアントアプリケーションと、APIを実行しているアプリケーションで、この値のどれかが異なっている場合Vault クライアントで変更したフォルダパスを取得することが出来ません。これらの値を合わせたうえで、変更後のフォルダパスが取得できるかを確認してください。
記事全体を表示
現象 Inventorを、VBAや.NET FrameworkのCreateObject()等のCOM API経由で起動後、カスタマイズプログラムからQuit()を実行せずに、GUIで終了(xボタン押下当)した場合、バックグラウンドプロセスとしてInventorが残ってしまう。   診断 外部プロセスから、VBAや.NET Framework等のCreateObject()等を用いて外部アプリケーションを起動した場合、対象のアプリケーションはQuit()メソッドにより終了をさせる必要があります。Quit()を実行せずアプリケーションGUI側から終了した場合バックグラウンドにプロセスが残存してしまいます。 この挙動はInventorのみならずExcel等でも同様で、COMオブジェクトを公開するアプリケーションに共通の挙動となります。   解決策 CreateObject()により取得したアプリケーションオブジェクトをQuit()メソッドで終了せず利用したい場合は、CreateObject()ではなくProcess.Start()等によりプロセスを起動し、GetObject()等を用いて起動中のアプリケーションのCOMオブジェクトを取得することで回避が可能です。   「APIでInventorを起動する際にバージョン指定する方法」にProcess.Start()を用いてInventorを起動し起動したInventorアプリケーションのCOMオブジェクトを取得する方法のサンプルコードがありますので、ご参照ください。  
記事全体を表示
Issue AutoCAD .NET API でフォルダ内の DWG ファイルを順に開いて処理していますが、サイズの大きい図面があると相対的に処理時間が長くなってしまいます。高速化するアイデアはありますか?   Solution   AutoCAD 上に図面を開いて表示する際、描画に多く時間がかかってしまいます。 もし、ユーザインターフェース上に図面を表示する必要がないのであれば、Database.ReadDwgFile メソッドを使って、メモリ上に図面を展開する方法を採用することで、描画にかかかる時間を省いて処理全体を高速化させることが出来ます。   次のコードは、フォルダを指定後にフォルダ内の .dwg ファイルを順に Database.ReadDwgFile メソッドでメモリ展開し、モデル空間のオブジェクト タイプを表示するものです。 [CommandMethod("MyCommand", CommandFlags.Modal)] public void MyCommand() { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; using (FolderBrowserDialog fd = new FolderBrowserDialog()) { if (fd.ShowDialog() == DialogResult.OK) { string folder = fd.SelectedPath; System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(folder); IEnumerable<System.IO.FileInfo> files = di.EnumerateFiles("*.dwg", System.IO.SearchOption.AllDirectories); if (files == null) return; ed.WriteMessage("\n\t{0}", folder); foreach (System.IO.FileInfo f in files) { string file = f.FullName; ed.WriteMessage("\n - {0}", file); try { using (Database db = new Database(false, true)) { db.ReadDwgFile(file, FileOpenMode.OpenForReadAndAllShare, false, null); using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead); foreach (ObjectId id in btr) { Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead); ed.WriteMessage("\n - {0}", ent.GetType().ToString()); } tr.Commit(); } } } catch (System.Exception ex) { ed.WriteMessage(ex.ToString()); } } } } }   なお、Database.ReadDwgFile メソッドの使用時には、次の点に注意が必要です。   Database.ReadDwgFile メソッドで読み込む Database インスタンスを new ステートメントで用意する必要があります。この際、最低限必要なシンボルテーブルとオーナーシップを持つ Database 構造は、読み込む DWG ファイルに定義されているため、コンストラクタには Database.Database([MarshalAs(UnmanagedType.U1)] bool, [MarshalAs(UnmanagedType.U1)] bool)  オーバーロードを使用して、第1パラメーターの値を false にして、読み込む DWG ファイルの Database 構造との競合を抑止する必要があります。 AutoCAD のユーザインターフェースに表示された Database インスタンスは、同図面を表示している MDI 子ウィンドウを閉じると、AutoCAD が Database 領域をメモリから削除します。ただし、Database.ReadDwgFile メソッドでメモリ上に展開した Database インスタンスの領域は、展開したアドイン アプリがメモリーから削除しなければなりません。削除には上、記コードのように using ステートメントを利用してスコープ内の処理後に削除させるか、using ステートメントでスコープ指定せずに Dispose メソッドを明示的に呼び出すことも出来ます。 Database.ReadDwgFile メソッドで読み込んだ Database インスタンス内の DBText オブジェクトや AttributeReference オブジェクトの位置合わせを変更する場合、Database インスタンスを HostApplicationServices.WorkingDatabase プロパティで設定していないと予期しないズレが発生する場合があります。これは、DBText クラス実装が、位置合わせ時に現在の図面データベース(Database)を参照している関係で発生してしまう現象です。Database インスタンスを HostApplicationServices.WorkingDatabase プロパティで設定して処理した場合、処理後にオリジナル(ユーザーインターフェースに開いている図面の Database インスタンスを HostApplicationServices.WorkingDatabase プロパティで再設定する必要があります。
記事全体を表示
長期にわたる Autodesk App Store 運営の知見を反映するかたちで、Windows 版 AutoCAD 2026 でパッケージ バンドルを利用した自動ローダーに重要な変更が加えられています。アドイン アプリ運用時のセキュリティを向上させるのが目的です。   従来のパッケージの検出では次の 3 か所のフォルダを利用することが出来ました。   一般的なインストール フォルダ Windows: %PROGRAMFILES%¥Autodesk¥ApplicationPlugins Mac OS: /Applications/Autodesk/ApplicationAddins すべてのユーザ プロファイル フォルダ Windows: %PROGRAMDATA%¥Autodesk¥ApplicationPlugins Mac OS: 該当なし ユーザ プロファイル フォルダ Windows: %APPDATA%¥Autodesk¥ApplicationPlugins Mac OS: ~/Library/Application Support/Autodesk/ApplicationAddins Windows 版 AutoCAD 2026 では、%ProgramData%\Autodesk\ApplicationPlugins(通常はC:\ProgramData\Autodesk\ApplicationPlugins)フォルダに配置したパッケージ バンドルからのアドイン アプリの自動ロードを抑止します。   このため、従来、%ProgramData%\Autodesk\ApplicationPlugins フォルダを利用していたアドイン アプリは、%PROGRAMFILES%¥Autodesk¥ApplicationPlugins フォルダ、または、%APPDATA%¥Autodesk¥ApplicationPlugins フォルダにパッケージ バンドルの配置を変更する必要があります。   %ProgramData%\Autodesk\ApplicationPlugins フォルダを利用する利点は、Windows 上のすべてのユーザー環境下で、AutoCAD にアドインを識別・ロードさせることが出来る点にありましたが、逆にすべてのユーザが書き込み可能な権限を持つことになり、潜在的なセキュリティの脆弱性を生む可能性があります。   一方、%PROGRAMFILES%¥Autodesk¥ApplicationPlugins フォルダ、または、%APPDATA%¥Autodesk¥ApplicationPlugins フォルダへの書き込みには管理者権限を必要とするため、この点で安全なインストールを保証することが出来ます。   %ProgramData%\Autodesk\ApplicationPlugins フォルダを利用する必要がある場合には、システム レジストリの  \HKEY_LOCAL_MACHINE\SOFTWARE\Autodesk\AutoCAD\R25.1\ACAD-9101\Applications\AcadAutoLoader に DWORD 値 1 を持つ LoadFromProgramData キーを追加することで、従来の動作を復元することも出来ます。ただし、前述のセキュリティ上の観点から非推奨となります。   一度、LoadFromProgramData キーを作成して AutoCAD がパッケージを識別すると、キーの値を 0 にしたり、キー自体を削除しても、パッケージを検出するようになりますのでご注意ください。   特に、デジタル署名されていないアドイン ファイルに対して、初回ロード時に [常にロードする] を選択してしまうと、無条件にパッケージ バンドル内のアドイン アプリをロードするようになってしまいます。     初期状態の動作に戻すには、AutoCAD 2026 の再インストールが必要になります。
記事全体を表示
Issue バルーン番号の番号部分を属性定義(タグ名 Index)したブロック定義(ブロック名 MyBlock)があります。     このブロック定義の挿入時にバルーン番号を加算しながら重複のないバルーン番号を持つブロック参照を配置することは可能でしょうか?   Solution 新たな MyBlock ブロック参照の挿入時に、モデル空間に配置されたすべての MyBlock を走査して Index タグ名を持つ属性値(文字列)を取得、最大値となり値をバルーン番号に設定することで実現することが出来るはずです。   次のサンプルは、MyBlock ブロック定義後に同処理を実装する VBA マクロの例です。属性値の妥当性チェックの処理はしていませんが、インデックス番号を保持するタグ名 Index を持つ属性には、半角整数の文字列が設定されているものとしています。IndexOnBlockRef プロシージャを実行してみてください。   ' 挿入時に属性値(インデックス番号)を順番に割り当てるメイン プロシージャ Public Sub IndexOnBlockRef() Dim strBlkName strBlkName = "MyBlock" CreateBlockDef (strBlkName) Dim insPt(0 To 2) As Double insPt(0) = 0: insPt(1) = 0: insPt(2) = 0 Dim retPt As Variant Dim index As Integer Dim blockRefObj As AcadBlockReference On Error Resume Next Do Err.Clear retPt = ThisDrawing.Utility.GetPoint(, vbCrLf & "ブロックの挿入点を指示 : ") If Err Then Exit Do End If Set blockRefObj = ThisDrawing.ModelSpace.InsertBlock(retPt, strBlkName, 1#, 1#, 1#, 0) index = FindMaxIndexAttribute() Call SetIndexAttribute(blockRefObj, index + 1) Loop End Sub ' 属性定義(タグ名 Index)を含むブロック定義 MyBlock を定義する関数 Public Function CreateBlockDef(strBlkName As String) Dim blockObj As AcadBlock Dim insPt(0 To 2) As Double insPt(0) = 0: insPt(1) = 0: insPt(2) = 0 On Error Resume Next Set blockObj = ThisDrawing.Blocks.Item(strBlkName) If Err Then Set blockObj = ThisDrawing.Blocks.Add(insPt, strBlkName) Dim circleObj As AcadCircle Set circleObj = blockObj.AddCircle(insPt, 100#) Dim attributeObj As AcadAttribute Set attributeObj = blockObj.AddAttribute(100#, acAttributeModePreset, "インデックス?", insPt, "Index", "0") attributeObj.Alignment = acAlignmentMiddleCenter End If End Function ' 与えられたブロック参照のタグ名 Index の属性値(整数)を返す関数 Public Function GetIndexAttribute(blockRefObj) As Integer Dim varAttributes As Variant varAttributes = blockRefObj.GetAttributes Dim strAttribute As String strAttribute = "-1" For Each blockAttr In varAttributes If blockAttr.TagString = "Index" Then strAttribute = blockAttr.TextString Exit For End If Next GetIndexAttribute = CInt(strAttribute) End Function ' モデル空間に配置されたすべての MyBlock ブロック参照を走査して割り当てられた最大の Index の属性値(整数)を返す関数う Public Function FindMaxIndexAttribute() As Integer Dim sset As AcadSelectionSet On Error Resume Next Set sset = ThisDrawing.SelectionSets.Item("ssblocks") If Not Err Then sset.Delete End If Set sset = ThisDrawing.SelectionSets.Add("ssblocks") Dim FilterType(1) As Integer Dim FilterData(1) As Variant FilterType(0) = 0 FilterData(0) = "Insert" FilterType(1) = 2 FilterData(1) = "MyBlock" sset.Select acSelectionSetAll, , , FilterType, FilterData Dim index As Integer index = -1 Dim maxIndex As Integer maxIndex = -1 If sset.Count > 0 Then Dim entityObj As AcadEntity For Each entityObj In sset Dim blockRefObj As AcadBlockReference Set blockRefObj = entityObj index = GetIndexAttribute(blockRefObj) If maxIndex < index Then maxIndex = index End If Next End If FindMaxIndexAttribute = maxIndex End Function ' 与えられたブロック参照1のタグ名 Index の属性値(整数)を設定する関数 Public Function SetIndexAttribute(blockRefObj, index) Dim varAttributes As Variant varAttributes = blockRefObj.GetAttributes For Each blockAttr In varAttributes If blockAttr.TagString = "Index" Then blockAttr.TextString = CStr(index) Exit For End If Next End Function     既に挿入配置済のブロック参照 My Block に新たにインデクス番号の属性値を割り当てる場合には、前述のコードに次の AssignIndexToBlockRef プロシージャを追加・実行することでブロック参照を順に選択して値を更新することも出来ます。   ' 配置済のブロック参照に指定値から属性値(インデックス番号)を順番に割り当てるメイン プロシージャ Public Sub AssignIndexToBlockRef() Dim strBlkName strBlkName = "MyBlock" Dim startIndex As Integer startIndex = FindMaxIndexAttribute() On Error Resume Next Err.Clear Dim returnInt As Integer ThisDrawing.Utility.InitializeUserInput (4) ' disallow negative returnInt = ThisDrawing.Utility.GetInteger(vbCrLf & "割り当てるインデクス開始値を入力<" & CStr(startIndex + 1) & "> : ") If Err = 0 Then If returnInt <= startIndex Then MsgBox ("指定した値と同じ、または、大きいインデックス値を持つブロック参照が既に存在します" & vbCrLf & _ "既に配置済のブロック参照とインデックス値が重複してしまう可能性があります") Exit Sub End If startIndex = returnInt - 1 End If Dim returnObj As AcadObject Dim basePnt As Variant Do Err.Clear ThisDrawing.Utility.GetEntity returnObj, basePnt, "ブロック参照を選択:" If Err = 0 Then If returnObj.EntityName = "AcDbBlockReference" Then Dim blockRefObj As AcadBlockReference Set blockRefObj = returnObj If blockRefObj.Name = strBlkName Then startIndex = startIndex + 1 Call SetIndexAttribute(blockRefObj, startIndex) End If End If Else Exit Do End If Loop End Sub    
記事全体を表示
Issue AutoCAD .NET API でアプリケーションのフォーカス イベントを処理することは出来ますか?   Solution AutoCAD の Application ウィンドウ レベルでは、COM API の Application.AppActivate イベントと Application.AppDeactivate イベントを COM Interop でお使いいただくことが出来ます。 ご参考:COM ベースのイベントを登録する(.NET)   Autodesk.AutoCAD.Interop.AcadApplication? acAppCom = null; [CommandMethod("AddCOMEvent")] public void AddCOMEvent() { acAppCom = (Autodesk.AutoCAD.Interop.AcadApplication)Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication; acAppCom.AppActivate += new _DAcadApplicationEvents_AppActivateEventHandler(appComAppActivate); acAppCom.AppDeactivate += new _DAcadApplicationEvents_AppDeactivateEventHandler(appComAppDeactivate); } [CommandMethod("RemoveCOMEvent")] public void RemoveCOMEvent() { if (acAppCom != null) { acAppCom.AppActivate -= new _DAcadApplicationEvents_AppActivateEventHandler(appComAppActivate); acAppCom.AppDeactivate -= new _DAcadApplicationEvents_AppDeactivateEventHandler(appComAppDeactivate); acAppCom = null; } } public void appComAppActivate() { Autodesk.AutoCAD.ApplicationServices.Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; ed.WriteMessage("\n*** AppActivate ***\n"); } public void appComAppDeactivate() { Autodesk.AutoCAD.ApplicationServices.Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; ed.WriteMessage("\n*** AppDeactivate ***\n"); }  
記事全体を表示
Autodesk Knowledge Network には、過去、よくある質問を中心に、次のような内容を記載していました。   Revit API Tips: 未使用の項目を削除を実行する方法 Revit API Tips: 壁プロファイルの取得方法 Revit API Tips: 複数のファミリを組み合わせて(ネストして)新しいファミリを作成する方法 Revit API Tips: ソリッドやメッシュのジオメトリをプロジェクト上に作図する方法 Revit API Tips: アドインでバッチ処理を実装する方法 InventorのAPIで、IDWファイルをバージョンを指定してDXFに変換する方法 InventorのPack And Go を、VBAから実行する場合の参照設定 Inventor APIでPDF出力後にPDFを表示しないようにしたい Inventor APIでコンテンツセンターの言語設定を切り替える方法 Inventor APIで放射状マーキングメニューをカスタマイズする方法 Inventorの2D図面に配置したView内の各コンポーネントを、AutoCADのブロックにする方法 Inventor API でインスタンスプロパティを取得・設定する方法 Inventor APIでiLogicを実行する方法 Inventor APIでアセンブリ、パートファイルの単位数量と基準単位を出力したい InventorのAPIで図面のシートをコピーする方法 Visual Studioで「InventorViewCtrl.ocxの自己登録に失敗しました」エラーが発生して、Inventor ViewコントロールをWindowsフォームへ追加することが出来ない InventorのFileAccessEvents.OnFileResolutionイベントでFullFileNameに指定したファイルが読み込まれない Inventor ApprenticeServerComponent.Openメソッドを実行すると、「エラー -xxx-xxxxxxxx(80004005) Openメソッドは失敗しました」が発生する APIでパーツリストの一覧をエクセルに出力する方法 API を用いて派生元のモデルの面から、派生先のモデルでの面を特定する方法 APIで、シートメタルの展開図の折り曲げ位置のエッジ線から、山折り/谷折の情報を参照する方法 API で面を指定して移動、削除を行う方法 Vault APIを使用して作成したカスタムアプリケーションからVaultにログインをするとFailed to acquire a license.ダイアログが表示されログインができない 「Valuts」のAPIを利用して、「Vault」で管理されているInventorアセンブリファイルと子のファイルをローカルフォルダに取得してInventorで開く方法 「Valuts」のAPIを利用して、「Vault」で管理されているInventorアセンブリファイルの構成情報を取得する方法 Vaultクライアントで表示されているファイル名と、Vault APIのFileAssoc.ExpectedVaultPathで取得した値が異なっている場合がある Managed .Net API でレイアウト空間のビューポート表示範囲のオブジェクトを取得する方法 AutoCAD .net APIででデータリンク元ファイルの変更の有無を知る方法 AutoCAD .net APIで球の中心座標を取得する方法 AutoCAD .net APIでDBTextの幅を取得する方法 AutoCAD .net APIで図面をブロックとして挿入すると、属性の編集ができない AutoCAD ObjectARX .net APIで3D上の中心点、半径、開始点、終了点、法線を指定して円弧を作成する方法 AutoCAD Plant3D .net APIでスペックエディターのカタログデータ内部品種類総数を取得する方法 AutoCAD Plant3D .net APIで流向記号の向きと、流向記号に結びついている配管を取得する方法 AutoCAD Plant3D .net APIでアイソメメッセージの注記を取得する方法 AutoCAD Plant3D APIで3Dモデルの配管のライン番号タグの値を取得する方法 AutoCAD MechanicalのAPIでパーツリストの値を取得する方法 AutoCAD Mechanical APIでパーツ参照の値を取得する方法 AutoLispでマルチ引出線のスタイルを設定する方法 AutoCAD .NET API :トグルボタンの実現 AutoCAD .NET API :ドラッグシーケンス中の画面移動 AutoCAD .NET API :未参照の PDF アンダーレイ参照の削除 AutoCAD .NET API:パージ処理の実装 AutoCAD .NET API :AutoLISP 関数の定義 AutoCAD .NET API :キーボード ボタン押下の検出 AutoCAD .NET API :ObjectARX 関数の P/Invoke AutoCAD .NET API :マウス左ボタン クリックの検出 AutoCAD .NET API :クロスヘア カーソル位置座標の取得 AutoCAD .NET API :属性値を維持した分解 AutoCAD .NET API :分解せずに寸法文字の情報を取得するには? AutoCAD .NET API:リボンタブの表示制御 AutoCAD .NET API :ユーザ座標系(UCS)の変更 AutoCAD .NET API :3D ソリッド構成面のサーフェス抽出 AutoCAD .NET API:3D ソリッドのエッジへのフィレット AutoCAD .NET API:特定領域の画像出力 AutoCAD .NET API :点がサーフェス上に位置しているか? AutoCAD .NET API :トポロジー情報のアクセス AutoCAD .NET API :画像データの図面への格納 AutoCAD .NET API :選択セットのセッション間の維持 AutoCAD .NET API :拡張ディクショナリの付加・取得・削除 AutoCAD .NET API :拡張エンティティ データの付加・取得・削除 AutoCAD .NET API :属性付きブロック定義とブロック参照の挿入 AutoCAD .NET API :ブロック参照の属性値の変更 AutoCAD .NET API :寸法スタイルに従属せずに寸法矢印を変更するには? AutoCAD .NET API :IGES ファイル出力 AutoCAD .NET API:パレット ダイアログを作成する方法 AutoCAD .NET API :サーフェスと線分の交点を得るには? AutoCAD .NET API :ポリラインの円弧セグメントの指定方法 AutoCAD .NET API:IExtensionApplication.Terminate() が呼び出されない AutoCAD .NET API :外部図⾯ファイル内のブロック定義の情報を現在の図⾯にコピーしたい AutoCAD .NET API :同⼀図⾯データベース内でオブジェクトを複写するには? AutoCAD .NET API:ブロック参照の分解挿入 AutoCAD .NET API :スイープ ソリッドとスイープ サーフェスの作成 AutoCAD .NET API :表示スタイルの変更 AutoCAD .NET API:指定した領域を ZOOM するには? AutoCAD .NET API :プリセットビューの変更 AutoCAD .NET API:図⾯監査の⾃動化は可能か? AutoCAD .NET API:図⾯修復を実装するには? AutoCAD .NET API:図面ウィンドウのタイル表示化 AutoCAD .NET API:パスに沿って押し出すソリッドの作成 AutoCAD .NET API :ロフト ソリッドとロフト サーフェスの作成 AutoCAD .NET API:起動中の AutoCAD が AutoCAD 単体か AutoCAD ベースの業種別製品か区別する方法 AutoCAD .NET API :外部図⾯データベースにオブジェクトを書き出したい ObjectARX:パージ機能の実装 ObjectARX :コマンド プロンプト メッセージの同期表示は可能なのか? ObjectARX:ObjectARX 開発者用ガイド ObjectARX:ObjectARX Wizards が動作しない AutoCAD VBA:自動ローダーで .dvb ファイルがロード出来ない AutoLISP:オブジェクトへの TrueColor 色の設定 AutoCAD API:「コマンドは 4 レベルより深くネストできません。」エラーについて AutoCAD API:ブール演算が失敗する AutoCAD API:Visual Studio 2019 に .NET Wizards が認識されない AutoCAD API:GetCanonicalMediaNames メソッドによる用紙サイズ名の変更について Inventor Apprentice Sever APIリファレンスはどこに有りますか? Inventor API で 外部EXEからカスタムアドインのメソッドの実行処理 Inventorプロジェクト.ipjファイルを変更する方法 アセンブリファイル内のコンポーネントファイルの物理的なファイル名を変更する方法 Vault API 関連の SDK や APIリファレンスはどこから入手できますか? AutoCAD ObjectARX Wizard を使用したカスタムコマンドの作成方法 ObjectARX Wizard 2015で作成したプロジェクトが他の PC の開発環境で開けない ObjectARX Wizard 2015 で新規にプロジェクトを作成できない Windows8.1 の ObjectARX Wizard 2015 で新規にプロジェクトを作成できない 混在開発PC環境にObjectARX Wizard 2015をインストールした時の問題 AutoCAD 2015 の ObjectARX で acedCommand のマイグレーション情報 AutoCAD .Net Wizard を使用した カスタムコマンドの作成 AutoCAD2016の .Net カスタムコマンドで APIによる PLOTコマンドを模倣する方法Managed .Net API で UCS コマンドの W オプションを模倣する方法 VB.Net カスタムコマンド内で COM/ActiveX を使って PDFファイルの作成 AutoCAD の COM 利用でプロットの用紙サイズにセットする文字列 AutoCAD 2019 の Visual LISP エディタ (VLISP コマンド) で日本語表示&入力ができない AutoCAD の PDF 出力で [印刷可能領域] を変更するAPIはありますか? Mechanical製品で下位バージョンのMechanical DWG として保存する方法 Mechanical 2017 と 2018 の混在インストール PC 環境で 外部 EXE より Mechanical のタイプライブラリ を利用する問題 VB.NET外部EXEから純粋なAutoCAD製品とMechanical製品を起動する方法
記事全体を表示
Issue AutoCAD .NET API を利用してサーフェス同士を結合することは出来ますか?   Solution AutoCAD .NET API には、サーフェス同士を結合する ObjectARX の AcDbSurface::booleanUnion() メンバ関数ラッパーである サーフェス同士を結合する Surface.BooleanUnion メソッドが用意されています。   次の C# 例は、Surface.BooleanUnion メソッドでサーフェス同士を結合するものです。   [CommandMethod("MyCommand", CommandFlags.Modal)] public void MyCommand() // This method can have any name { Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptEntityOptions peo = new PromptEntityOptions("\n結合するサーフェスを選択:"); peo.SetRejectMessage("\nサーフェスを選択してください..."); peo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Surface), false); PromptEntityResult per = ed.GetEntity(peo); if (per.Status != PromptStatus.OK) return; ObjectId objId1 = per.ObjectId; peo = new PromptEntityOptions("\n結合させたいサーフェスを選択:"); peo.SetRejectMessage("\nサーフェスを選択してください..."); peo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Surface), false); per = ed.GetEntity(peo); if (per.Status != PromptStatus.OK) return; ObjectId objId2 = per.ObjectId; try { using (Transaction tr = db.TransactionManager.StartTransaction()) { Autodesk.AutoCAD.DatabaseServices.Surface surf1 = tr.GetObject(objId1, OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Surface; Autodesk.AutoCAD.DatabaseServices.Surface surf2 = tr.GetObject(objId2, OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Surface; Autodesk.AutoCAD.DatabaseServices.Surface surf = surf1.BooleanUnion(surf2); if (surf == null) { if (surf1 != null) { surf1.ColorIndex = 5; surf1.LineWeight = LineWeight.LineWeight100; } if (surf2 != null) { surf2.Erase(); } } else { surf1.Erase(); surf2.Erase(); ObjectId objId = SymbolUtilityServices.GetBlockModelSpaceId(db); BlockTableRecord btr = tr.GetObject(objId, OpenMode.ForWrite) as BlockTableRecord; surf.ColorIndex = 5; surf.LineWeight = LineWeight.LineWeight100; btr.AppendEntity(surf); tr.AddNewlyCreatedDBObject(surf, true); } tr.Commit(); } } catch(Autodesk.AutoCAD.Runtime.Exception ex) { ed.WriteMessage("\n" + ex.Message); } }  
記事全体を表示
Issue サーフェスの外形エッジやパス形状をオブジェクトとして再作成することは出来ますか?   Solution サーフェスの外形エッジやパス形状はサーフェスのサブエンティティ(FullSubentityPath)から形状を模倣して再作成することが出来ます。  Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptEntityOptions peo = new PromptEntityOptions("\nサーフェスを選択:"); peo.SetRejectMessage("\nサーフェスを選択してください..."); peo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Surface), false); PromptEntityResult per = ed.GetEntity(peo); if (per.Status != PromptStatus.OK) return; using (Transaction tr = db.TransactionManager.StartTransaction()) { ObjectId objId = per.ObjectId; Entity ent = tr.GetObject(objId, OpenMode.ForWrite) as Entity; ObjectId[] entId = new ObjectId[] { ent.ObjectId }; IntPtr pSubentityIdPE = ent.QueryX(AssocPersSubentityIdPE.GetClass(typeof(AssocPersSubentityIdPE))); if (pSubentityIdPE == IntPtr.Zero) return; AssocPersSubentityIdPE subentityIdPE = AssocPersSubentityIdPE.Create(pSubentityIdPE, false) as AssocPersSubentityIdPE; SubentityId[] edgeIds = subentityIdPE.GetAllSubentities(ent, SubentityType.Edge); objId = SymbolUtilityServices.GetBlockModelSpaceId(db); BlockTableRecord btr = tr.GetObject(objId, OpenMode.ForWrite) as BlockTableRecord; foreach (SubentityId subentId in edgeIds) { FullSubentityPath path = new FullSubentityPath(entId, subentId); Entity edge = ent.GetSubentity(path); if (edge != null) { edge.ColorIndex = 3; edge.LineWeight = LineWeight.LineWeight100; btr.AppendEntity(edge); tr.AddNewlyCreatedDBObject(edge, true); } } tr.Commit(); }  
記事全体を表示
Issue AutoLISP のリスト操作で拡張エンティティ データを付加・参照・削除するには、それぞれ、どのようなコードを作成すればいいでしょうか?   Solution 拡張エンティティ データは、AutoCAD 図面内の任意のオブジェクトに任意のカスタム データの付加、参照する手法です。AutoLISP でも、他の API 同様、拡張エンティティ データの付加・参照・削除を実装することが出来ます。   次のコードは、リスト操作で拡張エンティティ データを付加する AddXData コマンド、参照する GetXData コマンド、削除する RemoveXData コマンドの例です。   ;https://help.autodesk.com/view/OARX/2025/JPN/?guid=GUID-A94BC605-5517-437F-A6FE-D3EB8116A01A ; 拡張エンティティデータの追加例 (defun C:AddXData (/) (setq ename (car (entsel))) (if (= ename nil) (exit) ) (setq appname "Test_App") (if (= (tblsearch "APPID" appname) nil) (if (= (regapp appname) nil) (princ (strcat "\n" appname " アプリケーション名が登録出来ません... ")) ) ) (setq edata (entget ename (list "*"))) (setq exist (cdr (assoc -3 edata))) (if (= exist nil) (progn ; 他の拡張エンティティデータも付加されていない場合 (setq xdata (list (list -3 (list appname (cons 1002 "{") (cons 1000 "あいうえお") ; 文字列データ (cons 1040 999.99) ; 実数データ (cons 1070 1111) ; 整数データ (cons 1002 "}") ) ) ) ) (setq newdata (append edata xdata)) (entmod newdata) ) (progn ; 既になんらかの拡張エンティティデータが付加されている場合 (foreach xdatas exist (progn (if (= appname (car xdatas)) (progn (princ (strcat "\n既に " appname " データが付加されています...")) (exit) ; 処理中断 ) ) (setq xdata (list (list appname (cons 1002 "{") (cons 1000 "あいうえお") ; 文字列データ (cons 1040 999.99) ; 実数データ (cons 1070 1111) ; 整数データ (cons 1002 "}") ) ) ) (setq xdatas (append (list -3) (append exist xdata))) (setq newdata (subst xdatas (append (list -3) exist) edata)) (entmod newdata) (princ (strcat "\n" appname " データが付加しました...")) ) ) ) ) (princ) ) ; 拡張エンティティデータの取得例 (defun C:GetXData (/) (setq ename (car (entsel))) (if (= ename nil) (exit) ) (setq edata (entget ename (list "*"))) (setq exist (cdr (assoc -3 edata))) (if (/= exist nil) (progn (foreach xdatas exist (progn (princ (strcat "\n*** " (car xdatas))) (setq xdata (cdr xdatas)) (foreach element xdata (setq code (car element)) (setq value (cdr element)) (cond ((= code 1000) (princ (strcat "\n文字列値:" value)) ) ((= code 1040) (princ (strcat "\n実数値:" (rtos value))) ) ((= code 1070) (princ (strcat "\n整数値:" (itoa value))) ) ) ) ) ) ) (progn (princ "\n拡張エンティティデータが付加されていません...") ) ) (princ) ) ; 拡張エンティティデータの削除例 (defun C:RemXData (/) (setq ename (car (entsel))) (if (= ename nil) (exit) ) (setq appname "Test_App") (if (= (tblsearch "APPID" appname) nil) (princ (strcat "\n" appname " アプリケーション名が登録されていません... ")) ) (setq edata (entget ename (list "*"))) (setq exist (cdr (assoc -3 edata))) (if (/= exist nil) (progn (foreach xdatas exist (progn (if (= appname (car xdatas)) (progn (setq xdata (list (list appname) ) ) (setq xdatas (append (list -3) (append exist xdata))) (setq newdata (subst xdatas (append (list -3) exist) edata)) (entmod newdata) (princ (strcat "\n付加された " appname " データを削除しました...")) ) ) ) ) ) ) (princ) ) 他の 3rd party アプリケーションや AutoCAD 自身も拡張エンティティデータ利用していますので、既に付加されている拡張エンティティデータに影響を与えずに独自データを付加、削除するようご留意ください。
記事全体を表示
Issue FIELD コマンドで選択したオブジェクトの面積をフィールド文字として作成することは出来ますか?        Solution AutoCAD .NET API では、文字(DBText)または、マルチテキスト(MText)ブロックを作成後、[フィールド] ダイアログ下部に表示される「フィールド式」を SetField メソッドで設定することで、特定のオブジェクトを参照するフィールド文字を作成することが出来ます。     フィールド式中の _ObjId の値は、選択したオブジェクトの ObjectId 値になります。 次の C# コードは、ポリラインの面積をフィールド文字として作図する例です。   [CommandMethod("MyCommand")] public void MyCommand() // This method can have any name { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; PromptEntityOptions options = new PromptEntityOptions("\nポリラインを選択:"); options.SetRejectMessage("\nポリラインを選択"); options.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline), false); PromptEntityResult acSSPrompt = ed.GetEntity(options); if (acSSPrompt.Status != PromptStatus.OK) return; PromptPointOptions ppo = new PromptPointOptions("\n挿入点を指示:"); PromptPointResult ppr = ed.GetPoint(ppo); if (ppr.Status != PromptStatus.OK) return; using (Transaction tr = db.TransactionManager.StartTransaction()) { // %<\AcObjProp.16.2 Object(%<\_ObjId 3132455955584>%).Area \f "%lu2%pr1%ps[面積:, ㎡]%ct8[0.001]">% string strId = acSSPrompt.ObjectId.OldIdPtr.ToString(); string str1 = "%<\\AcObjProp.16.2 Object(%<\\_ObjId "; string str2 = ">%).Area \\f \"%lu2%pr1%ps[面積:, ㎡]%ct8[0.001]\">%"; string format = str1 + strId + str2; DBText text = new DBText(); text.Height = 10.0; text.Position = ppr.Value; ObjectId objId = SymbolUtilityServices.GetBlockModelSpaceId(db); BlockTableRecord btr = tr.GetObject(objId, OpenMode.ForWrite) as BlockTableRecord; btr.AppendEntity(text); tr.AddNewlyCreatedDBObject(text, true); Field entField = new Field(format); entField.Evaluate(); text.SetField(entField); tr.AddNewlyCreatedDBObject(entField, true); tr.Commit(); } }   作図したフィールド文字は、参照したポリラインの変化に追従するようになります。  
記事全体を表示
Issue AutoCAD .NET API で SURFEXTEND[延長サーフェス] コマンド と同じような処理は出来ますか?   Solution サーフェス エッジの延長は、Surface.ExtendEdges メソッド で実装することが出来ます。   次の C# コードは、選択した1つのサーフェス エッジを 100 ポイント延長するものです。 SURFEXTEND[延長サーフェス] コマンド と同様に、エッジの延長でサーフェスに自己交差すると延長に失敗する場合があります。   var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; var db = doc.Database; var ed = doc.Editor; try { PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "\n延長するサーフェス エッジを選択:"; pso.SingleOnly = true; pso.SinglePickInSpace = true; pso.ForceSubSelections = true; PromptSelectionResult psr = ed.GetSelection(pso); if (psr.Status != PromptStatus.OK) return; SelectionSet ss = psr.Value; SelectedObject surfedge = ss[0]; ObjectId surfId = ss.GetObjectIds()[0]; if (!surfId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(Autodesk.AutoCAD.DatabaseServices.Surface)))) { ed.WriteMessage("\nサーフェス エッジを選択を選択してください ..."); return; } using (var tr = db.TransactionManager.StartTransaction()) { var surf = tr.GetObject(surfId, OpenMode.ForWrite) as Autodesk.AutoCAD.DatabaseServices.Surface; if (surf != null) { if (surfedge.GetSubentities()[0].FullSubentityPath.SubentId.Type != SubentityType.Edge) { ed.WriteMessage("\n{0} が選択されました ...\nサーフェス エッジを選択を選択してください ...", surfedge.GetSubentities()[0].FullSubentityPath.SubentId.Type); tr.Abort(); return; } FullSubentityPath[] edges = { surfedge.GetSubentities()[0].FullSubentityPath }; surf.ExtendEdges(edges, 100.0, Autodesk.AutoCAD.DatabaseServices.Surface.EdgeExtensionType.ExtendEdge, true); } tr.Commit(); } } catch (Autodesk.AutoCAD.BoundaryRepresentation.Exception ex) { ed.WriteMessage("\nエラー: {0}\r\n at {1}", ex.Message, ex.StackTrace); }   なお、SURFEXTEND[延長サーフェス] コマンド によるサーフェス延長とは異なり、Surface.ExtendEdges メソッド  による延長では、延長されたサーフェス部分は、無条件に元のサーフェスに結合された状態になります。 SURFEXTEND[延長サーフェス] コマンド では、延長されたサーフェスを元のサーフェスと結合(合成)するか、別のサーフェスとして追加するか(既定値)をコマンド プションで指定することが出来ます。  
記事全体を表示
Issue VBA では表を TABLE オブジェクトで作成することが出来ますが、データ値にオブジェクトのプロパティをフィールドとして利用、表の内容を最新に保つようなことは出来ますか?   Solution  TABLE オブジェクト のデータセルにフィールド文字を挿入することは可能です。どのようなフィールド文字列を値に設定するべきかは、FIELD[フィールド] コマンド 表示される [フィールド] ダイアログで、特定のオブジェクトと同オブジェクト タイプで利用可能なプロパティを選択すると、ダイアログ下部の「フィールド式」に表示される内容で取得することが出来ます。   このとき、特定のオブジェクトは AutoCAD API の識別子の 1つである ObjectId で関連付けされますので、VBA マクロでフィールド式をセルに指定する際に、適宜変更する必要があります。     次のマクロは、モデル空間に作図されているすべてのオブジェクトのハンドル番号とオブジェクト タイプ、オブジェクトの色を表に書き込むものです。色の情報がフィールド式で指定されているので、作図後に REGEN[再作図] コマンド を実行すると、値が更新されるようになります。   Option Explicit Public Sub FieldTable() ' 新しい表スタイルの作成 On Error Resume Next Dim oTblDict As AcadDictionary Set oTblDict = ThisDrawing.Dictionaries.Item("ACAD_TABLESTYLE") Dim oTblStyle As AcadTableStyle Set oTblStyle = oTblDict.Item("MyTableStyle") If Err Then ' 新しい表スタイル "MyTableStyle" を作成 Err.Clear Set oTblStyle = oTblDict.AddObject("MyTableStyle", "AcDbTableStyle") ' タイトル欄の設定(背景色:青、文字色:白、文字高さ:4.0) Dim oColor As AcadAcCmColor Set oColor = AcadApplication.GetInterfaceObject("AutoCAD.AcCmColor.25") oColor.ColorIndex = acWhite oTblStyle.SetColor acTitleRow, oColor oColor.ColorIndex = acBlue oTblStyle.SetBackgroundColorNone acTitleRow, False oTblStyle.SetBackgroundColor acTitleRow, oColor oTblStyle.SetTextHeight acTitleRow, 4# oTblStyle.TitleSuppressed = False ' 列見出し欄の色設定(背景色:白、文字色:緑、文字高さ:2.5) oColor.ColorIndex = acWhite oTblStyle.SetColor acHeaderRow, oColor oColor.ColorIndex = acGreen oTblStyle.SetBackgroundColorNone acHeaderRow, True oTblStyle.SetBackgroundColor acHeaderRow, oColor oTblStyle.SetTextHeight acHeaderRow, 2.5 oTblStyle.HeaderSuppressed = False ' データ欄の色設定(背景色:なし、文字色:白、文字高さ:2) oColor.ColorIndex = acWhite oTblStyle.SetColor acDataRow, oColor oTblStyle.SetBackgroundColorNone acDataRow, True oTblStyle.SetTextHeight acDataRow, 2 oTblStyle.SetAlignment acDataRow, acMiddleCenter End If ' 配置基点を指示 Dim ptBase As Variant ThisDrawing.Utility.InitializeUserInput 1 ptBase = ThisDrawing.Utility.GetPoint(, vbCrLf & "表の配置点を指定:") ' 表特性の算出 Dim nRow As Integer Dim nCol As Integer Dim dHeight As Double nRow = ThisDrawing.ModelSpace.Count + 2 ' タイトル+列見出し nCol = 3 dHeight = ThisDrawing.GetVariable("TEXTSIZE") ' 現在のレイアウトに表を配置 Dim oTbl As IAcadTable Set oTbl = ThisDrawing.ActiveLayout.Block.AddTable(ptBase, nRow, nCol, dHeight, dHeight * 10#) oTbl.RegenerateTableSuppressed = True oTbl.StyleName = "MyTableStyle" oTbl.GenerateLayout ' タイトルの設定 oTbl.SetText 0, 0, "モデル空間図形の色一覧" oTbl.SetRowHeight 0, 7# oTbl.SetText 1, 0, "ハンドル番号" oTbl.SetText 1, 1, "クラス名" oTbl.SetText 1, 2, "色" oTbl.SetRowHeight 1, 5# ' データの設定 Dim nRowCnt As Integer Dim strField As String Dim oEnt As AcadEntity nRowCnt = 2 For Each oEnt In ThisDrawing.ModelSpace ' ハンドル番号 oTbl.SetText nRowCnt, 0, oEnt.Handle ' クラス名 oTbl.SetText nRowCnt, 1, oEnt.ObjectName ' フィールド式(オブジェクトID で特定したオブジェクトの色) strField = "%<\AcObjProp Object(%<\_ObjId " & CStr(oEnt.ObjectID) & ">%).TrueColor>%" oTbl.SetText nRowCnt, 2, strField ' 行高さの設定 oTbl.SetRowHeight nRowCnt, 5# ' 行カウンタ nRowCnt = nRowCnt + 1 Next oTbl.RegenerateTableSuppressed = False End Sub   このマクロコードでは、表スタイルを登録して表に使用しています。表スタイルの内容と図面の尺度が適切でない場合がありますので、必要に応じて文字高さ等を変更してください。AutoCAD VBA では、表スタイルは TableStyle オブジェクト で作成・編集することが出来ます。この例では、椅子のブロック参照の色を水色(cyan)から青(blue)に変更しています。    
記事全体を表示
Issue VBA マクロで特定のブロック名パターンを持つブロックのブロック属性を得たいのですが、可能でしょうか? 例えば、図面内の A で始まるブロック名を持つすべてのブロックのみを対象にする、といった方法です。   Solution 特定のブロック名パターンに検索には、選択セットのフィルタ リストにアスタリスク記号でワイルドカード(*)を組み合わせて指定することが出来ます。A で始まるブロック名を持つブロックは、A* で指定可能です。   次のコードは、ワイルドカードを含めたブロック名パターンを指定して、対象ブロック参照を取得、ブロック属性の有無をチェックして、ブロック属性が含まれる場合に属性のタグと値を表示するものです。なお、*fix* や *tub など、ワイルドカードはブロック名中、どこに置いても指定することが出来ます。   Public Sub GetBlockAttribute2() On Error Resume Next Dim sset As AcadSelectionSet ThisDrawing.SelectionSets.Item("ssblocks").Delete Set sset = ThisDrawing.SelectionSets.Add("ssblocks") ThisDrawing.Utility.InitializeUserInput NoNull returnString = ThisDrawing.Utility.GetString(True, "対象のブロック名を入力 [すべて (*) ] : ") If returnString = "" Then returnString = "*" End If Dim FilterType(1) As Integer Dim FilterData(1) As Variant FilterType(0) = 0 FilterData(0) = "Insert" FilterType(1) = 2 FilterData(1) = returnString sset.Select acSelectionSetAll, , , FilterType, FilterData If sset.Count > 0 Then Dim ent As AcadEntity For Each ent In sset Dim blkRef As AcadBlockReference Set blkRef = ent ThisDrawing.Utility.Prompt vbCrLf & blkRef.Name & " ブロック参照が検出されました." Dim varAttributes As Variant varAttributes = blkRef.GetAttributes If UBound(varAttributes) < 0 Then ThisDrawing.Utility.Prompt vbCrLf & " ブロック参照に属性がありません..." Else Dim strAttributes As String For Each blkAttr In varAttributes strAttributes = "" strAttributes = strAttributes & " タグ名: " & blkAttr.TagString & " - 属性値 " & blkAttr.TextString & vbLf & " " ThisDrawing.Utility.Prompt vbCrLf & strAttributes Next End If Next Else ThisDrawing.Utility.Prompt vbCrLf & returnString & " ブロック名パターンに合致するブロック参照がありません..." End If End Sub   次の例では、ブロック名パターン * で全ブロックのブロック属性を、A* で A で始まるブロック名を持つブロック参照のブロック属性を表示しています。  
記事全体を表示