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

ngokiet

Thành viên
  • Số lượng nội dung

    404
  • Đã tham gia

  • Lần ghé thăm cuối

  • Ngày trúng

    43

Bài đăng được đăng bởi ngokiet


  1. 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à.


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


  3. Bác xem lại cấu trúc lệnh cond nhé.

    Mấy dòng đỏ ở đầu bạn sửa lại 1 chút

    (or (> (getvar 'USERI1) -1) (setvar 'USERI1 2))
      (initget 4)
      (or (setq stp (getint (strcat "\nSo chu so thap phan <" (itoa (getvar 'USERI1)) ">: ")))

            (setq stp (getvar 'USERI1)))
      (setvar 'USERI1 stp)

    Sorry. Cái trên cũng đúng rồi.

    Hình như copy trên diền đàn dán vào Vlisp nó hay thêm dấu ? ở phía sau hay sao.


  4. 1 giờ} trướ}c, Doan Van Ha đã nói:

    Ghi các chuỗi ra file Excel tiếng Việt Unicode thì tôi đã làm được. Tốc độ nhanh.

    Nhưng đọc 1 file Excel tiếng Việt Unicode thì đang tìm tòi. Đang chờ xem ai có để tham khảo, và sợ nhất là nó đọc rất chậm!

    Bác dùng cách nào để ghi chỉ mĩnh được không?

    Còn cách đọc thì ngoài cách mình đề cập ở trên thì cũng có thể viết ra file csv, hay unicode text để đọc cũng nhanh mà.

    Còn ghi ra csv thì dễ nhưng không có multi sheet.

    @to showmans.hms.

    Mình cũng biết là có thể ghi thẳng ra VBProject/VBComponents cũng được. Nhưng có file temp cũng vui vì dù sao autolisp cũng có mấy file ngoài như DCL.

    Với lại đôi khi dùng các cell của file temp này để đọc string unicode để đọc/ghi các file có đường dẫn là unicode.


  5. - Tạo text/mtext tử clipboard

    Thông thường thì khi viết lisp đọc text từ clipboard thì mọi người thường hay dùng (vlax-create-object "htmlfile") để đọc "text" từ clipboard. Tuy nhiên khi text là unicode thì việc đọc sẽ không cho kết quả là text unicode. Vì vậy mình mới thử dùng cơ chế sendkeys để tạo text/mtext để tạo text/mtext sau đó đọc dữ liệu từ text/mtext đó.

    Code: tạo text

    (vlax-invoke-method (setq wss (vlax-create-object "WScript.Shell")) 'sendkeys "-text\n0,0\n2\n0\n ^{v} \n")
    (vlax-release-object wss)

     

    tạo mtext

    (vlax-invoke-method (setq wss (vlax-create-object "WScript.Shell")) 'sendkeys "-mtext\n0,0\n2\n0\n ^{v} \n")
    (vlax-release-object wss)

     

    Khi chạy thì text/mtext sẽ tạo ở vị trí 0,0. và có thể đọc lại bằng (cdr(assoc 1 (entlast)))

    - Cái này khá thú vị vì khi đọc file excel có unicode thì mình có thể copy cái cell cần đọc vào clipboard để đọc lại theo chuẩn của CAD.

    Tuy nhiên nếu bạn nào sài lisp mà dùng được lệnh "pastespec" trong autolisp thì chỉ mình với vì khi select multi cell thì đọc lại bằng cách trên nó mất ký tự TAB ("\t") nên không tách các cell ra được nên phải đọc từng cell.

     

    Nói thêm về sendkeys dùng "WScript.Shell" thì có thể gởi các ký tự đặc biệt như Ctrl hay Alt. Còn không cần thì dùng menthod sendcommand của (vla-get-activedocument(vlax-get-acad-object)) cũng được vì đó cũng là cơ chế sendkeys mà thôi.

     

    - Đọc / ghi unicode cho file excel

    Do autocad hiểu unicode theo kiểu của mình mà các lệnh lisp không thể chuyển dổi được nên chỉ thường xuất ra file txt/cvs mới có thể đọc được unicode.

    Mặc dù "excel.Application" vẫn có thể gởi vbstring unicode cho cad nhưng khi dùng lệnh vlax-variant-value thì các ký tự unicode sẽ chuyển thành dấu ?. Nếu các bạn vẫn lưu biến variant thì khi ghi biến variant vào cell khác nó vẫn hiển thị unicode đúng.

    Giải pháp mình chọn là dùng macro của Excel để chuyển mã string unicode sang string ansi của Cad.

    Mình có viết 2 functions và 2 macro1 & 2 chép vào thư mục (giải nén file đính kèm)

    C:\Users\xxx\AppData\Roaming\Microsoft\Excel\XLSTART

    Lúc đó khi truy xuất file excel

    (setq excel (vlax-get-or-create-object "Excel.Application"))

    (setq book (vla-open (vlax-get-property app "WorkBooks") filename))

    (setq sheet (vlax-get-property (vlax-get-property file "Sheets") "Item" "Sheet1")))

    (setq cell  (vlax-get-property (vlax-get-property sheet 'Cells) "Range" "A1"))

    (vlax-invoke cell 'select) :Select cell A1

    (vlax-invoke excel 'run "cad.xlsm!Macro1") ; Nó sẽ chuyển cell select unicode sang format CAD

    ;(vlax-invoke excel 'run "cad.xlsm!Macro2"); Nó sẽ chuyển cell select format CAD về unicode.

     

    (vlax-variant-value(vlax-get-property cell 'value2)) : Đọc giá trị tại cell A1

     

    Hay là 1 cách khác là lấy 1 cell của "cad.xlsm" sau đó ghi giá tri nó 

    (vlax-put-property (vlax-get-property (vlax-get-property sheet 'Cells) "Range" "A1") 'Value2 (vlax-make-variant "=uni2cad([Book1]Sheet1!A1)"))

    và sau đó đọc lại value2 nó sè cho kết quả từ unicode-> cad

     

    Hai hàm mình viết là cad2uni và uni2cad

     

     

    cad.rar

    • Like 2
    • Vote tăng 1

  6. Bạn làm theo hướng dẫn ở trên xem có kết quả gì không? Nếu có thì có báo lỗi gì thì mình sử lý dùm cho.

    File của dạn do dim hơi rối. Text nhập có, text tự động có. Với lại do dim làm tròn số là 5 mà dim của CAD làm tròn mình hơi khó chịu một chút

    (vd: 662.5 thì làm tròn thành 660- 662.6 thì thành 665 nên mấy lisp trước mình thấy sai so với Kq của bạn)

    Bạn tải lại cái lisp mới nhật đó. Nếu không chọn điểm chèn text thì kiểm tra text ở vị trí 0,0

     


  7. Giờ bạn thử mở file bạn gởi lên.

    - Tắt tất cả layer chỉ mở 2 layer "cat6"  và "text ghi chu mang"

    - Nhấn "explore" select all

    - Chọn layer hiên hành là layer "cat6"  và "text ghi chu mang"

    - Nhân ap chọn lisp mình tải lên

    - Đánh lệnh tt để chạy

    -chọn select all

    - chọn 1 điểm để chèn text

     

    tt.lsp


  8. Chạy được mà. Lúc trước mình có nói text 2.5

    Mình mới sửa lại là text cao 100.

    Do các dim của bạn là block nên explore ra là chạy được.

     

    Mình mới xem lại bản vẽ của bạn thì có text nhập trực tiếp và có text tự động cũa dim. Nhưng phần lisp của mình mới chỉ nhận phần text đánh vào thôi.

     

    Mình mới sửa thêm 1 chút cho bạn rồi đó.

    Yêu cầu là Dim không ở trong block.

    Không biết bạn tính bản phía dưới đúng hay không nhưng mình chạy list thấy hơi sai 1 chút. Còn ít thì thấy chạy đúng không biết sai ở đâu vì lười kiểm tra.

     


  9. 44 phút trước, Doan Van Ha đã nói:

    File txt thì đã OK. Còn file XLS thì sao bạn. Có thể cho 1 ví dụ đọc XLS Unicode được không?

    XLS chắc phải hỏi bác snowman.hms ở trên chứ mình chưa mò tới :-)

    Do mình thấy là autolisp chỉ gởi nhận string là ansi text cho tất cả các phần mềm liên kết khác nên khi sử dụng nó không thể đọc unicode từ các phần mềm khác. Trừ trường hợp các chương trình khác chỉ gởi ansi code.

    Vì vậy muốn đọc unicode bằng các thì phải dùng ứng dụng chuyển mã về format của cad mới có thể sử dụng.

    - Có 1 cách của cad là dùng lệnh datalink và table để tạo bảng sau đó đọc dữ liệu từ table đó


  10. Mình thấy file txt,csv đọc unicode cũng dễ mà.

    Thường thì file txt sử dụng unicode-utf-8.

    Mà file này có cấu trúc là đầu file có 2 mã #239 #187 #191 nằm đầu. Nên khi đọc dòng text đầu tiên thì kiểm tra có 3 mã này ko để kiểm tra có phải là file utf-8 hay ko và xóa nó đi.

    Còn khi ghi file thì thêm string này trước dòng đầu tiên

    (vl-list->string '(239 187 191)).

    - Tiếp theo là đọc string bình thường. 

    Lưu ý là string txt uft-8 theo chuẩn utf-8.

    Viết 2 hàm chuyển String uft-8 thành string của CAD và ngược lại.

    Chuẩn uft-8 như thế nào thì tham khảo ở đây:

    https://en.wikipedia.org/wiki/UTF-8

    Tóm tắt như sau

    -  <= (chr 127) là giống như Acad

    - (chr 128)~ (chr 191) Sử dụng 2 ký tự nếu ký tự kế >= 128

    - (chr 192)~ (chr 223) Sử dụng 2 ký tự

    - (chr 224)~ (chr 239) Sử dụng 3 ký tự

    - (chr 240)~ (chr 247) Sử dụng 4 ký tự

    - (chr 248)~ (chr 251) Sử dụng 5 ký tự

    - (chr 252)~ (chr 255) Sử dụng 6 ký tự

    * (4-5-6 ký tự thì chưa sử dụng) 

    Nên viết function để chuyển ký tự thành /U+XXXX tương ứng của string CAD.

     

     

     

     

     


  11. Vì các block bạn toàn là block anonymous nên có dấu * phía trước nên khi copy thì nó hay tự động đổi tên. Và không copy ở property dc. nếu block thường thì khi bạn dùng lệnh wblock ghi block ra file cùng tên block. khi bạn dùng lệnh insert chọn browse tới file đó thì nếu trong bve bạn có block cùng tên thì nó sẽ hỏi có cập nhật hay ko.

    Còn vẽ balloon của bạn thì bạn nên tạo block động có atttext và điểm insert là điểm bạn cần nhập vào là dc.


  12. Bạn copy 3 dòng dưới tạo thành 1 file .lisp là có lệnh cnb dùng copy name block vào clipboard.

    Lea65nh Amballoon của bạn là lisp hả???

    Còn muốn copy block từ bản vẽ khác qua mà tự động cập nhật thì bạn phải write block rồi insert file vào. Nhưng với block với dấu * đầu thì mình chưa thử.

     

    (defun c:cnb() 
      (vlax-invoke (vlax-get (vlax-get (vlax-create-object "htmlfile") 'ParentWindow) 'ClipBoardData)
        'setData "TEXT" (cdr (assoc 2 (entget(car(entsel)))))))

     

     

    • Vote tăng 1
×