shujh1989 发表于 2023-10-8 21:32:10

属性块参数复制到另一个属性块

本帖最后由 shujh1989 于 2023-10-9 22:50 编辑

(defun C:CCT (/ source_obj target_obj source_attrs target_attrs num-attrs)
(vl-load-com)
(setvar "cmdecho" 0)
; 选择需要复制信息的图框
(setq source_obj (vlax-ename->vla-object (car (entsel "\n选择需要复制信息的图框"))))
; 如果选择的对象不是属性块,退出
(if (not (vlax-property-available-p source_obj 'HasAttributes))
    (progn
      (alert "选择的对象不是属性块。")
      (exit)
    )
)
; 选择需要替换信息的图框
(setq target_obj (vlax-ename->vla-object (car (entsel "\n选择需要替换信息的图框"))))
; 如果选择的对象不是属性块,退出
(if (not (vlax-property-available-p target_obj 'HasAttributes))
    (progn
      (alert "选择的对象不是属性块。")
      (exit)
    )
)
; 获取属性列表
(setq source_attrs (vlax-safearray->list (vlax-variant-value (vla-GetAttributes source_obj))))
(setq target_attrs (vlax-safearray->list (vlax-variant-value (vla-GetAttributes target_obj))))
; 检查属性数量是否匹配
(setq num-attrs (min (length source_attrs) (length target_attrs)))
(if (< num-attrs 17)
    (alert "警告: 属性数量小于17,只复制现有属性。")
)
; 遍历属性列表,从第0到第n-1个属性
(setq i 0)
(while (< i num-attrs)
    (vla-put-TextString
      (nth i target_attrs)
      (vla-get-TextString (nth i source_attrs)))
    (setq i (1+ i))
)
(setvar "cmdecho" 1)
)
写这个的原因是想把A0动态属性块图框的信息复制到其他尺寸的图框上去,应用比较局限。一开始写的代码很累赘,用ai优化了下,但是ai犯错了一直运行不了,查了很久才弄清。这个应用的局限性很大,两个属性块的属性排列顺序必须是一样的。如果考虑两个块的属性排列顺序不一样需要比较属性块的tagstring,tagstring一致的再复制信息。我没有这个应用场景,就没搞这么麻烦。程序里标的是图框,其实对属性块都可以用。我用的图框只有17个属性,数量可以改。



升级了下,现在不用考虑属性排序了,可以自动匹配标签一致的属性复制信息。

(defun C:CCT (/ source_obj target_obj source_attrs target_attrs num-attrs)
(vl-load-com)
(setvar "cmdecho" 0)

; 选择需要复制信息的图框
(setq source_obj (vlax-ename->vla-object (car (entsel "\n选择需要复制信息的图框"))))

; 检查选择的对象是否是属性块
(if (not (vlax-property-available-p source_obj 'HasAttributes))
    (progn
      (alert "选择的对象不是属性块。")
      (exit)
    )
)

; 选择需要替换信息的图框
(setq target_obj (vlax-ename->vla-object (car (entsel "\n选择需要替换信息的图框"))))

; 检查选择的对象是否是属性块
(if (not (vlax-property-available-p target_obj 'HasAttributes))
    (progn
      (alert "选择的对象不是属性块。")
      (exit)
    )
)

; 获取属性列表
(setq source_attrs (vlax-safearray->list (vlax-variant-value (vla-GetAttributes source_obj))))
(setq target_attrs (vlax-safearray->list (vlax-variant-value (vla-GetAttributes target_obj))))

; 检查属性数量是否匹配
(setq num-attrs (min (length source_attrs) (length target_attrs)))
(if (< num-attrs 17)
    (alert "警告: 属性数量小于17,只复制现有属性。")
)

; 遍历属性列表并复制属性
(setq i 0)
(while (< i num-attrs)
    (setq target_attr (nth i target_attrs))
    (setq source_attr (nth i source_attrs))
    (setq j 0)
    (while (< j num-attrs)
      (setq target_attr_2 (nth j target_attrs))
      (setq tagstring_source (vla-get-TagString source_attr))
      (setq tagstring_target (vla-get-TagString target_attr_2))
      (if (equal tagstring_source tagstring_target) ; 检查tagstring是否相同
      (vla-put-TextString target_attr_2 (vla-get-TextString source_attr)) ; 如果相同,则复制textstring到目标属性中
      )   ; 如果tagstring不同,则不执行复制操作
      (setq j (1+ j))
    )
    (setq i (1+ i))
)
(setvar "cmdecho" 1)
)


飞雪神光 发表于 2023-10-10 13:07:31

就像这样 拾取一个原图块 批量覆盖有相同属性的属性块 不考虑数据是否对等(defun c:tt(/ bj get-insert-tag&value lm-set-attribute obj ss ss-enlst sx sxlst ty)
        (defun get-insert-Tag&value (blk / lst)
                (if (= (type blk) 'ENAME)
                        (if        (safearray-value(setq        lst (vlax-variant-value(vla-getattributes (vlax-ename->vla-object blk)))))
                                (mapcar'(lambda (x)(cons (vla-get-tagstring x) (vla-get-textstring x)))(vlax-safearray->list lst))
                        )
                        nil
                )
        )
        (defun lm-set-attribute(ty biaoji va / att_list)
                (setq ty (if(=(type ty)'ename)(vlax-ename->vla-object ty)ty))
                (setq att_list (vlax-safeArray->list (vlax-variant-value (vla-getattributes ty))))
                (setq xx(vl-some'(lambda(a)(if(=(strcase(vla-get-TagString a))(strcase biaoji))a))att_list))
                (if xx
                        (vla-put-textstring xx va)
                )
                (princ)
        )
        (setq
                ty(car(entsel "\n原属性块:"))
                obj(vlax-ename->vla-object ty)
        )
        (setq sxlst(get-insert-Tag&value ty))
        (princ"\n覆盖属性块:")
        (setq ss(ssget '((0 . "insert"))))
        (foreach ty (vl-remove-if-not '(lambda (x) (= (type x) 'ENAME)) (mapcar 'cadr (ssnamex ss)))
                (foreach x sxlst
                        (setq
                                bj(car x)
                                sx(cdr x)
                        )
                        (lm-set-attribute ty bj sx)
                )
        )
        (princ)
)

llsheng_73 发表于 2023-10-10 17:31:27

飞雪神光 发表于 2023-10-10 13:07
就像这样 拾取一个原图块 批量覆盖有相同属性的属性块 不考虑数据是否对等
块参照的属性是以数组形式出现的,也就是无法使用item,因此,不宜针对一个tag在它的所有属性里边查找
(defun getatts(blk);|获取块参照图元(对象)的属性参照,返回值((属性标记 属性值 属性对象)...)以便进一步修改指定标记的属性值|;
(if(equal(VL-CATCH-ALL-APPLY(function vlax-get-property)(list(setq blk(if(=(type blk)'ename)(vlax-ename->vla-object blk)blk))'HasAttributes)):vlax-true)
    (mapcar(function(lambda(x)(list(strcase(vlax-get-property x'TagString))(vlax-get-property x'TextString)x)))
         (vlax-safearray->list(vlax-variant-value(vlax-invoke-method blk'GetAttributes))))))
(defun putatts(enblk lst / a);|enblk属性块图元或对象,lst((标记 值)(标记 值)(标记 值)...)|;
(and(setq a(getatts enblk))
      (vl-some(function(lambda(x / b)(and(setq b(assoc(strcase(car x))a))(vlax-put-property(caddr b)'TextString(cadr x)))))lst)))

飞雪神光 发表于 2024-1-10 11:30:39

lxl217114 发表于 2024-1-10 10:35
大佬,如果方便的话。
看看如图的这样可以实现么?



(defun c:tt(/ bj get-insert-tag&value lm-set-attribute obj ss ss-enlst sx sxlst ty)
        (defun get-insert-Tag&value (blk / lst)
                (if (= (type blk) 'ENAME)
                        (if (safearray-value(setq lst (vlax-variant-value(vla-getattributes (vlax-ename->vla-object blk)))))
                                (mapcar'(lambda (x)(cons (vla-get-tagstring x) (vla-get-textstring x)))(vlax-safearray->list lst))
                        )
                        nil
                )
        )
        (defun lm-set-attribute(ty biaoji va / att_list)
                (setq ty (if(=(type ty)'ename)(vlax-ename->vla-object ty)ty))
                (setq att_list (vlax-safeArray->list (vlax-variant-value (vla-getattributes ty))))
                (setq xx(vl-some'(lambda(a)(if(=(strcase(vla-get-TagString a))(strcase biaoji))a))att_list))
                (if xx
                        (vla-put-textstring xx va)
                )
                (princ)
        )
        (defun ss-enlst (ss / enlst)
                (cond
                        ((= (type ss) 'PICKSET)
                                (vl-remove-if-not '(lambda (x) (= (type x) 'ENAME)) (mapcar 'cadr (ssnamex SS)))
                        )
                        ((= (type ss) 'LIST)
                                (setq enlst (ssadd))
                                (last (mapcar '(lambda (x) (ssadd x enlst)) ss))
                        )
                )
        )
        (defun lm-Get-LwPts(en / x)
                (mapcar
                        'cdr
                        (vl-remove-if-not
                                '(lambda(x)
                                       (= (car x) 10)
                               )
                                (entget en)
                        )
                )
        )
        (setq ss(ssget '((0 . "LWPOLYLINE")(8 . "jm-创建块图框"))))
        (foreach ty (ss-enlst ss)
                (setq pts (lm-Get-LwPts ty))
                (setq yss(ssget "cp" pts '((0 . "INSERT")(8 . "图签")(2 . "原始图签"))))
                (if (and yss (> (sslength yss) 0))
                        (progn
                                (setq
                                        ty (ssname yss 0)
                                        obj(vlax-ename->vla-object ty)
                                        sxlst (get-insert-Tag&value ty)
                                )
                                (entdel ty)
                                (setq xss(ssget "cp" pts '((0 . "INSERT")(2 . "新图签"))))
                                (foreach ty (vl-remove-if-not '(lambda (x) (= (type x) 'ENAME)) (mapcar 'cadr (ssnamex xss)))
                                        (foreach x sxlst
                                                (setq
                                                        bj(car x)
                                                        sx(cdr x)
                                                )
                                                (lm-set-attribute ty bj sx)
                                        )
                                )
                        )
                )
        )
        (princ)
)

飞雪神光 发表于 2023-10-8 23:04:02

直接用原有的去覆盖就行了 有对应属性则覆盖 没有的他自己就跳过了看代码是操作反了 用被替换的图框去查找原图框属性

shujh1989 发表于 2023-10-8 23:23:45

飞雪神光 发表于 2023-10-8 23:04
直接用原有的去覆盖就行了 有对应属性则覆盖 没有的他自己就跳过了看代码是操作反了 用被替换的图框去查 ...

这个程序是完整的,功能可以实现啊,没有反。ai错的地方是少了一个函数,我的原始程序是只拷三个属性,没有用循环。

xiaocainiao 发表于 2023-10-9 08:10:53

(not (vlax-property-available-p source_obj 'HasAttributes))这个代码好像不能判断是不是属性块吧、我试了一下普通块也不提示

shujh1989 发表于 2023-10-9 09:30:38

xiaocainiao 发表于 2023-10-9 08:10
(not (vlax-property-available-p source_obj 'HasAttributes))这个代码好像不能判断是不是属性块吧、我试 ...

不是判断块的,是判断其他类型对象的,比如选中文字线之类的会提示,有点多余。

xiaocainiao 发表于 2023-10-9 10:15:18

shujh1989 发表于 2023-10-9 09:30
不是判断块的,是判断其他类型对象的,比如选中文字线之类的会提示,有点多余。

好吧、我看注释以为是判断属性块的、特意试了一下

飞雪神光 发表于 2023-10-9 12:18:13

shujh1989 发表于 2023-10-8 23:23
这个程序是完整的,功能可以实现啊,没有反。ai错的地方是少了一个函数,我的原始程序是只拷三个属性,没 ...

我的意思是 如果没反的话 两个属性块的属性排列不必是一样的 数量也可以是不对等的

cghdy 发表于 2023-10-9 13:45:39

论坛有批量改属性的,批量改属性都是先获取再移植到别的属性块。

shujh1989 发表于 2023-10-9 17:45:50

飞雪神光 发表于 2023-10-9 12:18
我的意思是 如果没反的话 两个属性块的属性排列不必是一样的 数量也可以是不对等的

是可以的。那要把第一个块的属性跟第二个块的每一个属性比较,标签一致的再替换,不一致的跳过。然后去掉替换过的再做成列表,再挨个比较。好复杂,不适合我这个初学者,搞不来。

wharan 发表于 2023-10-9 19:30:26

本帖最后由 wharan 于 2023-10-9 19:34 编辑

我是这么做的:选定样板图框(图标)的共用属性,如:工程名称、项目编号、阶段、版本号、日期等,然后循环,把每个图框(图标)的共用属性修改,保留局部特性,如图名、图号等。
页: [1] 2 3 4
查看完整版本: 属性块参数复制到另一个属性块