AutoCADで数値を一括加算・乗算するLISP「IK・IJ」/元の数値を残して二段書き

「複数の数値に同じ値を足したい」
「選択した数値をまとめて1.2倍にしたい」

このような修正を電卓と手入力で繰り返すと、数が多いほど時間がかかり、入力ミスも起こりやすくなります。

加算用LISP「IK」と乗算用LISP「IJ」を使えば、選択した数値をまとめて計算し、結果を元の文字の上へ配置できます。元の数値を消さないため、変更前後の確認もしやすくなります。

この記事では、機能がよく似たIKとIJを1記事にまとめて、違いと使い方を紹介します。

IK
指定した値を加算
IK_AddValue.lsp

JK
指定した値を乗算
IJ_MultiplyValue.lsp

フクロウ
フクロウ

コマンドは覚えやすいように、IKは一括(I)加算(K),IJは一括(I)乗算(J)の頭文字をとってます。

💡このLISPでできること

  • 選択した数値テキストに、指定した値を一括で加算・乗算
  • 計算結果は元の文字の真上(文字高さの1.5倍の位置)に自動配置
  • 二段書きなので、元の数値を消さずに残せる(検図・確認がしやすい)
  • 加算・乗算した数値は専用画層に自動振り分け(IKは「kasan1」、IJは「kasan2」)
  • 小数点以下の表示桁数を指定でき、末尾のゼロも省略せずそのまま表示

なぜ「二段書き」なのか

このLISPは、数値を上書きするのではなく、元の数値の真上に新しい数値を追加する「二段書き」方式を採用しています。

これは、変更のプロセスを後から追いやすくするためです。元の数値を残しておくことで、チェック(検図)が楽になり、ミスを防げます。配置する数字はレイヤーが変わるので扱いやすいです。

⚙️運用の準備(確実に動かすための初期設定)

このLISPは単体でも動作しますが、当ブログで推奨している共通ユーティリティや自動ロード設定を行っておくと、万が一のエラー時や「元に戻す(UNDO)」の動作が完璧になります。

まだ設定が終わっていない方は、先に以下の記事を読んで「爆速作図の土台」を作っておくと便利です。(後でゆっくやる、今はすぐ使いたい方は次へ↓)

🕺使い方はたったの4ステップ!

IK(一括加算)とIJ(一括乗算)の使い方は同じです、足すか掛けるかの違いだけです

  1. IK(IJ)入力して Space(又は右クリック) で決定
  2. 加えたい(掛けたい)数字を入力して Space(又は右クリック)で確定
  3. 小数点以下の表示桁数を入力
  4. 対象のテキストを選択してSpace(または右クリック)で確定

⚠️ マルチテキストは選択されません、また、50mなど単位が一緒になってる場合も弾かれます。

動画は10を足して、0.5を掛けてます。

💾LISPのダウンロードと追加方法

※ダウンロードしたファイルを右クリックして「すべて展開(解凍)」してからご使用ください。
ロードがうまくいかない方はこちらを確認してください

💡「LISPの使い方が全くわからない!」という方は、まずこちらの記事で読み込み方をマスターしてください。とても簡単です。
→ AutoCADでLISPをロードする3つの方法

🗒️コピーしたい方はこちら↓

IK_AddValue.lsp
;;; Support: https://easycadwork.com
;;; X(follow me!): https://x.com/easycadwork
;;; 概要: 選択した文字の数値に指定値を加算し、元の文字の真上に新しい画層で二段書きする

(defun c:ik (/ layerName tx0 tt ssgt ssln cnt ssna entg tx1 txVal xy10 xy11 tx11 tx12
               rot90 dist dx dy n-xy10 n-xy11 *dimzin-save* okCnt skipCnt errCnt entResult)

  ;; --- 0. エラー時もDIMZINを確実に戻すための専用エラーハンドラ ---
  ;;    ECW_Utility.lsp はDIMZINを管理対象にしていないため、
  ;;    このLISP専用でエラー・キャンセル時の復元を保証する
  (defun ik-error (msg)
    (if *dimzin-save* (setvar "DIMZIN" *dimzin-save*))
    (if (and (type ECW_Error) (/= msg "Function cancelled") (/= msg "quit / exit abort"))
      (ECW_Error msg)
      (progn
        (if (type ECW_End) (ECW_End))
        (setq *error* nil)
      )
    )
    (princ)
  )
  (setq *error* ik-error)

  ;; 共通ユーティリティの有無を確認して実行(ハイブリッド設計)
  (if (type ECW_Start) (ECW_Start))

  ;; --- 1. 末尾ゼロを省略させないための一時設定 ---
  (setq *dimzin-save* (getvar "DIMZIN"))
  (setvar "DIMZIN" 0)   ; 0 = 末尾・先頭ゼロを省略しない

  ;; --- 2. 画層の準備 (新規レイヤー: kasan1) ---
  (setq layerName "kasan1")
  (if (not (tblsearch "LAYER" layerName))
    (entmake (list '(0 . "LAYER")
                   '(100 . "AcDbSymbolTableRecord")
                   '(100 . "AcDbLayerTableRecord")
                   (cons 2 layerName)
                   '(70 . 0)
                   '(62 . 2)
                   '(6 . "Continuous")))
  )

  ;; --- 3. ユーザー入力(桁数は0~8の範囲でチェック、範囲外は再入力) ---
  (setq tx0 (getreal "\n加算する値を入力 (+): "))

  (setq tt nil)
  (while (null tt)
    (setq tt (getint "\n小数点以下の表示桁数を入力 (0~8): "))
    (if (or (null tt) (< tt 0) (> tt 8))
      (progn
        (princ "\n※0~8の範囲で入力してください。")
        (setq tt nil)
      )
    )
  )

  (princ "\n対象の文字(TEXT)を選択: ")
  (setq ssgt (ssget '((0 . "TEXT"))))

  (if (and tx0 tt ssgt)
    (progn
      (setq ssln    (sslength ssgt)
            cnt     0
            okCnt   0
            skipCnt 0
            errCnt  0)

      ;; --- 4. メイン処理 (ループ) ---
      (while (< cnt ssln)
        (setq ssna (ssname ssgt cnt)
              entg (entget ssna)
              tx1  (cdr (assoc 1 entg)))

        (if (setq txVal (distof tx1))
          (progn
            (setq xy10 (cdr (assoc 10 entg))
                  xy11 (cdr (assoc 11 entg))
                  tx11 (cdr (assoc 40 entg))
                  tx12 (cdr (assoc 50 entg)))

            ;; --- 必要なDXF値が揃っているか確認してから計算する ---
            (if (and xy10 tx11 tx12)
              (progn
                (setq txVal (+ tx0 txVal))

                (setq rot90 (+ tx12 (/ pi 2.0))
                      dist  (* tx11 1.5)
                      dx    (* dist (cos rot90))
                      dy    (* dist (sin rot90)))

                (setq n-xy10 (list (+ (car xy10) dx) (+ (cadr xy10) dy) (caddr xy10)))
                (setq n-xy11 (if xy11
                               (list (+ (car xy11) dx) (+ (cadr xy11) dy) (caddr xy11))
                               n-xy10))

                ;; --- 5. 文字の生成 (entmake) ---
                ;; DIMZIN=0 の状態で rtos するため、指定桁数の末尾ゼロがそのまま表示される
                (setq entResult
                  (entmake
                    (vl-remove nil
                      (list '(0 . "TEXT")
                            (cons 1 (rtos txVal 2 tt))
                            (cons 10 n-xy10)
                            (cons 11 n-xy11)
                            (cons 40 tx11)
                            (cons 50 tx12)
                            (cons 8 layerName)
                            (assoc 7 entg)
                            (assoc 71 entg)
                            (assoc 72 entg)
                            (assoc 73 entg)
                      )
                    )
                  )
                )

                ;; --- entmakeの成否を確認 ---
                (if entResult
                  (setq okCnt (1+ okCnt))
                  (progn
                    (setq errCnt (1+ errCnt))
                    (princ (strcat "\n※エラー: '" tx1 "' の配置に失敗しました。"))
                  )
                )
              )
              (progn
                (setq errCnt (1+ errCnt))
                (princ (strcat "\n※エラー: '" tx1 "' は座標・高さ・角度の情報が不足しているためスキップしました。"))
              )
            )
          )
          (progn
            (setq skipCnt (1+ skipCnt))
            (princ (strcat "\n※警告: '" tx1 "' は数値でないためスキップしました。"))
          )
        )
        (setq cnt (1+ cnt))
      )

      ;; --- 6. 完了メッセージ(処理件数の内訳+目視確認の案内) ---
      (princ (strcat "\n完了: " (itoa okCnt) "件を加算し画層「" layerName "」に配置しました"
                     "(数値以外のためスキップ: " (itoa skipCnt) "件"
                     (if (> errCnt 0) (strcat " / エラー: " (itoa errCnt) "件") "")
                     ")。"))
      (princ "\n配置した数値と位置を図面上でご確認ください。")
    )
    (princ "\nキャンセルされました。")
  )

  ;; --- 7. DIMZINを元の値に復元 ---
  (setvar "DIMZIN" *dimzin-save*)

  ;; 共通ユーティリティの有無を確認して実行(ハイブリッド設計)
  (if (type ECW_End) (ECW_End))
  (setq *error* nil)
  (princ)
)
IJ_MultiplyValue.lsp
;;; Support: https://easycadwork.com
;;; X(follow me!): https://x.com/easycadwork
;;; 概要: 選択した文字の数値に指定値を掛け、元の文字の真上に新しい画層で二段書きする

(defun c:ij (/ layerName tx0 tt ssgt ssln cnt ssna entg tx1 txVal xy10 xy11 tx11 tx12
               rot90 dist dx dy n-xy10 n-xy11 *dimzin-save* okCnt skipCnt errCnt entResult)

  ;; --- 0. エラー時もDIMZINを確実に戻すための専用エラーハンドラ ---
  ;;    ECW_Utility.lsp はDIMZINを管理対象にしていないため、
  ;;    このLISP専用でエラー・キャンセル時の復元を保証する
  (defun ij-error (msg)
    (if *dimzin-save* (setvar "DIMZIN" *dimzin-save*))
    (if (and (type ECW_Error) (/= msg "Function cancelled") (/= msg "quit / exit abort"))
      (ECW_Error msg)
      (progn
        (if (type ECW_End) (ECW_End))
        (setq *error* nil)
      )
    )
    (princ)
  )
  (setq *error* ij-error)

  ;; 共通ユーティリティの有無を確認して実行(ハイブリッド設計)
  (if (type ECW_Start) (ECW_Start))

  ;; --- 1. 末尾ゼロを省略させないための一時設定 ---
  (setq *dimzin-save* (getvar "DIMZIN"))
  (setvar "DIMZIN" 0)   ; 0 = 末尾・先頭ゼロを省略しない

  ;; --- 2. 画層の準備 (新規レイヤー: kasan2) ---
  (setq layerName "kasan2")
  (if (not (tblsearch "LAYER" layerName))
    (entmake (list '(0 . "LAYER")
                   '(100 . "AcDbSymbolTableRecord")
                   '(100 . "AcDbLayerTableRecord")
                   (cons 2 layerName)
                   '(70 . 0)
                   '(62 . 5)
                   '(6 . "Continuous")))
  )

  ;; --- 3. ユーザー入力(桁数は0~8の範囲でチェック、範囲外は再入力) ---
  (setq tx0 (getreal "\n掛ける値を入力 (×): "))

  (setq tt nil)
  (while (null tt)
    (setq tt (getint "\n小数点以下の表示桁数を入力 (0~8): "))
    (if (or (null tt) (< tt 0) (> tt 8))
      (progn
        (princ "\n※0~8の範囲で入力してください。")
        (setq tt nil)
      )
    )
  )

  (princ "\n対象の文字(TEXT)を選択: ")
  (setq ssgt (ssget '((0 . "TEXT"))))

  (if (and tx0 tt ssgt)
    (progn
      (setq ssln    (sslength ssgt)
            cnt     0
            okCnt   0
            skipCnt 0
            errCnt  0)

      ;; --- 4. メイン処理 (ループ) ---
      (while (< cnt ssln)
        (setq ssna (ssname ssgt cnt)
              entg (entget ssna)
              tx1  (cdr (assoc 1 entg)))

        (if (setq txVal (distof tx1))
          (progn
            (setq xy10 (cdr (assoc 10 entg))
                  xy11 (cdr (assoc 11 entg))
                  tx11 (cdr (assoc 40 entg))
                  tx12 (cdr (assoc 50 entg)))

            ;; --- 必要なDXF値が揃っているか確認してから計算する ---
            (if (and xy10 tx11 tx12)
              (progn
                (setq txVal (* tx0 txVal))

                (setq rot90 (+ tx12 (/ pi 2.0))
                      dist  (* tx11 1.5)
                      dx    (* dist (cos rot90))
                      dy    (* dist (sin rot90)))

                (setq n-xy10 (list (+ (car xy10) dx) (+ (cadr xy10) dy) (caddr xy10)))
                (setq n-xy11 (if xy11
                               (list (+ (car xy11) dx) (+ (cadr xy11) dy) (caddr xy11))
                               n-xy10))

                ;; --- 5. 文字の生成 (entmake) ---
                ;; DIMZIN=0 の状態で rtos するため、指定桁数の末尾ゼロがそのまま表示される
                (setq entResult
                  (entmake
                    (vl-remove nil
                      (list '(0 . "TEXT")
                            (cons 1 (rtos txVal 2 tt))
                            (cons 10 n-xy10)
                            (cons 11 n-xy11)
                            (cons 40 tx11)
                            (cons 50 tx12)
                            (cons 8 layerName)
                            (assoc 7 entg)
                            (assoc 71 entg)
                            (assoc 72 entg)
                            (assoc 73 entg)
                      )
                    )
                  )
                )

                ;; --- entmakeの成否を確認 ---
                (if entResult
                  (setq okCnt (1+ okCnt))
                  (progn
                    (setq errCnt (1+ errCnt))
                    (princ (strcat "\n※エラー: '" tx1 "' の配置に失敗しました。"))
                  )
                )
              )
              (progn
                (setq errCnt (1+ errCnt))
                (princ (strcat "\n※エラー: '" tx1 "' は座標・高さ・角度の情報が不足しているためスキップしました。"))
              )
            )
          )
          (progn
            (setq skipCnt (1+ skipCnt))
            (princ (strcat "\n※警告: '" tx1 "' は数値でないためスキップしました。"))
          )
        )
        (setq cnt (1+ cnt))
      )

      ;; --- 6. 完了メッセージ(処理件数の内訳+目視確認の案内) ---
      (princ (strcat "\n完了: " (itoa okCnt) "件を乗算し画層「" layerName "」に配置しました"
                     "(数値以外のためスキップ: " (itoa skipCnt) "件"
                     (if (> errCnt 0) (strcat " / エラー: " (itoa errCnt) "件") "")
                     ")。"))
      (princ "\n配置した数値と位置を図面上でご確認ください。")
    )
    (princ "\nキャンセルされました。")
  )

  ;; --- 7. DIMZINを元の値に復元 ---
  (setvar "DIMZIN" *dimzin-save*)

  ;; 共通ユーティリティの有無を確認して実行(ハイブリッド設計)
  (if (type ECW_End) (ECW_End))
  (setq *error* nil)
  (princ)
)

📐実務で大活躍するシーン

【① 基準高さ変更時の一括修正】
「KBMの高さが変わった」「TP→OPに変更したい」といった変更があったとき、対象の高さ表記の数字を窓選択してIKを実行するだけで、修正後の数値が二段書きで配置されます。

【② 安全率・割増係数の一括適用(IJ)】
様々な計算や数量算出で「安全率1.2倍」「割増10%(×1.1)」を一括で反映したいとき、IJで対象の数値をまとめて乗算できます。

【③ 単位換算(IJ)】
mm表記の数値をm表記に変換したい(×0.001)など、単位変換が必要な場面でも活躍します。

✏️まとめ:すべてに+、すべてに×を一瞬で

「測量図のTP表示をFL基準に変える」「せっかく表を作ったのに安全率を1.2倍に変更」、こうした一括修正の指示は、実務の中で突然やってきます。

手作業でやると、数値を一つずつ確認しながら計算し、配置し直すという地味な作業になりますが、IK・IJを使えば、あなたがやることは対象を選択するだけです。計算も配置もLISPが正確にやってくれます。

気にするべきは「拾い忘れがないか」の1点だけ。急な変更指示にも、慌てず対応できるようになります。

フクロウ
フクロウ

「全部直しといて」に秒で対応できると、周りもびっくり
ただし、寸法や文字(単位や接頭語)が入っていると拾わないので注意

コメント