Đến nội dung


Hình ảnh
- - - - -

Kết hợp Excel-AutoLisp-AutoCAD


  • Please log in to reply
60 replies to this topic

#21 ndtnv

ndtnv

    biết lệnh minsert

  • Members
  • PipPipPipPipPipPip
  • 437 Bài viết
Điểm đánh giá: 384 (khá)

Đã gửi 04 November 2008 - 07:18 AM

Wow wow wow , được nhiều hồi âm giúp đỡ quá , Em cảm ơn rất nhiều

*
cài này em tạm lưu để dành sử dụng khi khác, vì kích thước của em phải theo mẩu của cty , không giống kiểu này.

*
cái này em không biết xài
làm theo hướng dẫn nhưng nó báo thế này , A xem và chỉ giúp nhé, cài này thấy hay vì chỉ thay đổi tại 1 vị trí cố định
Hình 1
Hình 2
*
anh này đã giúp em giảm bớt được 99% thời gian làm công việc này

1% là em phải vào cad nhập thêm chiều dài thanh sắt là xong

Còn 1% này anh giúp được không vậy, không thì cũng rất ok rồi
Em dùng Cad 2005, excel 2003


Đó là vì chế độ security ở mức cao.
Vào Tools->Marcro->security và chọn mức medium
Sau đó khi mở file thì chọn enable macro là chạy được
Nếu bạn đưa bản vẽ hoàn chỉnh, tôi sẽ giúp 100% thời gian làm công việc này
Dĩ nhiên là phải làm chi tiết bên excel rồi
  • 0

#22 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 04 November 2008 - 10:11 AM

Trước tiên là PP xin cảm ơn bác Ssg đã rất quan tâm trao đổi về đề tài này.
Như đã nói trên, đây mới chỉ là 1 idea của PP, vả lại cũng cần phải nói trước là công việc của PP (và cty) không phải là detailing các chi tiết trên. Muốn detailing thì cty thuê thợ bên ngoài dùng Tekla để model và cung cấp bv luôn. Idea này chỉ dùng để hổ trợ các bác Drafter về việc xuất bv chi tiết của các tháp thép hoặc các công việc khác liên quan đến các thanh và lỗ...
Trong link này có 1 bv 3D của tháp thép, 1 bv chi tiết thanh để làm mẫu, các information dùng để detailing.
http://www.cadviet.c...es/Tower_DS.zip
Như PP đã nêu trong bước 14 là tạo 1 sheet set manager để tiện việc quản lý tất cả các bv. PP đã làm thử như hình đính kèm trong link.
Vì để dể dàng quản lý hàng trăm bv, các bv chi tiết nên save vảo mỗi folder cho từng đoạn tháp thép. Sheet set manager sẽ giúp việc mở các bv cần xem một cách tiện lợi và nhanh chóng.
Cái tháp DG20 có khoảng 500 bản vẽ đó bác Ssg.
PP muốn biết làm sao để "gom lại và "chơi" luôn một lần?". Xin bác viết cho đoạn LISP đó nhé. Thanks you

Các file bạn up lên không đủ thông tin cần thiết để lập trình! Các file *.jpg và file 3d của bạn chỉ giúp được cái nhìn tổng quan, chưa nói lên điều gì cả, có chăng là một vài nhận định chung nhất về tính khả thi của ý tưởng cũng như định hướng chung chung về lập trình. Để có chương trình, cần phải mô tả chi tiết hơn, cụ thể "đến từng sợi tóc". Bạn phải cung cấp cái Input và Output chính xác. Cụ thể:
- Input: file *.xls và các file *.dwg, *.dwt có liên quan trong library
- Output: khoảng 5 đến 10 file *.dwg khác nhau và mang tính chất điển hình trong toàn bộ project của bạn
Chương trình sẽ lấy data từ cái Input, xử lý và tạo ra cái Output như bạn đã post

Lưu ý:
Phải là các file y chang như bạn thực hiện thật sự cho Cty, không thiếu bất cứ chi tiết nhỏ nào chứ không phải các file ví dụ chung chung. Rất nhiều thông tin chứa trong file, có khi bạn cho là không quan trọng, không cần đề cập đến, nhưng chúng rất quan trọng đối với người lập trình. Tóm lại, các file tự chúng sẽ nói lên nhiều điều, bạn không cần giải thích dài dòng.

Nếu bạn thấy vướng vấn đề security của Cty thì thôi, không phải miễn cưỡng!
  • 0

#23 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 04 November 2008 - 11:20 AM

Cảm ơn ssg đã trả lời, việc lấy dữ liệu từ *.txt ntsơn đã lấy nhiều, có trường hợp các dòng dữ lệu thay đổi liên tục nhưng vẫn có quy luật. Tuy nhiên thuật toán lấy dữ lệu vẫn còn thủ công. Ví dụ khi kết thúc tệp thì phải có 1 ký tự đặc biệt nào đó, khi các dòng có dữ liệu thay đổi (dòng 1 có 2 dữ liệu cần lấy, dòng 2 có 3 dữ liệu cần lấy...) thì phải thêm 1 ký tự trống vào cuối dòng 1 (hoặc n ký tự trống), số ký tự phụ thuộc vào số dữ liệu cần lấy trên 1 dòng nhiều nhất....Vì năng lực có hạn, ntson không nghĩ được thuật toán khả thi hơn.
Còn file *.csv ntson trưa tiếp xúc bao giờ.
Mong ssg trả lời.


Trước hết, cần nhìn nhận vấn đề một cách tổng quát như sau:
Cả 3 trình Excel, Lisp và Acad đều làm việc với data (dữ liệu). Mỗi công cụ có một cách thức riêng của mình để xử lý data, dùng cái này rất khó (hoặc không thể) can thiệp vào "công việc nội bộ" của cái kia được. Biện pháp hiệu quả để thực hiện mối liên kết giữa 3 công cụ nói trên là: chỉ cần đọc hiểu data của nhau theo một chuẩn chung nào đó. Khi đã hiểu rồi thì tự xử lý theo cách riêng của mình.
Ví dụ: Bạn không thể biết Acad tổ chức, quản lý data của các đối tượng trong bản vẽ *.dwg như thế nào (trừ khi bạn là nhân viên lập trình của Autodesk), nhưng bạn có thể truy cập được chúng bằng hàm entget. Kết quả bạn nhận được là một list, chứa đủ các thông tin bạn cần, sau đó tuỳ nghi xử lý và sử dụng chúng cho nhiều mục đích khác nhau.
Bạn hãy làm tương tự như vậy với các file dữ liệu của excel: *.xls, *.csv, *.txt (bản chất các file này ssg sẽ phân tích sau), nghĩa là đọc tất tần tật những gì có thể đọc được trong file, convert (chuyển đổi) chúng sang dạng list (kiểu dữ liệu cơ bản, có thể nói là "sở trường" của ngôn ngữ Lisp). Có list rồi, bạn có thể bày ra đủ "trò phù thuỷ" từ chúng vì ngôn ngữ Lisp cung cấp rất nhiều function (hàm) thao tác với list.

Về các loại file data đã đề cập trên, bạn hãy làm các thử nghiệm sau:

1. Tạo và save file Data01.xls như thế này:

Hình đã gửi

2. Saveas -> trong listbox Save as type, bạn chọn "Text (Tab delimited) (*.txt)"
Đây là kiểu file dữ liệu, phân biệt các field bằng dấu tab. Khi bạn save dạng này, trình Excel sẽ cảnh báo "Dạng file này không thể lưu được nhiều sheet". Bạn cứ mặc nó, phớt lờ bấm "OK". Nó sẽ báo tiếp "Dạng này sẽ có một số tính năng không khả dụng". Bạn cũng kệ xác nó, tỉnh bơ bấm "Yes" -> bạn đã có 1 file Data01.txt theo kiểu Tab delimited lưu trên đĩa.

3. Làm tương tự bước 2, với dạng "CSV (Comma delimited) (*.csv)" -> bạn sẽ có file Data01.csv

4. Thoát Excel. Lúc này nó lại hỏi "Do you want to save...?", bạn hãy bấm "No" (hỏi gì mà hỏi lắm không biết!)

5. Mở Notepad, trong "File of type" chọn "All File", open file *.txt lúc nãy, bạn sẽ thấy như sau:

Hình đã gửi

Dùng các phím mũi tên Right-Left di chuyển con trỏ, bạn sẽ thấy các thành phần cách nhau bằng 1 dấu tab. Với dạng file này, cách ssg lấy dữ liệu như sau:
- Dùng read-line đọc một mạch từ đầu đến cuối cho đến EOF (End Of File). Chỗ này lưu ý bạn, trong file text, không cần phải đặt dầu hiệu kết thúc vì trong bản thân mỗi file tự nó đã có dầu hiệu EOF. Hệ điều hành hoặc các ứng dụng đều căn cứ vào dấu hiệu này để kết thúc thao tác đọc file. Bạn không nhìn thấy EOF vì các trình Editor (soạn thảo văn bản) không hiển thị nó, nhưng hàm read-line thì biết, khi gặp EOF, nó return (hoàn trả) giá trị nil.
- Trong quá trình đọc, sau mỗi dòng, bạn có thể dùng append để ghi nhận thông tin từng dòng vào một list
- Kết thúc quá trình, bạn sẽ nhận đuợc 1 list chứa toàn bộ nội dung của file Data01.txt. Mỗi phần tử của list là 1 string (chuỗi ký tự). Mỗi string sẽ chứa các dữ liệu bạn cần, được phân biệt bằng dầu tab ("\t"). Đến đây có lẽ bạn đã biết cách tách ra cái mình cần?
- Ssg đã xây dựng sẵn hàm FtoL, convert trực tiếp từ file *.txt kiểu như trên sang List 2 cấp (mỗi phần tử của list cấp 1 là 1 list cấp 2, mỗi phần tử của list cấp 2 chính là dữ liệu của 1 cell trong bảng). Bạn có thể vào chương trình Mechanical CadViet (trong box CadViet Utility) để tham khảo.

6. Làm tương tự bước 5 với file Data01.csv, bạn sẽ thấy như sau:

Hình đã gửi

Nó không ngay hàng thẳng lối, nhưng cung cách tổ chức giống y chang như với file Data01.txt, chỉ khác ở chỗ dấu tab được thay bằng dấu phẩy. Hoàn toàn tương tự như trên, bạn cũng tách ra được các dữ liệu, cái nào ra cái đó như ý muốn dựa vào dấu phẩy ngăn cách.

Bạn hãy tự làm và tự chiêm nghiệm với 2 kiểu database trên. Khi bạn đã thông suốt với *.txt và *.csv, ssg sẽ giới thiệu kiểu *.xls (kiểu này lôi thôi hơn, nếu không thông 2 kiểu trên e rằng hơi khó trình bày).

Hẹn gặp lại!
  • 0

#24 ntson

ntson

    biết zoom

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

Đã gửi 04 November 2008 - 01:48 PM

Trước hết, cần nhìn nhận vấn đề một cách tổng quát như sau:
Cả 3 trình Excel, Lisp và Acad đều làm việc với data (dữ liệu). Mỗi công cụ có một cách thức riêng của mình để xử lý data, dùng cái này rất khó (hoặc không thể) can thiệp vào "công việc nội bộ" của cái kia được. Biện pháp hiệu quả để thực hiện mối liên kết giữa 3 công cụ nói trên là: chỉ cần đọc hiểu data của nhau theo một chuẩn chung nào đó. Khi đã hiểu rồi thì tự xử lý theo cách riêng của mình.
Ví dụ: Bạn không thể biết Acad tổ chức, quản lý data của các đối tượng trong bản vẽ *.dwg như thế nào (trừ khi bạn là nhân viên lập trình của Autodesk), nhưng bạn có thể truy cập được chúng bằng hàm entget. Kết quả bạn nhận được là một list, chứa đủ các thông tin bạn cần, sau đó tuỳ nghi xử lý và sử dụng chúng cho nhiều mục đích khác nhau.
Bạn hãy làm tương tự như vậy với các file dữ liệu của excel: *.xls, *.csv, *.txt (bản chất các file này ssg sẽ phân tích sau), nghĩa là đọc tất tần tật những gì có thể đọc được trong file, convert (chuyển đổi) chúng sang dạng list (kiểu dữ liệu cơ bản, có thể nói là "sở trường" của ngôn ngữ Lisp). Có list rồi, bạn có thể bày ra đủ "trò phù thuỷ" từ chúng vì ngôn ngữ Lisp cung cấp rất nhiều function (hàm) thao tác với list.

Về các loại file data đã đề cập trên, bạn hãy làm các thử nghiệm sau:

1. Tạo và save file Data01.xls như thế này:

Hình đã gửi

2. Saveas -> trong listbox Save as type, bạn chọn "Text (Tab delimited) (*.txt)"
Đây là kiểu file dữ liệu, phân biệt các field bằng dấu tab. Khi bạn save dạng này, trình Excel sẽ cảnh báo "Dạng file này không thể lưu được nhiều sheet". Bạn cứ mặc nó, phớt lờ bấm "OK". Nó sẽ báo tiếp "Dạng này sẽ có một số tính năng không khả dụng". Bạn cũng kệ xác nó, tỉnh bơ bấm "Yes" -> bạn đã có 1 file Data01.txt theo kiểu Tab delimited lưu trên đĩa.

3. Làm tương tự bước 2, với dạng "CSV (Comma delimited) (*.csv)" -> bạn sẽ có file Data01.csv

4. Thoát Excel. Lúc này nó lại hỏi "Do you want to save...?", bạn hãy bấm "No" (hỏi gì mà hỏi lắm không biết!)

5. Mở Notepad, trong "File of type" chọn "All File", open file *.txt lúc nãy, bạn sẽ thấy như sau:

Hình đã gửi

Dùng các phím mũi tên Right-Left di chuyển con trỏ, bạn sẽ thấy các thành phần cách nhau bằng 1 dấu tab. Với dạng file này, cách ssg lấy dữ liệu như sau:
- Dùng read-line đọc một mạch từ đầu đến cuối cho đến EOF (End Of File). Chỗ này lưu ý bạn, trong file text, không cần phải đặt dầu hiệu kết thúc vì trong bản thân mỗi file tự nó đã có dầu hiệu EOF. Hệ điều hành hoặc các ứng dụng đều căn cứ vào dấu hiệu này để kết thúc thao tác đọc file. Bạn không nhìn thấy EOF vì các trình Editor (soạn thảo văn bản) không hiển thị nó, nhưng hàm read-line thì biết, khi gặp EOF, nó return (hoàn trả) giá trị nil.
- Trong quá trình đọc, sau mỗi dòng, bạn có thể dùng append để ghi nhận thông tin từng dòng vào một list
- Kết thúc quá trình, bạn sẽ nhận đuợc 1 list chứa toàn bộ nội dung của file Data01.txt. Mỗi phần tử của list là 1 string (chuỗi ký tự). Mỗi string sẽ chứa các dữ liệu bạn cần, được phân biệt bằng dầu tab ("\t"). Đến đây có lẽ bạn đã biết cách tách ra cái mình cần?
- Ssg đã xây dựng sẵn hàm FtoL, convert trực tiếp từ file *.txt kiểu như trên sang List 2 cấp (mỗi phần tử của list cấp 1 là 1 list cấp 2, mỗi phần tử của list cấp 2 chính là dữ liệu của 1 cell trong bảng). Bạn có thể vào chương trình Mechanical CadViet (trong box CadViet Utility) để tham khảo.

6. Làm tương tự bước 5 với file Data01.csv, bạn sẽ thấy như sau:

Hình đã gửi

Nó không ngay hàng thẳng lối, nhưng cung cách tổ chức giống y chang như với file Data01.txt, chỉ khác ở chỗ dấu tab được thay bằng dấu phẩy. Hoàn toàn tương tự như trên, bạn cũng tách ra được các dữ liệu, cái nào ra cái đó như ý muốn dựa vào dấu phẩy ngăn cách.

Bạn hãy tự làm và tự chiêm nghiệm với 2 kiểu database trên. Khi bạn đã thông suốt với *.txt và *.csv, ssg sẽ giới thiệu kiểu *.xls (kiểu này lôi thôi hơn, nếu không thông 2 kiểu trên e rằng hơi khó trình bày).

Hẹn gặp lại!

ntSon đã thông hiểu với file *.txt, *.csv. Rất mong SSG nói về cách lấy dữ liệu ở file *.xls, và có 1 ví dụ cụ thể
vd tách dữ liệu từ 1 file *.xls như sau:
A1 A2 A3 A4
B1 B2 B4
C1 C2 C3
D1 D2 D3 D4
E1 E2
(Nhiều nhất có 4 cột)
Cảm ơn SSG rất nhiều.
  • 0

#25 Phiphi-

Phiphi-

    biết lệnh minsert

  • Members
  • PipPipPipPipPipPip
  • 434 Bài viết
Điểm đánh giá: 175 (tàm tạm)

Đã gửi 04 November 2008 - 09:15 PM

Các file bạn up lên không đủ thông tin cần thiết để lập trình! Các file *.jpg và file 3d của bạn chỉ giúp được cái nhìn tổng quan, chưa nói lên điều gì cả, có chăng là một vài nhận định chung nhất về tính khả thi của ý tưởng cũng như định hướng chung chung về lập trình. Để có chương trình, cần phải mô tả chi tiết hơn, cụ thể "đến từng sợi tóc". Bạn phải cung cấp cái Input và Output chính xác. Cụ thể:
- Input: file *.xls và các file *.dwg, *.dwt có liên quan trong library
- Output: khoảng 5 đến 10 file *.dwg khác nhau và mang tính chất điển hình trong toàn bộ project của bạn
Chương trình sẽ lấy data từ cái Input, xử lý và tạo ra cái Output như bạn đã post

Lưu ý:
Phải là các file y chang như bạn thực hiện thật sự cho Cty, không thiếu bất cứ chi tiết nhỏ nào chứ không phải các file ví dụ chung chung. Rất nhiều thông tin chứa trong file, có khi bạn cho là không quan trọng, không cần đề cập đến, nhưng chúng rất quan trọng đối với người lập trình. Tóm lại, các file tự chúng sẽ nói lên nhiều điều, bạn không cần giải thích dài dòng.

Nếu bạn thấy vướng vấn đề security của Cty thì thôi, không phải miễn cưỡng!

Từ idea biến thảnh hiện thực phải cần có thời gian bác Ssg ạ.
PP chưa có cái "- Input: file *.xls và các file *.dwt có liên quan trong library"
PP cần phải giàn xếp thời gian để tạo bảng Excel mẫu, các chủng loại cho library... rồi mới gởi Bác.
Output thì tuỳ khung tên của từng cty yêu cầu, nhưng đối với PP thì bv đã post trên là đầy đủ rồi đó bác Ssg.
Để model hoặc detailing cái tháp thép, bv 3D cùng với list vật liệu, số bolts+size mỗi thanh và hình cho biết ID của từng thanh như trong link trên cũng là đầy đủ (ngoài trừ các plate). Drafter cần lấy kích thước trong bv 3D rồi vẽ thành các chi tiết gia công. Cám ơn ý kiến của bác Ssg.
  • 0

#26 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 06 November 2008 - 07:49 AM

ntSon đã thông hiểu với file *.txt, *.csv. Rất mong SSG nói về cách lấy dữ liệu ở file *.xls, và có 1 ví dụ cụ thể
vd tách dữ liệu từ 1 file *.xls như sau:
A1 A2 A3 A4
B1 B2 B4
C1 C2 C3
D1 D2 D3 D4
E1 E2
(Nhiều nhất có 4 cột)
Cảm ơn SSG rất nhiều.

Các file *.txt, *.csv có cách tổ chức data khác nhau nhưng bản chất của chúng đều là TextFile (bao gồm các ký tự ASCII, có thể đọc hiểu được một cách tường minh). Với *.xls thì không phải như vậy. Ví dụ, bạn thử dùng NotePad để open *.xls xem, chỉ thấy một đám ký tự lằng nhằng chẳng hiểu gì cả. Hàm read-line cũng chào thua!

AutoLisp "cổ điển" không thể truy xuất *.xls được. Từ khi Autodesk phát triển Visual Lisp (bắt đầu từ version nào ssg không nhớ chính xác, nhưng chắc chắn phải từ 2000 trở đi), kỹ thuật ActiveX được đưa vào, mở ra một khả năng ứng dụng rộng rãi, có thể giao tiếp được với nhiều phần mềm khác nhau, không riêng gì với Excel. Kỹ thuật ActiveX là một mảng rất rộng, có lẽ còn tốn nhiều... giấy mực cho đề tài này. Hãy đợi đấy!

Trong Visual Lisp, các function sử dụng kỹ thuật ActiveX được bắt đầu bằng tiếp đầu ngữ VLA. Bạn dùng function GET_xl (lưu ý: luôn luôn phải kèm theo nó function phụ rec-rem-dupl) trong bài ssg trả lời bạn caothang sẽ truy xuất được dữ liệu từ bất kỳ cell nào bạn muốn trong file *.xls. Lưu ý thêm, trước khi gọi các function VLA, bạn phải gọi (vl-load-com) và chỉ cần 1 lần duy nhất trong 1 tài liệu *.dwg đang mở.
Ví dụ:

(defun C:E2C ()
(vl-load-com)
(setq
fn (getfiled "Select Data File" "" "xls" 0)
d (get_xl fn)
)
)


Bạn chạy E2C cho file *.xls hôm nọ, kết quả d bạn nhận được là:
Command: E2C
Return:
(("Sheet1$" ("STT" "Ho" "TenDem" "Ten") (1.0 "Kha" "Tran" "Ac") (2.0 "Au" "Duong" "Phong") (3.0 "Hoang" "Duoc" "Su") (4.0 "Hoang" nil "Dung") (5.0 "Quach" nil "Tinh") (6.0 "Hong" "That" "Cong")) ("Sheet2$") ("Sheet3$"))

Đây là một list 3 cấp:
- Cấp 1: chứa các sheet
- Cấp 2: chứa các record trong sheet
- Cấp 3: thành phần field trong record

Lấy toàn bộ nội dung của sheet1:
Command: (setq s1 (cdr (car d)))
Return:
(("STT" "Ho" "TenDem" "Ten") (1.0 "Kha" "Tran" "Ac") (2.0 "Au" "Duong" "Phong")
(3.0 "Hoang" "Duoc" "Su") (4.0 "Hoang" nil "Dung") (5.0 "Quach" nil "Tinh")
(6.0 "Hong" "That" "Cong"))

Cell B4 chẳng hạn (họ của đảo chủ đảo Đào hoa) được lấy như sau:
Command: (nth 1 (nth 3 s1))
Return:
"Hoang"

Tương tự như vậy, bạn có thể truy xuất bất kỳ cell nào trong cả file *.xls mà bạn muốn.
  • 0

#27 ntson

ntson

    biết zoom

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

Đã gửi 07 November 2008 - 05:18 PM

Các file *.txt, *.csv có cách tổ chức data khác nhau nhưng bản chất của chúng đều là TextFile (bao gồm các ký tự ASCII, có thể đọc hiểu được một cách tường minh). Với *.xls thì không phải như vậy. Ví dụ, bạn thử dùng NotePad để open *.xls xem, chỉ thấy một đám ký tự lằng nhằng chẳng hiểu gì cả. Hàm read-line cũng chào thua!

AutoLisp "cổ điển" không thể truy xuất *.xls được. Từ khi Autodesk phát triển Visual Lisp (bắt đầu từ version nào ssg không nhớ chính xác, nhưng chắc chắn phải từ 2000 trở đi), kỹ thuật ActiveX được đưa vào, mở ra một khả năng ứng dụng rộng rãi, có thể giao tiếp được với nhiều phần mềm khác nhau, không riêng gì với Excel. Kỹ thuật ActiveX là một mảng rất rộng, có lẽ còn tốn nhiều... giấy mực cho đề tài này. Hãy đợi đấy!

Trong Visual Lisp, các function sử dụng kỹ thuật ActiveX được bắt đầu bằng tiếp đầu ngữ VLA. Bạn dùng function GET_xl (lưu ý: luôn luôn phải kèm theo nó function phụ rec-rem-dupl) trong bài ssg trả lời bạn caothang sẽ truy xuất được dữ liệu từ bất kỳ cell nào bạn muốn trong file *.xls. Lưu ý thêm, trước khi gọi các function VLA, bạn phải gọi (vl-load-com) và chỉ cần 1 lần duy nhất trong 1 tài liệu *.dwg đang mở.
Ví dụ:


(defun C:E2C ()
(vl-load-com)
(setq
fn (getfiled "Select Data File" "" "xls" 0)
d (get_xl fn)
)
)


Bạn chạy E2C cho file *.xls hôm nọ, kết quả d bạn nhận được là:
Command: E2C
Return:
(("Sheet1$" ("STT" "Ho" "TenDem" "Ten") (1.0 "Kha" "Tran" "Ac") (2.0 "Au" "Duong" "Phong") (3.0 "Hoang" "Duoc" "Su") (4.0 "Hoang" nil "Dung") (5.0 "Quach" nil "Tinh") (6.0 "Hong" "That" "Cong")) ("Sheet2$") ("Sheet3$"))

Đây là một list 3 cấp:
- Cấp 1: chứa các sheet
- Cấp 2: chứa các record trong sheet
- Cấp 3: thành phần field trong record

Lấy toàn bộ nội dung của sheet1:
Command: (setq s1 (cdr (car d)))
Return:
(("STT" "Ho" "TenDem" "Ten") (1.0 "Kha" "Tran" "Ac") (2.0 "Au" "Duong" "Phong")
(3.0 "Hoang" "Duoc" "Su") (4.0 "Hoang" nil "Dung") (5.0 "Quach" nil "Tinh")
(6.0 "Hong" "That" "Cong"))

Cell B4 chẳng hạn (họ của đảo chủ đảo Đào hoa) được lấy như sau:
Command: (nth 1 (nth 3 s1))
Return:
"Hoang"

Tương tự như vậy, bạn có thể truy xuất bất kỳ cell nào trong cả file *.xls mà bạn muốn.

Cảm ơn SSG
  • 0

#28 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 01 December 2008 - 10:30 AM

Một ví dụ minh hoạ về kết hợp Lisp - Excel - AutoCAD:

http://www.cadviet.c...es/ThenBang.zip

Chương trình tra số liệu và vẽ mặt cắt của rãnh then bằng trên trục hoặc lỗ. Ví dụ của Cơ khí nhưng có lẽ các bạn ở các ngành khác cũng có thể tham khảo được. Sơ đồ tổng quát của chương trình như sau:

1. Nhập "dữ liệu thô" vào Excel: số liệu đo, tính được hoặc có sẵn từ các bảng tiêu chuẩn kỹ thuật
2. Dùng các công thức, công cụ của Excel để tính toán, xử lý thành "dữ liệu tinh"
3. Trình lisp đọc dữ liệu tinh từ file *.xls, xử lý tiếp tuỳ theo yêu cầu và thể hiện kết quả bằng các đối tượng AutoCAD

Các functions liên quan đến Excel trong trình Lisp là của... Tây nó viết, member CadViet đã post lên diễn đàn (ở chỗ nào ssg không nhớ nữa). Để hiểu hết các code của nó còn phải dày công. Tuy nhiên, dù chưa hiểu lắm, các bạn cũng có thể sử dụng chúng rất hiệu quả. Cụ thể:

1. GetExcel: đọc data trong 1 file *.xls mà không cần khởi động Excel
2. GetExcel0: đọc data trong 1 file *.xls đang open. Cái này ssg modify từ cái trên và chưa chỉnh sửa gì nhiều
3. GetCell: đọc dữ liệu từ 1 cell
4. PutCell: ghi dữ liệu vào 1 cell
5. OpenExcel: mở 1 file *.xls
6. CloseExcel: thoát trình Excel đang chạy

Chương trình còn đang ở dạng sơ khai. Bạn nào thấy thích thì "ngâm cứu" tiếp. Thấy cái gì hay hay thì post lên để anh em cùng học hỏi.

PS: Sau khi load file lsp, gõ FK để chạy

Bài viết đã được chỉnh sửa nội dung bởi ssg: 01 December 2008 - 11:32 AM

  • 1

#29 mrmoon273

mrmoon273

    biết pan

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

Đã gửi 14 January 2009 - 11:27 AM

Bác Ssg chưa hiểu toàn bộ ý của PP.
PP muốn là sẽ xuất ra các bản vẽ hoàn chỉnh ngoài cái hình "ban ve gia cong" post ở trên thì còn chứa mọi thông tin của 1 bản vẽ chi tiết cần phải có như khung tên, tên project, chi tiết gia công, yêu cầu kỹ thuật, BOM, chi tiết người vẽ, duyệt, kiểm tra, khách hàng, thời gian, liệt kê mọi chi tiết các revisions liên quan vv... Bời vậy phải cần có sheet Info, để điền các data này sau đó LISP mới đọc và input tự động vào bv. (Lợi ích của bảng Excel này còn giúp người quản lý chỉ cần mở bảng này ra xem là biết mọi information của mọi bv, Excel cho phép copy các text giống nhau trong các bv bằng 1 vài cái "click", giúp cho Drafter khỏi phải đánh text trong bv).....



Y tưởng này của Phiphi đúng là thứ mình đang tìm kiếm. Tuyệt vời.... ^_^

Tại chỗ mình làm hiện nay đang phải chuyển đổi tất cả các bản vẽ để quản lý theo sheet set. Có rất nhiều bản vẽ, và việc nhập lại, đánh lại tên các bản vẽ mất rất nhiều thời gian, thêm vào đó, cái list dwgs (bằng Excel) thì thay đổi liên miên.

Các bạn có thể giúp mình tạo 1 lisp mà có thể: cập nhật Rivision, số bản vẽ, tên bản vẽ TV, tên bản vẽ TA, tỉ lệ bản vẽ từ 1 file list dwg bằng Excel vào trong Sheet set, (Vì các bản vẽ đã đc tạo các att tương ứng với các trường của sheet set), từ đó khi muốn thay đổi tên bản vẽ, số hiện bản vẽ v.v.... ta chỉ việc thay đổi ở Excel, thì các bản vẽ sẽ được tự cập nhật tương ứng.

cảm ơn rất nhiều
  • 0

#30 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 15 January 2009 - 02:20 PM

Y tưởng này của Phiphi đúng là thứ mình đang tìm kiếm. Tuyệt vời.... ^_^

Tại chỗ mình làm hiện nay đang phải chuyển đổi tất cả các bản vẽ để quản lý theo sheet set. Có rất nhiều bản vẽ, và việc nhập lại, đánh lại tên các bản vẽ mất rất nhiều thời gian, thêm vào đó, cái list dwgs (bằng Excel) thì thay đổi liên miên.

Các bạn có thể giúp mình tạo 1 lisp mà có thể: cập nhật Rivision, số bản vẽ, tên bản vẽ TV, tên bản vẽ TA, tỉ lệ bản vẽ từ 1 file list dwg bằng Excel vào trong Sheet set, (Vì các bản vẽ đã đc tạo các att tương ứng với các trường của sheet set), từ đó khi muốn thay đổi tên bản vẽ, số hiện bản vẽ v.v.... ta chỉ việc thay đổi ở Excel, thì các bản vẽ sẽ được tự cập nhật tương ứng.

cảm ơn rất nhiều

Bạn post lên 1 file *.xls và vài file *.dwg (có ký hiệu tương ứng trong file *.xls), có khung tên thiết kế bằng att theo mẫu chuẩn nhất của bạn.
  • 0

#31 mrmoon273

mrmoon273

    biết pan

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

Đã gửi 15 January 2009 - 04:47 PM

Bạn post lên 1 file *.xls và vài file *.dwg (có ký hiệu tương ứng trong file *.xls), có khung tên thiết kế bằng att theo mẫu chuẩn nhất của bạn.


Cảm ơn Ssg đã quan tâm đến câu hỏi của mình.

Để mọi người tiện theo dõi là giúp đỡ, mình xin post 1 ví dụ giữa Sheet set và Excel.

Trong ví dụ này, tất cả các bản vẽ trong thư mục HVAC\Hotel đc quản lý bởi sheet set đặt tại thư mục Stds. Giữa file Excel và sheet set hiện giờ chưa có sự liên kết nào. Khi nhập, sửa dữ liệu tại file Excel thì sau đó lại phải vào sheet set để sửa lại bằng tay, rất mất thời gian và hay bị nhầm lẫn khi mà số lượng bản vẽ lớn.

Các bạn có thể giúp mình tạo lisp để liên kết 2 thằng lại với nhau: khi chỉnhh sửa gì ở Excel thì thằng sheet set tự cập nhật --> bản vẽ cũng đc cập nhật theo.

Cảm ơn rất nhiều.

Đây là link để down file ví dụ:
http://www.4shared.c...995/sample.html
  • 0

#32 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 16 January 2009 - 10:09 AM

Cảm ơn Ssg đã quan tâm đến câu hỏi của mình.

Để mọi người tiện theo dõi là giúp đỡ, mình xin post 1 ví dụ giữa Sheet set và Excel.

Trong ví dụ này, tất cả các bản vẽ trong thư mục HVAC\Hotel đc quản lý bởi sheet set đặt tại thư mục Stds. Giữa file Excel và sheet set hiện giờ chưa có sự liên kết nào. Khi nhập, sửa dữ liệu tại file Excel thì sau đó lại phải vào sheet set để sửa lại bằng tay, rất mất thời gian và hay bị nhầm lẫn khi mà số lượng bản vẽ lớn.

Các bạn có thể giúp mình tạo lisp để liên kết 2 thằng lại với nhau: khi chỉnhh sửa gì ở Excel thì thằng sheet set tự cập nhật --> bản vẽ cũng đc cập nhật theo.

Cảm ơn rất nhiều.

Đây là link để down file ví dụ:
http://www.4shared.c...995/sample.html

Sheet Set là một dạng quản lý bản vẽ mới. Bản thân ssg cũng chưa dùng cái này bao giờ. Có yêu cầu của bạn, ssg mới xem qua một lượt, khá hay! Ssg cũng đã tìm trong Developer Help của Cad2007, nhưng thật đáng tiếc, chỉ có VBA tương tác được với Sheet Set (VBA không phải là sở trường của ssg), còn với Lisp thì theo ssg là "bó tay chấm com"! Dù sao thì ssg cũng ghi nhận, sẽ tìm hiểu kỹ hơn, có phát hiện gì mới ssg sẽ post lên cho bạn.
Hơi thắc mắc một chút: bạn đã dùng Sheet Set thì cần gì đến file *.xls? Tự thân file *.dst đã chứa đầy đủ thông tin cần thiết rồi?
  • 0

#33 mrmoon273

mrmoon273

    biết pan

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

Đã gửi 16 January 2009 - 04:10 PM

Sheet Set là một dạng quản lý bản vẽ mới. Bản thân ssg cũng chưa dùng cái này bao giờ. Có yêu cầu của bạn, ssg mới xem qua một lượt, khá hay! Ssg cũng đã tìm trong Developer Help của Cad2007, nhưng thật đáng tiếc, chỉ có VBA tương tác được với Sheet Set (VBA không phải là sở trường của ssg), còn với Lisp thì theo ssg là "bó tay chấm com"! Dù sao thì ssg cũng ghi nhận, sẽ tìm hiểu kỹ hơn, có phát hiện gì mới ssg sẽ post lên cho bạn.
Hơi thắc mắc một chút: bạn đã dùng Sheet Set thì cần gì đến file *.xls? Tự thân file *.dst đã chứa đầy đủ thông tin cần thiết rồi?


SSG nói hoàn toàn chính xác.

Thắng sheet set sau khi mình tạo xong, có có thể xuất ra 1 bảng dạng Table của CAD với đầy đủ các thông tin mình có trong sheet set, Table đó còn insert được thêm các cột theo mục đích sử dụng của người dùng và có thể export ra file *.CSV.
để thay đổi cái dữ liệu của bản vẽ, mình buộc phải thực hiện trên sheet set, sau đó update ra table, mà thực hiện trên thằng sheet set thì tương đối mất thời gian và khó làm, trong khi các yêu cầu sửa đổi thường đc đưa ra bằng file Excel.

Như vậy cái mình muốn nói đến ở đây là quá trình thực hiện công việc ở thưc tế, và nó lại ngược với những cái CAD cho làm. ^_^, tức là khi có dự liệu thay đổi tại file excel, thằng sheet set sẽ đc cập nhật ( bằng lệch update hay gì đó ) để tự động thay đổi các bản vẽ mà nó quản lý....

Mình nghĩ bài toán này tương đối hay, mong đc các cao thủ quan tâm, trợ giúp.hi hi...

Cảm ơn các bạn nhiều.
  • 0

#34 Canhdome

Canhdome

    biết vẽ ellipse

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

Đã gửi 16 January 2009 - 04:54 PM

Đó là vì chế độ security ở mức cao.
Vào Tools->Marcro->security và chọn mức medium
Sau đó khi mở file thì chọn enable macro là chạy được
Nếu bạn đưa bản vẽ hoàn chỉnh, tôi sẽ giúp 100% thời gian làm công việc này
Dĩ nhiên là phải làm chi tiết bên excel rồi

^_^ Hinh như là file excell này ko update được đâu. có nghĩa như sau nè. Nếu bạn làm xong rùi mà có chỉnh sửa thì bạn đành vào cad chỉnh chứ ko chỉnh từ excell rồi update qua cad được đâu. Mong được bác giúp đở dùm . Thanks . Chúc anh em có 1 ngày cuối tuần thật là vui vẽ & hạnh phúc :D
  • 0

#35 Phiphi-

Phiphi-

    biết lệnh minsert

  • Members
  • PipPipPipPipPipPip
  • 434 Bài viết
Điểm đánh giá: 175 (tàm tạm)

Đã gửi 20 January 2009 - 07:06 PM

SSG nói hoàn toàn chính xác.

Thắng sheet set sau khi mình tạo xong, có có thể xuất ra 1 bảng dạng Table của CAD với đầy đủ các thông tin mình có trong sheet set, Table đó còn insert được thêm các cột theo mục đích sử dụng của người dùng và có thể export ra file *.CSV.
để thay đổi cái dữ liệu của bản vẽ, mình buộc phải thực hiện trên sheet set, sau đó update ra table, mà thực hiện trên thằng sheet set thì tương đối mất thời gian và khó làm, trong khi các yêu cầu sửa đổi thường đc đưa ra bằng file Excel.

Như vậy cái mình muốn nói đến ở đây là quá trình thực hiện công việc ở thưc tế, và nó lại ngược với những cái CAD cho làm. ^_^, tức là khi có dự liệu thay đổi tại file excel, thằng sheet set sẽ đc cập nhật ( bằng lệch update hay gì đó ) để tự động thay đổi các bản vẽ mà nó quản lý....

Mình nghĩ bài toán này tương đối hay, mong đc các cao thủ quan tâm, trợ giúp.hi hi...

Cảm ơn các bạn nhiều.

Gần Tết rồi nên pà con bận rộn, sau Tết sẽ có bài giải.
PP có 1 bài tham khảo này: http://www.cadviet.c...art=#entry48708
  • 0

#36 tuananhcmd

tuananhcmd

    biết zoom

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

Đã gửi 05 February 2009 - 09:37 AM

tôi đã lấy được dữ liệu từ exel liên kết vào cad
nhưng khi dữ liệu trong exel là 1 chuỗi string có dấu thì mọi việc trở nên phức tạp
nó không còn nguyên dạng được nữa kể cả tôi đã dùng field để liên kết (sau khi đổi font cho trùng giữa cad và exel)
ssg có cách nào không
  • 0

#37 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 05 February 2009 - 02:23 PM

tôi đã lấy được dữ liệu từ exel liên kết vào cad
nhưng khi dữ liệu trong exel là 1 chuỗi string có dấu thì mọi việc trở nên phức tạp
nó không còn nguyên dạng được nữa kể cả tôi đã dùng field để liên kết (sau khi đổi font cho trùng giữa cad và exel)
ssg có cách nào không

Ssg dùng Get_XL (đã post hôm nọ) vẫn chuyển được "dấu má" đầy đủ từ Excel qua đối tượng Text của Acad.
Font trong Excel: .VnArial, .VnTime, ...
Font trong CAD: như trên, hoặc vnsimple.shx, vnsimli.shx, ...
Bạn thử xem sao!
  • 0

#38 tuananhcmd

tuananhcmd

    biết zoom

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

Đã gửi 05 February 2009 - 02:48 PM

mình dùng theo cái này
bạn có cách gì để sử dụng nó không



(defun GetExcel (ExcelFile$ SheetName$ MaxRange$ / Column# ColumnRow@ Data@ ExcelRange^
ExcelValue ExcelValue ExcelVariant^ MaxColumn# MaxRow# Range$ Row# Worksheet)
(if (= (type ExcelFile$) 'STR)
(if (not (findfile ExcelFile$))
(progn
(alert (strcat "Excel file " ExcelFile$ " not found."))
(exit)
);progn
);if
(progn
(alert "Excel file not specified.")
(exit)
);progn
);if
(gc)
(if (setq *ExcelApp% (vlax-get-object "Excel.Application"))
(progn
(alert "Close all Excel spreadsheets to continue!")
(vlax-release-object *ExcelApp%)(gc)
);progn
);if
(setq *ExcelApp% (vlax-get-or-create-object "Excel.Application"))
(vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Open ExcelFile$)
(if SheetName$
(vlax-for Worksheet (vlax-get-property *ExcelApp% "Sheets")
(if (= (vlax-get-property Worksheet "Name") SheetName$)
(vlax-invoke-method Worksheet "Activate")
);if
);vlax-for
);if
(setq ColumnRow@ (ColumnRow MaxRange$))
(setq MaxColumn# (nth 0 ColumnRow@))
(setq MaxRow# (nth 1 ColumnRow@))
(setq *ExcelData@ nil)
(setq Row# 1)
(repeat MaxRow#
(setq Data@ nil)
(setq Column# 1)
(repeat MaxColumn#
(setq Range$ (strcat (Number2Alpha Column#)(itoa Row#)))
(setq ExcelRange^ (vlax-get-property *ExcelApp% "Range" Range$))
(setq ExcelVariant^ (vlax-get-property ExcelRange^ 'Value))
(setq ExcelValue (vlax-variant-value ExcelVariant^))
(setq ExcelValue
(cond
((= (type ExcelValue) 'INT) (itoa ExcelValue))
((= (type ExcelValue) 'REAL) (rtosr ExcelValue))
((= (type ExcelValue) 'STR) (vl-string-trim " " ExcelValue))
((/= (type ExcelValue) 'STR) "")
);cond
);setq
(setq Data@ (append Data@ (list ExcelValue)))
(setq Column# (1+ Column#))
);repeat
(setq *ExcelData@ (append *ExcelData@ (list Data@)))
(setq Row# (1+ Row#))
);repeat
(vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook") 'Close :vlax-False)
(vlax-invoke-method *ExcelApp% 'Quit)
(vlax-release-object *ExcelApp%)(gc)
(setq *ExcelApp% nil)
*ExcelData@
);defun GetExcel
;-------------------------------------------------------------------------------
; GetCell - Returns the cell value from the *ExcelData@ list
; Arguments: 1
; Cell$ = Cell ID
; Syntax example: (GetCell "E19") = value of cell E19
;-------------------------------------------------------------------------------
(defun GetCell (Cell$ / Column# ColumnRow@ Return Row#)
(setq ColumnRow@ (ColumnRow Cell$))
(setq Column# (1- (nth 0 ColumnRow@)))
(setq Row# (1- (nth 1 ColumnRow@)))
(setq Return "")
(if *ExcelData@
(if (and (>= (length *ExcelData@) Row#)(>= (length (nth 0 *ExcelData@)) Column#))
(setq Return (nth Column# (nth Row# *ExcelData@)))
);if
);if
Return
);defun GetCell
;-------------------------------------------------------------------------------
; OpenExcel - Opens an Excel spreadsheet
; Arguments: 3
; ExcelFile$ = Excel filename or nil for new spreadsheet
; SheetName$ = Sheet name or nil for not specified
; Visible = t for visible or nil for hidden
; Syntax examples:
; (OpenExcel "C:\\Temp\\Temp.xls" "Sheet2" t) = Opens C:\Temp\Temp.xls on Sheet2 as visible session
; (OpenExcel "C:\\Temp\\Temp.xls" nil nil) = Opens C:\Temp\Temp.xls on current sheet as hidden session
; (OpenExcel nil "Parts List" nil) = Opens a new spreadsheet and creates a Part List sheet as hidden session
;-------------------------------------------------------------------------------
(defun OpenExcel (ExcelFile$ SheetName$ Visible / Sheet$ Sheets@ Worksheet)
(if (= (type ExcelFile$) 'STR)
(if (findfile ExcelFile$)
(setq *ExcelFile$ ExcelFile$)
(progn
(alert (strcat "Excel file " ExcelFile$ " not found."))
(exit)
);progn
);if
(setq *ExcelFile$ "")
);if
(gc)
(if (setq *ExcelApp% (vlax-get-object "Excel.Application"))
(progn
(alert "Close all Excel spreadsheets to continue!")
(vlax-release-object *ExcelApp%)(gc)
);progn
);if
(setq *ExcelApp% (vlax-get-or-create-object "Excel.Application"))
(if ExcelFile$
(if (findfile ExcelFile$)
(vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Open ExcelFile$)
(vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Add)
);if
(vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Add)
);if
(if Visible
(vla-put-visible *ExcelApp% :vlax-true)
);if
(if (= (type SheetName$) 'STR)
(progn
(vlax-for Sheet$ (vlax-get-property *ExcelApp% "Sheets")
(setq Sheets@ (append Sheets@ (list (vlax-get-property Sheet$ "Name"))))
);vlax-for
(if (member SheetName$ Sheets@)
(vlax-for Worksheet (vlax-get-property *ExcelApp% "Sheets")
(if (= (vlax-get-property Worksheet "Name") SheetName$)
(vlax-invoke-method Worksheet "Activate")
);if
);vlax-for
(vlax-put-property (vlax-invoke-method (vlax-get-property *ExcelApp% "Sheets") "Add") "Name" SheetName$)
);if
);progn
);if
(princ)
);defun OpenExcel
;-------------------------------------------------------------------------------
; PutCell - Put values into Excel cells
; Arguments: 2
; StartCell$ = Starting Cell ID
; Data@ = Value or list of values
; Syntax examples:
; (PutCell "A1" "PART NUMBER") = Puts PART NUMBER in cell A1
; (PutCell "B3" '("Dim" 7.5 "9.75")) = Starting with cell B3 put Dim, 7.5, and 9.75 across
;-------------------------------------------------------------------------------
(defun PutCell (StartCell$ Data@ / Cell$ Column# ExcelRange Row#)
(if (= (type Data@) 'STR)
(setq Data@ (list Data@))
)
(setq ExcelRange (vlax-get-property *ExcelApp% "Cells"))
(if (Cell-p StartCell$)
(setq Column# (car (ColumnRow StartCell$))
Row# (cadr (ColumnRow StartCell$))
);setq
(if (vl-catch-all-error-p
(setq Cell$ (vl-catch-all-apply 'vlax-get-property
(list (vlax-get-property *ExcelApp% "ActiveSheet") "Range" StartCell$))
);setq
);vl-catch-all-error-p
(alert (strcat "The cell ID \"" StartCell$ "\" is invalid."))
(setq Column# (vlax-get-property Cell$ "Column")
Row# (vlax-get-property Cell$ "Row")
);setq
);if
);if
(if (and Column# Row#)
(foreach Item Data@
(vlax-put-property ExcelRange "Item" Row# Column# (vl-princ-to-string Item))
(setq Column# (1+ Column#))
);foreach
);if
(princ)
);defun PutCell
;-------------------------------------------------------------------------------
; CloseExcel - Closes Excel spreadsheet
; Arguments: 1
; ExcelFile$ = Excel saveas filename or nil to close without saving
; Syntax examples:
; (CloseExcel "C:\\Temp\\Temp.xls") = Saveas C:\Temp\Temp.xls and close
; (CloseExcel nil) = Close without saving
;-------------------------------------------------------------------------------
(defun CloseExcel (ExcelFile$ / Saveas)
(if ExcelFile$
(if (= (strcase ExcelFile$) (strcase *ExcelFile$))
(if (findfile ExcelFile$)
(vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook") "Save")
(setq Saveas t)
);if
(if (findfile ExcelFile$)
(progn
(vl-file-delete (findfile ExcelFile$))
(setq Saveas t)
);progn
(setq Saveas t)
);if
);if
);if
(if Saveas
(vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook")
"SaveAs" ExcelFile$ -4143 "" "" :vlax-false :vlax-false nil
);vlax-invoke-method
);if
(vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook") 'Close :vlax-False)
(vlax-invoke-method *ExcelApp% 'Quit)
(vlax-release-object *ExcelApp%)(gc)
(setq *ExcelApp% nil *ExcelFile$ nil)
(princ)
);defun CloseExcel
;-------------------------------------------------------------------------------
; ColumnRow - Returns a list of the Column and Row number
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
; Cell$ = Cell ID
; Syntax example: (ColumnRow "ABC987") = '(731 987)
;-------------------------------------------------------------------------------
(defun ColumnRow (Cell$ / Column$ Char$ Row#)
(setq Column$ "")
(while (< 64 (ascii (setq Char$ (strcase (substr Cell$ 1 1)))) 91)
(setq Column$ (strcat Column$ Char$)
Cell$ (substr Cell$ 2)
);setq
);while
(if (and (/= Column$ "") (numberp (setq Row# (read Cell$))))
(list (Alpha2Number Column$) Row#)
'(1 1);default to "A1" if there's a problem
);if
);defun ColumnRow
;-------------------------------------------------------------------------------
; Alpha2Number - Converts Alpha string into Number
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
; Str$ = String to convert
; Syntax example: (Alpha2Number "ABC") = 731
;-------------------------------------------------------------------------------
(defun Alpha2Number (Str$ / Num#)
(if (= 0 (setq Num# (strlen Str$)))
0
(+ (* (- (ascii (strcase (substr Str$ 1 1))) 64) (expt 26 (1- Num#)))
(Alpha2Number (substr Str$ 2))
);+
);if
);defun Alpha2Number
;-------------------------------------------------------------------------------
; Number2Alpha - Converts Number into Alpha string
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
; Num# = Number to convert
; Syntax example: (Number2Alpha 731) = "ABC"
;-------------------------------------------------------------------------------
(defun Number2Alpha (Num# / Val#)
(if (< Num# 27)
(chr (+ 64 Num#))
(if (= 0 (setq Val# (rem Num# 26)))
(strcat (Number2Alpha (1- (/ Num# 26))) "Z")
(strcat (Number2Alpha (/ Num# 26)) (chr (+ 64 Val#)))
);if
);if
);defun Number2Alpha
;-------------------------------------------------------------------------------
; Cell-p - Evaluates if the argument Cell$ is a valid cell ID
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
; Cell$ = String of the cell ID to evaluate
; Syntax examples: (Cell-p "B12") = t, (Cell-p "BT") = nil
;-------------------------------------------------------------------------------
(defun Cell-p (Cell$)
(and (= (type Cell$) 'STR)
(or (= (strcase Cell$) "A1")
(not (equal (ColumnRow Cell$) '(1 1)))
);or
);and
);defun Cell-p
;-------------------------------------------------------------------------------
; Row+n - Returns the cell ID located a number of rows from cell
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 2
; Cell$ = Starting cell ID
; Num# = Number of rows from cell
; Syntax examples: (Row+n "B12" 3) = "B15", (Row+n "B12" -3) = "B9"
;-------------------------------------------------------------------------------
(defun Row+n (Cell$ Num#)
(setq Cell$ (ColumnRow Cell$))
(strcat (Number2Alpha (car Cell$)) (itoa (max 1 (+ (cadr Cell$) Num#))))
);defun Row+n
;-------------------------------------------------------------------------------
; Column+n - Returns the cell ID located a number of columns from cell
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 2
; Cell$ = Starting cell ID
; Num# = Number of columns from cell
; Syntax examples: (Column+n "B12" 3) = "E12", (Column+n "B12" -1) = "A12"
;-------------------------------------------------------------------------------
(defun Column+n (Cell$ Num#)
(setq Cell$ (ColumnRow Cell$))
(strcat (Number2Alpha (max 1 (+ (car Cell$) Num#))) (itoa (cadr Cell$)))
);defun Column+n
;-------------------------------------------------------------------------------
; rtosr - Used to change a real number into a short real number string
; stripping off all trailing 0's.
; Arguments: 1
; RealNum~ = Real number to convert to a short string real number
; Returns: ShortReal$ the short string real number value of the real number.
;-------------------------------------------------------------------------------
(defun rtosr (RealNum~ / DimZin# ShortReal$)
(setq DimZin# (getvar "DIMZIN"))
(setvar "DIMZIN" 8)
(setq ShortReal$ (rtos RealNum~ 2 8))
(setvar "DIMZIN" DimZin#)
ShortReal$
);defun rtosr


  • 0

#39 ssg

ssg

    biết lệnh adcenter

  • Vip
  • PipPipPipPipPipPipPip
  • 1228 Bài viết
Điểm đánh giá: 1087 (rất tốt)

Đã gửi 05 February 2009 - 04:07 PM

mình dùng theo cái này
bạn có cách gì để sử dụng nó không

Người ta đã ghi rõ comment và cách sử dụng rồi mà. Bạn tham khảo code sau, có thêm vài dòng comment của ssg và các ví dụ ở cuối file. Bạn appload, chạy lần lượt các lệnh từ VD1 đến VD5, quan sát các phản ứng trên Cad lẫn Excel sẽ hiểu rõ hơn:

;;;(defun GetExcel (ExcelFile$ SheetName$ MaxRange$ / Column# ColumnRow@ Data@ ExcelRange^
;;;ExcelValue ExcelValue ExcelVariant^ MaxColumn# MaxRow# Range$ Row# Worksheet)

(defun GetExcel (ExcelFile$ SheetName$ MaxRange$)
(if (= (type ExcelFile$) 'STR)
(if (not (findfile ExcelFile$))
(progn
(alert (strcat "Excel file " ExcelFile$ " not found."))
(exit)
);progn
);if
(progn
(alert "Excel file not specified.")
(exit)
);progn
);if
(gc)
(if (setq *ExcelApp% (vlax-get-object "Excel.Application"))
(progn
(alert "Close all Excel spreadsheets to continue!")
(vlax-release-object *ExcelApp%)
(gc)
);progn
);if

;;;Phan chu yeu cua function
(setq *ExcelApp% (vlax-get-or-create-object "Excel.Application"))
(vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Open ExcelFile$)
(if SheetName$
(vlax-for Worksheet (vlax-get-property *ExcelApp% "Sheets")
(if (= (vlax-get-property Worksheet "Name") SheetName$)
(vlax-invoke-method Worksheet "Activate")
);if
);vlax-for
);if
(setq ColumnRow@ (ColumnRow MaxRange$))
(setq MaxColumn# (nth 0 ColumnRow@))
(setq MaxRow# (nth 1 ColumnRow@))
(setq *ExcelData@ nil)
(setq Row# 1)
(repeat MaxRow#
(setq Data@ nil)
(setq Column# 1)
(repeat MaxColumn#
(setq Range$ (strcat (Number2Alpha Column#)(itoa Row#)))
(setq ExcelRange^ (vlax-get-property *ExcelApp% "Range" Range$))
(setq ExcelVariant^ (vlax-get-property ExcelRange^ 'Value))
(setq ExcelValue (vlax-variant-value ExcelVariant^))
(setq ExcelValue
(cond
((= (type ExcelValue) 'INT) (itoa ExcelValue))
((= (type ExcelValue) 'REAL) (rtosr ExcelValue))
((= (type ExcelValue) 'STR) (vl-string-trim " " ExcelValue))
((/= (type ExcelValue) 'STR) "")
);cond
);setq
(setq Data@ (append Data@ (list ExcelValue)))
(setq Column# (1+ Column#))
);repeat
(setq *ExcelData@ (append *ExcelData@ (list Data@)))
(setq Row# (1+ Row#))
);repeat
(vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook") 'Close :vlax-False)
(vlax-invoke-method *ExcelApp% 'Quit)
(vlax-release-object *ExcelApp%)(gc)
(setq *ExcelApp% nil)
*ExcelData@
)
;-------------------------------------------------------------------------------
; GetCell - Returns the cell value from the *ExcelData@ list
; Arguments: 1
; Cell$ = Cell ID
; Syntax example: (GetCell "E19") = value of cell E19
;-------------------------------------------------------------------------------
(defun GetCell (Cell$ / Column# ColumnRow@ Return Row#)
(setq ColumnRow@ (ColumnRow Cell$))
(setq Column# (1- (nth 0 ColumnRow@)))
(setq Row# (1- (nth 1 ColumnRow@)))
(setq Return "")
(if *ExcelData@
(if (and (>= (length *ExcelData@) Row#)(>= (length (nth 0 *ExcelData@)) Column#))
(setq Return (nth Column# (nth Row# *ExcelData@)))
);if
);if
Return
);defun GetCell
;-------------------------------------------------------------------------------
; OpenExcel - Opens an Excel spreadsheet
; Arguments: 3
; ExcelFile$ = Excel filename or nil for new spreadsheet
; SheetName$ = Sheet name or nil for not specified
; Visible = t for visible or nil for hidden
; Syntax examples:
; (OpenExcel "C:\\Temp\\Temp.xls" "Sheet2" t) = Opens C:\Temp\Temp.xls on Sheet2 as visible session
; (OpenExcel "C:\\Temp\\Temp.xls" nil nil) = Opens C:\Temp\Temp.xls on current sheet as hidden session
; (OpenExcel nil "Parts List" nil) = Opens a new spreadsheet and creates a Part List sheet as hidden session
;-------------------------------------------------------------------------------
(defun OpenExcel (ExcelFile$ SheetName$ Visible / Sheet$ Sheets@ Worksheet)
(if (= (type ExcelFile$) 'STR)
(if (findfile ExcelFile$)
(setq *ExcelFile$ ExcelFile$)
(progn
(alert (strcat "Excel file " ExcelFile$ " not found."))
(exit)
);progn
);if
(setq *ExcelFile$ "")
);if
(gc)
(if (setq *ExcelApp% (vlax-get-object "Excel.Application"))
(progn
(alert "Close all Excel spreadsheets to continue!")
(vlax-release-object *ExcelApp%)(gc)
);progn
);if
(setq *ExcelApp% (vlax-get-or-create-object "Excel.Application"))
(if ExcelFile$
(if (findfile ExcelFile$)
(vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Open ExcelFile$)
(vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Add)
);if
(vlax-invoke-method (vlax-get-property *ExcelApp% 'WorkBooks) 'Add)
);if
(if Visible
(vla-put-visible *ExcelApp% :vlax-true)
);if
(if (= (type SheetName$) 'STR)
(progn
(vlax-for Sheet$ (vlax-get-property *ExcelApp% "Sheets")
(setq Sheets@ (append Sheets@ (list (vlax-get-property Sheet$ "Name"))))
);vlax-for
(if (member SheetName$ Sheets@)
(vlax-for Worksheet (vlax-get-property *ExcelApp% "Sheets")
(if (= (vlax-get-property Worksheet "Name") SheetName$)
(vlax-invoke-method Worksheet "Activate")
);if
);vlax-for
(vlax-put-property (vlax-invoke-method (vlax-get-property *ExcelApp% "Sheets") "Add") "Name" SheetName$)
);if
);progn
);if
(princ)
);defun OpenExcel
;-------------------------------------------------------------------------------
; PutCell - Put values into Excel cells
; Arguments: 2
; StartCell$ = Starting Cell ID
; Data@ = Value or list of values
; Syntax examples:
; (PutCell "A1" "PART NUMBER") = Puts PART NUMBER in cell A1
; (PutCell "B3" '("Dim" 7.5 "9.75")) = Starting with cell B3 put Dim, 7.5, and 9.75 across
;-------------------------------------------------------------------------------
(defun PutCell (StartCell$ Data@ / Cell$ Column# ExcelRange Row#)
(if (= (type Data@) 'STR)
(setq Data@ (list Data@))
)
(setq ExcelRange (vlax-get-property *ExcelApp% "Cells"))
(if (Cell-p StartCell$)
(setq Column# (car (ColumnRow StartCell$))
Row# (cadr (ColumnRow StartCell$))
);setq
(if (vl-catch-all-error-p
(setq Cell$ (vl-catch-all-apply 'vlax-get-property
(list (vlax-get-property *ExcelApp% "ActiveSheet") "Range" StartCell$))
);setq
);vl-catch-all-error-p
(alert (strcat "The cell ID \"" StartCell$ "\" is invalid."))
(setq Column# (vlax-get-property Cell$ "Column")
Row# (vlax-get-property Cell$ "Row")
);setq
);if
);if
(if (and Column# Row#)
(foreach Item Data@
(vlax-put-property ExcelRange "Item" Row# Column# (vl-princ-to-string Item))
(setq Column# (1+ Column#))
);foreach
);if
(princ)
);defun PutCell
;-------------------------------------------------------------------------------
; CloseExcel - Closes Excel spreadsheet
; Arguments: 1
; ExcelFile$ = Excel saveas filename or nil to close without saving
; Syntax examples:
; (CloseExcel "C:\\Temp\\Temp.xls") = Saveas C:\Temp\Temp.xls and close
; (CloseExcel nil) = Close without saving
;-------------------------------------------------------------------------------
(defun CloseExcel (ExcelFile$ / Saveas)
(if ExcelFile$
(if (= (strcase ExcelFile$) (strcase *ExcelFile$))
(if (findfile ExcelFile$)
(vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook") "Save")
(setq Saveas t)
);if
(if (findfile ExcelFile$)
(progn
(vl-file-delete (findfile ExcelFile$))
(setq Saveas t)
);progn
(setq Saveas t)
);if
);if
);if
(if Saveas
(vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook")
"SaveAs" ExcelFile$ -4143 "" "" :vlax-false :vlax-false nil
);vlax-invoke-method
);if
(vlax-invoke-method (vlax-get-property *ExcelApp% "ActiveWorkbook") 'Close :vlax-False)
(vlax-invoke-method *ExcelApp% 'Quit)
(vlax-release-object *ExcelApp%)(gc)
(setq *ExcelApp% nil *ExcelFile$ nil)
(princ)
);defun CloseExcel
;-------------------------------------------------------------------------------
; ColumnRow - Returns a list of the Column and Row number
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
; Cell$ = Cell ID
; Syntax example: (ColumnRow "ABC987") = '(731 987)
;-------------------------------------------------------------------------------
(defun ColumnRow (Cell$ / Column$ Char$ Row#)
(setq Column$ "")
(while (< 64 (ascii (setq Char$ (strcase (substr Cell$ 1 1)))) 91)
(setq Column$ (strcat Column$ Char$)
Cell$ (substr Cell$ 2)
);setq
);while
(if (and (/= Column$ "") (numberp (setq Row# (read Cell$))))
(list (Alpha2Number Column$) Row#)
'(1 1);default to "A1" if there's a problem
);if
);defun ColumnRow
;-------------------------------------------------------------------------------
; Alpha2Number - Converts Alpha string into Number
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
; Str$ = String to convert
; Syntax example: (Alpha2Number "ABC") = 731
;-------------------------------------------------------------------------------
(defun Alpha2Number (Str$ / Num#)
(if (= 0 (setq Num# (strlen Str$)))
0
(+ (* (- (ascii (strcase (substr Str$ 1 1))) 64) (expt 26 (1- Num#)))
(Alpha2Number (substr Str$ 2))
);+
);if
);defun Alpha2Number
;-------------------------------------------------------------------------------
; Number2Alpha - Converts Number into Alpha string
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
; Num# = Number to convert
; Syntax example: (Number2Alpha 731) = "ABC"
;-------------------------------------------------------------------------------
(defun Number2Alpha (Num# / Val#)
(if (< Num# 27)
(chr (+ 64 Num#))
(if (= 0 (setq Val# (rem Num# 26)))
(strcat (Number2Alpha (1- (/ Num# 26))) "Z")
(strcat (Number2Alpha (/ Num# 26)) (chr (+ 64 Val#)))
);if
);if
);defun Number2Alpha
;-------------------------------------------------------------------------------
; Cell-p - Evaluates if the argument Cell$ is a valid cell ID
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 1
; Cell$ = String of the cell ID to evaluate
; Syntax examples: (Cell-p "B12") = t, (Cell-p "BT") = nil
;-------------------------------------------------------------------------------
(defun Cell-p (Cell$)
(and (= (type Cell$) 'STR)
(or (= (strcase Cell$) "A1")
(not (equal (ColumnRow Cell$) '(1 1)))
);or
);and
);defun Cell-p
;-------------------------------------------------------------------------------
; Row+n - Returns the cell ID located a number of rows from cell
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 2
; Cell$ = Starting cell ID
; Num# = Number of rows from cell
; Syntax examples: (Row+n "B12" 3) = "B15", (Row+n "B12" -3) = "B9"
;-------------------------------------------------------------------------------
(defun Row+n (Cell$ Num#)
(setq Cell$ (ColumnRow Cell$))
(strcat (Number2Alpha (car Cell$)) (itoa (max 1 (+ (cadr Cell$) Num#))))
);defun Row+n
;-------------------------------------------------------------------------------
; Column+n - Returns the cell ID located a number of columns from cell
; Function By: Gilles Chanteau from Marseille, France
; Arguments: 2
; Cell$ = Starting cell ID
; Num# = Number of columns from cell
; Syntax examples: (Column+n "B12" 3) = "E12", (Column+n "B12" -1) = "A12"
;-------------------------------------------------------------------------------
(defun Column+n (Cell$ Num#)
(setq Cell$ (ColumnRow Cell$))
(strcat (Number2Alpha (max 1 (+ (car Cell$) Num#))) (itoa (cadr Cell$)))
);defun Column+n
;-------------------------------------------------------------------------------
; rtosr - Used to change a real number into a short real number string
; stripping off all trailing 0's.
; Arguments: 1
; RealNum~ = Real number to convert to a short string real number
; Returns: ShortReal$ the short string real number value of the real number.
;-------------------------------------------------------------------------------
(defun rtosr (RealNum~ / DimZin# ShortReal$)
(setq DimZin# (getvar "DIMZIN"))
(setvar "DIMZIN" 8)
(setq ShortReal$ (rtos RealNum~ 2 8))
(setvar "DIMZIN" DimZin#)
ShortReal$
);defun rtosr
;-------------------------------------------------------------------------------
(princ);End of GetExcel.lsp
;;;******************************************************************

;;;Vi du ap dung cac function tren
;;;---------------------------------------------------------------------
(defun C:VD1()
(vl-load-com)
(setq fn (getfiled "Select Excel File" "" "xls" 0))
(getexcel fn "sheet1" "d11")
)
;;;---------------------------------------------------------------------
(defun C:VD2() (alert (strcat "B3 = " (getcell "B3"))))
;;;---------------------------------------------------------------------
(defun C:VD3() (openexcel fn "sheet4" T))
;;;---------------------------------------------------------------------
(defun C:VD4()
(putcell "B10" (list "How" "are you?"))
(setq mycell (getstring "\nCell address:"))
(putcell mycell "I'm fine, thank you!")
)
;;;---------------------------------------------------------------------
(defun C:VD5() (closeExcel fn))
;;;----------------------------------------------------------------------


Góp ý:
Các nội dung code bạn nên cho vào codebox để topic được gọn gàng. Mặt khác, các định dạng code (như các chỗ ra vô đầu dòng chẳng hạn) sẽ được bảo toàn y như nguyên mẫu. Ssg đã edit bài của bạn và cho nó vô rồi đó, nhìn tổng thể trang topic cảm thấy dễ chịu hơn!
  • 0

#40 tuananhcmd

tuananhcmd

    biết zoom

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

Đã gửi 05 February 2009 - 04:25 PM

tôi hiểu cách sử dụng của nó rồi
cái mà tôi muốn hỏi là nếu dùng theo cách này thì không đưa dữ liệu từ exel vào lispvariable nguyên vẹn được:
chẳng hạn trên exel là:
tiểu khu
thì lispvariable là:
ti?u khu
và tôi ko có cách nào để lấy nguyên nó được
  • 0