明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1049|回复: 15

[基础] 我写的蹩脚的程序!

[复制链接]
发表于 2023-9-1 14:42 | 显示全部楼层 |阅读模式
我写了个提取cad中的文字、坐标、图层、颜色的程序,太不理想了(非常蹩脚),有大哥能给改下改成用vla对象写的么?
  1. (defun c:Q2(/ ff ffn i ss ssdata ssn sstyp sx sy sz txt txtxy)
  2.    (setvar "cmdecho" 0) ;;关闭变量
  3. (setvar "blipmode" 0);;关闭控制点
  4. (vl-load-com)        ;;加载vlax扩展函数
  5.   
  6.   
  7.   
  8.   ;(setq ffn (getfiled "写出文件" "C:/Users/Administrator/Desktop/" "csv" 1))  ;弹对话框提示设置保存路径及名称
  9.   (princ "\n选取文字:")                                                      ;提示选取文字
  10.   (setq ff (open "C://Users//Administrator//Desktop//文字.xls"  "w"))   ;建立文本;W会把文本里面的内容清除         
  11.   (setq i 0 ss '())                                                                  ;设置i初始值
  12.   (if (setq ss (ssget '((0 . "*TEXT"))))                                      ;星号通配符,TEXT或者MTEXT都可以。
  13.     (repeat (sslength ss)                                                       ;对循环体中的表达式求SS图元个数值
  14.       (setq ssn (ssname ss i))                                                    ;返回SS集中第i个图元名称
  15.       (setq ssdata (entget ssn))                                                  ;返回图元的数据集
  16.       (setq txt (cdr (assoc 1 ssdata)))                                           ;取文本数值
  17.       (setq txtxy (cdr (assoc 10 ssdata)))                                         ;取文本坐标
  18.       (setq sx (rtos (nth 1 txtxy) 2 3))                                              ;将X坐标值实数转换成字符(目前没单独提取)
  19.       (setq sy (rtos (nth 0 txtxy) 2 3))                                              ;将y坐标值实数转换成字符(目前没单独提取)
  20.       (setq sz (rtos (nth 2 txtxy) 2 3))                                              ;将z坐标值实数转换成字符(目前没单独提取)
  21.       (setq tc (cdr (assoc 8 ssdata)))
  22.       (progn
  23.        (or
  24.         (setq col(cdr(assoc 62 ssdata)))
  25.         (setq col(cdr(assoc 62(tblsearch "layer" tc))))                        ;随层颜色提取方式
  26.        )
  27.           col
  28.       )
  29.       
  30.       (princ txt ff)
  31.       (princ "\t" ff);这个格式就是在同一行下一个内容
  32.       (princ txtxy ff)
  33.       (princ "\t" ff);这个格式就是在同一行下一个内容
  34.       (princ tc ff)
  35.       (princ "\t" ff);这个格式就是在同一行下一个内容
  36.       (princ col ff)
  37.       (princ "\t" ff);这个格式就是在同一行下一个内容
  38.       (princ sx ff)
  39.       (princ "\t" ff);这个格式就是在同一行下一个内容
  40.       (princ sy ff)
  41.       (princ "\t" ff);这个格式就是在同一行下一个内容
  42.       (princ sz ff)
  43.       (princ "\t" ff);这个格式就是在同一行下一个内容
  44.       (princ "\n" ff);这个格式就换行
  45.       ;write-line不用换行,princ要用/n换行,princ要用/t下一列,(在同一行下一个内容)
  46.       (setq i (1+ i))
  47.     )
  48.   )
  49.      (close ff)                           ;关闭ff文件
  50.   ;(princ (strcat "\n写出文件 " ffn))   ;提示提取文字完成
  51.      (princ)                              ;让提示行只显示一行
  52. )
CAD带文字的文件我就不传了,随便在CAD中新建几个文字提取试试就行。先谢谢大神了哈,我这是在研究CAD跟excel的转换问题,没整明白。
发表于 2023-9-1 17:28 | 显示全部楼层
;;;;声明,下面的这些子函数我只是在原有基础修改,并非原创,请记住是这个人写的:落魄山人
(Defun Excel:WorkBooks-Add (ExcelApp FileName ishide / ExcelApp)
        ;;;示例(Excel:WorkBooks-Add ExcelApp "e:\\test.xlsx" t)
  ;(if (setq ExcelApp (vlax-get-or-create-object "Excel.Application"))
    (progn
      (setq newBooks(vlax-invoke
                                (vlax-get-property ExcelApp 'WorkBooks)
                                'Add
      ))
                        (if FileName (vlax-invoke newBooks "SaveAs" Filename));;;这里不能使用vlax-invoke-method
                 
      (if ishide
                                (vla-put-visible ExcelApp 1)
                                (vla-put-visible ExcelApp 0)
      )
    )
  ;)
  newBooks
)

(Defun Excel:Range:Value-Put (ExcelApp index value / range)
  (setq range (Excel:Range-Get ExcelApp SheetSpecify index))
  (if (= 'list (type value))
    (progn
                        (setq value$ (if (= 'list (type (car value))) (apply 'append value) value))
      (vlax-for        it range;;;对range对象,从左往右,再从上往下遍历,如"H10:I11",先后顺序为H10 H11  I10 I11
                                (PutP it 'value2 (car value$))
                                (setq value$ (cdr value$))
      )
    )
    (progn
      (vlax-for        it range
                                (PutP it 'value2 value)
      )
    )
  )
)

(defun Excel:Range-Get (ExcelApp SheetSpecify indexRange)
       
  (vlax-get-property
    (if SheetSpecify SheetSpecify(GetP ExcelApp "ActiveWorkbook.ActiveSheet"))
    'range
    (Excel:Index2A1 indexRange)
  )
)


(defun Excel:Index2A1 (lst / num->col)
;;;(Excel:Index2A1 '(1 2 3 4))->"B1:D3" (Excel:Index2A1 '(1 2 ))->"B1"
       
        ;;说明:把数字转换为字母,转换规律为如1-26转换为字母A-Z,相当于十进制转换为27进制,不是26,隐藏了一个0
        ;;参数:n:数字,不限范围
        ;;返回:字符串,字母A-Z-ZZZZ......
  (defun num->col (n)                        ;数字转为列,leemac
    (if        (< n 27)
      (chr (+ 64 n))
      (strcat
                                (num->col (/ (1- n) 26))
                                (num->col (1+ (rem (1- n) 26)))
      )
    )
  )
  (if (= 'list (type lst))
    (cond
      ((= 2 (length lst))
                                (strcat (num->col (cadr lst)) (itoa (car lst)))
      )
      ((= 4 (length lst))
                                (strcat (num->col (cadr lst))
                                        (itoa (car lst))
                                        ":"
                                        (num->col (last lst))
                                        (itoa (caddr lst))
                                )
      )
      (t
                                "A1"
      )
    )
    lst
  )
)

(defun GetP (obj prop / Rtn Rtn2)
  (cond        ((= (type prop) 'sym)
                                                                 (if(vl-catch-all-error-p(setq Rtn2(vl-catch-all-apply 'vlax-get-property (list obj prop) )))
                                                                         (princ(strcat"\n不具备属性:" (vl-prin1-to-string(eval(quote prop))))) (setq Rtn Rtn2) )
                                                                 
                                                         )
    ((= (type prop) 'str)
                        (if (null (vl-string-search "." prop))
                                (if(vl-catch-all-error-p(setq Rtn2(vl-catch-all-apply 'vlax-get-property (list obj prop) )))
                                                                         (princ(strcat"\n不具备属性:" prop)) (setq Rtn Rtn2) )
                               
                               
                                (foreach item (Str:Split prop ".")
                                        (if (null Rtn)
                                                (if(vl-catch-all-error-p(setq Rtn2(vl-catch-all-apply 'vlax-get-property (list obj item) )))
                                                        (princ(strcat"\n不具备属性:" item))(setq Rtn Rtn2) )
                                               
                                                (if(vl-catch-all-error-p(setq Rtn2(vl-catch-all-apply 'vlax-get-property (list Rtn item) )))
                                                        (princ(strcat"\n不具备属性:" item))(setq Rtn Rtn2) )
                                               
                                               
                                               
                                        )
                                )
                        )
    )
  )

  (Excel-Utils-GetValue Rtn)
)


(defun PutP (obj prop value / Rtn Rtn2)
  (cond        ((= (type prop) 'sym)
                                                                 (if(vl-catch-all-error-p(setq Rtn2(vl-catch-all-apply 'vlax-put-property (list obj prop value) )))
                                                                         (princ(strcat"\n不可更改属性:" (vl-prin1-to-string(eval(quote prop))))) (setq Rtn Rtn2) )
                                                                 
                                                         )
    ((= (type prop) 'str)
                        (if (null (vl-string-search "." prop))
                                (if(vl-catch-all-error-p(setq Rtn2(vl-catch-all-apply 'vlax-put-property (list obj prop value) )))
                                                                         (princ(strcat"\n不可更改属性:" prop)) (setq Rtn Rtn2) )
                               
                               
                                (progn
                                        (setq items (Str:Split prop "."))
                                        (foreach item (reverse(cdr(reverse items)))
                                        (if (null Rtn)
                                                (if(vl-catch-all-error-p(setq Rtn2(vl-catch-all-apply 'vlax-get-property (list obj item) )))
                                                        (princ(strcat"\n不具备属性:" item))(setq Rtn Rtn2) )
                                               
                                                (if(vl-catch-all-error-p(setq Rtn2(vl-catch-all-apply 'vlax-get-property (list Rtn item) )))
                                                        (princ(strcat"\n不具备属性:" item))(setq Rtn Rtn2) )
                                               
                                               
                                               
                                        )
                                )
                                        (if(vl-catch-all-error-p(setq Rtn2(vl-catch-all-apply 'vlax-put-property (list Rtn (last items) value) )))
                                                        (princ(strcat"\n不可更改属性:" item)) )
                                )
                        )
    )
  )

  
)

(defun Str:Split (str del / pos)
        (if (setq pos (vl-string-search del str))
                (cons (substr str 1 pos)
                        (Str:Split (substr str (+ pos 1 (strlen del))) del)
                )
                (list str)
        )
)


(defun Excel-Utils-GetValue (var)
  (cond
    ((= 'list (type var))
                        (mapcar 'Excel-Utils-GetValue var)
    )
    ((= 'variant (type var))
                        (Excel-Utils-GetValue
                                (vlax-variant-value
                                        (if (member (vlax-variant-type Var) '(5 4 3 2));;;如果变体类型是双精度 单精度 长整型 整型
                                                (setq Var (vlax-variant-change-type Var vlax-vbString));;;变体类型转换为字符串
                                                var
                                        )
                                )
                        )
    )
    ((= 'safearray (type var))
                        (mapcar 'Excel-Utils-GetValue (vlax-safearray->list var))
    )
    (T var)
  )
)
 楼主| 发表于 2023-9-1 16:35 | 显示全部楼层
花开富贵 发表于 2023-9-1 15:45
这个写的不挺好吗,是不是觉得不简洁,多练练就好了

大神建议我不用open新建excel我用的vla对象新建的excel,然后就不会写了,下边是我想写的格式,就是想新建一个看不见的excel然后把数据写进去,然后另存一个名字,或者保存,然后关闭。中间获取数据的还是那些,但是就是不好使,不知道为啥。
  1. ;;;说明:新建Excel工作簿
  2. (Defun BF-Excel-New (ishide / Rtn)
  3.         (if (setq Rtn (vlax-get-or-create-object "Excel.Application"))
  4.     (progn
  5.       (vlax-invoke
  6.                                 (vlax-get-property Rtn 'WorkBooks)
  7.                                 'Add
  8.       )
  9.       (if ishide
  10.                                 (vla-put-visible Rtn 1)
  11.                                 (vla-put-visible Rtn 0)
  12.       )
  13.     )
  14.   )
  15.   Rtn
  16. )

  17. ;;;另存为excel文件
  18. (Defun BF-Excel-SaveAs (XLApp Filename)
  19.   (vlax-invoke
  20.     (vlax-get-property XLApp "ActiveWorkbook")
  21.     "SaveAs"
  22.     Filename
  23.   )
  24. )
  25. ;;:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  26. (defun XJB()
  27.         (vl-load-com)
  28. (setq ff (BF-Excel-New nil))                                                                  ;新建excel文件
  29.        
  30.         (setq i 0 ss '())                                                                  ;设置i初始值
  31.         (if (setq ss (ssget '((0 . "*TEXT"))))                                             ;星号通配符,TEXT或者MTEXT都可以。
  32.                 (repeat (sslength ss)                                                            ;对循环体中的表达式求SS图元个数值
  33.                         (setq ssn (ssname ss i))                                                       ;返回SS集中第i个图元名称
  34.                         (setq ssdata (entget ssn))                                                     ;返回图元的数据集
  35.                         (setq txt (cdr (assoc 1 ssdata)))                                              ;取文本数值
  36.                         (setq txtxy (cdr (assoc 10 ssdata)))                                                  ;取文本坐标
  37.                         (setq sx (rtos (nth 1 txtxy) 2 3))                                             ;将X坐标值实数转换成字符(目前没单独提取)
  38.                         (setq sy (rtos (nth 0 txtxy) 2 3))                                             ;将y坐标值实数转换成字符(目前没单独提取)
  39.                         (setq sz (rtos (nth 2 txtxy) 2 3))                                             ;将z坐标值实数转换成字符(目前没单独提取)
  40.                         (setq tc (cdr (assoc 8 ssdata)))
  41.                         (progn
  42.        (or
  43.         (setq col(cdr(assoc 62 ssdata)))
  44.         (setq col(cdr(assoc 62(tblsearch "layer" tc))))                        ;随层颜色提取方式
  45.        )
  46.           col
  47.       )
  48.                        
  49.                         (princ txt ff)
  50.       (princ "\t" ff);这个格式就是在同一行下一个内容
  51.                         (princ txtxy ff)
  52.       (princ "\t" ff);这个格式就是在同一行下一个内容
  53.                         (princ tc ff)
  54.       (princ "\t" ff);这个格式就是在同一行下一个内容
  55.                         (princ col ff)
  56.       (princ "\t" ff);这个格式就是在同一行下一个内容
  57.                         (princ "\n" ff);这个格式就换行
  58.                         ;write-line不用换行,princ要用/n换行,princ要用/t下一列,(在同一行下一个内容)
  59.                         (setq i (1+ i))
  60.           )
  61.   )
  62.           
  63. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;       

  64.         (BF-Excel-SaveAs ff "C:\\Users\\administrator\\Desktop\\2.xlsx") ;另存excel文件并重命名为2
  65.          (close ff)                                                                 ;关闭excel
  66.         (princ)
  67. )
发表于 2023-9-1 17:21 | 显示全部楼层
;;说明:我写了个提取cad中的文字、坐标、图层、颜色的程序,太不理想了(非常蹩脚)
(defun c:Q2(/ enames ff ss)
        (setvar "cmdecho" 0) ;;关闭变量
        (setvar "blipmode" 0);;关闭控制点
        (vl-load-com)        ;;加载vlax扩展函数
  (setq excelapp(cond((vlax-get-or-create-object "excel.application")) ((vlax-get-or-create-object "ket.application"))))
        (setq ss (ssget '((0 . "*TEXT"))))
        (setq rowRela(sslength ss))
        (setq enames (reverse(mapcar 'cadr (vl-remove-if-not '(lambda(x) (>= (car x) 0) )(ssnamex ss)))))       
        (Excel:WorkBooks-Add excelapp nil t)       
        (Excel:Range:Value-Put excelapp '(1 1 1 6) '("文字"        "x坐标""y坐标""z坐标"        "图层"        "颜色"))
        (Excel:Range:Value-Put excelapp (list 2 1 (+ 2 rowRela) 6)                
                (mapcar
                        '(lambda(x)
                                 (setq ent$(entget x)
                                         coor (cdr(assoc 10 ent$))
                                 )
                                 (list
                                         (cdr(assoc 1 ent$))
                                         (car coor)
                                         (cadr coor)
                                         (last coor)
                                         (cdr(assoc 8 ent$))
                                         (cdr(assoc 62 ent$)))
                                 
                         )
                        enames)
        )
        (princ"\n**********完成**********")
        (princ)                              
)





发表于 2023-9-1 15:40 来自手机 | 显示全部楼层
自己知道怎么用的,达到目的就行,有空逛论坛看看例程例句,碎片化吸收学的快一些
发表于 2023-9-1 15:42 | 显示全部楼层
(defun c:Q2(/ enames ff ss)
   (setvar "cmdecho" 0) ;;关闭变量
(setvar "blipmode" 0);;关闭控制点
(vl-load-com)        ;;加载vlax扩展函数
  
  
  
  ;(setq ffn (getfiled "写出文件" "C:/Users/Administrator/Desktop/" "csv" 1))  ;弹对话框提示设置保存路径及名称
  (princ "\n选取文字:")                                                      ;提示选取文字
  (setq ff (open "C://Users//Administrator//Desktop//文字.xls"  "w"))   ;建立文本;W会把文本里面的内容清除         
        (setq ss (ssget '((0 . "*TEXT"))))
        (setq enames (reverse(mapcar 'cadr (vl-remove-if-not '(lambda(x) (>= (car x) 0) )(ssnamex ss)))))
        (princ "文字        坐标        图层        颜色\n"ff)
        (mapcar
                '(lambda(x)
                         (setq ent$(entget x))
                         (princ (cdr(assoc 1 ent$)) ff)
                         (princ"\t" ff)
                         
                         (princ (cdr(assoc 10 ent$)) ff)
                         (princ"\t" ff)
                         
                         
                         (princ (cdr(assoc 8 ent$)) ff)
                         (princ"\t" ff)
                         
                         (princ (cdr(assoc 62 ent$)) ff)
                         (princ"\n" ff)
                         
                 )
                enames)
  
     (close ff)                           ;

     (princ)                              
)

评分

参与人数 1明经币 +1 收起 理由
USER2128 + 1 赞一个!

查看全部评分

发表于 2023-9-1 15:42 | 显示全部楼层
楼上大神有宝物
可以搜搜
发表于 2023-9-1 15:45 | 显示全部楼层
这个写的不挺好吗,是不是觉得不简洁,多练练就好了
发表于 2023-9-1 17:15 | 显示全部楼层
可以分开写,一个程序是提取文本的数据为一列表,另一个程序是将列表输出到Excel中,这样程序的通用性会强一些.
建议你先熟悉一下ACAD的对象模型和Excel的对象模型
发表于 2023-9-1 17:31 | 显示全部楼层
不会做gif,凑活预览吧

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

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

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-2 08:09 , Processed in 0.290235 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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