AutoCAD – Bản vẽ

Nhập tọa độ từ Excel vào AutoCAD: chấm điểm hoặc nối thành đa tuyến

Nhập tọa độ từ Excel vào AutoCAD bằng một tệp lisp đọc CSV, chấm điểm hoặc nối thành đa tuyến. Đọc được cả tệp Excel tiếng Việt dùng dấu phẩy.

  • TS. Đỗ Quốc Hoàng
  • 16 phút đọc
Bốn điểm toạ độ đọc từ tệp Excel, nối thành đa tuyến kín để đối chiếu chu vi và diện tích Ảnh: Sơ đồ của Viện Tin học Xây dựng

Đội trắc địa gửi về một tệp Excel hai trăm điểm đo. Cần đưa chúng lên bản vẽ để dựng ranh thửa, vẽ tim đường, hay chấm mốc. Gõ tay bốn trăm con số thì mất buổi sáng và chắc chắn sai vài chỗ.

Nhập tọa độ từ Excel vào AutoCAD là việc AutoCAD không làm được: nó không đọc bảng tính. Bài này phát hành tệp lisp của Viện làm đúng việc ấy, in trọn mã nguồn, và nói rõ chỗ nguy hiểm nhất — đọc sai mà không báo gì. Muốn học trọn khâu dựng hồ sơ từ số liệu đo thì xem khóa AutoCAD Xây Dựng.

Chèn Excel vào CAD: ba cách và chúng khác nhau thế nào

Ba cách hay được nhắc, và chúng giải ba bài toán khác hẳn nhau.

CáchCho ra cái gìDùng khi nào
Dán bảng làm đối tượng OLEMột bức ảnh của bảng tínhChỉ cần hiện bảng lên bản vẽ để in
Liên kết dữ liệu DATALINKMột bảng thật trong CAD, cập nhật theo tệp ExcelBảng khối lượng cần đồng bộ
Đọc toạ độ bằng lispĐiểm và đường thật đúng toạ độDựng hình từ số liệu đo

Hai cách đầu không cho ra toạ độ. Chèn bảng Excel vào CAD kiểu OLE trông thì giống bảng, nhưng đó là một bức ảnh: không bắt điểm được, không đo được, không vẽ tiếp lên được. Ai cần dựng ranh thửa từ bảng toạ độ mà làm theo cách ấy là đi nhầm đường ngay từ đầu.

Bài này nói về cách thứ ba, tức cái mà người ta hay gõ tìm là lisp nhập tọa độ từ excel vào cad. Việc ngược lại — xuất toạ độ từ bản vẽ ra Excel — có trong bài lisp xuất toạ độ.

Cách thứ hai cũng đáng biết cho đúng việc của nó. Lệnh DATALINK tạo một bảng thật trong AutoCAD gắn với tệp Excel; sửa tệp Excel rồi cập nhật thì bảng trên bản vẽ đổi theo. Tài liệu Autodesk ghi: "A table can be linked to data in a Microsoft Excel (XLS, XLSX, or CSV) file." Nó hợp cho bảng khối lượng, hoàn toàn không hợp cho toạ độ — bảng ấy vẫn chỉ là bảng, không phải điểm trên bản vẽ.

Tải tệp của Viện

Tải tệp NTD-IIC.lspba lệnh. Mã để nguyên trong bài, vì chạy mã lạ trên máy mình là việc đáng cẩn thận.
LệnhViệc nó làm
NTDđọc tệp, chấm điểm và ghi số hiệu từng điểm
NTDPđọc tệp, nối các điểm thành một đa tuyến
NTDKđọc tệp rồi chỉ in ra để kiểm, không vẽ gì

Dạng tệp đọc được là tệp văn bản thường, mỗi dòng một điểm, kiểu số hiệu,X,Y hoặc chỉ X,Y. Từ Excel thì chọn File → Save As → CSV.

;;; ==================================================================
;;;  NTD-IIC.LSP  -  doc toa do tu tep CSV (xuat tu Excel) vao ban ve
;;;  Vien Tin hoc Xay dung (IIC) - Truong Dai hoc Xay dung Ha Noi
;;;  https://iic.huce.edu.vn  -  Tel: 0989 427 809
;;; ------------------------------------------------------------------
;;;  Ba lenh:
;;;    NTD     doc tep CSV, cham diem va ghi so hieu tung diem
;;;    NTDP    doc tep CSV, noi cac diem thanh mot da tuyen
;;;    NTDK    doc tep CSV roi chi DEM va IN ra, khong ve gi
;;;
;;;  Vi sao can tep nay: AutoCAD khong doc duoc bang tinh. Cach duy nhat
;;;  san co la chen bang Excel lam doi tuong OLE - nhin thi giong bang
;;;  nhung KHONG phai toa do, khong bat diem duoc, khong do duoc. Muon
;;;  dua 200 diem do dac tu Excel vao ban ve thi phai go tay tung cap so.
;;;
;;;  DANG TEP DOC DUOC: tep van ban thuong, moi dong mot diem.
;;;       so_hieu,X,Y        hoac       X,Y
;;;  Tu Excel: File > Save As > CSV (Comma delimited).
;;;
;;;  NAM DIEU CAN BIET TRUOC KHI CHAY:
;;;    1. QUY UOC TRUC. Trac dia Viet Nam lay X la truc BAC, Y la truc
;;;       DONG, con AutoCAD lay X ngang Y doc. Lenh HOI ban truoc khi ve
;;;       chu khong tu doi bua. Chon sai la ban ve quay 90 do.
;;;    2. DAU THAP PHAN. Tep xuat tu Excel dat ngon ngu tieng Viet dung
;;;       dau PHAY lam dau thap phan. Lenh doc duoc ca kieu ay: con so
;;;       nao khong doc duoc ma co dau phay thi thu lai sau khi doi thanh
;;;       dau cham, VA BAO RA o cuoi da doi bao nhieu con so. Khong sua
;;;       lut mot cai nao.
;;;    3. DONG DAU tep thuong la tieu de cot. Dong nao khong doc ra so
;;;       thi tu dong bi bo qua, nen khong phai xoa tieu de truoc.
;;;    4. DAU PHAN CACH COT chon theo TUNG DONG: dong nao co dau cham
;;;       phay thi tach theo cham phay, khong thi tach theo dau phay.
;;;       Tach theo ca hai cung luc la sai: dong "1;2000,5;1000,5" se vo
;;;       thanh nam manh va lenh lay nham (2000, 5) lam toa do - da do
;;;       duoc loi nay khi thu, va da sua.
;;;    5. Diem cham ra la doi tuong POINT. Muon nhin thay thi dat kieu
;;;       diem bang lenh DDPTYPE, vi kieu mac dinh la mot cham gan nhu
;;;       khong thay gi.
;;;  Sau khi chay, lenh IN ra so dong doc duoc va so dong bo qua.
;;;
;;;  Ten lenh da do truoc khi dat: tep bi danh acad.pgp cua ban 2027
;;;  khong co NTD, NTDP lan NTDK.
;;;
;;;  Nap tep: go APPLOAD, chon tep nay, bam Load.
;;;  Tep luu bang ma UTF-8. Sua bang Notepad thi nho luu lai dung UTF-8.
;;; ==================================================================

(vl-load-com)

;;; ------------------------------------------------------------------
;;;  Tach mot dong thanh danh sach chuoi.
;;;
;;;  Dau phan cach cot chon THEO TUNG DONG: dong nao co DAU CHAM PHAY
;;;  thi tach theo cham phay, khong thi tach theo dau phay.
;;;
;;;  KHONG duoc tach theo ca hai cung luc. Da do tren ban 2027: dong
;;;  "1;2000,5;1000,5" (kieu Excel ngon ngu tieng Viet) khi tach theo ca
;;;  hai se vo thanh NAM manh 1 / 2000 / 5 / 1000 / 5, roi lenh lay nham
;;;  hai manh dau thanh toa do (2000, 5). Diem roi vao cho hoan toan
;;;  khac ma KHONG co dau hieu gi bao sai - nguy hiem hon han viec bo qua.
;;; ------------------------------------------------------------------
(defun iic-tach (s / ds o c i pc)
  (setq pc (if (vl-string-search ";" s) ";" ","))
  (setq ds nil o "" i 1)
  (while (<= i (strlen s))
    (setq c (substr s i 1))
    (if (= c pc)
      (progn (setq ds (cons o ds)) (setq o ""))
      (setq o (strcat o c))
    )
    (setq i (1+ i))
  )
  (reverse (cons o ds))
)

;;; ------------------------------------------------------------------
;;;  Doi chuoi thanh so, nil neu khong phai so.
;;;
;;;  Neu chuoi khong doc duoc va co DAU PHAY thi thu lai mot lan nua sau
;;;  khi doi dau phay thanh dau cham - day la tep xuat tu Excel dat ngon
;;;  ngu tieng Viet. Moi lan phai doi nhu vay deu duoc DEM va BAO ra o
;;;  cuoi, chu khong sua lut.
;;; ------------------------------------------------------------------
(defun iic-so (s / v)
  (if s
    (progn
      (setq s (vl-string-trim " \t\r\n\"" s))
      (cond
        ((= s "") nil)
        ((setq v (distof s 2)) v)
        ((vl-string-search "," s)
         (setq v (distof (vl-string-translate "," "." s) 2))
         (if v (progn (setq *IIC-DOIPHAY* (1+ (if *IIC-DOIPHAY* *IIC-DOIPHAY* 0))) v))
        )
        (T nil)
      )
    )
  )
)

;;; ------------------------------------------------------------------
;;;  Doc tep, tra ve danh sach (so_hieu x y) theo TRUC CUA AUTOCAD
;;;  qu = "T" (trac dia: cot thu nhat sau so hieu la X-bac)
;;;       "C" (cad: cot thu nhat sau so hieu la X-ngang)
;;;  Tra ve (danh_sach . so_dong_bo_qua)
;;; ------------------------------------------------------------------
(defun iic-doc (tep qu / f dong o a b n ds bo stt)
  (setq f (open tep "r"))
  (if (null f)
    nil
    (progn
      (setq ds nil bo 0 stt 0 *IIC-DOIPHAY* 0)
      (while (setq dong (read-line f))
        (setq o (iic-tach dong))
        (cond
          ;; ba cot tro len: so_hieu , so , so
          ;; Doi chuoi thanh so NGAY TRONG phep thu, khong goi iic-so hai
          ;; lan cho cung mot o: goi hai lan thi bo dem "da doi dau phay"
          ;; cong len gap doi, va con so bao cho nguoi dung se sai.
          ((and (>= (length o) 3)
                (setq a (iic-so (nth 1 o)))
                (setq b (iic-so (nth 2 o))))
           (setq ds (cons (list (vl-string-trim " \t\r\n\"" (nth 0 o))
                                (if (= qu "T") b a)
                                (if (= qu "T") a b)) ds))
          )
          ;; hai cot: so , so
          ((and (= (length o) 2)
                (setq a (iic-so (nth 0 o)))
                (setq b (iic-so (nth 1 o))))
           (setq stt (1+ stt))
           (setq ds (cons (list (itoa stt)
                                (if (= qu "T") b a)
                                (if (= qu "T") a b)) ds))
          )
          (T (setq bo (1+ bo)))
        )
      )
      (close f)
      (cons (reverse ds) bo)
    )
  )
)

;;; hoi tep + quy uoc truc, tra ve (danh_sach . bo_qua) hoac nil
(defun iic-hoi (/ tep qu r)
  (setq tep (getfiled "Chon tep toa do (CSV hoac TXT)" "" "csv;txt" 4))
  (if (null tep)
    (progn (princ "\nChua chon tep.") nil)
    (progn
      (initget "Tracdia Cad")
      (setq qu (getkword "\nQuy uoc truc [Tracdia/Cad] <Tracdia>: "))
      (if (null qu) (setq qu "Tracdia"))
      (setq r (iic-doc tep (if (= qu "Tracdia") "T" "C")))
      (if (null r)
        (progn (princ "\nKhong mo duoc tep.") nil)
        (progn
          (princ (strcat "\n  Doc duoc : " (itoa (length (car r))) " diem"))
          (princ (strcat "\n  Bo qua   : " (itoa (cdr r)) " dong"))
          (if (> (cdr r) 0)
            (princ "\n  (dong tieu de, dong trong, hoac dong khong doc ra so)")
          )
          (if (and *IIC-DOIPHAY* (> *IIC-DOIPHAY* 0))
            (princ (strcat "\n  Da doi dau phay thanh dau cham o "
                           (itoa *IIC-DOIPHAY*)
                           " con so (tep xuat tu Excel tieng Viet)."))
          )
          r
        )
      )
    )
  )
)

;;; ------------------------------------------------------------------
;;;  NTD - cham diem va ghi so hieu
;;; ------------------------------------------------------------------
(defun c:NTD (/ r ds cao o)
  (setq r (iic-hoi))
  (if r
    (progn
      (setq ds (car r))
      (setq cao (getvar "TEXTSIZE"))
      (if (or (null cao) (<= cao 0)) (setq cao 2.5))
      (foreach o ds
        (entmake (list (cons 0 "POINT") (cons 10 (list (cadr o) (caddr o) 0.0))))
        (entmake (list (cons 0 "TEXT")
                       (cons 10 (list (+ (cadr o) (* cao 0.5))
                                      (+ (caddr o) (* cao 0.5)) 0.0))
                       (cons 40 cao)
                       (cons 1 (car o))))
      )
      (princ (strcat "\n  Da cham " (itoa (length ds)) " diem kem so hieu."))
      (princ "\n  Neu khong thay diem thi go DDPTYPE roi chon mot kieu diem de nhin.")
    )
  )
  (princ)
)

;;; ------------------------------------------------------------------
;;;  NTDP - noi cac diem thanh mot da tuyen
;;; ------------------------------------------------------------------
(defun c:NTDP (/ r ds kin dt o)
  (setq r (iic-hoi))
  (if r
    (progn
      (setq ds (car r))
      (if (< (length ds) 2)
        (princ "\n  Can it nhat hai diem moi noi duoc.")
        (progn
          (initget "Co Khong")
          (setq kin (getkword "\nKhep kin da tuyen [Co/Khong] <Khong>: "))
          (setq dt (list (cons 0 "LWPOLYLINE")
                         (cons 100 "AcDbEntity")
                         (cons 100 "AcDbPolyline")
                         (cons 90 (length ds))
                         (cons 70 (if (= kin "Co") 1 0))))
          (foreach o ds
            (setq dt (append dt (list (cons 10 (list (cadr o) (caddr o))))))
          )
          (entmake dt)
          (princ (strcat "\n  Da noi " (itoa (length ds)) " diem thanh mot da tuyen."))
        )
      )
    )
  )
  (princ)
)

;;; ------------------------------------------------------------------
;;;  NTDK - chi doc va in ra, khong ve gi
;;; ------------------------------------------------------------------
(defun c:NTDK (/ r ds o n)
  (setq r (iic-hoi))
  (if r
    (progn
      (setq ds (car r) n 0)
      (princ "\n")
      (princ "\n  So hieu        X (cad)          Y (cad)")
      (princ "\n  ---------------------------------------------")
      (foreach o ds
        (setq n (1+ n))
        (if (<= n 20)
          (princ (strcat "\n  " (car o) "\t" (rtos (cadr o) 2 3)
                         "\t" (rtos (caddr o) 2 3)))
        )
      )
      (if (> n 20) (princ (strcat "\n  ... va " (itoa (- n 20)) " diem nua")))
      (princ "\n")
    )
  )
  (princ)
)

(princ "\nNTD-IIC da nap. Lenh: NTD (cham diem), NTDP (noi da tuyen), NTDK (chi doc thu).")
(princ)

Quy ước trục trắc địa: chỗ làm quay bản vẽ 90 độ

Đây là điều phải quyết trước khi vẽ, và là lý do lệnh hỏi chứ không tự đoán.

Trắc địa Việt Nam quy ước X là trục bắc, Y là trục đông. AutoCAD thì X là trục ngang, Y là trục dọc. Nghĩa là cột X trong bảng của đội đo phải vào Y của AutoCAD.

Nhiều tệp lisp lưu hành đổi trục sẵn mà không hỏi câu nào. Dùng cho bản đồ địa chính thì đúng, nhưng dùng cho một bảng toạ độ đã ghi theo trục CAD thì hình ra lật ngang, và không có gì báo.

Lệnh trong tệp này hỏi [Tracdia/Cad] ngay sau khi chọn tệp. Mặc định là trắc địa vì đó là phần lớn trường hợp, nhưng một lần Enter nhầm thì vẫn quay được về bằng UNDO.

Con số đối chiếu: bốn điểm thành một hình khép kín

Cách chắc chắn nhất để biết đọc đúng hay sai là nối các điểm lại rồi đo hình.

Tệp thử có sáu dòng: một dòng tiêu đề, bốn dòng toạ độ, một dòng hỏng cố ý. Bốn điểm ấy theo trục trắc địa phải cho một hình chữ nhật 1000 × 800.

Đo cái gìGiá trị
Số điểm đọc được4
Số dòng bỏ qua2 (tiêu đề và dòng hỏng)
Chu vi đa tuyến kín, tính tay 3.6003.600,0
Diện tích, tính tay 800.000800.000,0

Khớp tuyệt đối. Và bốn đỉnh sinh ra đúng chỗ phải đến: (1000, 2000), (2000, 2000), (2000, 2800), (1000, 2800) — tức là phép đổi trục đã làm đúng.

Dòng tiêu đề bị bỏ qua tự động, nên không phải xoá nó trước khi chạy.

Đọc toạ độ từ Excel Ảnh: Bốn điểm đọc từ tệp, nối thành đa tuyến kín, chu vi và diện tích khớp phép tính tay

Tệp Excel tiếng Việt: dấu phẩy thập phân

Đây là chỗ gây hỏng nhiều nhất trong thực tế Việt Nam, và cũng là chỗ tệp này khác các bản đang lưu hành.

Excel đặt ngôn ngữ tiếng Việt xuất CSV ra kiểu này: cột ngăn bằng dấu chấm phẩy, còn số thập phân viết bằng dấu phẩy. Một dòng trông như 1;2000,5;1000,5.

Tệp của Viện đọc được đúng dòng ấy:

Đo cái gìKết quả
Số điểm đọc được3
Toạ độ điểm đầu1000,5 và 2000,5 — đúng số trong tệp
Số con số phải đổi dấu phẩy4
Cùng tệp nhưng viết dấu chấm0 con số phải đổi

Quan trọng là nó báo ra đã đổi bao nhiêu con số, chứ không sửa lút. Nếu bạn nghĩ tệp của mình viết dấu chấm mà máy báo đã đổi vài chục con số, thì có chuyện cần xem lại.

Chỗ nguy hiểm nhất không phải bỏ sót mà là đọc sai âm thầm

Trong lúc thử tệp này, một bản nháp trước đó tách cột theo cả dấu phẩy lẫn dấu chấm phẩy cùng lúc. Nghe thì tiện, nhưng gặp dòng 1;2000,5;1000,5 nó vỡ thành năm mảnh: 1, 2000, 5, 1000, 5. Lệnh lấy hai mảnh đầu làm toạ độ và chấm điểm ở (2000; 5) thay vì (1000,5; 2000,5).

Điểm rơi cách chỗ đúng gần hai nghìn đơn vị, và không có một dòng cảnh báo nào. Nếu chỉ nhìn số điểm đọc được thì mọi thứ trông hoàn hảo.

Bản phát hành đã sửa: dấu phân cách cột được chọn theo từng dòng — dòng nào có dấu chấm phẩy thì tách theo chấm phẩy, không thì tách theo dấu phẩy.

Bài học chung cho mọi tệp lisp đọc dữ liệu: bỏ sót thì còn phát hiện được, đọc sai âm thầm thì không. Cách tự kiểm duy nhất đáng tin là nối các điểm lại rồi đo chu vi hoặc diện tích, so với con số biết trước. Cách đo có trong bài tính diện tích trong CAD.

Hướng dẫn dùng, từng bước một

BướcLàm gì
1Trong Excel: File → Save As → CSV
2Trong AutoCAD: APPLOAD, chọn tệp NTD-IIC.lsp, bấm Load
3NTDK để đọc thử, xem số điểm và số dòng bỏ qua có đúng không
4Đúng rồi thì gõ NTD để chấm điểm, hoặc NTDP để nối thành đa tuyến

Việc nhập tọa độ từ Excel vào AutoCAD chỉ mất vài giây, nên bước kiểm mới là chỗ đáng bỏ công. Bước 3 là bước nên làm thành thói quen. Lệnh NTDK không vẽ gì cả, chỉ in ra danh sách toạ độ và hai con số thống kê. Nhìn chúng trước khi vẽ thì phát hiện sai định dạng ngay, thay vì phát hiện sau khi bản vẽ đã có hai trăm điểm sai chỗ.

Nếu chấm điểm xong mà không nhìn thấy gì trên màn hình thì không phải lỗi: kiểu điểm mặc định của AutoCAD là một chấm gần như vô hình. Gõ DDPTYPE rồi chọn một kiểu dễ nhìn — cách đặt có trong bài lệnh point style trong CAD.

Mấy điều hay nghe nhưng không đúng

Người ta hay nóiThực tế đo được
Chèn bảng Excel vào CAD là đưa được toạ độ vàoBảng OLE là một bức ảnh, không bắt điểm được
Tệp lisp nào cũng đổi trục giống nhauNhiều bản đổi sẵn mà không hỏi; sai quy ước là hình lật ngang
Phải xoá dòng tiêu đề trước khi đọcDòng nào không đọc ra số thì tự bị bỏ qua
Tệp Excel tiếng Việt thì phải sửa tayTệp này đọc được và báo đã đổi bao nhiêu con số
Đọc sai thì máy sẽ báoTách cột sai cho ra điểm lệch gần hai nghìn đơn vị mà không báo gì

Câu hỏi thường gặp

Tệp Excel phải lưu dạng gì?

Lưu thành CSV: File → Save As → CSV. Tệp văn bản .txt mỗi dòng một điểm cũng đọc được.

Cột phải xếp thế nào?

số hiệu,X,Y hoặc chỉ X,Y. Thiếu cột số hiệu thì lệnh tự đánh số 1, 2, 3.

Toạ độ của tôi theo trục trắc địa hay trục CAD?

Nếu bảng do đội đo gửi thì gần như chắc chắn là trắc địa, X là trục bắc. Chọn Tracdia ở câu hỏi thứ hai.

Tệp của tôi dùng dấu phẩy thập phân thì sao?

Đọc được. Lệnh tự thử đổi sang dấu chấm và báo ra đã đổi bao nhiêu con số.

Chấm điểm xong không thấy gì trên bản vẽ?

Kiểu điểm mặc định gần như vô hình. Gõ DDPTYPE rồi chọn một kiểu khác.

Làm sao biết đọc đúng hay sai?

Chạy NTDK đọc thử trước. Hoặc nối các điểm thành đa tuyến kín rồi so chu vi và diện tích với con số biết trước.

Về tác giả

TS. Đỗ Quốc Hoàng — Phó Viện trưởng Viện Tin học Xây dựng – Trường Đại học Xây dựng Hà Nội, chuyên gia lập trình phần mềm trong xây dựng