[AutoLISP x ChatGPT] オブジェクトのDXFコード一覧をエクセルに出力する

AutoLisp

こんにちは、ISDです。

AutoCAD では数値を扱う場面が多いです。
そして、数値を扱うアプリと言えば Excel ですね。(個人的な感想です)
ということは、AutoCADExcel を連携できると、とても作業効率が上がりそうです。

ということで、ChatGPT を使ってAutoCAD から Excel を操作するオリジナルコマンドを作成してみたいと思います。

ChatGPTでオリジナルコマンドを作成する

では、ChatGPT にお願いしてみようと思います。

まずは、Hello World 的なもので
・A2セルに ”Hello World” の文字列
・B4セルに 12345の数値
を出力してみます。

早速プロンプトを投げてみます。

AutoCADのオリジナルコマンドを作成したい。
使用言語は AutoLISP

### コマンドの概要
・AutoCAD から Excel を起動
・A2セルに “Hello World” を出力
・B4セルに 12345 を出力

そして、ChatGPT の返答がこちら。

以下は要件どおりの 最小・実用版 AutoLISP コマンドです。
(Excel を起動/取得 → 表示 → A2 に “Hello World”、B4 に 12345 を書き込み)

(vl-load-com)

(defun c:XLS_HELLO ( / app wbs wb sh rngA2 rngB4)
  ;; Excel 起動(起動済みならそのインスタンス取得)
  (setq app (vlax-get-or-create-object "Excel.Application"))
  (vlax-put-property app 'Visible :vlax-true)

  ;; ブックが無ければ追加、あればアクティブブックを使う
  (setq wbs (vlax-get-property app 'Workbooks))
  (if (= (vlax-get-property wbs 'Count) 0)
    (setq wb (vlax-invoke-method wbs 'Add))
    (setq wb (vlax-get-property app 'ActiveWorkbook))
  )

  ;; アクティブシート取得
  (setq sh (vlax-get-property wb 'ActiveSheet))

  ;; A2 = "Hello World"
  (setq rngA2 (vlax-get-property sh 'Range "A2"))
  (vlax-put-property rngA2 'Value2 (vlax-make-variant "Hello World"))

  ;; B4 = 12345
  (setq rngB4 (vlax-get-property sh 'Range "B4"))
  (vlax-put-property rngB4 'Value2 (vlax-make-variant 12345))

  (princ "\n[XLS_HELLO] Excelへ出力しました。")
  (princ)
)

使い方

  1. 上のコードを .lsp に保存
  2. AutoCADで (load "ファイル名")
  3. コマンドラインで XLS_HELLO

必要なら「既存ブックに追記」「指定シート名を作る/選ぶ」「書き込み前にクリア」などもこの骨格に追加できます。

何か出してきました。
早速テストしてみましょう。

上記のコードを読ませて、コマンドラインから XLS_HELLO と打ち込んでみます。


すると、Excel が立ち上がり……

A2セルに ”Hello World”、B4セルに 12345 が出力されています。

まずは OK ですね。

オブジェクトのDXFコード一覧を Excel に出力する

続いてのお題はこちら、
「オブジェクトのDXFコード一覧を Excel に出力する」
です。

プロンプトを投げます。

AutoCADのオリジナルコマンドを作成したい。
使用言語は AutoLISP

### コマンドの概要
・選択したオブジェクト(1つ)のDXFコード一覧をEXCELに出力する
・entget で得た リストの各要素を1行ずつ表示
・A列にDXFコード、B列に値を出力

以下は、要件どおり **「選択したオブジェクト1つの entget リスト(DXFコード一覧)を Excel に出力」**する AutoLISP コマンドの完成版サンプルです。

  • A列:DXFコード(例 10, 8, 62…)
  • B列:値
  • entget の各要素((code . value))を 1行ずつ出力
  • 書き込み前にシートをクリア
  • Excel が起動していなければ起動、起動済みならそのインスタンスを掴みます

コマンド:DXF2XLS(完成版)

;; ============================================================
;; DXF2XLS.lsp
;; 選択した1オブジェクトのDXF(entget)一覧をExcelへ出力
;; A列=DXFコード / B列=値
;; ============================================================

(vl-load-com)

;; --- Excel表示用に「値」を安全に文字列化 ---
(defun _dxf-val->string (v /)
  (cond
    ((null v) "")
    ((= (type v) 'STR) v)
    ((= (type v) 'INT) (itoa v))
    ((= (type v) 'REAL) (rtos v 2 15))
    ((= (type v) 'ENAME) (vl-princ-to-string v))
    ((= (type v) 'LIST)
     ;; 10/11/12 等の点や、拡張データっぽいものもまとめて表示
     (vl-princ-to-string v)
    )
    (t (vl-princ-to-string v))
  )
)

;; --- Excelアプリ取得/起動 ---
(defun _excel-getapp (/ app)
  (setq app
    (vl-catch-all-apply
      '(lambda () (vlax-get-or-create-object "Excel.Application"))
    )
  )
  (if (vl-catch-all-error-p app)
    nil
    app
  )
)

;; --- アクティブブック/シート取得(なければ作成) ---
(defun _excel-get-sheet (app / wbs wb sh)
  (setq wbs (vlax-get-property app 'Workbooks))
  (if (= (vlax-get-property wbs 'Count) 0)
    (setq wb (vlax-invoke-method wbs 'Add))
    (setq wb (vlax-get-property app 'ActiveWorkbook))
  )
  (setq sh (vlax-get-property wb 'ActiveSheet))
  sh
)

;; --- シート全消去(UsedRange だけだと残るケースがあるので Cells を推奨) ---
(defun _excel-clear-sheet (sh / cells)
  (setq cells (vlax-get-property sh 'Cells))
  (vlax-invoke-method cells 'Clear)
)

;; --- 2列分を一括書き込み(高速) ---
(defun _excel-write-dxf-table (sh dxfList / n r arr sa rng)
  ;; dxfList: ((code . value) (code . value) ...)
  (setq n (length dxfList))
  (if (= n 0)
    nil
    (progn
      ;; 2列(A,B)× n行 の 2次元 safearray を作る
      ;; Excel(VBA)は通常 1-based だが、safearrayは 0-based でもOK
      (setq sa (vlax-make-safearray vlax-vbVariant (cons 0 (1- n)) (cons 0 1)))

      (setq r 0)
      (foreach it dxfList
        ;; 列0=A: DXFコード
        (vlax-safearray-put-element sa r 0 (vlax-make-variant (car it)))
        ;; 列1=B: 値(文字列化して入れる)
        (vlax-safearray-put-element sa r 1 (vlax-make-variant (_dxf-val->string (cdr it))))
        (setq r (1+ r))
      )

      ;; 書き込み範囲 A1:B{n}
      (setq rng (vlax-get-property sh 'Range "A1"
                 (strcat "B" (itoa n))))
      (vlax-put-property rng 'Value2 sa)
    )
  )
)

;; --- メインコマンド ---
(defun c:DXF2XLS (/ sel en ed app sh)
  (princ "\n[DXF2XLS] 1つオブジェクトを選択してください: ")
  (setq sel (entsel))
  (cond
    ((null sel)
     (princ "\n[DXF2XLS] キャンセル")
    )
    (t
     (setq en (car sel))
     (setq ed (entget en)) ; DXFペアリスト

     (setq app (_excel-getapp))
     (if (null app)
       (princ "\n[DXF2XLS] Excelを起動/取得できませんでした。")
       (progn
         (vlax-put-property app 'Visible :vlax-true)

         (setq sh (_excel-get-sheet app))
         (_excel-clear-sheet sh)

         ;; entget の各要素をそのまま (code . value) でテーブル化して書き込み
         (_excel-write-dxf-table sh ed)

         (princ (strcat "\n[DXF2XLS] 出力完了: " (itoa (length ed)) " 行"))
       )
     )
    )
  )
  (princ)
)

使い方

  1. 上記を DXF2XLS.lsp として保存
  2. AutoCAD で (load "DXF2XLS")
  3. コマンドラインで DXF2XLS
  4. オブジェクトを1つ選択 → Excel に A列/B列で出力

補足(実務でよく欲しくなる追加)

必要になりがちな拡張、すぐ足せます:

  • 1行目にヘッダ(A1=Code, B1=Value)を入れて、データは2行目から
  • フィルタ(特定DXFコードだけ出す:例 10/11/12/8/62…)
  • (entget en ‘(“*”)) で拡張データ(XData)も含める
  • ハンドルやオブジェクト名を上段に付記(vla-get-ObjectName 等)

必要なら、次の返答で「ヘッダ付き」「XData込み」「見やすい整形(点は X,Y,Z を別列)」版に拡張した完成版も出します。

何か出てきました。
早速テストしてみましょう。

とりあえず、中心点(10,20,15)半径 2.5円オブジェクトで試してみます。

コマンドラインDXF2XLS と打ち込んでみます。


そして、Excel が起動して、

円オブジェクトDXFコードが出力されました。

まとめ

とりあえずのところ、ChatGPT を使って AutoCAD から Excel を操作する簡単なオリジナルコマンドを作成することが出来ました。

とりあえずのところ、小手調べ的なものですが、
この次は、もう少し実用性あるコマンドに挑戦してみたいと思います。

コメント

タイトルとURLをコピーしました