CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 403|回复: 1

自己写了一个自动编号的小程序错误: 参数类型错误: numberp...

[复制链接]

1

主题

2

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2024-12-8 03:01:18 | 显示全部楼层 |阅读模式
自己写了一个给图框自动编号的小程序,但是一直提示这个错误错误: 参数类型错误: numberp: nil,改了好几次了也不行,但是我另一个小程序是通过修改原有编号在进行自动编号的就不会报错,麻烦大神帮忙看看咋回事
(defun cSB (/ prefix startNumber frames frames-list frame center row-count col-count i number-sequence number-text text-position totalFrames totalColumns pageCount obj blkRef)
  ;; 获取图号前缀
  (setq prefix (getstring "\n请输入图号前缀(可以包含特殊符号和任意字符): "))

  ;; 获取起始编号(文本类型)
  (setq startNumber (getstring "\n请输入起始编号(如:001):"))

  ;; 检查输入是否为空
  (if (or (not startNumber) (= (strlen startNumber) 0))
    (progn
      (princ "\n起始编号不能为空,操作已取消!")
      (exit)
    )
  )

  ;; 输出调试:查看获取的起始编号
  (princ (strcat "\n成功获取起始编号: " startNumber))

  ;; 获取所有图框(包括LWPOLYLINE和块参照)
  (setq frames (ssget '((0 . "LWPOLYLINE,INSERT")))) ;; 选择所有多段线和块参照
  (if (not frames)
    (progn
      (princ "\n未找到图框!")
      (exit)
    )
  )

  ;; 将选择集转换为列表,提取所有图框并按位置排序
  (setq frames-list '())
  (setq i 0)
  (setq frames-count (sslength frames))

  ;; 遍历选择集
  (while (< i frames-count)
    (setq frame (ssname frames i))
    (setq obj (vlax-ename->vla-object frame))

    ;; 如果是块参照,获取其边界框
    (if (= (vla-get-objectname obj) "AcDbBlockReference")
      (progn
        ;; 获取块参照的边界框
        (setq blkRef obj)
        (setq ext (vlax-invoke blkRef 'GetBoundingBox (setq min (list)) (setq max (list))))
        (setq center (list (/ (+ (car min) (car max)) 2) (/ (+ (cadr min) (cadr max)) 2)))
      )
    )
    ;; 如果是多段线,获取其边界框
    (if (= (vla-get-objectname obj) "AcDbPolyline")
      (progn
        (setq ext (vlax-invoke-method obj 'GetBoundingBox (setq min (list)) (setq max (list))))
        (setq center (list (/ (+ (car min) (car max)) 2) (/ (+ (cadr min) (cadr max)) 2)))
      )
    )

    ;; 将图框及其中心添加到列表中
    (setq frames-list (cons (list frame center) frames-list))
    (setq i (1+ i))
  )

  ;; 按 Y 坐标排序图框,纵向图框
  (setq frames-list (vl-sort frames-list '(lambda (a b) (< (cadr (cadr a)) (cadr (cadr b))))))

  ;; 获取图框排列的行列数
  (setq row-count (length frames-list))
  (setq col-count (length (car frames-list)))

  ;; 获取横向图框数量
  (setq totalColumns col-count)

  ;; 获取页数总数
  (setq pageCount (length frames-list))

  ;; 遍历所有图框并为每个图框生成编号
  (setq i 0)
  (foreach frame frames-list
    (setq frame-center (cadr frame))

    ;; 纵向编号,横向页码递增
    (setq row-index (1+ (mod i row-count)))  ;; 纵向编号
    (setq page-index (1+ (mod i totalColumns))) ;; 横向页码

    ;; 生成编号:图号-编号-(页码)
    (setq number-text (strcat prefix startNumber "-" (itoa row-index) "-" "(" (itoa page-index) "/" (itoa totalColumns) ")"))

    ;; 设置文本位置(可以调整偏移量)
    (setq text-position (mapcar '+ frame-center (list 0 0)))

    ;; 创建文本对象
    (entmake
      (list
        (cons 0 "TEXT")
        (cons 10 text-position)   ; 设置文本位置
        (cons 40 2.5)             ; 设置文本高度
        (cons 1 number-text)      ; 插入的文本
        (cons 7 "Standard")       ; 字体样式
        (cons 8 "0")              ; 图层
      )
    )

    ;; 更新编号(仅更新纵向编号)
    (setq startNumber (itoa (+ (atoi startNumber) 1))) ;; 递增编号(保持为三位数格式)
    (setq i (1+ i))
  )

  (princ "\n图框自动编号完成!")
  (princ)
)

(princ "\n输入 'DSB' 运行程序。")
(princ)


回复

使用道具 举报

1

主题

2

帖子

7

积分

新手上路

Rank: 1

积分
7
 楼主| 发表于 2024-12-8 03:34:20 | 显示全部楼层
现在问题解决了,但是不生成任何文字 却提示编号完成,咋回事
(defun cSB (/ prefix startNumber frames frames-list frame center row-count col-count i number-sequence number-text text-position outer-frames base-point)
  ;; 获取图号前缀
  (setq prefix (getstring "\n请输入图号前缀(可以包含特殊符号和任意字符): "))
  
  ;; 获取起始编号(文本类型)
  (setq startNumber (getstring "\n请输入起始编号(如:001):"))

  ;; 检查输入是否为空
  (if (or (not startNumber) (= (strlen startNumber) 0))
    (progn
      (princ "\n起始编号不能为空,操作已取消!")
      (exit)
    )
  )

  ;; 输出调试:查看获取的起始编号
  (princ (strcat "\n成功获取起始编号: " startNumber))

  ;; 获取所有图框(包括LWPOLYLINE和INSERT块参照),允许选择包括所有类型对象
  (setq frames (ssget '((0 . "LWPOLYLINE,INSERT")))) ;; 选择所有多段线和块参照
  (if (not frames)
    (progn
      (princ "\n未找到图框!")
      (exit)
    )
  )

  ;; 将选择集转换为列表,提取所有图框并按位置排序
  (setq frames-list '())
  (setq outer-frames '()) ;; 用来存储最外层图框
  (setq i 0)
  (setq frames-count (sslength frames))
  
  ;; 遍历选择集
  (while (< i frames-count)
    (setq frame (ssname frames i))
    (setq obj (vlax-ename->vla-object frame))
   
    ;; 获取块参照或多段线的边界框
    (if (= (vla-get-objectname obj) "AcDbBlockReference")
      (progn
        ;; 获取块参照的边界框
        (setq blkRef obj)
        (setq ext (vlax-invoke blkRef 'GetBoundingBox (setq min (list)) (setq max (list))))
        (if ext
          (setq center (list (/ (+ (car min) (car max)) 2) (/ (+ (cadr min) (cadr max)) 2)))
        )
      )
    )
    ;; 如果是多段线,获取其边界框
    (if (= (vla-get-objectname obj) "AcDbPolyline")
      (progn
        (setq ext (vlax-invoke-method obj 'GetBoundingBox (setq min (list)) (setq max (list))))
        (if ext
          (setq center (list (/ (+ (car min) (car max)) 2) (/ (+ (cadr min) (cadr max)) 2)))
        )
      )
    )
   
    ;; 如果中心点存在,则将图框及其中心添加到列表中
    (if center
      (setq frames-list (cons (list frame center min max) frames-list))
    )
   
    (setq i (1+ i))
  )

  ;; 输出调试信息:查看所有图框的中心点
  (princ "\n图框中心点:")
  (foreach frame frames-list
    (princ (strcat "\n图框中心点: " (rtos (car (cadr frame)) 2 2) ", " (rtos (cadr (cadr frame)) 2 2)))
  )

  ;; 找出最外层图框
  (foreach frame frames-list
    (setq outer t)
    (foreach inner-frame frames-list
      (if (and (not (= frame inner-frame))
               (< (car (cadr frame)) (car (cadr inner-frame)))
               (> (car (cadr frame)) (car (cadr inner-frame)))
               (< (cadr (cadr frame)) (cadr (cadr inner-frame)))
               (> (cadr (cadr frame)) (cadr (cadr inner-frame)))
          )
        (setq outer nil)
      )
    )
    (if outer
      (setq outer-frames (cons frame outer-frames))
    )
  )

  ;; 输出最外层图框
  (princ "\n最外层图框:")
  (foreach frame outer-frames
    (princ (strcat "\n图框: " (itoa (car frame))))
  )

  ;; 获取用户选择的第一个图框位置作为基准点
  (setq base-point (getpoint "\n请选择第一个图框的位置:"))

  ;; 输出用户选择的基准点
  (princ (strcat "\n选择的基准点: " (rtos (car base-point) 2 2) ", " (rtos (cadr base-point) 2 2)))

  ;; 按 Y 坐标排序图框,纵向图框
  (setq frames-list (vl-sort outer-frames '(lambda (a b) (< (cadr (cadr a)) (cadr (cadr b))))))

  ;; 获取图框排列的行列数
  (setq row-count (length frames-list))
  (setq col-count (length (car frames-list)))

  ;; 获取横向图框数量
  (setq totalColumns col-count)

  ;; 获取页数总数
  (setq pageCount (length frames-list))

  ;; 遍历所有图框并为每个图框生成编号
  (setq i 0)
  (foreach frame outer-frames
    (setq frame-center (cadr frame))

    ;; 纵向编号,横向页码递增
    (setq row-index (1+ (mod i row-count)))  ;; 纵向编号
    (setq page-index (1+ (mod i totalColumns))) ;; 横向页码

    ;; 计算文本位置(基于用户选择的第一个图框位置)
    (setq text-position (list (+ (car base-point) (* page-index 10))  ; 横向偏移增加
                              (+ (cadr base-point) (* row-index 10)))) ; 纵向偏移增加

    ;; 生成编号:图号-编号-(页码)
    (setq number-text (strcat prefix startNumber "-" (itoa row-index) "-" "(" (itoa page-index) "/" (itoa totalColumns) ")"))

    ;; 输出调试信息:查看生成的文本位置和内容
    (princ (strcat "\n插入文本位置: " (rtos (car text-position) 2 2) ", " (rtos (cadr text-position) 2 2)))
    (princ (strcat "\n生成的文本: " number-text))

    ;; 创建文本对象
    (entmake
      (list
        (cons 0 "TEXT")
        (cons 10 text-position)   ; 设置文本位置
        (cons 40 5)               ; 增加文本高度
        (cons 1 number-text)      ; 插入的文本
        (cons 7 "Standard")       ; 字体样式
        (cons 8 "0")              ; 图层
      )
    )

    ;; 更新编号(仅更新纵向编号)
    (setq startNumber (itoa (+ (atoi startNumber) 1))) ;; 递增编号(保持为三位数格式)
    (setq i (1+ i))
  )

  (princ "\n图框自动编号完成!")
  (princ)
)

(princ "\n输入 'DSB' 运行程序。")
(princ)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1   苏公网安备32011402011833)

GMT+8, 2025-1-18 19:11

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表