fabiospark 发表于 2022-7-5 22:29:25

全局替换每个值o

大家好,我想在每个具有属性的块中用类似“Att\u 11”的标记替换属性的值。要替换的当前值在任何块中都可能不同。我尝试了(command-attedit“n”“n”“*”“Att_11”“*”)。但当它要求更改值时,它不接受通配符:有没有其他方法来告诉函数,我想替换存储在该属性中的每个当前值,即使我不知道哪些值是当前值?感谢您的时间和关注。fabio

Tharwat 发表于 2022-7-5 22:39:42

欢迎来到CADTutor。
 
您是否根据属性的标记名更改了属性值?如果是,标记名字符串是什么?

BIGAL 发表于 2022-7-5 22:45:58

下面是更改块中每个属性的示例。在这种情况下,块是布局中的标题栏,但无论在dwg中的何处,都会找到每个块。
 

; changes to project number
(vl-load-com)
(setq oldtag1 "your block tag name") ;attribute tag name in capitals
(setq newstr1 (getstring "\nEnter project code"))
(setq ss1 (ssget "x"'((0 . "INSERT") (2 . "yourblockname"))))
(setq inc (sslength ss1))
(repeat inc      
(foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS1 (setq inc (1- inc)) )) 'getattributes)
(if (= oldtag1 (strcase (vla-get-tagstring att)))
(vla-put-textstring att newstr1)
) ; end if
) ; end for
) ;end repeat
(setq ss1 nil)
(princ)

Emmanuel Delay 发表于 2022-7-5 22:48:01

这就是你需要的。
 
命令:RB(如在读取块中);可以随意重命名底部函数
在该函数中,您可以设置模式(现在是“*”)新的价值观(现在是“你好,世界!”)
(当我将模式设置为带小大写字母的“*”,这给我带来了问题;
使用大写字母,它可以工作(对于我的dwg)
 
(顺便说一句,标签应该是大写字母,最好没有特殊字符,除了“_”,但那只是我,我在这类事情上有点过时了)
 
如果它不完全符合你的期望,请告诉我。
 
现在,星号需要在在中间的某个地方。它需要前面有东西,后面有东西。(我应该解决这个问题)
 

;; @file: Kind of a QSELECT, where we select blocks with attributes with a certain pattern with wildcard
;; @author: Emmanuel Delay - emmanueldelay@gmail.com - september 2014
;; - First thing, we want a system for wild cards.The pattern is ""*"", where the * is the wildcard.
;; so we want to find values like ""Att_11""
;; - We want to find all blocks in the dwg with an attribute where the tag has such a pattern.
;; - We give all those attributes a new value

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Read blocks with attributes, pass through wildcard, set value to attributes
(defun readBlocks (pattern newValue / blocks block i)
(setq
   i 0
   blocks (ssget "x"'((0 . "INSERT")(66 . 1)) )
)
(repeat (sslength blocks)
   (setq block (vlax-ename->vla-object (ssname blocks i)))
   (foreach att (vlax-invokeblock 'GetAttributes)
   (setq tag (vla-get-tagstring att))
   (if (wildcard pattern tag)
       (LM:vl-setattributevalue block tag newValue)
   )
   )
   (setq i (+ i 1))
)
)

;; Set Attribute Value-Lee Mac
;; Sets the value of the first attribute with the given tag found within the block, if present.
;; blk - VLA Block Reference Object
;; tag - Attribute TagString
;; val - Attribute Value
;; Returns: Attribute value if successful, else nil.
;; @see http://www.lee-mac.com/attributefunctions.html#vlgetattributevalue
(defun LM:vl-setattributevalue ( blk tag val )
   (setq tag (strcase tag))
   (vl-some
      '(lambda ( att )
         (if (= tag (strcase (vla-get-tagstring att)))
               (progn (vla-put-textstring att val) val)
         )
       )
       (vlax-invoke blk 'getattributes)
   )
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; String operations

;; Wild card.Compares two strings: a pattern containing 1 "*" character; and a value to be evaluated.
;; Returns T if the value contains the pattern
;; examples:
;; (wildcard "AZERTYU*IOP" "AZERTYU12345IOP")   ;; returns T
;; (wildcard "AZERTYU*IOP" "AZRTYU12345IOP")    ;; returns nil
(defun wildcard (pattern val / result startString endString asteriskPlace charsLeft)
;; we search for the place of the asterisk in the string.(nil = nothing found)
(setq
   asteriskPlace (vl-string-search "*" pattern)
   charsLeft (- (- (strlen pattern) 1) asteriskPlace)
   result nil
)
(if (= asteriskPlace nil)
   (setq result nil);; no asterisk in found in the pattern
   (progn
   (setq startString (substring pattern 0 asteriskPlace))
   (setq endString (substring pattern (- 0 charsLeft) nil))
   (if (and    ;; so we check if the start and end of the pattern and value are equal
         (= startString (substring val 0 asteriskPlace))
         (= endString (substring val (- 0 charsLeft) nil))
       )
       (setq result T)
       (setq result nil)
   )
   )
)
result
)

;; I want substr to work like it does in PHP (and most languages I know).the lisp subst is too limited
;; So I made my own substring
;; unlike civilized languages, for some reason substr is "1-based" (first character of start is 1); who ever invented this ...
;; also I add negative numbers to the start parameter.
;; A start of -2 means it starts looking at the second-last character
;; set len to nil to let the lenth parameter empty
;;
;; examples:
;; (substring "AZERTYUIOP" 3 4)       returns "RTYU"      ;; start from letter 3 (0 based), give 4 letters
;; (substring "AZERTYUIOP" 4 nil)   returns "TYUIOP"    ;; start from letter 4 (0 based), give all the rest of the letters
;; (substring "AZERTYUIOP" -3 nil)    returns "IOP"       ;; start from the last 3 letters, give all the rest of the letters
;; (substring "AZERTYUIOP" -5 2)      returns "YU"      ;; start from the last 5 letters, give 2 letters
(defun substring (string start len / st ln)
(if (< start 0)
   (setq st (+ (strlen string) (+ start 1)))
   (setq st (+ start 1))
)
(if (= len nil)
   (setq ln (strlen string))
   (setq ln len)
)
(substr string st len)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun c:rb ()
(readBlocks"&QUOT;*&QUOT;" "Hello World!")
(princ)
)

Lee Mac 发表于 2022-7-5 22:55:26

你好,Emmanuel,
 
首先,感谢您遵守保留我的函数附带的代码头的礼节,我真的非常感谢您的这一小礼节。
 
下面是编写“子字符串”函数的另一种方法,供您考虑:
关于“通配符”函数,为什么不使用AutoLISP wcmatch函数?此功能的文档可在此处找到。
 

Emmanuel Delay 发表于 2022-7-5 23:00:46

我在其他语言中也有同样的问题。如果我没有找到它,我自己写,而不是看起来更努力一点。
 
我将在周一尝试这两个功能。

BIGAL 发表于 2022-7-5 23:09:36

关于名字中的大写字母问题,你可以使用STRCASE强制所有大写字母,毕竟英语字母表中有52个字符。

Emmanuel Delay 发表于 2022-7-5 23:16:01

好的,她是改进的代码。
 
感谢李和比格尔
 
看起来一切都在按照要求进行
 
3

Tharwat 发表于 2022-7-5 23:22:06

@Emmanuel延迟
 
首先,在例程中包含了不需要的函数子字符串。
然后,您已经检索了两次属性,一次在函数readblocks中,另一次已经由Lee LM:vl setattributevalue函数支持

Emmanuel Delay 发表于 2022-7-5 23:23:57

哦,是的,我不再需要子字符串了,对吗。
是的,李的函数再次读取属性;我还是喜欢用它。
页: [1] 2
查看完整版本: 全局替换每个值o