Chuyển đến nội dung
Diễn đàn CADViet
Jin Yong

Hỏi về Lisp (thuật toán, ý tưởng, coding,...)

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

12 giờ trước, Doan Van Ha đã nói:

Chẳng hạn hàm này đọc cách user đã đặt về dấu ngăn cách, và hàm ghi chắc cũng tương tự:
(vl-registry-read "HKEY_CURRENT_USER\\Control Panel\\International" "sList")

Cháu ghi vào thẻ theo đường dẫn ở dưới. Trong thẻ này cháu ghi các thông tin vào đó bác ạ!

Nhưng nếu ko tích dấu chọn Allow thì không tạo được.

HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows


(defun sv:key-r	(Sub typ)
  (setq Main "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows")
  (setq sVal (vl-registry-read Main Sub))
  (cond
    ((= typ "i") (setq nVal (atoi sVal)))
    ((= typ "r") (setq nVal (atof sVal)))
    ((= typ "s") (setq nVal sVal))
  )
)

(defun sv:key-w	(Sub Val typ)
  (setq Main "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows")
  (cond
    ((= typ "i") (vl-registry-write Main Sub (rtos Val 2 0)))
    ((= typ "r") (vl-registry-write Main Sub (rtos Val 2 2)))
    ((= typ "s") (vl-registry-write Main Sub Val))
  )
)

 

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

Mình muốn viết 1 lisp nhỏ về in ấn và rất cần sợ trợ giúp của các bạn, cụ thể như sau:

Công việc của mình là tổng hợp, in ấn bản vẽ của các bộ môn khác nhau, vì tất cả các bản vẽ đều đã trình bày sẵn layout, nên mình chỉ cần check lại khổ giấy, nét in, ... sau đó publish ra 1 file pdf rồi in ấn = pdf (chứ không phải in = cad).

Về cái vấn đề in ấn này thì mình cũng mới tìm hiểu, sau khi mày mò thì viết được cái lisp này, ý nghĩa là tự động setup nét in, khổ giấy của tất cả các layout (chỉ setup chứ không in).

Tuy nhiên còn 1 vấn đề đó là cửa sổ vùng in, mình thử hiệu chỉnh cái thuộc tính PlotOrigin nhưng cửa sổ nó không dịch chuyển theo ý mình muốn. Mình muốn chọn cửa sổ vùng in là từ điểm 0,0 đến 841,594 (vì mình in khổ A1) nhưng chưa biết phải làm thế nào.

Mong được các bạn giúp đỡ. Mình xin cảm ơn !

(defun C:zz ()
  (setq acadobj (vlax-get-acad-object))
  (setq doc (vla-get-ActiveDocument acadobj))
  (vlax-for layout (vla-get-layouts doc)
    (if (/= (vla-get-Name layout) "Model")
      (progn
	(vla-put-Configname layout "DWG To PDF.pc3")
	(vla-put-CanonicalMediaName layout "ISO_A1_(841.00_x_594.00_MM)")
	(vla-put-PaperUnits layout 1)
	(vla-put-PlotHidden layout :vlax-false)
	(vla-put-PlotOrigin layout (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble '(0 . 1)) '(0 0)))
	(vla-put-PlotType layout 4)
	(vla-put-PlotViewportBorders layout :vlax-false)
	(vla-put-PlotViewportsFirst layout :vlax-true)
	(vla-put-PlotWithLineweights layout :vlax-true)
	(vla-put-PlotWithPlotStyles layout :vlax-true)
	(vla-put-ScaleLineweights layout :vlax-false)
	(vla-put-StandardScale layout 0)
	(vla-put-StyleSheet layout "acad.ctb")
	(vla-put-TabOrder layout 3)
	(vla-put-UseStandardScale layout :vlax-true)
	)
      )
    )
  (print)
  )

 

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
15 giờ trước, Duong Nhat Duy đã nói:

Mình muốn viết 1 lisp nhỏ về in ấn và rất cần sợ trợ giúp của các bạn, cụ thể như sau:

Công việc của mình là tổng hợp, in ấn bản vẽ của các bộ môn khác nhau, vì tất cả các bản vẽ đều đã trình bày sẵn layout, nên mình chỉ cần check lại khổ giấy, nét in, ... sau đó publish ra 1 file pdf rồi in ấn = pdf (chứ không phải in = cad).

Về cái vấn đề in ấn này thì mình cũng mới tìm hiểu, sau khi mày mò thì viết được cái lisp này, ý nghĩa là tự động setup nét in, khổ giấy của tất cả các layout (chỉ setup chứ không in).

Tuy nhiên còn 1 vấn đề đó là cửa sổ vùng in, mình thử hiệu chỉnh cái thuộc tính PlotOrigin nhưng cửa sổ nó không dịch chuyển theo ý mình muốn. Mình muốn chọn cửa sổ vùng in là từ điểm 0,0 đến 841,594 (vì mình in khổ A1) nhưng chưa biết phải làm thế nào.

Mong được các bạn giúp đỡ. Mình xin cảm ơn !


(defun C:zz ()
  (setq acadobj (vlax-get-acad-object))
  (setq doc (vla-get-ActiveDocument acadobj))
  (vlax-for layout (vla-get-layouts doc)
    (if (/= (vla-get-Name layout) "Model")
      (progn
	(vla-put-Configname layout "DWG To PDF.pc3")
	(vla-put-CanonicalMediaName layout "ISO_A1_(841.00_x_594.00_MM)")
	(vla-put-PaperUnits layout 1)
	(vla-put-PlotHidden layout :vlax-false)
	(vla-put-PlotOrigin layout (vlax-safearray-fill (vlax-make-safearray vlax-vbDouble '(0 . 1)) '(0 0)))
	(vla-put-PlotType layout 4)
	(vla-put-PlotViewportBorders layout :vlax-false)
	(vla-put-PlotViewportsFirst layout :vlax-true)
	(vla-put-PlotWithLineweights layout :vlax-true)
	(vla-put-PlotWithPlotStyles layout :vlax-true)
	(vla-put-ScaleLineweights layout :vlax-false)
	(vla-put-StandardScale layout 0)
	(vla-put-StyleSheet layout "acad.ctb")
	(vla-put-TabOrder layout 3)
	(vla-put-UseStandardScale layout :vlax-true)
	)
      )
    )
  (print)
  )

 

 

(vla-SetWindowToPlot layout
    (vlax-safearray-fill
		  (vlax-make-safearray vlax-vbDouble '(0 . 1))
		  (list 0 0)
		)
    (vlax-safearray-fill
		  (vlax-make-safearray vlax-vbDouble '(0 . 1))
		  (list 841 594)
		)
    )

 

  • 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

@tien2005

Cảm ơn bạn rất nhiều nhé, mình tìm kiếm cái hàm này mỏi mắt rồi mà không ra nổi.

Nhờ có bạn mình biết thêm hàm vla-SetWindowToPlot, 1 lần nữa cảm ơn bạn nhé :)).

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

Các bạn cho mình hỏi ngu phát:

Mình tạo 1 cái selection set, tạo bằng lệnh SELECT của cad, sau đó ấn ESC;

Giả sử muốn chọn lại cái selection set đó mình ấn SELECT, enter, P, enter;

Nhưng khi cho vào command: (command "SELECT" "P" "") thì lại chẳng ra cái gì, tương tự mình thay "P" là một selection set bất kỳ (mình tạo sẵn), sau khi chạy, cad nó cũng không chọn cho mình cái selection set đó.

Bạn nào giải thích giúp mình với, mình cảm ơ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
35 phút trước, Duong Nhat Duy đã nói:

Các bạn cho mình hỏi ngu phát:

Mình tạo 1 cái selection set, tạo bằng lệnh SELECT của cad, sau đó ấn ESC;

Giả sử muốn chọn lại cái selection set đó mình ấn SELECT, enter, P, enter;

Nhưng khi cho vào command: (command "SELECT" "P" "") thì lại chẳng ra cái gì ?

Bạn nào giải thích giúp mình với, mình cảm ơn !

 

Bác thử (Command "PSELECT" "P" "")

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
5 phút trước, CadExTools đã nói:

 

Bác thử (Command "PSELECT" "P" "")

Mình đã thử và không được bạn ơi. Thậm chí cad nó còn báo không có lệnh PSELECT, mình dùng cad18. Và mình có nhớ là hồi trước dùng cad10 có lệnh PSELECT này, nhưng cũng không rõ nó khác SELECT ở điểm nào.

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
18 phút trước, Duong Nhat Duy đã nói:

Mình đã thử và không được bạn ơi. Thậm chí cad nó còn báo không có lệnh PSELECT, mình dùng cad18. Và mình có nhớ là hồi trước dùng cad10 có lệnh PSELECT này, nhưng cũng không rõ nó khác SELECT ở điểm nào.

Thử bấm (Ctrl+1), bật bảng Property , rồi thực hiện lại lệnh Pselect xem?

  • 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
5 phút trước, Danh Cong đã nói:

Thử bấm (Ctrl+1), bật bảng Property , rồi thực hiện lại lệnh Pselect xem?

Cảm ơn bạn nhé, mình đã làm được. Phải chăng đây vẫn là 1 lỗi nhỏ của cad ?

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

MÌnh có bolck động có thể kéo ra kéo dô. Bác nào cho mình xin đoạn lisp đọc giá trị chiều dài của cái line và pline sau khi kéo giản với.

bld.dwg

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
18 phút trước, duy782006 đã nói:

MÌnh có bolck động có thể kéo ra kéo dô. Bác nào cho mình xin đoạn lisp đọc giá trị chiều dài của cái line và pline sau khi kéo giản với.

bld.dwg

Tham khảo

(defun GetDynamicProperty(Block Property / oVal)
  (if(= 'ENAME(type Block))
    (setq Block(vlax-ename->vla-object Block)) )
  (if(= :vlax-true(vla-get-IsDynamicBlock Block))
    (foreach p(vlax-safearray->list
		(vlax-variant-value
		  (vla-GetDynamicBlockProperties Block)))
      (if(=(strcase Property)(strcase(vla-get-PropertyName p)))
	(if(vl-catch-all-error-p
	     (setq oVal(vl-catch-all-apply 'vla-get-Value(list p))))
	  nil
	  (setq oVal(vlax-variant-value oVal)) )	)) )
  oVal )

(defun c:getpro(/ )
  (setq bl(car(entsel)))
  ;Get property "Distance":
  (setq dis (GetDynamicProperty bl "Distance"))
;;;  (setq dis1 (GetDynamicProperty bl "Distance1"))
;;;  (setq dis2 (GetDynamicProperty bl "Distance2"))
;;;  (setq dis3 (GetDynamicProperty bl "Distance3"))
  (princ)  )
  • 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
3 giờ trước, duy782006 đã nói:

MÌnh có bolck động có thể kéo ra kéo dô. Bác nào cho mình xin đoạn lisp đọc giá trị chiều dài của cái line và pline sau khi kéo giản với.

bld.dwg

(defun dyn_get (ent)
  (mapcar '(lambda (dyn) (cons (vla-get-propertyname dyn) (vlax-get dyn 'value)))
	  (vlax-invoke (vlax-ename->vla-object ent) 'getdynamicblockproperties)
	  )
  )

 

  • 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

Các bạn cho mình hỏi, lisp có hàm nào trả về tọa độ đỉnh lân cận từ một điểm bất kỳ nằm trên một pline không. Cái này mình viết được hàm con nhưng ko rõ là lisp có hàm này hay ko nên lên đây hỏi các bạ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

 

Không hiểu rõ ý hàm con của bạn lắm

Nhưng bạn có thể dùng hàm vlax-obj-getparamatpoint để tìm param tại điểm trên pline. Dùng hàm fix để làm tròn param . Sau đó lại dùng hàm vlax-obj-getpointatparam để lấy tọa độ đỉnh kế tiếp. Không biết mình viết đúng hàm không vì đang dùng đthoai. Nhưng về ý tuỏng là như thế

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
13 giờ trước, Phamdung01 đã nói:

 

Không hiểu rõ ý hàm con của bạn lắm

Nhưng bạn có thể dùng hàm vlax-obj-getparamatpoint để tìm param tại điểm trên pline. Dùng hàm fix để làm tròn param . Sau đó lại dùng hàm vlax-obj-getpointatparam để lấy tọa độ đỉnh kế tiếp. Không biết mình viết đúng hàm không vì đang dùng đthoai. Nhưng về ý tuỏng là như thế

Cảm ơn bạn nhé, hàm này mình biết, mà do lười và ko muốn viết nhiều hàm con nên mình mới hỏi vậy :))

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

Bằng công cụ thông thường có thể Saveas 1 file Excel (đuôi xls) sang 1 file Unicode Text (đuôi txt) mà các chuỗi Unicode vẫn bảo toàn.

Vậy có thể dùng Lisp để saveas 1 file xls sang txt tương tự được không? Ai biết mách nước giù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
3 giờ trước, Doan Van Ha đã nói:

Bằng công cụ thông thường có thể Saveas 1 file Excel (đuôi xls) sang 1 file Unicode Text (đuôi txt) mà các chuỗi Unicode vẫn bảo toàn.

Vậy có thể dùng Lisp để saveas 1 file xls sang txt tương tự được không? Ai biết mách nước giùm.

dùng menthod saveAs của workbook excel.application

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
2 phút trước, ngokiet đã nói:

dùng menthod saveAs của excel.application

Thử cho dòng code đó đi bạn! Tôi cũng dùng nhưng lưu thì chữ nó biến qua mã tùm lum

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

(vlax-invoke (vlax-get (vlax-get-object “Excel.Application”) ‘Activeworkbook) ‘SaveAs “c://a//aaa.txt” 42)

test thử xem. Đó là save current sheet active. excel phải mở sẵn sheet đó.

42 là mã save unicode txt

  • Like 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

Cám ơn bạn NgoKiet với mã 42 mà mình tìm mãi chưa ra!

Gởi mọi người ai cần thì dùng: lisp saveas 1 file excel nhiều sheets sang các files Unicode Text (TXT) tương ứng.

Nhờ chuyển XLS sang TXT mà việc đọc và ghi file Excel Unicode dễ dàng và tốc độ.

(defun C:HA()
 (setq fn (getfiled "Chon file Excel de Saveas to Unicode Text (.TXT)" "" "xls;xlsx" 0))
 (XLS2TXT fn))
(defun XLS2TXT (fn / xlApp xlSho SheetName)
 (setq xlApp (vlax-get-or-create-object "Excel.Application"))
 (setq xlSho (vlax-get-property (vla-open (vlax-get-property xlApp 'Workbooks) fn) 'Sheets))
 (vlax-for xlShe xlSho
  (setq SheetName (vlax-get-property xlShe "Name"))
  (vlax-invoke (vlax-get-property xlSho 'Item SheetName) "Activate")
  (vlax-invoke-method (vlax-get-property xlApp "ActiveWorkbook") "Saveas" (strcat (vl-filename-directory fn) (vl-filename-base fn) "_" SheetName ".txt") 42 "" "" :vlax-false :vlax-false nil))
 (princ))

  • 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
Vào lúc 24/1/2019 tại 16:09, Doan Van Ha đã nói:

Cám ơn bạn NgoKiet với mã 42 mà mình tìm mãi chưa ra!

Gởi mọi người ai cần thì dùng: lisp saveas 1 file excel nhiều sheets sang các files Unicode Text (TXT) tương ứng.

Nhờ chuyển XLS sang TXT mà việc đọc và ghi file Excel Unicode dễ dàng và tốc độ.


(defun C:HA()
 (setq fn (getfiled "Chon file Excel de Saveas to Unicode Text (.TXT)" "" "xls;xlsx" 0))
 (XLS2TXT fn))
(defun XLS2TXT (fn / xlApp xlSho SheetName)
 (setq xlApp (vlax-get-or-create-object "Excel.Application"))
 (setq xlSho (vlax-get-property (vla-open (vlax-get-property xlApp 'Workbooks) fn) 'Sheets))
 (vlax-for xlShe xlSho
  (setq SheetName (vlax-get-property xlShe "Name"))
  (vlax-invoke (vlax-get-property xlSho 'Item SheetName) "Activate")
  (vlax-invoke-method (vlax-get-property xlApp "ActiveWorkbook") "Saveas" (strcat (vl-filename-directory fn) (vl-filename-base fn) "_" SheetName ".txt") 42 "" "" :vlax-false :vlax-false nil))
 (princ))

Sao phải xuất ra unicode txt cho mệt vậy. Vẫn không giải quyết vấn đề tên file unicode và tên sheet unicode. Nếu tên sheet unicode thì tên file txt là unicode nên cũng khó truy cập.

Với lại dữ liệu number dễ bị làm tròn theo format text của excel.

 

Nếu chỉ cần đọc cell unicode thì có thể đọc trực tiếp luôn đượ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
23 giờ trước, ngokiet đã nói:

Sao phải xuất ra unicode txt cho mệt vậy. Vẫn không giải quyết vấn đề tên file unicode và tên sheet unicode. Nếu tên sheet unicode thì tên file txt là unicode nên cũng khó truy cập.

Với lại dữ liệu number dễ bị làm tròn theo format text của excel.

 

Nếu chỉ cần đọc cell unicode thì có thể đọc trực tiếp luôn được mà.

Làm việc file Excel đủ lớn bạn sẽ thấy giá trị của tốc độ đọc cell excel.

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ới ý tưởng tạo đường bao tối ưu chứa tập hợp các điểm Point và khoảng cách giữa các đoạn không vượt quá con số a nào đó nhằm tìm kiếm đường bao tối ưu bám sát các điểm nhất. Em đã cố gắng nghiên cứu rất lâu rồi nhưng chưa tìm ra cách. Mong các Pro chỉ giáo, viết hoặc gợi ý cho em với ạ! Em có sưu tầm được lisp của Lee-Mac về đường bao lồi Convex Hull nhưng chưa chỉnh sửa được theo đúng ý mình. Em xin gửi code tham khảo lên đây và hình ảnh.

Cảm ơn các bác đã quan tâm.

(defun C:00 (/ LST LTSPOINT SSPOINT X )
  (setq ssPoint (ssget '((0 . "POINT"))))
  (if ssPoint
    (progn
      (setq LtsPoint (LM:ss->ent ssPoint))
      (setq lst (mapcar '(lambda (x) (cdr (assoc 10 (entget x)))) LtsPoint))
      (setq lst (LM:ConvexHull lst))
      (entmakex
	(append
	  (list
	    '(000 . "LWPOLYLINE")
	    '(100 . "AcDbEntity")
	    '(100 . "AcDbPolyline")
	    (cons 90 (length lst))
	    '(070 . 1)
	  )
	  (mapcar '(lambda (x) (cons 10 x)) lst)
	)
      )
    )
  )
  (princ)
)




;; Convex Hull  -  Lee Mac
;; Implements the Graham Scan Algorithm to return the Convex Hull of
;; a
;; list of
;; points.

(defun LM:ConvexHull (lst  / ch p0)
  (cond
    ((< (length lst) 4) lst)
    ((setq p0 (car lst))
     (foreach p1 (cdr lst)
       (if (or (< (cadr p1) (cadr p0))
	       (and (equal (cadr p1) (cadr p0) 1e-8)
		    (< (car p1) (car p0))
	       )
	   )
	 (setq p0 p1)
       )
     )
     (setq lst
	    (vl-sort
	      lst
	      (function
		(lambda	(a b / c d)
		  (if
		    (equal (setq c (angle p0 a)) (setq d (angle p0 b)) 1e-8)
		     (< (distance p0 a) (distance p0 b))
		     (< c d)
		  )
		)
	      )
	    )
     )
     (setq ch (list (caddr lst) (cadr lst) (car lst)))
     (foreach pt (cdddr lst)
       (setq ch (cons pt ch))
       (while
	 (and (caddr ch) (LM:Clockwise-p (caddr ch) (cadr ch) pt))
	  (setq ch (cons pt (cddr ch)))
       )
     )
     ch
    )
  )
)

;; Clockwise-p  -  Lee Mac
;; Returns T if p1,p2,p3 are clockwise oriented or collinear

(defun LM:Clockwise-p (p1 p2 p3)
  (< (-	(* (- (car p2) (car p1)) (- (cadr p3) (cadr p1)))
	(* (- (cadr p2) (cadr p1)) (- (car p3) (car p1)))
     )
     1e-8
  )
)




(defun LM:ss->ent (ss / i l)
  (if ss
    (repeat (setq i (sslength ss))
      (setq l (cons (ssname ss (setq i (1- i))) l))
    )
  )
)

 

https://s844.photobucket.com/user/thanhduan2407/media/sssss_zpsxbqp2zsn.png.html

 

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

×