nanoCAD 5.0 VB.NET + LISP サンプル
ncadNTED.dll for nanoCAD 5.0 2024/12/07 ~ 23
・点在した TEXT をまとめて編集(選択順、または座標順)
・内部ブロックのイメージ表示、挿入 + 挿入後、交差する線分をカット
■ダイアログ表示のコマンド
□NTEDN : 選択順で TEXT を一括で編集します。TEXT の追加はできません。
空白行の TEXT は削除されます。
編集の行数が取得した TEXT 数を超えると、背景色が変わります。
取得した TEXT 数だけが、更新の対象になり、以降は無視されます。
□NTEDY : 座標順にソート後 TEXT を一括で編集します。
取得した TEXT が横方向に広がっているときは、X 座標の昇順、
縦方向に広がっているときは、Y座標の降順でソートします。
取得した TEXT の一番下側または、一番右側とその直前の TEXT の座標の
X 座標または Y 座標の差で、次の TEXT を作成します。
□BLKIN : 図面内のブロックのイメージ表示と挿入をします。
LINE, ARC, CIRCLE, LWPOLYLINE は白色で表示。
TEXT, MTEXTは緑色の四角形、ブロックは赤色の四角形+X印で表示。
ATTDEF、他の図形は表示されません
挿入は、原点 0,0 に挿入。COPYBASE 0,0 でコピー。PASTECLIP で挿入しています。
失敗した場合は、0,0 にブロックが残ります。
BlkInLsp.lsp がロードされているときは、挿入後ブロックに交差する線分をカットします。
■ncadnted.dll で追加されるその他のコマンド
□BLKJOIN
ブロックに交差する線分を結合
[Enter]で繰り返し可能
□BLKCUT
ブロックに交差する線分をカット
[Enter]で繰り返し可能
□LINEJOIN
選択した線分のうち、同一直線上の線分を結合
画層、線種、線色が違うときは、何もしない
[Enter]で繰り返し可能
■BlkInLsp.lsp で追加されるコマンド
いずれもブロック内の図形取得は、LINE, LWPOLYLINE, ARC, CIRCLE のみ
□BLKINLSP
DLL コマンド BLKIN から呼ばれる
[Enter] での繰り返しは不可(最後のコマンド "PASTE" が動く)
原点 0,0 にブロックを挿入、COPYBASE でコピー、ERASE で削除
PASTECLIP コマンドでコピー先を指示
ブロックに交差する線分をカット処理
ブロックに属性名 NAME, NAME1, SENBAN が含まれる場合は、属性値の入力。
次の PASTECLIP 先を指示
... を繰り返す
ESC で終了
□DWGRUN_BLOCKCUT
DwgRun.exe からブロック挿入後に呼ばれる
挿入されたブロックに交差する線分をカット処理
ブロックに属性名 NAME, NAME1, SENBAN が含まれる場合は、属性値の入力
[Enter] での繰り返しは不可
□BLINE
始点-終点の2点指示で、線分を作成
現在の画層が WIRE 画層のときは、電気配線作成(水平、垂直線分のみ、交点シンボル処理)
※交点シンボルは自動作成
上記以外は、通常の線分を作成(斜め線分も作成可能)
作成後、2点間にあるブロックの交差線分をカット
... を繰り返す
[Enter] での繰り返しは不可(最後のコマンド LINE コマンドが動く)
□BMOVE
ブロック、LINE、POLYLINEの1辺、TEXT を移動
ブロック:移動元のブロックの周囲の線分を結合。移動先でブロックに交差する線分をカット
ブロック名が、*KOUTEN*,*CMARK* にマッチするときはカットしない
LINE :線分上の1点を指示、
水平、垂直線分につながるブロック、LINE をストレッチコマンドで水平、垂直移動
線分の端点につながる POLYLINE の頂点も移動
移動対象ブロックにつながる線分は追従しない
POLYLINE:1辺上にあるブロックと周囲 2.5mm にある TEXT を一緒に移動
期待どおりにならないことがあるので注意!
TEXT :TEXT を移動、移動の基点は TEXT の基点
... を繰り返す
[Enter] での繰り返しは不可(最後のコマンド STRETCH コマンドが動く)
□BCUT
ブロック1個、または線分の1点を指示
ブロック:交差線分をカットカット
ブロック名が、*KOUTEN*,*CMARK* にマッチするときはカットしない
LINE :端点、または交点シンボルまでをカット、交点シンボルが不要であれば削除
... を繰り返す
[Enter] で繰り返し可能
□BCOPY
ブロック1個、または TEXT 1個をコピー
ブロック:コピー先で、ブロックに交差する線分をカット
ブロック名が、*KOUTEN*,*CMARK* にマッチするときはカットしない
ブロックに属性名 NAME, NAME1, SENBAN が含まれる場合は、
属性値の入力、数字が含まれる場合はカウントアップ
TEXT :TEXT をコピー、数字が含まれる場合はカウントアップ
[Enter] での繰り返しは不可(最後のコマンド PASTECLIP コマンドが動く)
□BERASE
削除するブロック1個、またはカットする線分の1点を指示
ブロック:削除後、周囲の線分を結合
LINE :端点、または交点シンボルまでをカット、交点シンボルが不要であれば削除
... を繰り返す
[Enter] で繰り返し可能
□BMARK
交点シンボルを反転
交点マークを消す座標、または追加する座標を指示
... を繰り返す
□BLPF
WIRE 画層の配線間隔を変更、配線上のブロックも追従
... を繰り返す
□BPT
複数のブロックの水平または垂直位置を合わせる
線番、交点シンボルは除外
... を繰り返す
以下、ブロック+普通の図形(LINE, LWPOLYLINE, ARC, CIRCLE)でもカットされる
ただし、部分削除の対象は、始点ー終点の間にある図形との交点のうち相互距離が最大な2点間で、
交点が1個のときは何もしない
いずれもブロック内の図形取得は、LINE, LWPOLYLINE, ARC, CIRCLE のみ
□XMOVE
複数の図形を移動
選択図形にブロックが含まれる時、左上(または右上)にあるブロックの挿入基点が移動基点になる
移動元の図形にかかる複数の線分を結合、移動先で交差する複数の線分を部分削除
... を繰り返す
ブロックと他の図形を一緒に移動するときは便利
□XCOPY
複数の図形をコピー
選択図形にブロックが含まれる時、左上(または右上)にあるブロックの挿入基点がコピーの基点になる
TEXT だけのときは、TEXT の基点がコピーの起点になる
コピー先で交差する線分を部分削除
... を繰り返す
ブロックと他の図形を一緒にコピーするときは便利
含まれる TEXT が1個で数字が含まれるときはカウントアップ可能
□XERASE
複数の図形を削除
図形にかかる複数の線分を結合
... を繰り返す
複数のブロックと他の図形を一括で削除するときに便利
□XCUT
複数図形に交差する線分を部分削除
選択した図形の矩形範囲を取得し、それに交差する線分が対象になる
その線分ごとに交差する選択した図形との交点のうち相互距離が最大な2点でカット
... を繰り返す
※線分の1点を指示しての部分削除はできない
□XLN
現在の画層に線分を作成
すでに線分がある時は、その線分の画層、線種、線色で作成、既存の線分と結合
始点ー終点の間にある図形(LINE, LWPOLYLINE, ARC, CIRCLE, INSERT)との交点のうち
相互距離が最大な2点間を部分削除
交点が1個のときは何もしない
... を繰り返す
□XSTR
選択した図形を水平、または垂直方向にストレッチ
STRETCH コマンドの C オプションと同じ
... を繰り返す
□XBREAK
選択した図形に交差する線分を部分削除
... を繰り返す
□TXGCLIP
LINE, POLYLINE で作成された表形式の文字列をクリップボードにコピー
1つの格子内に文字が複数ある場合は、印刷されない画層(DEFPOINTSとか)にダミーの区切り線が必要
JOGAI*, HOJO* にマッチする画層の線分は区切り線として採用しない
クリッ プボード経由で Excel との連携が可能
□TXGPASTE
クリップボードの文字列を LINE, POLYLINE で作成された部品リストに流し込み
JOGAI*, HOJO* にマッチする画層の線分は区切り線とし採用しない
表の縦横のマス目の数が違う場合は、合うところまで作成、変更される
まったく TEXT が存在しない場合は、現在の画層に指定した文字高さ、文字基点 ML で作成される
クリッ プボード経由で Excel との連携が可能
新規の部品リストの場合、項目のタイトルとデータの1行目に参照用のダミーデータを入れておくと、
文字高さ、文字幅、文字基点が参照される
まったく何も無い場合は、現在の画層に左中基点、指定の文字高さ、文字幅1.0 で作成される
□TXGG
LINE, POLYLINE で囲われた格子内の文字位置を一括で ML, MC, MR に変更
TEXT の基点から上下左右4方向に *LINE を検出しているため、表形式でなくても使用可能
□TXCLIP
選択した TEXT をクリップボードにコピー
□TXPASTE
クリップボードの文字列を指定した文字高さ、行間で TEXT として作成
列幅は全体の文字幅+αで作成
必要であれば、罫線を作成
□TXGSPC
LINE, POLYLINE で作成された格子の縦横の大きさを変更
部品リスト、端子配列図等の行間、列幅の変更に使用
□TXUP
TEXT カウントアップコピー(10進数のみ)
□TXPLS
複数 TEXT の数字部の一括加算、減算
□TXPLS2
複数 TEXT の数字部の一括加算、減算( -, +, ±対応版)
□TXRP
TEXT の置換
□TXFILL, LNFILL, ENTFILL
TXFILL:2つの TEXT を選択して、その相互間隔で指定方向に 10進、16進、8進カウントアップコピー
TEXT が1つのときは、コピー間隔を2点で指示または距離を入力
ENTFILL:2 以上の図形を選択して、並び方向と同じ方向であれば、最後の相互間隔で指定方向にコピー
選択図形 が1のときは、コピー間隔を2点で指示または距離を入力
並び方向と違う方向であれば、選択図形すべてを相互間隔で指定方向にコピー
ブロックの等間隔コピーにも使える
LNFILL:表の行、列の2本の LINE を選択して、その相互間隔で指定方向にストレッチ、コピー
LINE の等間隔コピーは、ENTFILL を使う
□LLDR
LINE の先端に片矢印(LWPOLYLINE)を作成
■一時的なロード
メニュー -「ツール」-「アプリケーション」-「.NET アプリケーションをロード...」で
ncadnted.dll を選択し、[ロード]ボタンをクリックするとロードされます。
LISP ファイルも同様です。
または、
メニュー -「ツール」-「アプリケーション」-「アプリケーションをロード...」で
ncadnted.dll を選択し、[ロード]ボタンをクリックするとロードされます。
LISP ファイルも同様です。
または、
コマンドラインに NETLOAD[Enter]でも DLL ファイルはロードできます。
■自動ロード
自動ロードするには、「スタートアップスイート」の下のカバンボタンをクリック。
[追加] ボタンをクリック。ncadnted.dll を選択して[開く] をクリックすると登録されます。
以降、ドキュメント開くごとに自動でロードされます。
LISP ファイルも同様です。
■高解像度環境での使用について
こちらの環境(高 DPI 環境)では、nanoCAD 自体と自前のフォームが小さくなる現象がありました。
nanoCAD のアイコン(または、nCad.exe) を右クリック。「プロパティ」をクリック。
「互換性」タブをクリック。[高DPIの設定] をクリック。
「高いDPIスケールの動作を上書きします。拡大縮小の実行元:」のチェックをオン。
その下のリストから「システム」を選択。[OK] をクリック。
で、こちらの環境では、正常に表示されるようになりました。
■参考ツール
連番作成、半角<->全角変換、置換 ... 等が必要なときは、TEXTEDIT.exe
他の CAD で作成されたブロックの挿入には、DwgRun.exe を試してみて下さい。
nanoCAD 日本語化、他のツール
http://izawa-web.com/nanocad/ncadtools.html
からダウンロードできます。
■免責事項、著作権
本ツールをダウンロード、ロード、使用したことによる事故、損害等の一切について、
作者 f.izawa はその責を負いません。
ご自身の責任でお使い下さい。
本ツールの著作権は、作者 f.izawa が所有し、これを主張します。
■関数カタログ
http://www.izawa-web.com/txt/BlkInLsp_CommandsList.txt
■ダウンロード
最新版: BlkIn フォームに画層オン図形の描画チェックボックスを追加。
同梱 LISP に TEXT 置換 TXRP コマンドを追加。
http://www.izawa-web.com/zip/ncadnteddll_20241223.zip
最新版:DLL の変更はありません。
同梱 LISP に不要な文字が残っていたのを修正しました。
http://www.izawa-web.com/zip/ncadnteddll_20241222.zip
旧版:DLL の変更はありません。
http://www.izawa-web.com/zip/ncadnteddll_20241220.zip
旧版:
http://www.izawa-web.com/zip/ncadnteddll_20241219.zip
より izawa 仕様バージョン(LISP のエラー処理修正版):
http://www.izawa-web.com/zip/ncadnteddll_20241215b.zip
旧バージョン:
http://www.izawa-web.com/zip/ncadnteddll_20241215.zip
旧バージョン:
http://www.izawa-web.com/zip/ncadnteddll_20241214.zip
■参考ツール
連番作成、半角<->全角変換、置換 ... 等が必要なときは、TEXTEDIT.exe
他の CAD で作成されたブロックの挿入には、DwgRun.exe を試してみて下さい。
nanoCAD 日本語化、他のツール からダウンロードできます。
■履歴
2024/12/07 NTED 初版作成
2024/12/08 NTED フォームがリサイズされないのを手直し
2024/12/09 文字リストを削除しても TEXT が削除されないのを手直し
2024/12/11 BLKIN ブロックのイメージ表示、挿入を追加
2024/12/11a イメージ描画座標の計算に四捨五入を追加
2024/12/11b 属性を含むブロックを挿入した時、属性が作成されないため、
通常の -insert コマンドで挿入するに変更
2024/12/11c コマンドでの挿入を API での挿入に変更
ブロック、TEXT, MTEXT を四角形で表示を追加
微小円弧の描画でエラーになるのを対策
2024/12/12 LINE 描画で 片方の端点が 1 ピクセルずれるのを手直し
ブロックの矩形描画で X印の描画を追加
使用しない COM 参照が残っていたのを削除
2024/12/14 BLKIN に [INSERT + CUT] ボタンを追加
これに使用する LISP と関連するコマンドを追加
2024/12/15 LISP を変更
挿入後の属性値入力を追加
BCOPY を COPY コマンドから COPYBASE - PASTECLIP に変更
BCOPY の対象図形に TEXT を追加
BCOPY に TEXT、属性値 のカウントアップコピーを追加
2024/12/15a ブロック名が、*KOUTEN*,*CMARK* にマッチするときはカットしない
BMOVE の対象図形に、LINE, LWPOLYLINE を追加
2024/12/15b 同梱 LISP のエラー処理を修正
2024/12/16 BLINE で画層、線種、線色が違う線分を重ねて作成したとき、端点が変わってしまうのを修正
同梱 LISP をより電気仕様に変更
2024/12/19 LISP から DLL コマンドの呼び出しをとりやめ、不要なコマンドを削除
同梱 LISP を修正、コマンドを追加
2024/12/20 同梱 LISP にコマンドを追加
2024/12/21 同梱 LISP を修正、コマンドを追加
2024/12/22 同梱 LISP に不要な文字が残っていたのを修正
2024/12/23 BlkIn フォームに OnLayer チェックボックスを追加。
同梱 LISP に TXRP を追加
■作者連絡先
e-mail : f.izawa@dream.com
URL : http://www.izawa-web.com/
■ソースコード 2024/12/12
以下、最新ではありませんが、何かの参考になれば・・・。
'' Class1 ---------------------------------------- '' 2024/12/12 Imports Teigha.Runtime Imports HostMgd.ApplicationServices Imports Teigha.DatabaseServices Imports Teigha.Geometry Imports HostMgd.EditorInput '' Imports System.Drawing '' com 'Imports nanoCAD 'Imports OdaX ' alias Imports _AcRx = Teigha.Runtime Imports _AcAp = HostMgd.ApplicationServices Imports _AcDb = Teigha.DatabaseServices Imports _AcGe = Teigha.Geometry Imports _AcEd = HostMgd.EditorInput Imports _AcGi = Teigha.GraphicsInterface Imports _AcClr = Teigha.Colors Imports _AcWnd = HostMgd.Windows Public Class Class1 'Declare Function FindWindow Lib "user32" Alias _ ' "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As Integer) As Integer Public Shared Function GetPolar(ByVal pPt As Point3d, ByVal dAng As Double, ByVal dDist As Double) As Point3d Return New Point3d(pPt.X + dDist * Math.Cos(dAng), pPt.Y + dDist * Math.Sin(dAng), 0.0) End Function Public Shared Function GetPolar(ByVal pPt As Point2d, ByVal dAng As Double, ByVal dDist As Double) As Point2d Return New Point2d(pPt.X + dDist * Math.Cos(dAng), pPt.Y + dDist * Math.Sin(dAng)) End Function Public Shared Function GetAngle(p1 As Point2d, p2 As Point2d) As Double Dim fuzz = 0.0000001 Dim dx, dy As Double dx = p2.X - p1.X dy = p2.Y - p1.Y If Math.Abs(dx) >= fuzz And Math.Abs(dy) >= fuzz Then Return Math.Atan2(dy, dx) ElseIf Math.Abs(dx) < fuzz Then If p2.Y > p1.Y Then Return Math.PI * 0.5 Else Return Math.PI * 1.5 End If ElseIf Math.Abs(dy) < fuzz Then If p2.X > p1.X Then Return 0.0 Else Return Math.PI End If End If End Function Public Shared Function GetAngle(p1 As Point3d, p2 As Point3d) As Double Return GetAngle(New Point2d(p1.X, p1.Y), New Point2d(p2.X, p2.Y)) End Function Public Shared Function GetDistance(p1 As Point3d, p2 As Point3d) As Double Return Math.Sqrt((p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y)) End Function Public Shared Function GetDistance(p1 As Point2d, p2 As Point2d) As Double Return Math.Sqrt((p2.X - p1.X) * (p2.X - p1.X) + (p2.Y - p1.Y) * (p2.Y - p1.Y)) End Function Public Shared Sub BulgeToArc(p1 As Point2d, p2 As Point2d, bulge As Double, ByRef p0 As Point2d, ByRef rad As Double, ByRef st As Double, ByRef ed As Double) Dim naikaku, d, hankei, kakudo1 As Double ' 膨らみから、ARCの中心の内角を求める naikaku = Math.Atan(bulge) * 4.0 ' ARCの始点-終点間の距離の1/2を求める d = GetDistance(p1, p2) / 2.0 ' 半径を求める hankei = d / Math.Sin(naikaku / 2.0) rad = Math.Abs(hankei) ' 中心座標を求める kakudo1 = Math.PI / 2.0 - naikaku / 2.0 p0 = GetPolar(p1, kakudo1 + GetAngle(p1, p2), hankei) ' 膨らみの値により始点終点を入れ替える If bulge < 0.0 Then st = GetAngle(p0, p2) ed = GetAngle(p0, p1) Else st = GetAngle(p0, p1) ed = GetAngle(p0, p2) End If End Sub '' 四捨五入 Public Shared Function RoundOff(d As Double, keta As Integer) As Double Dim x As Double = 10 ^ keta If d > 0 Then Return Math.Floor(d * x + 0.5) / x Else Return Math.Floor(d * x + 0.5) / x End If End Function '' データ保持用構造体 Structure TxtRecord Dim index As Integer Dim objId As ObjectId Dim txtString As String Dim txtPos As Point3d End Structure Public Shared TxtAry() As TxtRecord Structure BlkRecord Dim objId As ObjectId Dim blkName As String End Structure Public Shared BlkAry() As BlkRecord ''ソート sortSw : 0=index 昇順, 1=X 昇順, 2=Y 降順 Public Shared Sub SortTxtAry(sortSw As Integer) If TxtAry.Length > 1 Then Dim temp As TxtRecord For i = 0 To TxtAry.Length - 2 For j = i + 1 To TxtAry.Length - 1 If (sortSw = 0 And TxtAry(i).index > TxtAry(j).index) Or (sortSw = 1 And TxtAry(i).txtPos.X > TxtAry(j).txtPos.X) Or (sortSw = 2 And TxtAry(i).txtPos.Y < TxtAry(j).txtPos.Y) Then temp = TxtAry(i) TxtAry(i) = TxtAry(j) TxtAry(j) = temp End If Next Next End If End Sub '' 最小、最大座標 Public Shared Sub RectTxtAry(ByRef minx As Double, ByRef miny As Double, ByRef maxx As Double, ByRef maxy As Double) If TxtAry.Length > 0 Then For i = 0 To TxtAry.Length - 1 With TxtAry(i).txtPos If i = 0 Then minx = .X miny = .Y maxx = .X maxy = .Y Else minx = Math.Min(minx, .X) miny = Math.Min(miny, .Y) maxx = Math.Max(maxx, .X) maxy = Math.Max(maxy, .Y) End If End With Next End If End Sub Public Shared Sub DispTxtAry(ByRef edform As Form1) With edform .TextBox1.Text = "" For i = 0 To TxtAry.Length - 1 .TextBox1.Text += TxtAry(i).txtString If i < TxtAry.Length - 1 Then .TextBox1.Text += vbCrLf End If Next .Label1.Text = "TEXT 数 = " & TxtAry.Length.ToString .txtarycnt = TxtAry.Length End With End Sub <CommandMethod("ntedn", CommandFlags.Modal)> Public Shared Sub NtextEditN() NtextEdit(False) End Sub <CommandMethod("ntedy", CommandFlags.Modal)> Public Shared Sub NtextEditY() NtextEdit(True) End Sub Public Shared Sub NtextEdit(sortFlag As Boolean) Dim doc As _AcAp.Document = _AcAp.Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Using tr As Transaction = db.TransactionManager.StartTransaction Try '' 選択フィルター Dim TypValAr(0) As TypedValue TypValAr.SetValue(New TypedValue(DxfCode.Start, "TEXT"), 0) Dim SelFtr As SelectionFilter = New SelectionFilter(TypValAr) If sortFlag Then ed.WriteMessage(vbLf & "座標順で一括編集する TEXT をガバっと選択して下さい.") Else ed.WriteMessage(vbLf & "選択順で一括編集する TEXT を順に選択して下さい.") End If '' 選択 Dim res As PromptSelectionResult = ed.GetSelection(SelFtr) If (res.Status = PromptStatus.OK) Then Dim SSet As _AcEd.SelectionSet = res.Value If SSet.Count > 0 Then Dim edForm As Form1 = New Form1() If sortFlag Then edForm.Text = "NTED-Y : TEXT 一括編集(座標順=追加可能)" Else edForm.Text = "NTED-N : TEXT 一括編集(選択順=追加不可)" End If '' データ格納 ReDim TxtAry(SSet.Count - 1) Dim idx As Integer = 0 For Each SSObj As SelectedObject In SSet If Not IsDBNull(SSObj) Then Dim ssTxt As DBText = tr.GetObject(SSObj.ObjectId, OpenMode.ForRead) If Not IsDBNull(ssTxt) Then With TxtAry(idx) .index = idx .txtString = ssTxt.TextString .objId = ssTxt.ObjectId If ssTxt.Justify = AttachmentPoint.BaseLeft Then .txtPos = ssTxt.Position Else .txtPos = ssTxt.AlignmentPoint End If End With idx += 1 End If End If Next If TxtAry.Length > 0 Then Dim sw As Integer = 0 '' TEXT の並び方向 If TxtAry.Length > 1 Then Dim minx, miny As Double Dim maxx, maxy As Double RectTxtAry(minx, miny, maxx, maxy) Dim tateFlag As Boolean = (maxy - miny) > (maxx - minx) ''縦並び If sortFlag Then If tateFlag Then sw = 2 Else sw = 1 End If End If edForm.sortSw = sw '' TextBox の背景色の切り換え用 ''ソート If sw > 0 Then SortTxtAry(sw) End If End If '' Form に表示 DispTxtAry(edForm) If _AcAp.Application.ShowModalDialog(edForm) = vbOK Then Dim arr() As String = Split(edForm.TextBox1.Text, vbCrLf) '' 修正 For i = 0 To arr.Length - 1 If i < TxtAry.Length Then Dim objTxt As DBText = tr.GetObject(TxtAry(i).objId, OpenMode.ForWrite) If arr(i) <> "" Then If objTxt.TextString <> arr(i) Then objTxt.TextString = arr(i) Else objTxt.Erase() ''空白文字を削除 End If Else '' あとで追加 End If Next ''削除 2024/12/08 追加 If TxtAry.Length > arr.Length Then For i = arr.Length To TxtAry.Length - 1 Dim objTxt As DBText = tr.GetObject(TxtAry(i).objId, OpenMode.ForWrite) objTxt.Erase() Next End If ''追加 Dim len As Integer = TxtAry.Length If sw > 0 And len > 1 And arr.Length > len Then Dim dx As Double = 0 Dim dy As Double = 0 If sw = 2 Then ''縦並び dy = TxtAry(len - 1).txtPos.Y - TxtAry(len - 2).txtPos.Y Else dx = TxtAry(len - 1).txtPos.X - TxtAry(len - 2).txtPos.X End If Dim Bt As BlockTable = TryCast(tr.GetObject(db.BlockTableId, OpenMode.ForWrite), BlockTable) Dim Btr As BlockTableRecord = TryCast(tr.GetObject(Bt("*Model_Space"), OpenMode.ForWrite), BlockTableRecord) '' 最後の TEXT Dim orgTxt As DBText = tr.GetObject(TxtAry(len - 1).objId, OpenMode.ForWrite) Dim n As Integer = 1 '' 追加 For i = len To arr.Length - 1 Dim clonedTxt As DBText = TryCast(orgTxt.Clone(), DBText) clonedTxt.TextString = arr(i) If clonedTxt.Justify = AttachmentPoint.BaseLeft Then clonedTxt.Position = New Point3d(clonedTxt.Position.X + dx * n, clonedTxt.Position.Y + dy * n, 0) Else clonedTxt.AlignmentPoint = New Point3d(clonedTxt.AlignmentPoint.X + dx * n, clonedTxt.AlignmentPoint.Y + dy * n, 0) End If Btr.AppendEntity(clonedTxt) tr.AddNewlyCreatedDBObject(clonedTxt, True) n += 1 Next Bt.Dispose() Btr.Dispose() End If '' 変更を反映 tr.Commit() End If '' フォーム破棄 edForm.Dispose() End If End If End If Catch ex As System.Exception _AcAp.Application.ShowAlertDialog(ex.Message) End Try End Using End Sub Public Shared Sub SortBlkAry() If BlkAry.Length > 1 Then Dim temp As BlkRecord For i = 0 To BlkAry.Length - 2 For j = i + 1 To BlkAry.Length - 1 If BlkAry(i).blkName.ToUpper() > BlkAry(j).blkName.ToUpper() Then temp = BlkAry(i) BlkAry(i) = BlkAry(j) BlkAry(j) = temp End If Next Next End If End Sub <CommandMethod("blkin", CommandFlags.Modal)> Public Shared Sub BlkIn() Dim doc As _AcAp.Document = _AcAp.Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Using tr As Transaction = db.TransactionManager.StartTransaction Try Dim tbl As BlockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead, False) Dim enu1 As IEnumerator = tbl.GetEnumerator() Dim objId As ObjectId Dim cnt As Integer = 0 While enu1.MoveNext() objId = enu1.Current Dim rec As BlockTableRecord = tr.GetObject(objId, OpenMode.ForRead, False) Dim c As String = Left(rec.Name, 1) If c <> "*" And c <> "_" And c <> "$" Then '' ブロック名の列挙 ''ed.WriteMessage(vbLf & rec.Name) cnt += 1 ReDim Preserve BlkAry(cnt - 1) With BlkAry(cnt - 1) .objId = objId .blkName = rec.Name End With End If End While If cnt > 0 Then SortBlkAry() Dim blkForm As Form2 = New Form2() Dim i As Integer For i = 0 To BlkAry.Length - 1 blkForm.ListBox1.Items.Add(BlkAry(i).blkName) Next If _AcAp.Application.ShowModalDialog(blkForm) = vbOK Then Dim blkName As String = blkForm.TextBox1.Text Dim index As Integer = blkForm.ListBox1.FindString(blkName) Dim blkRecId As ObjectId If BlkAry.Length > index Then blkRecId = BlkAry(index).objId If blkRecId <> ObjectId.Null Then Using blkref As New BlockReference(New Point3d(0, 0, 0), blkRecId) Dim curSpaceBlkTblRec As BlockTableRecord curSpaceBlkTblRec = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) curSpaceBlkTblRec.AppendEntity(blkref) tr.AddNewlyCreatedDBObject(blkref, True) '' 2024/12/11c Dim blkdef As BlockTableRecord = tr.GetObject(tbl(blkName), OpenMode.ForWrite) If blkdef.HasAttributeDefinitions Then For Each oid As ObjectId In blkdef Dim dbObj As DBObject = tr.GetObject(oid, OpenMode.ForRead) If TypeOf (dbObj) Is AttributeDefinition Then Dim acAtt As AttributeDefinition = dbObj If Not acAtt.Constant Then Using attref As AttributeReference = New AttributeReference() attref.SetAttributeFromBlock(acAtt, blkref.BlockTransform) attref.Position = acAtt.Position.TransformBy(blkref.BlockTransform) attref.TextString = acAtt.TextString blkref.AttributeCollection.AppendAttribute(attref) tr.AddNewlyCreatedDBObject(attref, True) End Using End If End If Next End If tr.Commit() doc.SendStringToExecute("copybase L " & vbCr & "0,0 ", True, False, False) doc.SendStringToExecute("erase L " & vbCr, True, False, False) doc.SendStringToExecute("pasteclip ", True, False, False) 'Dim ncadApp As Object = GetObject("", "nanoCAD.Application.5.0") 'Dim ncadDoc As Object = ncadApp.ActiveDocument 'ncadDoc.SendCommand("copybase L " & vbCr & "0,0 ") 'ncadDoc.SendCommand("erase L " & vbCr) 'ncadDoc.SendCommand("pasteclip ") End Using End If End If End If blkForm.Dispose() End If Catch ex As Exception _AcAp.Application.ShowAlertDialog(ex.Message) End Try End Using End Sub End Class '' Form1 ------------------------------------------------------- '' nted 用 Imports Teigha.Runtime Imports HostMgd.ApplicationServices Imports Teigha.DatabaseServices Imports Teigha.Geometry Imports HostMgd.EditorInput Public Class Form1 Public txtarycnt As Integer = 0 Public sortSw As Integer = 0 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Me.Hide() End Sub Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'フォームのLoadイベントハンドラ ''Me.AutoSize = True ''Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink Me.AutoSize = False Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowOnly 'フォームの最大サイズを画面サイズにする Me.MaximumSize = System.Windows.Forms.Screen.GetBounds(Me).Size 'Me.Width = System.Windows.Forms.Screen.GetBounds(Me).Width \ 2 'Me.Height = System.Windows.Forms.Screen.GetBounds(Me).Height \ 2 End Sub Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged Dim len As Integer = TextBox1.Lines().Length Label2.Text = "現在の行数 = " & len.ToString '' TextBox の背景色を変更 With TextBox1 If sortSw = 0 And txtarycnt > 0 And len > txtarycnt Then If .BackColor <> Drawing.Color.FromArgb(255, 255, 191) Then .BackColor = Drawing.Color.FromArgb(255, 255, 191) ElseIf sortSw > 0 And txtarycnt > 0 And len > txtarycnt Then If .BackColor <> Drawing.Color.FromArgb(191, 255, 255) Then .BackColor = Drawing.Color.FromArgb(191, 255, 255) Else If .BackColor <> Drawing.Color.White Then .BackColor = Drawing.Color.White End If End With End Sub Private Sub TextBox1_KeyDown(sender As Object, e As Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown If (e.Modifiers And Windows.Forms.Keys.Shift) = Windows.Forms.Keys.Shift Then If e.KeyCode = 13 Then 'Me.Text = "Shift+Enter" 'Button1_Click(Button1, EventArgs.Empty) End If ElseIf e.KeyCode = 27 Then Button2_Click(Button2, EventArgs.Empty) End If End Sub End Class '' Form2 ------------------------------------------------------- '' blkin 用 '' 2024/12/11c Imports Teigha.Runtime Imports HostMgd.ApplicationServices Imports Teigha.DatabaseServices Imports Teigha.Geometry Imports HostMgd.EditorInput '' for Form2 Imports System.Drawing ' alias Imports _AcRx = Teigha.Runtime Imports _AcAp = HostMgd.ApplicationServices Imports _AcDb = Teigha.DatabaseServices Imports _AcGe = Teigha.Geometry Imports _AcEd = HostMgd.EditorInput Imports _AcGi = Teigha.GraphicsInterface Imports _AcClr = Teigha.Colors Imports _AcWnd = HostMgd.Windows Public Class Form2 Sub DrawLine(bmpW As Integer, bmpH As Integer, cenx As Double, ceny As Double, scale As Double, p1 As Point3d, p2 As Point3d, ByRef g As Graphics, apen As Pen) Dim x1, y1, x2, y2 As Integer x1 = Class1.RoundOff((p1.X - cenx) * scale + bmpW / 2, 0) y1 = bmpH - Class1.RoundOff(((p1.Y - ceny) * scale + bmpH / 2), 0) x2 = Class1.RoundOff((p2.X - cenx) * scale + bmpW / 2, 0) y2 = bmpH - Class1.RoundOff(((p2.Y - ceny) * scale + bmpH / 2), 0) g.DrawLine(apen, x1, y1, x2, y2) End Sub Sub DrawCircle(bmpW As Integer, bmpH As Integer, cenx As Double, ceny As Double, scale As Double, p0 As Point3d, rad As Double, ByRef g As Graphics, apen As Pen) Dim x, y, d As Integer x = Class1.RoundOff((p0.X - cenx) * scale + bmpW / 2, 0) y = bmpH - Class1.RoundOff(((p0.Y - ceny) * scale + bmpH / 2), 0) x = Class1.RoundOff(x - rad * scale, 0) y = Class1.RoundOff(y - rad * scale, 0) d = Class1.RoundOff(rad * scale * 2, 0) If d > 0 Then '' 2024/12/11a g.DrawEllipse(apen, x, y, d, d) End If End Sub Sub DrawRect(bmpW As Integer, bmpH As Integer, cenx As Double, ceny As Double, scale As Double, p1 As Point3d, p2 As Point3d, ByRef g As Graphics, apen As Pen) Dim x1, y1, x2, y2 As Integer x1 = Class1.RoundOff((p1.X - cenx) * scale + bmpW / 2, 0) y1 = bmpH - Class1.RoundOff(((p1.Y - ceny) * scale + bmpH / 2), 0) x2 = Class1.RoundOff((p2.X - cenx) * scale + bmpW / 2, 0) y2 = bmpH - Class1.RoundOff(((p2.Y - ceny) * scale + bmpH / 2), 0) g.DrawRectangle(apen, x1, y2, x2 - x1, y1 - y2) End Sub Sub DrawArc(bmpW As Integer, bmpH As Integer, cenx As Double, ceny As Double, scale As Double, p0 As Point3d, rad As Double, stang As Double, edang As Double, ByRef g As Graphics, apen As Pen) Dim x, y, d As Integer x = Class1.RoundOff((p0.X - cenx) * scale + bmpW / 2, 0) y = bmpH - Class1.RoundOff(((p0.Y - ceny) * scale + bmpH / 2), 0) x = Class1.RoundOff(x - rad * scale, 0) y = Class1.RoundOff(y - rad * scale, 0) d = Class1.RoundOff(rad * scale * 2, 0) Dim deg1, deg2 As Integer deg1 = Class1.RoundOff(stang / Math.PI * 180.0, 0) deg2 = Class1.RoundOff(edang / Math.PI * 180.0, 0) If deg2 < deg1 Then deg2 += 360 End If Dim degsa As Integer = Math.Abs(deg2 - deg1) If degsa > 0 And d > 0 Then ''2024/12/11a g.DrawArc(apen, x, y, d, d, -deg1, -degsa) End If End Sub Public Sub DrawBlockImage(ByVal blkObjId As ObjectId) Dim doc As _AcAp.Document = _AcAp.Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor Using tr As Transaction = db.TransactionManager.StartTransaction Dim dxfName As String = "" Try Dim rec As BlockTableRecord = tr.GetObject(blkObjId, OpenMode.ForRead) '' ブロック名の列挙 ''ed.WriteMessage(vbLf & rec.Name) '' 描画範囲 Dim minx, miny, maxx, maxy As Double '' 描画対象の図形を保持 Dim objids As ObjectIdCollection = New ObjectIdCollection Dim ent As Entity Dim cnt As Integer = 0 Dim entcnt As Integer = 0 Dim txtcnt As Integer = 0 Dim mtxtcnt As Integer = 0 Dim attcnt As Integer = 0 Dim blkcnt As Integer = 0 For Each id As ObjectId In rec entcnt += 1 ent = tr.GetObject(id, OpenMode.ForRead) dxfName = ent.GetRXClass().DxfName If dxfName = "LINE" Or dxfName = "ARC" Or dxfName = "CIRCLE" Or dxfName = "LWPOLYLINE" Or dxfName = "INSERT" Then objids.Add(id) Dim ext As Extents3d = ent.Bounds If cnt = 0 Then minx = ext.MinPoint.X miny = ext.MinPoint.Y maxx = ext.MaxPoint.X maxy = ext.MaxPoint.Y Else minx = Math.Min(minx, ext.MinPoint.X) miny = Math.Min(miny, ext.MinPoint.Y) maxx = Math.Max(maxx, ext.MaxPoint.X) maxy = Math.Max(maxy, ext.MaxPoint.Y) End If cnt += 1 ElseIf dxfName = "TEXT" Then objids.Add(id) txtcnt += 1 ElseIf dxfName = "MTEXT" Then objids.Add(id) mtxtcnt += 1 ElseIf dxfName = "ATTDEF" Then attcnt += 1 Else ''ed.WriteMessage(vbLf & dxfName) End If If dxfName = "INSERT" Then blkcnt += 1 End If Next Label2.Text = "" Label3.Text = "" Label4.Text = "TEXT = " & txtcnt.ToString Label5.Text = "MTEXT = " & mtxtcnt.ToString Label6.Text = "ATTDEF = " & attcnt.ToString If attcnt > 0 Then Label6.ForeColor = Color.Red Else Label6.ForeColor = Color.Black End If Label7.Text = "INSERT = " & blkcnt.ToString Label1.Text = "図形数 = " & entcnt.ToString ''usesInsertCmd = attcnt > 0 '' 2024/12/11a Dim bmpW As Integer = PictureBox1.Width Dim bmpH As Integer = PictureBox1.Height Dim img As New Bitmap(bmpW, bmpH) Dim g As Graphics = Graphics.FromImage(img) g.FillRectangle(Brushes.Black, g.VisibleClipBounds) Try If cnt > 0 Then '' 描画範囲 Label3.Text = (maxx - minx).ToString("F1") & " x " & (maxy - miny).ToString("F1") '' 描画 Dim dx As Double = maxx - minx Dim dy As Double = maxy - miny Dim cenx As Double = (maxx + minx) / 2 Dim ceny As Double = (maxy + miny) / 2 Dim scale As Double If dx > dy Then scale = bmpW / dx Else scale = bmpH / dy End If scale *= 0.85 For Each objid As ObjectId In objids ent = tr.GetObject(objid, OpenMode.ForRead) dxfName = ent.GetRXClass().DxfName If dxfName = "LINE" Then Dim ln As Line = TryCast(ent, Line) DrawLine(bmpW, bmpH, cenx, ceny, scale, ln.StartPoint, ln.EndPoint, g, Pens.White) ElseIf dxfName = "CIRCLE" Then Dim cir As Circle = TryCast(ent, Circle) DrawCircle(bmpW, bmpH, cenx, ceny, scale, cir.Center, cir.Radius, g, Pens.White) ElseIf dxfName = "ARC" Then Dim arcEnt As Arc = TryCast(ent, Arc) DrawArc(bmpW, bmpH, cenx, ceny, scale, arcEnt.Center, arcEnt.Radius, arcEnt.StartAngle, arcEnt.EndAngle, g, Pens.White) ElseIf dxfName = "LWPOLYLINE" Then Dim pl As Polyline = TryCast(ent, Polyline) Dim pt1, pt2, pt0 As Point2d Dim bul1, bul2, rad, stang, edang As Double For i As Integer = 0 To pl.NumberOfVertices - 2 pt1 = pl.GetPoint2dAt(i) pt2 = pl.GetPoint2dAt(i + 1) bul1 = pl.GetBulgeAt(i) bul2 = pl.GetBulgeAt(i + 1) If Math.Abs(bul1) <= 0.000001 Then DrawLine(bmpW, bmpH, cenx, ceny, scale, New Point3d(pt1.X, pt1.Y, 0), New Point3d(pt2.X, pt2.Y, 0), g, Pens.White) Else Class1.BulgeToArc(pt1, pt2, bul1, pt0, rad, stang, edang) DrawArc(bmpW, bmpH, cenx, ceny, scale, New Point3d(pt0.X, pt0.Y, 0), rad, stang, edang, g, Pens.White) End If Next If pl.Closed Then pt1 = pt2 pt2 = pl.GetPoint2dAt(0) bul1 = bul2 If Math.Abs(bul1) <= 0.000001 Then DrawLine(bmpW, bmpH, cenx, ceny, scale, New Point3d(pt1.X, pt1.Y, 0), New Point3d(pt2.X, pt2.Y, 0), g, Pens.White) Else Class1.BulgeToArc(pt1, pt2, bul1, pt0, rad, stang, edang) DrawArc(bmpW, bmpH, cenx, ceny, scale, New Point3d(pt0.X, pt0.Y, 0), rad, stang, edang, g, Pens.White) End If End If ElseIf dxfName = "INSERT" Then Dim ext As Extents3d = ent.Bounds DrawRect(bmpW, bmpH, cenx, ceny, scale, ext.MinPoint, ext.MaxPoint, g, Pens.Red) DrawLine(bmpW, bmpH, cenx, ceny, scale, ext.MinPoint, ext.MaxPoint, g, Pens.Red) DrawLine(bmpW, bmpH, cenx, ceny, scale, New Point3d(ext.MinPoint.X, ext.MaxPoint.Y, 0), New Point3d(ext.MaxPoint.X, ext.MinPoint.Y, 0), g, Pens.Red) ElseIf dxfName = "TEXT" Or dxfName = "MTEXT" Then Dim ext As Extents3d = ent.Bounds DrawRect(bmpW, bmpH, cenx, ceny, scale, ext.MinPoint, ext.MaxPoint, g, Pens.Lime) End If Next End If ''PictureBox1.Image = img Finally g.Dispose() PictureBox1.Image = img End Try Catch ex As System.Exception Label2.Text = ex.Message & " " & dxfName PictureBox1.Image = Nothing Label4.Text = "TEXT = " Label5.Text = "MTEXT = " Label6.Text = "ATTDEF = " Label7.Text = "INSERT = " Label1.Text = "図形数 = " ''_AcAp.Application.ShowAlertDialog(ex.Message) End Try End Using End Sub Private Sub ListBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedIndexChanged Dim curItem As String = ListBox1.SelectedItem.ToString TextBox1.Text = curItem Dim index As Integer = ListBox1.FindString(curItem) If Class1.BlkAry.Length > index Then Dim objId As ObjectId = Class1.BlkAry(index).objId DrawBlockImage(objId) End If End Sub Private Sub Form2_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown With ListBox1 If .Items.Count > 0 Then .SelectedIndex = 0 End If End With End Sub End Class