Đến nội dung


Hình ảnh
- - - - -

[Nhờ chỉnh sửa] Thoát vòng lặp while có nhiều att


  • Please log in to reply
10 replies to this topic

#1 amateurday

amateurday

    biết lệnh break

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

Đã gửi 28 December 2011 - 02:26 PM

Trong Block att có 2 att trở lên, em muốn dùng vòng lặp để tìm đúng att trong block được chọn bằng nentsel, nhưng em không thoát ra khỏi while được. Các bác giúp em nhé. Giá trị trả về là mã DXF của att sau khi lọc qua các att trong block các bác nhé

(defun c:fff()
(setq att (nentsel "Chon att1"))
(setq dxfatt (entget(car att1))); [b]ma nay chi dung de lay tag thoi nhe[/b].
(setq tagatt (cdr(assoc 2 dxfatt)))
(setq Blockchon (car(entsel "\nChon Block:")))
(setq DXFBlockchon(entget Blockchon))
(setq attblock (entnext Blockchon))
(setq DXFattblock(entget attblock))
(while (= (cdr(assoc 0 DXFattblock)) "ATTRIB")
(if (= (cdr(assoc 2 DXFattblock)) tagatt)
(princ DXFattblock)
)
)
)

  • 0

#2 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 28 December 2011 - 03:03 PM

Trong Block att có 2 att trở lên, em muốn dùng vòng lặp để tìm đúng att trong block được chọn bằng nentsel, nhưng em không thoát ra khỏi while được. Các bác giúp em nhé. Giá trị trả về là mã DXF của att sau khi lọc qua các att trong block các bác nhé


(defun c:fff()
(setq att (nentsel "Chon att1"))
(setq dxfatt (entget(car att1))); [b]ma nay chi dung de lay tag thoi nhe[/b].
(setq tagatt (cdr(assoc 2 dxfatt)))
(setq Blockchon (car(entsel "\nChon Block:")))
(setq DXFBlockchon(entget Blockchon))
(setq attblock (entnext Blockchon))
(setq DXFattblock(entget attblock))
(while (= (cdr(assoc 0 DXFattblock)) "ATTRIB")
(if (= (cdr(assoc 2 DXFattblock)) tagatt)
(princ DXFattblock)
)
)
)

Có 3 cách:
1. Dùng repeat
2. Dùng foreach
3. Dùng while. Nếu chọn dùng while thì phải dùng entnext để hạ bậc dần, chứ bạn để điều kiện while như thế là luôn luôn thoả mãn nên nó chạy đến khi cúp điện luôn. Hề hề.
Hy vọng bạn làm được.
  • 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.


#3 amateurday

amateurday

    biết lệnh break

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

Đã gửi 28 December 2011 - 03:51 PM

OK, em làm được rồi, Thanks bác

(defun c:fff()
(setq att (nentsel "Chon att"))
(setq dxfatt (entget(car att)))
(setq tagatt (cdr(assoc 2 dxfatt)))
(setq Blockchon (car(entsel "\nChon Block:")))
(setq DXFBlockchon(entget Blockchon))
(setq attblock (entnext Blockchon))
(setq DXFattblock(entget attblock))
(while (= (cdr(assoc 0 DXFattblock)) "ATTRIB")
(if (= (cdr(assoc 2 DXFattblock)) tagatt)
(princ DXFattblock)
)
(setq attblock (entnext attblock))
(setq DXFattblock(entget attblock))
(princ)
)
)

  • 0

#4 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

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

OK, em làm được rồi, Thanks bác

Chúc mừng Amateurday đã không còn Amateur nữa! Tuy nhiên, bạn nên nghiên cứu thêm về biến cục bộ để khử nó, đồng thời viết lồng nhau bớt để nhìn nó đẹp hơn. Cứ từ từ, bởi: Ai cũng bắt đầu từ con số 0 cả mà!
  • 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.


#5 amateurday

amateurday

    biết lệnh break

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

Đã gửi 29 December 2011 - 05:46 PM

Vì biến cục bộ phải copy lên defun nên em lười quá, nhưng vì lisp sẽ tự thay thế biến sau mỗi lần thực thi lệnh nên không cần tạo biến cục bộ bác nhỉ (với điều kiện là thực hiện lệnh có sự tác động đến biến đó)
  • 0

#6 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

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

Đã gửi 30 December 2011 - 06:56 AM

Vì biến cục bộ phải copy lên defun nên em lười quá, nhưng vì lisp sẽ tự thay thế biến sau mỗi lần thực thi lệnh nên không cần tạo biến cục bộ bác nhỉ (với điều kiện là thực hiện lệnh có sự tác động đến biến đó)

Nhận định của bạn rất nguy hiểm, nhất là khi bạn sử dụng nhiều lisp khác nhau, có khi lisp này nó phá lisp kia. Trên CV có 1 bài rất hay (hình như của SSG) nói về biến cục bộ nhưng tôi tìm mãi chưa ra, bạn chịu khó tìm đọc sẽ thấy giá trị của việc tại sao phải khử biến cục bộ.
Thân thương!
  • 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.


#7 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 30 December 2011 - 07:23 AM

Nhận định của bạn rất nguy hiểm, nhất là khi bạn sử dụng nhiều lisp khác nhau, có khi lisp này nó phá lisp kia. ......
Thân thương!

Đúng như bạn DVH đã nói. Và có khi là trong 1 Lisp mà nó cũng có thể tự làm nó bị lỗi nữa nếu ta không cẩn thận khi coding đó bạn amateur :) .
Cái nữa là việc giải phóng biến cục bộ sẽ giải phóng bớt bộ nhớ làm Lisp chạy nhanh hơn.
Giống như cái đầu mà nhớ nhiều thứ trong đó thì sẽ gọi là..... nặng đầu hề hề
Bạn amateur tham khảo thêm : http://www.cadviet.c...?showtopic=2783

Và bạn nghiên cứu thêm ở điều kiện logic của vòng lặp while của bạn. Làm sao để vòng lặp While dừng lại khi
(= (cdr(assoc 2 DXFattblock)) tagatt)
Cái của bạn là phải duyệt qua toàn bộ ATT
Chắc bạn làm được. Chúc thành công
  • 1

#8 amateurday

amateurday

    biết lệnh break

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

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

Đúng như bạn DVH đã nói. Và có khi là trong 1 Lisp mà nó cũng có thể tự làm nó bị lỗi nữa nếu ta không cẩn thận khi coding đó bạn amateur :) .
Cái nữa là việc giải phóng biến cục bộ sẽ giải phóng bớt bộ nhớ làm Lisp chạy nhanh hơn.
Giống như cái đầu mà nhớ nhiều thứ trong đó thì sẽ gọi là..... nặng đầu hề hề
Bạn amateur tham khảo thêm : http://www.cadviet.c...?showtopic=2783

Và bạn nghiên cứu thêm ở điều kiện logic của vòng lặp while của bạn. Làm sao để vòng lặp While dừng lại khi
(= (cdr(assoc 2 DXFattblock)) tagatt)
Cái của bạn là phải duyệt qua toàn bộ ATT
Chắc bạn làm được. Chúc thành công

Vấn đề này thì chắc phải nhờ các bác vì em chưa nghĩ ra cách. Hic
  • 0

#9 ketxu

ketxu

    Copier - Paster - Editor

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

Đã gửi 30 December 2011 - 08:24 AM

Vấn đề này thì chắc phải nhờ các bác vì em chưa nghĩ ra cách. Hic

Về logic của while :
While sẽ tiếp tục hoạt động khi biểu thức điều kiện sau đó trả về khác Nil, cũng có nghĩa là nếu BTĐK bằng nil thì while sẽ dừng lại => bạn có tìm ra cách không ?
  • 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


#10 amateurday

amateurday

    biết lệnh break

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

Đã gửi 30 December 2011 - 09:02 AM

Thế này OK chưa các bác nhỉ

(defun c:taolistdxfatt()
(setq att (nentsel "\nChon ATT:"))
(setq dxfatt (entget(car att)))
(setq tagatt (cdr(assoc 2 dxfatt)))
(setq Blockchon (car(entsel "\nChon Block:")))
(setq DXFBlockchon(entget Blockchon))
(setq attblock (entnext Blockchon))
(setq DXFattblock(entget attblock))
(while (and (= (cdr(assoc 0 DXFattblock)) "ATTRIB")
(/= (cdr(assoc 2 DXFattblock)) tagatt)
)
(setq DXFattblock(entget attblock))
(setq attblock (entnext attblock))
)
(setq listdxfatt DXFattblock)
(princ listdxfatt)
(princ)
)

  • 0

#11 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 30 December 2011 - 09:12 AM

Thế này OK chưa các bác nhỉ


(defun c:taolistdxfatt()
(setq att (nentsel "\nChon ATT:"))
(setq dxfatt (entget(car att)))
(setq tagatt (cdr(assoc 2 dxfatt)))
(setq Blockchon (car(entsel "\nChon Block:")))
(setq DXFBlockchon(entget Blockchon))
(setq attblock (entnext Blockchon))
(setq DXFattblock(entget attblock))
(while (and (= (cdr(assoc 0 DXFattblock)) "ATTRIB")
(/= (cdr(assoc 2 DXFattblock)) tagatt)
)
(setq DXFattblock(entget attblock))
(setq attblock (entnext attblock))
)
(setq listdxfatt DXFattblock)
(princ listdxfatt)
(princ)
)

Bạn giải phóng thêm biến cục bộ và thêm 1 vài điều kiện kiểm tra nữa như kiểm tra Block có chứa ATT không, kiểm tra biến Block chọn có phải là Block không... mới OK :)
Chúc mừng bạn.
  • 1