Chuyển đến nội dung
Diễn đàn CADViet
  • Thông báo

    • Nguyen Hoanh

      CADViet đã hoàn tất nâng cấp   14/09/2017

      Chào các bạn, CADViet đã hoàn tất việc nâng cấp lên phiên bản mới. Tất cả các chức năng đã hoạt động theo kỳ vọng của ban quản trị. Nếu có vấn đề gì cần phản hồi, các bản post ở đây nhé: Trân trọng, Nguyễn Hoành.
Đăng nhập để thực hiện theo  
amateurday

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

Các bài được khuyến nghị

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)
)
)
)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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)
)
)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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à!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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 đó)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Đú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

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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 ?

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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)
)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

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.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay

Đăng nhập để thực hiện theo  

×