Đến nội dung


Hình ảnh
- - - - -

[Hỏi] Làm thế nào để truy xuất thông tin bên trong Block?


  • Please log in to reply
35 replies to this topic

#1 LoveLisp

LoveLisp

    biết lệnh extend

  • Members
  • PipPipPip
  • 195 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 05 October 2011 - 01:55 PM

Trên layer 0 có chứa nhiều đối tượng, các đối tượng này nằm trong Block
nhưng tất cả block đó không nằm trên layer 0.
Dùng câu lệnh (ssget "X" (8 . "0")) thì không chọn nó được.
Bạn có cách gì để chọn layer nằm bên trong Block không?
Mình đã thử qua các lệnh qselect, FILTER của CAD cũng không ăn thua.
  • 0

#2 npham

npham

    biết lệnh rotate

  • Members
  • PipPipPip
  • 136 Bài viết
Điểm đánh giá: 75 (tàm tạm)

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

nếu muốn chọn block sao bạn không dùng '((0 . "INSERT")(2 . "NAME")) ?
  • 0

#3 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 05 October 2011 - 10:32 PM

Bác npham không đọc kỹ câu hỏi rồi :) Ý OP là chọn các đối tượng nested ^^.
Hãy tìm trên mạng vài ví dụ về duyệt qua các đối tượng trong Block, thấy cái nào khớp layer 0 thì bạn cho vào 1 list Ename, rồi sau đó xử lý chúng :) Còn chọn gripset thì chắc là không được đâu bạn à
  • 0

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


#4 LoveLisp

LoveLisp

    biết lệnh extend

  • Members
  • PipPipPip
  • 195 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 06 October 2011 - 08:46 AM

nếu muốn chọn block sao bạn không dùng '((0 . "INSERT")(2 . "NAME")) ?

Thực tình là thế này: Mình có layerA, nó không chứa đối tượng nào hết. Tuy nhiên khi mình dùng lệnh LayDel để xóa lớp đó thì nó báo rằng có nhiều Block chứa đối tượng nằm trên lớp đó (nhưng nó không nói có bao nhiêu và những Block tên gì mới mệt chớ).
Mình nghĩ rằng trong lệnh LayDel đã có cách gì đó để chọn mà không cần duyệt qua từng Block (vì bản vẽ của mình rất nhiều Block mà mình thấy nó hầu như chẳng tốn chút thời gian nào để đưa ra thông báo).
Có ai biết mã nguồn của lệnh LayDel không?
  • 0

#5 LoveLisp

LoveLisp

    biết lệnh extend

  • Members
  • PipPipPip
  • 195 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 06 October 2011 - 08:48 AM

...Hãy tìm trên mạng vài ví dụ về duyệt qua các đối tượng trong Block...

hic, hic... thì mình đang tìm trên mạng đây, và tìm trên chính diễn đàn của người Việt!
Bạn biết cách duyệt qua từng Block thì xin chỉ giáo!! Hoặc bạn biết thì xin gửi link hữu ích nào đó cũng được.
  • 0

#6 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 06 October 2011 - 09:26 AM

À, mình đưa 1 ví dụ để bạn xử lý nhé.

(defun c:test(/ nla lstBlk lstBl)
(vl-load-com)
(setq nla "0") ;Layer chi dinh
(setq adoc (vla-get-activedocument (vlax-get-acad-object))) ;Active Document
(vlax-for block (vla-get-blocks adoc) ;Duyet qua tung Block Definition trong collection Block
(if (not (wcmatch (strcase (vla-get-name block) t) "*_space*")) ;Bo qua Anonymous
(vlax-for ent block ;Duyet qua tung doi tuong Ent trong Block
(progn
(if (and (wcmatch nla (vla-get-layer ent))(not (vl-position (vla-get-name block) lstBlk)))
(setq lstBlk (cons (vla-get-name block) lstBlk))
)
)
)
) ;=> Sau buoc nay la lay duoc cac block chua layer nla
)


(mapcar '(lambda(x) (if (setq ss (ssget "x" (list (cons 0 "INSERT")(cons 2 x))))
(setq lstBl (cons (cons x (sslength ss)) lstBl))
(setq lstBl (cons (cons x 0) lstBl))
)
)
lstBlk
)
;=> Sau doan nay lay duoc list loai bloc + so luong cua moi Block da chen tren ban ve
(princ (strcat "\nCac Block sau co chua doi tuong thuoc layer " nla ": \n"))
(mapcar '(lambda(x)(princ (strcat "\nBlock " (car x) " - So luong : " (vl-princ-to-string (cdr x))))) lstBl) ;In ra man hinh
(princ)
)

  • 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


#7 LoveLisp

LoveLisp

    biết lệnh extend

  • Members
  • PipPipPip
  • 195 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 06 October 2011 - 02:31 PM

À, mình đưa 1 ví dụ để bạn xử lý nhé.


(defun c:test(/ nla lstBlk lstBl)
(vl-load-com)
(setq nla "0") ;Layer chi dinh
(setq adoc (vla-get-activedocument (vlax-get-acad-object))) ;Active Document
(vlax-for block (vla-get-blocks adoc) ;Duyet qua tung Block Definition trong collection Block
(if (not (wcmatch (strcase (vla-get-name block) t) "*_space*")) ;Bo qua Anonymous
(vlax-for ent block ;Duyet qua tung doi tuong Ent trong Block
(progn
(if (and (wcmatch nla (vla-get-layer ent))(not (vl-position (vla-get-name block) lstBlk)))
(setq lstBlk (cons (vla-get-name block) lstBlk))
)
)
)
) ;=> Sau buoc nay la lay duoc cac block chua layer nla
)


(mapcar '(lambda(x) (if (setq ss (ssget "x" (list (cons 0 "INSERT")(cons 2 x))))
(setq lstBl (cons (cons x (sslength ss)) lstBl))
(setq lstBl (cons (cons x 0) lstBl))
)
)
lstBlk
)
;=> Sau doan nay lay duoc list loai bloc + so luong cua moi Block da chen tren ban ve
(princ (strcat "\nCac Block sau co chua doi tuong thuoc layer " nla ": \n"))
(mapcar '(lambda(x)(princ (strcat "\nBlock " (car x) " - So luong : " (vl-princ-to-string (cdr x))))) lstBl) ;In ra man hinh
(princ)
)

Tuyệt quá!! Đúng là siêu đại cao thủ! Bái phục, bái phục! Cám ơn, cám ơn!
Các câu lệnh được viết rất gọn gàng, trong sáng và mạnh mẽ, không thừa chữ nào, thật là đáng để học hỏi!
  • 1

#8 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 06 October 2011 - 02:51 PM

Tuyệt quá!! Đúng là siêu đại cao thủ! Bái phục, bái phục! Cám ơn, cám ơn!
Các câu lệnh được viết rất gọn gàng, trong sáng và mạnh mẽ, không thừa chữ nào, thật là đáng để học hỏi!

Bạn làm mình sốc quá ^^
  • 0

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 risusu

risusu

    biết vẽ circle

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

Đã gửi 06 October 2011 - 04:00 PM

Sao mình dùng lisp này thì trên màn hình cad2007 chỉ xuất hiện mủi tên con trỏ rồi 5s sau chuyển thành sợi tóc.
  • 0
^_^0905-0988.782004^_^

#10 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 06 October 2011 - 04:21 PM

Sao mình dùng lisp này thì trên màn hình cad2007 chỉ xuất hiện mủi tên con trỏ rồi 5s sau chuyển thành sợi tóc.

Tốt nhất là bạn nên đọc nội dung mọi người nói từ đầu đến cuối, xem mục đích của lisp là gì đã :)
  • 0

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 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 06 October 2011 - 09:52 PM

Thêm một cách nữa để chọn các block có chứa layer nào đó (có thể mở rộng để chọn theo color,linetype...).

(defun C:HA( / lay dsent) ;Doan Van Ha CADViet.com
(setq lay (getstring "\nNhap ten lop nam trong block: ") ss (ssadd))
(foreach ent (acet-ss-to-list (ssget '((0 . "INSERT"))))
(foreach ent1 (acet-ss-to-list (acet-explode ent))
(if (equal lay (cdr (assoc 8 (entget ent1))))
(setq dsent (if (not (member ent dsent)) (cons ent dsent) dsent))))
(command "u"))
(setq ss (if dsent (acet-list-to-ss dsent) nil)) ; ss la tap hop chon cua cac block co chua layer lay (2 dong duoi chi de test).
(princ (strcat "\nSo block co chua doi tuong thuoc layer " lay " la: " (if ss (itoa (sslength ss)) "0")))
(princ))

  • 1

* 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.


#12 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 06 October 2011 - 10:24 PM

Cách dùng mẹo này cũng hay, tuy nhiên, nếu để dùng trong 1 lisp thì e nghĩ là không nên, vì nó có vài nhược điểm sau :
- Số lượng của loại block . Cái này k chi tiết cũng k sao, tùy thuộc mục đích sử dụng. Nhưng mấy điểm sau thì nguy hiểm hơn :
- Command "U"
- Duyệt qua toàn bộ block đã được chèn trên bản vẽ (chứ k phải các định nghĩa block). Nếu bản vẽ có nhiều block cùng 1 loại đã được chèn, công việc Explode, duyệt qua từng đối tượng, Undo sẽ lặp đi lặp lại, tất nhiên tốc độ của nó sẽ bị giảm đi theo số lần tương ứng.
- Bỏ qua các block chưa được chèn
  • 0

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


#13 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 06 October 2011 - 10:57 PM

Cách dùng mẹo này cũng hay, tuy nhiên, nếu để dùng trong 1 lisp thì e nghĩ là không nên, vì nó có vài nhược điểm sau :
- Số lượng của loại block . Cái này k chi tiết cũng k sao, tùy thuộc mục đích sử dụng. Nhưng mấy điểm sau thì nguy hiểm hơn :
- Command "U"
- Duyệt qua toàn bộ block đã được chèn trên bản vẽ (chứ k phải các định nghĩa block). Nếu bản vẽ có nhiều block cùng 1 loại đã được chèn, công việc Explode, duyệt qua từng đối tượng, Undo sẽ lặp đi lặp lại, tất nhiên tốc độ của nó sẽ bị giảm đi theo số lần tương ứng.
- Bỏ qua các block chưa được chèn

1). "- Duyệt qua..." : cần thiết thì sort theo tên block để giảm số lượng.
2). "- Bỏ qua các block chưa được chèn": block chưa được chèn vào bản vẽ thì làm sao chọn được???
  • 0

* 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.


#14 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 06 October 2011 - 11:07 PM

1). "- Duyệt qua..." : cần thiết thì sort theo tên block để giảm số lượng.
2). "- Bỏ qua các block chưa được chèn": block chưa được chèn vào bản vẽ thì làm sao chọn được???

1. No comment ^^ Vì đã đi theo cách của bác thì nó nên là 1 bước Bắt buộc, chứ k phải là "nếu cần" nữa ạ ^^. bác cứ tưởng tượng 1 bản vẽ có 1000 block như nhau, mà bác cứ cho chạy hoài, chạy hoài... thì há chẳng vô nghĩa sao ^^
2. Không có yêu cầu Chọn gripset

Thực tình là thế này: Mình có layerA, nó không chứa đối tượng nào hết. Tuy nhiên khi mình dùng lệnh LayDel để xóa lớp đó thì nó báo rằng có nhiều Block chứa đối tượng nằm trên lớp đó (nhưng nó không nói có bao nhiêu và những Block tên gì mới mệt chớ).


  • 0

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


#15 LoveLisp

LoveLisp

    biết lệnh extend

  • Members
  • PipPipPip
  • 195 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 07 October 2011 - 08:36 AM

1). "- Duyệt qua..." : cần thiết thì sort theo tên block để giảm số lượng.
2). "- Bỏ qua các block chưa được chèn": block chưa được chèn vào bản vẽ thì làm sao chọn được???

Mình cũng nghĩ như bạn "ketxu". Mình thấy có thể dễ dàng lấy tên của tất cả các block trên bản vẽ (kể cả các block chưa được chèn) bằng lệnh (tblnext "block" T) và (tblnext "block").
Lisp của bạn "Doan Van Ha" có nhược điểm là khi Block chèn theo 2 phương có tỉ lệ khác nhau thì sẽ không thể Explode được.
  • 0

#16 LoveLisp

LoveLisp

    biết lệnh extend

  • Members
  • PipPipPip
  • 195 Bài viết
Điểm đánh giá: 20 (tàm tạm)

Đã gửi 07 October 2011 - 08:37 AM

À, các bạn cho mình hỏi thêm vấn đề này: Nếu trong Block đó có ... nhiều Block con nữa thì sao nhỉ???
  • 0

#17 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 07 October 2011 - 08:40 AM

Mọi Block đều nằm trong collection Blocks mà. Chỉ có điều lúc đó bảo chọn để ra số lượng thì hơi vất ^^
  • 0

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


#18 daik50

daik50

    biết vẽ point

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

Đã gửi 07 October 2011 - 09:26 AM

Thêm một cách nữa để chọn các block có chứa layer nào đó (có thể mở rộng để chọn theo color,linetype...).


(defun C:HA( / lay dsent) ;Doan Van Ha CADViet.com
(setq lay (getstring "\nNhap ten lop nam trong block: ") ss (ssadd))
(foreach ent (acet-ss-to-list (ssget '((0 . "INSERT"))))
(foreach ent1 (acet-ss-to-list (acet-explode ent))
(if (equal lay (cdr (assoc 8 (entget ent1))))
(setq dsent (if (not (member ent dsent)) (cons ent dsent) dsent))))
(command "u"))
(setq ss (if dsent (acet-list-to-ss dsent) nil)) ; ss la tap hop chon cua cac block co chua layer lay (2 dong duoi chi de test).
(princ (strcat "\nSo block co chua doi tuong thuoc layer " lay " la: " (if ss (itoa (sslength ss)) "0")))
(princ))


Bác cho em hỏi một câu nhé, đừng cười đấy
theo cách của bác thì em có một layer có tên VD: Tuong bao, như vậy giữa 2 chữ có một dấu cách, làm thế nào đánh được tên lớp nằm trong block
Cảm ơn bác
  • 0

#19 daik50

daik50

    biết vẽ point

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

Đã gửi 07 October 2011 - 09:28 AM

Tuyệt quá!! Đúng là siêu đại cao thủ! Bái phục, bái phục! Cám ơn, cám ơn! Các câu lệnh được viết rất gọn gàng, trong sáng và mạnh mẽ, không thừa chữ nào, thật là đáng để học hỏi!

À, mình đưa 1 ví dụ để bạn xử lý nhé.

 (defun c:test(/ nla lstBlk lstBl) (vl-load-com) (setq nla "0") ;Layer chi dinh (setq adoc (vla-get-activedocument (vlax-get-acad-object))) ;Active Document (vlax-for block (vla-get-blocks adoc) ;Duyet qua tung Block Definition trong collection Block (if (not (wcmatch (strcase (vla-get-name block) t) "*_space*")) ;Bo qua Anonymous (vlax-for ent block ;Duyet qua tung doi tuong Ent trong Block (progn (if (and (wcmatch nla (vla-get-layer ent))(not (vl-position (vla-get-name block) lstBlk))) (setq lstBlk (cons (vla-get-name block) lstBlk)) ) ) ) ) ;=> Sau buoc nay la lay duoc cac block chua layer nla ) (mapcar '(lambda(x) (if (setq ss (ssget "x" (list (cons 0 "INSERT")(cons 2 x)))) (setq lstBl (cons (cons x (sslength ss)) lstBl)) (setq lstBl (cons (cons x 0) lstBl)) ) ) lstBlk ) ;=> Sau doan nay lay duoc list loai bloc + so luong cua moi Block da chen tren ban ve (princ (strcat "\nCac Block sau co chua doi tuong thuoc layer " nla ": \n")) (mapcar '(lambda(x)(princ (strcat "\nBlock " (car x) " - So luong : " (vl-princ-to-string (cdr x))))) lstBl) ;In ra man hinh (princ) ) 


Thank bác phát
bác có thể giải thích rõ cái lisp này được không em chưa hiểu nhiều về lisp nhưng cũng muốn học đòi thay đổi cái lisp này, hj hj lại không được

(setq adoc (vla-get-activedocument (vlax-get-acad-object)))

Dòng trên có nghĩa là j bác

Cảm ơn bác rất nhiều
  • 0

#20 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 07 October 2011 - 09:46 AM


Bác cho em hỏi một câu nhé, đừng cười đấy
theo cách của bác thì em có một layer có tên VD: Tuong bao, như vậy giữa 2 chữ có một dấu cách, làm thế nào đánh được tên lớp nằm trong block
Cảm ơn bác

Với lisp của bác ĐVH, bạn thay

(getstring "\nNhap ten lop nam trong block: ")

bằng

(getstring T "\nNhap ten lop nam trong block: ")

Option T (not nil) cho phép nhập String có dấu " "



(setq adoc (vla-get-activedocument (vlax-get-acad-object)))

Dòng đấy lấy đối tượng VLA Activedocument (bản vẽ đang thao tác). Nếu bạn bắt đầu chơi với lisp thì những khái niệm này sẽ khó xơi đấy ^^
  • 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