Đến nội dung


Hình ảnh
- - - - -

[Yêu cầu]Lisp thay đổi giá trị trong block thuộc tính


  • Please log in to reply
11 replies to this topic

#1 mathan

mathan

    biết vẽ rectang

  • Members
  • PipPip
  • 83 Bài viết
Điểm đánh giá: 57 (tàm tạm)

Đã gửi 02 December 2011 - 11:14 PM

Bài toán đặt ra là:
1. Mình có một số block "A" thuộc tính ( có ít nhất 2 thuộc tính gọi "BB" và "CC" chẳng hạn)
2. Có các text trên bản vẽ
Mong muốn:
Có 1 lisp (hoặc 1 đoạn code)giống như copy nội dung text nhưng có thể chuyển được nội dung text chọn vào block "A" được chọn
và vào thuộc tính "BB" hoặc "CC" khi chọn
Mô tả lại công việc như sau:
Lisp: chọn text / lấy nội dung/ chọn block "A" cần chèn vào / chọn thuộc tính "BB" hoặc "CC" / cho kết quả
là Block "A" có thuộc tính "BB" hoặc "CC" có nội dung là text chọn
Mong các bạn giúp đỡ.
  • 0
-----------
Hình đã gửi Hãy chia sẻ để thấy có được nhiều hơn điều mình muốn!
Best regard,

#2 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5449 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 03 December 2011 - 10:08 AM

Bài toán đặt ra là:
1. Mình có một số block "A" thuộc tính ( có ít nhất 2 thuộc tính gọi "BB" và "CC" chẳng hạn)
2. Có các text trên bản vẽ
Mong muốn:
Có 1 lisp (hoặc 1 đoạn code)giống như copy nội dung text nhưng có thể chuyển được nội dung text chọn vào block "A" được chọn
và vào thuộc tính "BB" hoặc "CC" khi chọn
Mô tả lại công việc như sau:
Lisp: chọn text / lấy nội dung/ chọn block "A" cần chèn vào / chọn thuộc tính "BB" hoặc "CC" / cho kết quả
là Block "A" có thuộc tính "BB" hoặc "CC" có nội dung là text chọn
Mong các bạn giúp đỡ.


Đây bạn!

;Doan Van Ha - CADViet.com (03-12-2011)
;Thay 1 thuoc tinh cua cac Att_Block duoc chon (neu ten thuoc tinh ton tai trong Att_Block).
(defun C:HA( / ss objlst txt tth lst lst1 lst2 lst3)
(vl-load-com)
(princ "\nChon cac Att_Block de thay doi thuoc tinh...")
(setq ss (ssget (list (cons 0 "insert"))))
(setq objlst (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))))
(setq txt (cdr (assoc 1 (entget (car (entsel "\nChon text de lay thuoc tinh: "))))))
(setq tth (getstring "\nNhap ten thuoc tinh muon thay doi: "))
(foreach obj objlst
(setq lst (GetAtt obj))
(foreach lst1 lst
(if (= (strcase (car lst1)) (strcase tth))
(setq lst2 (cons (car lst1) txt))
(setq lst2 lst1))
(setq lst3 (cons lst2 lst3)))
(SetAtt obj lst3))
(princ))
;-----by MENZI ENGINEERING GmbH, Switzerland. Thank you.
(defun GetAtt (obj)
(mapcar '(lambda (att) (cons (vla-get-TagString att) (vla-get-TextString att))) (vlax-invoke obj 'GetAttributes)))
(defun SetAtt (obj lst / attval)
(mapcar '(lambda (att) (if (setq attval (cdr (assoc (vla-get-TagString att) lst))) (vla-put-TextString att attval))) (vlax-invoke obj 'GetAttributes))
(vla-update obj))

  • 3

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#3 mathan

mathan

    biết vẽ rectang

  • Members
  • PipPip
  • 83 Bài viết
Điểm đánh giá: 57 (tàm tạm)

Đã gửi 03 December 2011 - 10:31 AM

Lisp chạy đúng như những gì mình mong muốn
Cảm ơn bạn Doan Van Ha nhiều nhé.
  • 0
-----------
Hình đã gửi Hãy chia sẻ để thấy có được nhiều hơn điều mình muốn!
Best regard,

#4 cantona30002000

cantona30002000

    Chưa sử dụng CAD

  • Members
  • Pip
  • 2 Bài viết
Điểm đánh giá: 0 (bình thường)

Đã gửi 05 December 2011 - 08:44 PM

Mình nhờ ban Doan Van Ha phát triển tiếp lisp trên với nội dung như sau nhe:
Tương tư:
(1. Mình có một số block "A" thuộc tính ( có ít nhất 2 thuộc tính gọi "BB" và "CC" chẳng hạn)
2. Có các text trên bản vẽ)
Mô tả lại công việc như sau:
Lisp: chọn lần lượt text 1, text 2 ....text n / lấy nội dung/ chọn block "A" 1, block "A" 2.... block "A" n cần chèn vào / chọn thuộc tính "BB" hoặc "CC" / cho kết quả các block "A" có thuộc tính "BB" hoặc "CC" có nội dung tương ứng text1 với block 1, text 2 với block 2.....text n với block n
Mong bạn giúp minh nhé. Trong công việc thiết kế mình rất hay phải làm việc đó.
  • 0

#5 vodanhnxc

vodanhnxc

    biết vẽ ellipse

  • Members
  • PipPip
  • 57 Bài viết
Điểm đánh giá: 3 (bình thường)

Đã gửi 05 December 2011 - 09:28 PM

các bác cho em hỏi là muốn dùng các block thuộc tính cho các tỷ lệ hay các VP khác nhau thì làm ntn ạ ?
  • 0

#6 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5449 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 05 December 2011 - 09:30 PM

Mình nhờ ban Doan Van Ha phát triển tiếp lisp trên với nội dung như sau nhe:
Tương tư:
(1. Mình có một số block "A" thuộc tính ( có ít nhất 2 thuộc tính gọi "BB" và "CC" chẳng hạn)
2. Có các text trên bản vẽ)
Mô tả lại công việc như sau:
Lisp: chọn lần lượt text 1, text 2 ....text n / lấy nội dung/ chọn block "A" 1, block "A" 2.... block "A" n cần chèn vào / chọn thuộc tính "BB" hoặc "CC" / cho kết quả các block "A" có thuộc tính "BB" hoặc "CC" có nội dung tương ứng text1 với block 1, text 2 với block 2.....text n với block n
Mong bạn giúp minh nhé. Trong công việc thiết kế mình rất hay phải làm việc đó.


Lisp thay đổi 1 thuộc tính của tất cả Att_Block được chọn theo tất cả giá trị của Text/Mtext được chọn.
Số lượng Block và Text được chọn phải bằng nhau.
Thứ tự tính theo thứ tự chọn. Chú ý điều này kẻo nó lấy râu ông nầy cắm cằm bà nọ nhé!

;Doan Van Ha - CADViet.com (05-12-2011)
;Thay 1 thuoc tinh cua N Att_Block duoc chon theo N Text/Mtext duoc chon (neu ten thuoc tinh ton tai trong Att_Block). Thu tu theo thu tu chon.
(defun C:HA( / ss ss1 objlst entlst txt tth lst lst1 lst2 lst3 i)
(vl-load-com)
(princ "\nChon cac Att_Block de thay doi thuoc tinh...")
(setq ss (ssget (list (cons 0 "insert"))))
(setq objlst (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))))
(princ "\nChon cac Text/Mtext de lay thuoc tinh...")
(setq ss1 (ssget (list (cons 0 "text,mtext"))))
(setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1))))
(if (/= (length objlst) (length entlst)) (progn (alert "So luong cua Block va Text khac nhau.") (exit)))
(setq tth (getstring "\nNhap ten thuoc tinh muon thay doi: "))
(setq i 0)
(repeat (length objlst)
(setq lst (GetAtt (nth i objlst)))
(setq txt (cdr (assoc 1 (entget (nth i entlst)))))
(foreach lst1 lst
(if (= (strcase (car lst1)) (strcase tth))
(setq lst2 (cons (car lst1) txt))
(setq lst2 lst1))
(setq lst3 (cons lst2 lst3)))
(SetAtt (nth i objlst) lst3)
(setq i (1+ i)))
(princ))
;-----by MENZI ENGINEERING GmbH, Switzerland. Thank you.
(defun GetAtt (obj)
(mapcar '(lambda (att) (cons (vla-get-TagString att) (vla-get-TextString att))) (vlax-invoke obj 'GetAttributes)))
(defun SetAtt (obj lst / attval)
(mapcar '(lambda (att) (if (setq attval (cdr (assoc (vla-get-TagString att) lst))) (vla-put-TextString att attval))) (vlax-invoke obj 'GetAttributes))
(vla-update obj))

  • 2

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#7 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6009 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 06 December 2011 - 11:23 AM

Lisp thay đổi 1 thuộc tính của tất cả Att_Block được chọn theo tất cả giá trị của Text/Mtext được chọn. Số lượng Block và Text được chọn phải bằng nhau. Thứ tự tính theo thứ tự chọn. Chú ý điều này kẻo nó lấy râu ông nầy cắm cằm bà nọ nhé!

Hề hề hề,
Lại làm trâu chậm rồi.
Mình không thạo lắm về vla-, vlax-, vl- , nên viết cái ni theo cái kiểu cắn dần. Nhờ các bác test thử cói nhé. Có lẽ nó sẽ chậm hơn của bác DoanVanHa, nhưng lỡ làm rối chả nhẽ vứt đi nên cứ post vào đây để ai thấy khoái thì dùng và cũng để nhờ bạn Cnatona30002000 test giùm. (mình không có các block thuộc tính như của bạn để test)
Hề hề hề,

(defun c:cawt (/ ssb sst tt en i )
(vl-load-com)
(alert "\n Chon tap hop cac block can thay the gia tri thuoc tinh bang cach pick theo thu tu")
(setq ssb (acet-ss-to-list (ssget (list (cons 0 "insert"))))
tt (getstring t "\n Nhap ten thuoc tinh can thay the: ")
)
(alert "\n Chon tap hop cac text nguon bang cach pick chon theo thu tu tuong ung voi thu tu cua cac block can thay the)
(setq sst (acet-ss-to-list (ssget (list (cons 0 "*text")))))
(foreach bl ssb
(command "undo" "be")
(setq en (entnext bl)
i (vl-position bl ssb))
(while (/= (cdr (assoc 0 (setq els (entget en)))) "SEQEND")
(if (= (cdr (assoc 2 els)) tt)
(entmod (subst (cons 1 (nth i sst)) (assoc 1 els) els))
)
(setq en (entnext en))
)
(entupd bl)
(command "undo" "e")
)
(princ)
)
Xin lỗi mọi người nếu như bài này làm phiền mọi người nhé.
Hề hề hề,
  • 2
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#8 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 06 December 2011 - 11:33 AM

THeo em thì nên :
- THay Getstring bằng Nentselp hoặc list ATT ra để chọn
- SSGet lọc ATTBlock
Bác B ơi, command undo ở mỗi lần lặp ??
  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#9 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6009 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 06 December 2011 - 12:31 PM

THeo em thì nên :
- THay Getstring bằng Nentselp hoặc list ATT ra để chọn
- SSGet lọc ATTBlock
Bác B ơi, command undo ở mỗi lần lặp ??

Hề hề hề,
1, Cái thằng nentselp này mình chưa thạo lắm,, để lấy được list các att mình mới chỉ biết cách dùng vòng lặp với hàm entnext. Cái hàm vlax-dump-object thì nó trả kết quả ra màn hình nên chưa biết cách lấy giá trị từ hàm này ngoài cách vlax-get-property....
2, Dùng ssget với các đối tượng phụ từ hàm nentsel mình không rõ có được hay không.
3. Mình dùng undo như vậy để nhỡ có thay sai giữa chừng thì không phải làm lại từ đầu.
Hề hề hề.
Cám ơn bác mình sẽ ngâm cứu thêm các gợi ý của bác.
  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#10 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 06 December 2011 - 01:30 PM

Hì bác, ngu ý của em là :
- Giả sử attObj là 1 vlaObject nentsel chọn lúc đầu => vla-get-tagString để lấy Tag của nó (tag Source),(tất nhiên phải check loại object người dùng pick)
- ssget dxf 0,66 để chỉ lấy ATTBlock, dạng Selection Set
- Quét qua từng vlaObj của SS (vlax-for), ta sẽ có :
+ list1 : (vlax-invoke vlaObj 'GetAttributes) = list VLA các ATT Obj chứa trong Block (ở đây bỏ qua constanAtt)
+ list2 : (mapcar 'vla-get-tagstring list1) = list các tag string của các ATT.
Dễ thấy là nếu tag Source không tồn tại trong list này thì loại nó ra khỏi tập đang xét. Nếu có, thì lấy position của nó áp vào list1 => AttObj chứa Tag ta cần thay đổi => Append vào list3
- Lấy tập *Text và so sánh số lượng (nếu cần thiết) => list4
- Cuối cùng :
(Foreach AttObj list3 (vla-put-TextString AttObj (text tương ứng trong list4))
Chắc là sẽ dài và rườm rà hơn cách các bác đã xử lý ^^
Chủ yếu e nói về cách lấy những AttObj bên trong 1 Insert th
  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#11 Thaistreetz

Thaistreetz

    biết lệnh adcenter

  • Advance Member
  • PipPipPipPipPipPipPip
  • 903 Bài viết
Điểm đánh giá: 505 (tốt)

Đã gửi 06 December 2011 - 02:41 PM

1, Cái thằng nentselp này mình chưa thạo lắm,, để lấy được list các att mình mới chỉ biết cách dùng vòng lặp với hàm entnext. Cái hàm vlax-dump-object thì nó trả kết quả ra màn hình nên chưa biết cách lấy giá trị từ hàm này ngoài cách vlax-get-property....
2, Dùng ssget với các đối tượng phụ từ hàm nentsel mình không rõ có được hay không.

1. Nentsel dùng giống như entsel nhưng cho phép chọn tới tận đối tượng con của đối tượng phức tại điểm pick
Nentselp nếu không có tham số hoặc chỉ có tham số string thì nó giống hệt Nentsel, nếu có thêm 1 tham số nữa sau tham số string mô tả 1 tọa độ 1 điểm (P) thì hàm không chờ người dùng pick chuột nữa. nó trả về ename của đối tượng được tìm thấy tại điểm P và tọa độ điểm P. nếu không tìm thấy đối tượng nào trả về nil.
Có thể thấy (entsel) và (nentsel) là 1 cặp thì tương đương với nó là cặp hàm (ssget point) và (nentselp point)
2. không được bác ạ :)
  • 1

Hình đã gửi
IN HIM, I TRUST. THE TRUST IN MY GOD


#12 tuminh_85

tuminh_85

    Chưa sử dụng CAD

  • Members
  • Pip
  • 1 Bài viết
Điểm đánh giá: 0 (bình thường)

Đã gửi 11 May 2013 - 10:27 AM


Lisp thay đổi 1 thuộc tính của tất cả Att_Block được chọn theo tất cả giá trị của Text/Mtext được chọn.
Số lượng Block và Text được chọn phải bằng nhau.
Thứ tự tính theo thứ tự chọn. Chú ý điều này kẻo nó lấy râu ông nầy cắm cằm bà nọ nhé!

;Doan Van Ha - CADViet.com (05-12-2011)
;Thay 1 thuoc tinh cua N Att_Block duoc chon theo N Text/Mtext duoc chon (neu ten thuoc tinh ton tai trong Att_Block). Thu tu theo thu tu chon.
(defun C:HA( / ss ss1 objlst entlst txt tth lst lst1 lst2 lst3 i)
(vl-load-com)
(princ "\nChon cac Att_Block de thay doi thuoc tinh...")
(setq ss (ssget (list (cons 0 "insert"))))
(setq objlst (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))))
(princ "\nChon cac Text/Mtext de lay thuoc tinh...")
(setq ss1 (ssget (list (cons 0 "text,mtext"))))
(setq entlst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1))))
(if (/= (length objlst) (length entlst)) (progn (alert "So luong cua Block va Text khac nhau.") (exit)))
(setq tth (getstring "\nNhap ten thuoc tinh muon thay doi: "))
(setq i 0)
(repeat (length objlst)
  (setq lst (GetAtt (nth i objlst)))
  (setq txt (cdr (assoc 1 (entget (nth i entlst)))))
  (foreach lst1 lst
   (if (= (strcase (car lst1)) (strcase tth))
	(setq lst2 (cons (car lst1) txt))
	(setq lst2 lst1))
   (setq lst3 (cons lst2 lst3)))
  (SetAtt (nth i objlst) lst3)
  (setq i (1+ i)))
(princ))
;-----by MENZI ENGINEERING GmbH, Switzerland. Thank you.
(defun GetAtt (obj)
(mapcar '(lambda (att) (cons (vla-get-TagString att) (vla-get-TextString att))) (vlax-invoke obj 'GetAttributes)))
(defun SetAtt (obj lst / attval)
(mapcar '(lambda (att) (if (setq attval (cdr (assoc (vla-get-TagString att) lst))) (vla-put-TextString att attval))) (vlax-invoke obj 'GetAttributes))
(vla-update obj))

Cũng phát triển theo lisp trên. anh Doan Van Ha có thể sửa lisp ngược lại được không. tức sửa text/Mtext theo thứ tự và lấy ra gán theo thuộc tính trong block. (sửa text ngoài theo thuôc tính ). thanhk anh!


  • 0