Connect visual basic to excel

Liên hệ QC

minhthanhnguyen

Thành viên mới
Tham gia
13/8/07
Bài viết
7
Được thích
5
Chào các bạn,

Mình vừa tạo ra một file visual basic có các box dùng để nhập một số thông tin của khách hàng vào trong đó.

Sau khi nhập xong, mình muốn export data này vào file excel. Cho mình hỏi mình cần làm những gì để có thể export được ?

Cám ơn các bạn,
 
trước bọn mình làm thì thường phải thông qua CSDL acess. Mọi DL nhập vào sẽ được lưu vào CSDL sao đó việc xuất DL từ acess sang excel thì tất đơn giản . Chúc bạn thành công.
 
Liên kết với Excel từ Visual Basic 6.0

Đây là những kiến thức cơ bản trong việc điều khiển Excel từ VB6 thông qua thư viện liên kết động DLL và EXE. Đây là hướng phát triển rất hay khi bạn đã đạt được những kiến thức nhất định về VBA và cần phải bảo vệ thành quả của mình không bị bẻ khoá. Nội dung này tôi dịch từ "Professional Excel Development: The Definitive Guide to Developing Applications Using Microsoft® Excel and VBA®
By Stephen Bullen, Rob Bovey, John Green
". Tôi cũng đã test lại cẩn thận rồi! --=0 , chúng ta sẽ tìm hiểu dần dần... Nắm được nội dung này bạn sẽ hiểu hơn một số ví dụ do anh Tuân đã post lên diễn đàn.

Trước khi tìm hiểu công việc này, bạn biết rằng Visual Basic 6.0 (VB 6.0) được xây dựng bởi tập đoàn Microsoft. Hiện này VB 6.0 đã được thay thế bởi VB.NET, tuy nhiên VB 6.0 vẫn là phần mềm được nhiều nhà lập trình sử dụng rộng rãi nhất trên thế giới. VB 6.0 mạnh mẽ hơn người anh em VBA vì VB 6.0 là ngôn ngữ lập trình hoạt động mang tính độc độc lập. Nhìn chung nội dung, cấu trúc, mã lệnh trong thủ tục của VB 6.0 và VBA rất giống nhau. Vì vậy, đối với những người am hiểu về VBA thì có thể nhanh chóng tiếp cận và sử dụng VB 6.0.
Chương này sẽ chỉ dẫn bước đầu tạo mối liên kết giữa Excel với VB 6.0 và những lý do tại sao sử dụng VB 6.0 cho các dự án VBA của bạn. VB 6.0 có thể tạo ra hơn 6 kiểu ứng dụng, nhưng chỉ có hai kiểu liên kết được với Excel là ActiveX DLL và Standard EXE. Mục này sẽ hướng dẫn bạn cách sử dụng ActiveX DLL và Standard EXE trong VB 6.0 cho Excel với ứng dụng đơn giản “Hello World”. Chúng ta sẽ khám phá sự liên kết giữa Excel và Standard EXE trong mục tiếp theo.
Như vậy bạn sẽ thắc mắc tại sao cần phải sử dụng VB 6.0 trong khi đó VBA sẵn có trong Excel?! VB 6.0 có một số khả năng mà VBA không có như khả năng biên dịch code trong form của DLL (Dynamic Link Library - Thư viện liên kết động), tạo file hoạt động một cách độc lập, đóng gói form, khả năng lập trình hướng đối tượng cao hơn, hỗ trợ các thư viện tài nguyên,... Ngoài ra khả năng điều khiển mảng dữ liệu liên liên kết được tăng cường hơn so với VBA. Dưới đây là những nét chính để bạn quyết định có nên sử dụng VB 6.0 để liên kết với Excel hay không?!
- Khả năng bảo mật code: VBA có khả năng bảo mật code để chống người khác có thể xem bằng cách sử dụng mã khoá cho dự án VBA của bạn. Điều đó là cần thiết khi bạn đã bỏ công sức để xây dựng sản phẩm của mình. Tuy nhiên hiện nay có rất nhiều chương trình có thể dò tìm và phá được khóa, khi đó code sẽ được hiện ra. Dự án của bạn lúc đó rất dễ bị phân tán để mọi người sử dụng. Nguyên nhân là do VBA không biên dịch được code, điều đó không thể ngăn chặn được người khác truy cập vào.
- Sử dụng VB 6.0 Form nâng cao: Form được đóng gói trong VB 6.0 so với sử dụng trong VBA. Đối tượng Form được tạo trong ứng dụng Excel được gọi là MSForm, còn trong VB 6.0 thì được hiểu là Ruby Form. Sự giống nhau về bên ngoài giữa chúng là Form ban đầu đều trống rỗng để bạn có thể xây dựng, di chuyển các điều khiển trong Form. Ngoài ra các điều khiển trong cả hai kiểu đều sử dụng các sự kiện xả ra với nó để thi hành thủ tục. Đương nhiên giữa chúng có sự khác nhau, ví dụ như thuộc tính, phương thức, sự kiện và kể cả các điều khiển của VB 6.0 rộng hơn...
- Hỗ trợ điều khiển ActiveX tốt hơn: Không chỉ mỗi VB 6.0 Form cung cấp khả năng hỗ trợ tốt hơn so với UserForm của các điều khiển đa dạng xây dựng trong Window. Chúng còn có hàng trăm điều khiển ActiveX nhóm 3 mà không có đầy đủ cho UserForm. Lý do như trên là hầu hết điều khiển ActiveX nhóm 3 trở thành phiên bản 2. Khi bạn xây dựng dự án thì phiên bản bạn sử dụng được gọi là design-time version của điều khiển. Khi dự án của bạn được phân phối (distributed) và chạy trong trạng thái biên dịch thì được gọi là runtime version của điều khiển. Khi bạn có được điều khiển ActiveX nhóm 3, có nghĩa là bạn đã mua bản quyền để xây dựng VB 6.0 Form bằng cách sử dụng design-time version của điều khiển. Runtime version của điều khiển, là kết quả của VB 6.0 Form sau khi được biên dịch, có thể phân phối lại không bị hạn chế trong phần lớn các trường hợp. Đây là lý do không thể sử dụng trong tài nguyên design-time và việc đó không thể sử dụng để xây dựng dự án mới.
Ngược lại UserForm trong VBA được thiết kế ở dạng mở, như vậy runtime version của điều khiển ActiveX không hoạt động với chúng. Nếu bạn đã phân phối design-time version của điều khiển để chạy trong VBA UserForm không biên dịch, về cơ bản là bạn sẽ gửi điều khiển đó cho người khác một cách miễn phí. Ai đó mà có design-time version của điều khiển được cài đặt trong máy tính thì có thể sử dụng những dự án đó, ngoài ra họ phải mua hoặc không sử dụng được.Ứng dụng Active DLL “Hello World” sẽ giải thích cho bạn cách một cách tạo liên kết từ Excel tới DLL. Chúng ta sẽ mở rộng ví dụ trên theo cách thứ hai. Excel sẽ liên kết với DLL và DLL sẽ liên kết trở lại với Excel. Tiếp theo chúng ta sẽ nghiên cứu cách sử dụng Form của VB 6.0 như là UserForm sẵn có trong Excel.


Nội dung này tôi đã tải lên trong phần Thư viện:

http://www.giaiphapexcel.com/forum/showthread.php?p=209714#post209714
 
Lần chỉnh sửa cuối:
1. Tạo dự án ActiveX DLL

Khi bạn mở chương trình VB 6.0 thì cửa sổ New Project hiện ra như hình 1 Trong trường hợp cửa sổ New Project không hiện ra, bạn vào menu File/New Project. Trong cửa sổ New Project bạn chọn kiểu dự án ActiveX DLL. Sau khi bạn lựa chọn kiểu dự án và bấm vào nút Open, VB 6.0 sẽ tạo ra một dự án mới ActiveX DLL cho bạn.
Trong form đơn giản nhất, nơi mà bạn sẽ xây dựng ứng dụng “Hello World” đầu tiên, ActiveX DLL sẽ chỉ chứa hai phần Project (dự án) và Class Module (hình 1). Dự án đó sẽ xác định tên của ứng dụng trong DLL của bạn, và Class Module sẽ thể hiện các tính năng của DLL trong các chương trình khác. Hình 2 thể hiện cấu trúc của một dự án mới ActiveX DLL trong cửa sổ Project. Nếu bạn thấy cửa sổ Project xuất hiện trông rất quen thuộc, điều đó không có ảnh hưởng gì cả. Bạn sẽ tìm thấy tài nguyên phát triển VB 6.0 và VBA giống nhau đến mức dễ gây nên sự xáo trộn khi làm việc với chúng. Điều đó sẽ giúp bạn dễ dàng làm việc với VB 6.0 khi bạn đã có kinh nghiệm về VBA. Chúng ta sử dụng cửa sổ Project trong VB 6.0 gần như tương tự với VBA.

VB6_1.jpg


Hình 1: Cửa sổ New Project của VB 6.0
Bạn sẽ thay đổi tên của Project thành AFirstProject (dự án đầu tiên), tên của Class1 thành HelloWorld bằng cách gõ vào trong hộp Name của cửa sổ Properties của chúng (hình 3). Kết quả thay đổi thể hiện tại hình 3. Bạn sẽ thấy tên file trong ngoặc đơn nằm phía bên ngoài là thành phần trong dự án của bạn. Đó là một sự khác nhau giữa VBA và VB 6.0. Trong VBA, các thành phần của dự án được lưu bên trong file riêng của Excel. Trong VB 6.0, tất cả các thành phần được lưu giữ trong các file riêng biệt của dự án của bạn.
Sau đó bạn lưu giữ tên dự án đó lại với hai phần Project (dự án) và Class Module (hình 4) với tên mặc định bạn đã đặt.

VB6_2.jpg


Hình 2: Dự án lúc đầu

VB6_3.jpg


Hình 3: Dự án đã đặt tên

VB6_4.jpg


Hình 4: Lưu Class Module “HelloWorld” dưới dạng file Class Files (*.cls)

VB6_5.jpg


Hình 5: Lưu dự án “AFirstProject” dưới dạng file Project Files (*.vbp)


Bạn sẽ thấy khi dự án của bạn đã được lưu thì tên dự án với đuôi xác định sẽ hiển thị trong cửa sổ Project (hình 5).
 
1.1. Cách tạo liên kết đơn giản một hướng

Bây giờ chúng ta sẽ tìm hiểu cấu trúc của dự án ActiveX DLL hoàn chỉnh, hãy bổ sung thủ tục để thực hiện công việc nào đó. Trong dự án “Hello World”, DLL sẽ cho hiện hộp thông báo với nội dung “Hello World!” khi được nhắc đến. Việc đó sẽ được hoàn thành khi bạn thêm phương thức tới Class Module HelloWorld mà sẽ hiển thị hộp thông báo khi được gọi. Việc thêm phương thức tới VB 6.0 Class Module sẽ làm việc tương tự như là thêm phương thức tới VBA Class Module. Bạn bấm đúp chuột vào Class Module HelloWorld trong cửa sổ Project, cửa sổ soạn code hiện ra. Khi đó bạn gõ thủ tục ShowMessage như sau (hình 6):

Mã:
Public Sub ShowMessage()
   MsgBox "Hello World!", vbInformation
End Sub

Bạn sẽ thấy công việc thật đơn giản! Bây giờ chúng ta cần phải biên dịch ActiveX DLL của bạn và gọi ra được từ ứng dụng Excel để hiển thị lời nhắn đó. Trước khi bạn sử dụng dự án VB 6.0, bạn hãy biên dịch code đó.
Công việc đó được khi bạn vào menu File trong cửa sổ VB 6.0, chọn Make AFirstProject.dll... (hình 7). Sau đó cửa sổ Make Project hiện ra như hình 8, bạn chọn nút OK để tạo AFirstProject.dll trong thư mục chứa dự án của bạn.

Vb6_6.jpg

Hình 6: Tạo thủ tục ShowMeesage trong Class Modules HelloWorld

Bây giờ bạn sẽ làm gì trong Excel? Công việc đó rất dễ dàng khiến bạn phải ngạc nhiên. Bước đầu tiên bạn khởi động Excel, sau đó bạn mở cửa sổ VBE. Sau đó bạn vào menu Tools/References..., cửa sổ References - VBAProject hiện ra như hình 9. Bạn tìm dự án AFirstProject.dll trong danh sách Available References và chọn. Nếu dự án đó không xuất hiện trong danh sách thì bạn bấm nào nút Browse... để tìm. Sau đó bấm OK để xác nhận.

Vb6_7.jpg


Hình 7: Tạo DLL cho dự án AFirstProject

Vb6_8.jpg


Hình 8: Đặt tên cho dự án DLL của bạn

Vb6_9.jpg


Hình 9: Xác nhận dự án AFirstProject

Vb6_10.jpg


Hình 10: Dự án của bạn được tạo trong thư mục VB6.0 với đầy đủ các thành phần


Sau đó bạn lưu workbook đó với tên Hello.xls trong thư mục chứa dự án đó, việc lưu trong cùng thư mục giúp bạn dễ dàng tìm kiếm và sử dụng chứ không phải bắt buộc. Trong thực tế, DLL có thể sử dụng bởi ứng dụng Excel ở mọi nơi trong máy tính.
Sau đó bạn thêm module vào trong cửa sổ VBE và lập thủ tục ShowDLLMessage như sau:

Mã:
Public Sub ShowDLLMessage()
  'Khai báo 
  Dim HelloWorld As AFirstProject.HelloWorld
    Set HelloWorld = New AFirstProject.HelloWorld
    HelloWorld.ShowMessage
    Set HelloWorld = Nothing
End Sub

Ban đầu, bạn sẽ thấy công việc khó khăn khi sử dụng các thủ tục xây dựng trong DLL. Tuy nhiên, khi hiểu rõ phương thức sử dụng DLL bằng VBA thì bạn sẽ dễ dàng thực hiện được. Trong ví dụ trên, các đối tượng trong DLL được nhận biết trong Excel như sau:
 
Bang_1.jpg


Vb6_11.jpg

Hình 11: Thư viện AFirstProject và các đối tượng chứa bên trong

Vb6_12.jpg

Hình 12: VBA tự nhận biết thư viện AFirstProject bằng chức năng Auto List Memmbers

Vb6_13.jpg

Hình 13: VBA tự nhận biết Classe HelloWorld bằng chức năng Auto List Memmbers


Vb6_14.jpg

Hình 14: VBA tự nhận biết thủ tục ShowMessage trong Classe HelloWorld

Khi bạn thực thi thủ tục ShowDLLMessage, kết quả thể hiện như tại hình dưới đây. Bạn sẽ thấy kết quả tạo hộp nhắn tin này tương tự khi sử dụng VBA.

Vb6_15.jpg

Hình 15: Lời nhắn được thể hiện khi bạn chạy thủ tục ShowDLLMessage

Và một điều đáng quan tâm nữa là tiêu đề (title) trong hộp thông báo. Nếu bạn không cung cấp tên tiêu đề của bạn thì hộp thông báo sẽ thể hiện tên tiêu đề mặc định, đó là tên của dự án bạn đang sử dụng (AFirstProject). Ví dụ nếu bạn muốn hộp thông báo hiển thị “Excel” ở thanh tiêu đề thì bạn bổ sung “Excel” như dưới đây:

MsgBox "Hello World!", vbInformation, "Excel"
 
1.2. Cách tạo liên kết hoàn thiện hai hướng

Dự án đầu tiên AFirstProject đã giải thích cách tạo ActiveX DLL không phức tạp. Kết quả thực hiện được là dự án trong Excel mà bạn có thể liên kết bằng DLL. Nhưng ví dụ trên đã truyền đạt một cách giới hạn bởi vì tất cả các liên kết chỉ là một đường, Excel gọi DLL.
Để nâng cao khả năng liên kết giữa Excel với VB 6.0, bạn phải tạo ra cấu trúc mà cho phép liên kết được truyền theo cả hai hướng. Trong ứng dụng Hello World ở trên, chúng ta mở rộng ứng dụng để cho phép liên kết theo cả hai hướng.
DLL là cơ bản để các thành phần dựa vào. DLL không thể tạo ra các hành động trong nó mà chỉ đáp ứng những yêu cầu từ các ứng dụng khác sử dụng trong nó để làm việc. Sau đó yêu cầu sẽ được thực hiện bởi vì DLL có thể liên kết trực tiếp với ứng dụng đã gọi nó ra. Việc đầu tiên chúng ta sẽ làm cho có thể liên kết hai hướng giữa Excel và DLL bằng cách cung cấp DLL với hướng để nhận biết được chương trình nào gọi.
Bước đầu tiên không yêu cầu hoàn thành công việc thiết lập tham chiếu từ DLL tới thư viện đối tượng Excel, mà chỉ cần cung cấp DLL với những thông tin về Excel mà liên kết
Công việc cài đặt tham chiếu trong VB 6.0 gần như giống hệt với cách cài đặt tham chiếu trong VBA. Chỉ có điều khác là vị trí của thực đơn. Để thiết lập tham chiếu tới Excel từ VB 6.0 ActiveX DLL, bạn vào menu Project và chọn References... (hình16). Hình 16 thể hiện tham chiếu từ dự án VB 6.0 của bạn tới thư viện đối tượng Excel 11.0. Đây là thư viện đối tượng của Excel 2003, còn nếu bạn làm việc với phiên bản trước đó thì số hiệu sẽ khác đi (giảm đi).

Vb6_16.jpg


Hình 16: Tạo tham chiếu trong VB 6.0

Vb6_17.jpg


Hình 17: Chọn thư viện đối tượng Excel

Bây giờ DLL của bạn đã tham chiếu tới thư viện đối tượng trong Excel, bạn có thể bổ sung thêm code để cho phép DLL liên kết với chương trình ứng dụng Excel đã được tải. Cơ sở của DLL là dựa vào các thành phần, nó có nhiệm vụ để mã lệnh VBA thi hành trong ứng dụng Excel thiết lập liên kết bởi cung cấp DLL với tham chiếu tới đối tượng ứng dụng Excel. DLL phải đơn giản để chuẩn bị tiếp nhận và lưu trữ các tham chiếu đó.
Để giải thích quá trình xử lý trong ứng dụng Hello World, bạn sẽ lập ra cách thứ hai để khi gọi bằng Excel, chuỗi “Hello World!” sẽ xuất hiện tại ô đang được chọn của worksheet hiện hành. Bạn sẽ tạo ra biến module-level (cấp bậc module) để lưu giữ tham chiếu gọi đối tượng trong Excel và thuộc tính mới mà Excel có thể sử dụng để tham chiếu tới bản thân nó vào trong DLL.
Bởi vì DLL của bạn hiện tại phải mượn tham chiếu tới ứng dụng bên ngoài nên bạn phải chắc chắc rằng tham chiếu đó sẽ bị mất đi khi DLL không tải được từ bộ nhớ. Bạn sử dụng sự kiện Class_Terminate để hoàn thành điều đó. Bạn thêm đoạn mã lệnh vào Class Module như sau:

Option Explicit 'Yêu cầu toàn bộ biến phải khai báo

'*************************************************************
'Khai báo biến Class (lớp) ở dưới
'*************************************************************
'Đối tượng tham chiếu sẽ gọi ứng dụng Excel
Private mxlApp As Excel.Application

'*************************************************************
'Đặt thuộc tính của Class
'*************************************************************
Public Property Set ExcelApp(ByRef xlApp As Excel.Application)
Set mxlApp = xlApp
End Property

'*************************************************************
'Tạo sự kiện của Class sau khi kết thúc công việc
'*************************************************************
Private Sub Class_Terminate()
Set mxlApp = Nothing
End Sub

'*************************************************************
'Các phương thức trong Class hoạt động
'*************************************************************
Public Sub ShowMessage()
MsgBox "Hello World!", vbInformation
End Sub

Public Sub WriteMessage()
mxlApp.ActiveCell.Value = "Hello World!"
End Sub

Thế đã :-=
 
Tôi giải thích các biến như sau:

- Biến module-level mxlApp sẽ chứa đựng tham chiếu tới đối tượng trong Excel mà được gọi là DLL.
- Thuộc tính ExcelApp trên được sử dụng bởi ứng dụng Excel gọi DLL cung cấp tham chiếu tới nó.
- Sự kiện Class_Terminate sẽ thực hiện khi tham chiếu module-level tới đối tượng trong Excel bị mất đi khi class bị mất đi (destroy).
- Phương thức WriteMessage sẽ gán nội dung “Hello World!” vào ô hiện hành trong worksheet đang được kích hoạt trong ứng dụng Excel mà gọi phương thức đó.

Và bây giờ, bạn biên dịch lại DLL trên. Trong trường hợp cửa sổ Excel chứa DLL cũ (1 hướng) vẫn đang mở thì VB 6.0 sẽ không cho phép biên dịch cho đến khi bạn phải đóng cửa sổ Excel. Biểu hiện là hộp báo lỗi “Permission denied:” khi bạn cố gắng biên dịch. Sau khi ứng dụng Excel đã tải được DLL, DLL sẽ không nhả khỏi bộ nhớ cho đến khi bạn đóng cửa sổ Excel. Nếu bạn đóng workbook thì vẫn chưa được mà phải thoát ra khỏi Excel.
Sau khi bạn đã đóng cửa sổ Excel, trong cửa sổ VB 6.0 bạn vào menu File và chọn Make AFirstProject.dll như hình 8. Khi đó AFirstProject.dll đã được biên dịch lại và khi đó VB 6.0 sẽ cảnh báo và hỏi bạn có thay thế cái cũ hay không, bạn bấm vào Yes để thay thế DLL cũ. Khi đó cửa sổ trình duyệt đối tượng sẽ thể hiện các đối tượng trong thư viện AFirstProject như hình dưới đây.
 
1.3. Hiển thị Form của VB 6.0 trong Excel

Tiếp theo bạn thực hiện những thao tác hoàn thiện hơn trong ứng dụng VB 6.0 Hello World, đó là hiển thị Form của VB 6.0 trong Excel giống như là UserForm của VBA. Đây có thể là lý do mà bạn muốn thực hiện, tôi sẽ trình bày chi tiết trong mục sau. Bây giờ bạn hãy để những rắc rối sang một bên và xem cách tối thiểu nhất để hiển thị Form của VB 6.0 trong Excel.
Bước đầu tiên bạn mở dự án Hello World (AFirstProject) trong VB 6.0, sau đó bổ sung thêm Form bằng cách vào menu Project và chọn Add Form, sau đó bấm Open. Đối tượng Form mới sẽ được bổ sung vào dự án của bạn. Trước khi lưu giữ dự án của bạn với Form mới bên trong, cần thiết phải thay đổi một số thuộc tính trong Form. Nội dung một số thay đổi như bảng dưới đây:

Mã:
Thuộc tính	Đổi thành
          (Name)	FHelloWorld
          BorderStyle	3 - Fixed Dialog
          Caption	Hello From VB 6.0
          Icon	(None) (bạn xoá giá trị mặc định)
          StartupPosition	1 - Center Owner

Hinh21_VB.jpg


Hình 21: Tạo Form trong VB 6.0

Hinh22_VB.jpg


Hình 22: Form được tạo ra và cấu trúc mới của dự án AFirstProject

Sau khi đã thay đổi một số thuộc tính trên, bạn hãy lưu dự án lại. Vì Form chưa được lưu nên sẽ có hộp thông báo lưu lại với tên mới (mặc định trùng với tên trong thuộc tính Name). Bạn hãy giữ nguyên tên và chọn vị trí cùng thư mục với dự án trước. Kết quả thực hiện như hình 22. Tiếp theo bạn bổ sung điều khiển CommandButton và Label trong Form mới. Tên (Name) của CommandButton đặt là cmdOK, thuộc tính Caption đặt là OK. Thuộc tính Caption của Label đặt là “Hello World!”, thuộc tính Alignment đặt là 2 - Center, thuộc tính Font đặt là 24. Bạn đã hoàn thành công việc xây dựng Form giống như hình 23, bạn không phải lo lắng nếu có chút khác biệt.

Hinh23_VB.jpg

Hình 23: Form của dự án đã được thiết kế xong

Bạn tạo một thủ tục khi bấm chuột vào nút OK, Form sẽ biến mất. Cách thực hiện là nháy kép chuột vào nút OK, khi đó thủ tục cmdOK_Click hiện ra, bạn thực hiện như hình dưới đây:

Hinh24_VB.jpg

Hình 24: Gán thủ tục vào sự kiện bấm nút OK

Đối tượng Form trong VB 6.0 ActiveX DLL không sử dụng được trực tiếp ngoài ứng dụng. Bởi vậy cần phải thêm mã lệnh trong class module để cho phép ứng dụng Excel của bạn hiện được Form này. Bạn cần phải tạo ra cái ngắt tới Form để Excel cư xử giống như là UserForm. Thủ tục hoàn chỉnh của HelloWorld class được thể hiện với mã lệnh mới bổ sung
 
Lần chỉnh sửa cuối:
Mã:
Option Explicit

'*********************************************************
'Khai báo hằng số Class (lớp) ở dưới
'*********************************************************
'Hằng số SetWindowLongA API.
Private Const GWL_HWNDPARENT As Long = -8

'*********************************************************
'Khai báo biến Class (lớp) ở dưới
'*********************************************************
'Đối tượng tham chiếu sẽ gọi ứng dụng Excel
Private mxlApp As Excel.Application

'Window truy cập vào bộ nhớ phát triển để gọi ứng dụng Excel
Private mlXLhWnd As Long

'*********************************************************
'Khai báo Class DLL ở dưới đây
'*********************************************************
Private Declare Function FindWindowA Lib "user32" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetWindowLongA Lib "user32" (ByVal hWnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

'*********************************************************
'Đặt thuộc tính của Class
'*******************************************************
Public Property Set ExcelApp(ByRef xlApp As Excel.Application)
   Set mxlApp = xlApp
   'Lây handle của cửa sổ ứng dụng Excel ngay khi nó vừa thực hiện thành công xong.
   mlXLhWnd = FindWindowA(vbNullString, mxlApp.Caption)
End Property

'*********************************************************
'Tạo sự kiện của Class sau khi kết thúc công việc
'*********************************************************
Private Sub Class_Terminate()
   Set mxlApp = Nothing
End Sub

'********************************************************
'Các phương thức trong Class hoạt động
'*********************************************************
Public Sub ShowMessage()
   MsgBox "Hello World!"
End Sub

Public Sub WriteMessage()
   mxlApp.ActiveCell.Value = "Hello World!"
End Sub

Public Sub ShowVB6Form()
   Dim frmHelloWorld As FHelloWorld
   Set frmHelloWorld = New FHelloWorld
   Load frmHelloWorld
   'Cửa sổ Form mẹ tới cửa sổ ứng dụng Excel.
   SetWindowLongA frmHelloWorld.hWnd, GWL_HWNDPARENT, mlXLhWnd
   frmHelloWorld.Show vbModal
   Unload frmHelloWorld
   Set frmHelloWorld = Nothing
End Sub

Form trong VB 6.0 là cửa sổ cao nhất được mặc định, có thể nói rằng đó chỉ là cửa sổ con trên màn hình nền. Để tạo VB 6.0 Form hoạt động giống như UserForm trong Excel, bạn cần phải sử dụng Windows API để thay đổi cửa sổ mẹ của VB 6.0 Form từ màn hình nền tới cửa sổ đối tượng ứng dụng Excel mà được gọi. Để thay đổi cửa sổ mẹ của Form, bạn thực hiện 2 bước sau:
1. Lấy lại handle của cửa sổ mà bạn muốn sử dụng như cửa sổ mẹ của Form. Trong Microsoft Windows, vùng nhớ global heap sẽ bao gồm tất cả các nhiệm vụ, gọi là các object, đã được định vị trong bộ nhớ. Mỗi object đều được gán một handle (sự điều khiển).
2. Thay đổi cửa sổ mẹ của Form bằng cách đặt handle của cửa sổ mà bạn đã lấy vào khu vực lưu trữ cửa sổ cấu trúc Form mà được sử dụng để chỉ định cửa sổ mẹ của Form.
Bạn sẽ phải khai báo biến mới module-level mlXLhWnd để giữ được handle của cửa sổ đối tượng ứng dụng Excel mà được gọi là Class của bạn. Bạn phải khia báo thêm hai hàm API: FindWindowA định vị handle ở cửa sổ ứng dụng Excel, và SetWindowLongA để thay đổi cửa sổ mẹ của Form. Hằng số mới GWL_HWNDPARENT sẽ xác minh vị trí cửa sổ cấu trúc Form của bạn nằm ở đâu trong cửa sổ mẹ mới sẽ được thay đổi. Bạn phải thêm dòng mới vào trong thuộc tính ExcelApp để rút ra handle của các đối tượng trong cửa sổ Excel khi nó vừa đặt xong thuộc tính.
Bạn đã tạo phương thức mới ShowVB6Form mà sẽ hiển thị trong cửa sổ ứng dụng Excel. Phương thức đó được sử dụng theo từng bước để hoàn thành công việc như sau:
- Tạo ra form mới FHelloWorld.
- Tải form FHelloWorld vào trong bộ nhớ.
- Thay đổi cửa sổ mẹ của form từ cửa sổ màn hình nền sang cửa sổ ứng dụng Excel bằng cách sử dụng hàm API SetWindowLongA.
- Hiện form bằng cách sử dụng cờ hiệu vbModal. Không giống như UserForm, form của VB 6.0 sẽ hiện ra với mẫu được mặc định. Đây không phải là điều bạn thực hiện trong ví dụ này, bởi vì bạn sử dụng cờ hiệu vbModal của phương thức Show.
- Khi người sử dụng đã đóng form bằng phương thức không tải biến đối tượng đó từ bộ nhớ và sẽ làm mất hiệu lực (destroy) tham chiếu tới nó.
Khi bạn đã bổ sung thêm mã lệnh trong dự án VB 6.0 của bạn, bạn nhớ phải đóng cửa sổ ứng dụng trước khi biên dịch lại DLL của bạn. Trong file Hello.xls bạn tạo thủ tục DisplayDLLForm (như ở dưới đây) và gán vào một nút điều khiển “Hiện Form VB 6.0”. Kết quả thủ tục này thực hiện như hình ....

Mã:
Public Sub DisplayDLLForm()
    Dim HelloWorld As AFirstProject.HelloWorld
    Set HelloWorld = New AFirstProject.HelloWorld
    Set HelloWorld.ExcelApp = Application
    HelloWorld.ShowVB6Form
    Set HelloWorld = Nothing
End Sub

Hinh25_VB.jpg

Hình 25: Form Hello From VB 6.0 hiện ra trong ứng dụng Excel
 
Lần chỉnh sửa cuối:
Bài viết của anh Hướng hay quá. Nhưng em chưa hệ thống được hết về các thuộc tính nên mới chỉ hiểu đc sơ sơ ! Hic
 
giap_engineer đã viết:
Bài viết của anh Hướng hay quá. Nhưng em chưa hệ thống được hết về các thuộc tính nên mới chỉ hiểu đc sơ sơ ! Hic

Cái này tôi cũng phải làm nhiều bằng DLL mới hiểu rõ dần dần thôi.

Còn hiện nay chỉ bảo mật bằng dll vẫn chưa ổn lắm, vẫn phải thêm code chống debug.
 
Nói thật bác Hướng rất chi là tuyệt vời.
Cảm ơn! Chúc bác có nhiều niềm vui trong cuộc sống
 
Quả thực là một bài viết bổ ích, xin chân thành cảm ơn Anh Hướng đã chỉ ra những giải pháp VBA rất hay cho ứng dụng Excel. Nếu còn giải pháp nào hay đề nghị anh cung cấp tiếp để chỉ giáo cho bàn dân thiên hạ cùng chúng tôi học tập. Xin cảm ơn./.
 
Quả thực là một bài viết bổ ích, xin chân thành cảm ơn Anh Hướng đã chỉ ra những giải pháp VBA rất hay cho ứng dụng Excel. Nếu còn giải pháp nào hay đề nghị anh cung cấp tiếp để chỉ giáo cho bàn dân thiên hạ cùng chúng tôi học tập. Xin cảm ơn./.

Chính xác cái đo đỏ ở trên là dùng VB6 chứ không phải VBA, VBA chỉ sử dụng để gọi ra từ dll thôi bạn ạ.
 
bài viết rất hay, nhưng còn 1 điểm, tôi chưa thấy việc gói dll tiện hơn việc code bình thường (trong vba của excel) như thế nào. ai có thể giải thích hộ.
 
bài viết rất hay, nhưng còn 1 điểm, tôi chưa thấy việc gói dll tiện hơn việc code bình thường (trong vba của excel) như thế nào. ai có thể giải thích hộ.

Hình như bạn chưa đọc kỹ đoạn đầu, tôi đã phân tích ưu điểm của dll VB so với VBA rồi đấy.
 
Đây là những kiến thức cơ bản trong việc điều khiển Excel từ VB6 thông qua thư viện liên kết động DLL và EXE. Đây là hướng phát triển rất hay khi bạn đã đạt được những kiến thức nhất định về VBA và cần phải bảo vệ thành quả của mình không bị bẻ khoá. Nội dung này tôi dịch từ "Professional Excel Development: The Definitive Guide to Developing Applications Using Microsoft® Excel and VBA®
By Stephen Bullen, Rob Bovey, John Green". Tôi cũng đã test lại cẩn thận rồi! --=0 , chúng ta sẽ tìm hiểu dần dần... Nắm được nội dung này bạn sẽ hiểu hơn một số ví dụ do anh Tuân đã post lên diễn đàn.

Trước khi tìm hiểu công việc này, bạn biết rằng Visual Basic 6.0 (VB 6.0) được xây dựng bởi tập đoàn Microsoft. Hiện này VB 6.0 đã được thay thế bởi VB.NET, tuy nhiên VB 6.0 vẫn là phần mềm được nhiều nhà lập trình sử dụng rộng rãi nhất trên thế giới. VB 6.0 mạnh mẽ hơn người anh em VBA vì VB 6.0 là ngôn ngữ lập trình hoạt động mang tính độc độc lập. Nhìn chung nội dung, cấu trúc, mã lệnh trong thủ tục của VB 6.0 và VBA rất giống nhau. Vì vậy, đối với những người am hiểu về VBA thì có thể nhanh chóng tiếp cận và sử dụng VB 6.0.
Chương này sẽ chỉ dẫn bước đầu tạo mối liên kết giữa Excel với VB 6.0 và những lý do tại sao sử dụng VB 6.0 cho các dự án VBA của bạn. VB 6.0 có thể tạo ra hơn 6 kiểu ứng dụng, nhưng chỉ có hai kiểu liên kết được với Excel là ActiveX DLL và Standard EXE. Mục này sẽ hướng dẫn bạn cách sử dụng ActiveX DLL và Standard EXE trong VB 6.0 cho Excel với ứng dụng đơn giản “Hello World”. Chúng ta sẽ khám phá sự liên kết giữa Excel và Standard EXE trong mục tiếp theo.
Như vậy bạn sẽ thắc mắc tại sao cần phải sử dụng VB 6.0 trong khi đó VBA sẵn có trong Excel?! VB 6.0 có một số khả năng mà VBA không có như khả năng biên dịch code trong form của DLL (Dynamic Link Library - Thư viện liên kết động), tạo file hoạt động một cách độc lập, đóng gói form, khả năng lập trình hướng đối tượng cao hơn, hỗ trợ các thư viện tài nguyên,... Ngoài ra khả năng điều khiển mảng dữ liệu liên liên kết được tăng cường hơn so với VBA. Dưới đây là những nét chính để bạn quyết định có nên sử dụng VB 6.0 để liên kết với Excel hay không?!
- Khả năng bảo mật code: VBA có khả năng bảo mật code để chống người khác có thể xem bằng cách sử dụng mã khoá cho dự án VBA của bạn. Điều đó là cần thiết khi bạn đã bỏ công sức để xây dựng sản phẩm của mình. Tuy nhiên hiện nay có rất nhiều chương trình có thể dò tìm và phá được khóa, khi đó code sẽ được hiện ra. Dự án của bạn lúc đó rất dễ bị phân tán để mọi người sử dụng. Nguyên nhân là do VBA không biên dịch được code, điều đó không thể ngăn chặn được người khác truy cập vào.
- Sử dụng VB 6.0 Form nâng cao: Form được đóng gói trong VB 6.0 so với sử dụng trong VBA. Đối tượng Form được tạo trong ứng dụng Excel được gọi là MSForm, còn trong VB 6.0 thì được hiểu là Ruby Form. Sự giống nhau về bên ngoài giữa chúng là Form ban đầu đều trống rỗng để bạn có thể xây dựng, di chuyển các điều khiển trong Form. Ngoài ra các điều khiển trong cả hai kiểu đều sử dụng các sự kiện xả ra với nó để thi hành thủ tục. Đương nhiên giữa chúng có sự khác nhau, ví dụ như thuộc tính, phương thức, sự kiện và kể cả các điều khiển của VB 6.0 rộng hơn...
- Hỗ trợ điều khiển ActiveX tốt hơn: Không chỉ mỗi VB 6.0 Form cung cấp khả năng hỗ trợ tốt hơn so với UserForm của các điều khiển đa dạng xây dựng trong Window. Chúng còn có hàng trăm điều khiển ActiveX nhóm 3 mà không có đầy đủ cho UserForm. Lý do như trên là hầu hết điều khiển ActiveX nhóm 3 trở thành phiên bản 2. Khi bạn xây dựng dự án thì phiên bản bạn sử dụng được gọi là design-time version của điều khiển. Khi dự án của bạn được phân phối (distributed) và chạy trong trạng thái biên dịch thì được gọi là runtime version của điều khiển. Khi bạn có được điều khiển ActiveX nhóm 3, có nghĩa là bạn đã mua bản quyền để xây dựng VB 6.0 Form bằng cách sử dụng design-time version của điều khiển. Runtime version của điều khiển, là kết quả của VB 6.0 Form sau khi được biên dịch, có thể phân phối lại không bị hạn chế trong phần lớn các trường hợp. Đây là lý do không thể sử dụng trong tài nguyên design-time và việc đó không thể sử dụng để xây dựng dự án mới.
Ngược lại UserForm trong VBA được thiết kế ở dạng mở, như vậy runtime version của điều khiển ActiveX không hoạt động với chúng. Nếu bạn đã phân phối design-time version của điều khiển để chạy trong VBA UserForm không biên dịch, về cơ bản là bạn sẽ gửi điều khiển đó cho người khác một cách miễn phí. Ai đó mà có design-time version của điều khiển được cài đặt trong máy tính thì có thể sử dụng những dự án đó, ngoài ra họ phải mua hoặc không sử dụng được.Ứng dụng Active DLL “Hello World” sẽ giải thích cho bạn cách một cách tạo liên kết từ Excel tới DLL. Chúng ta sẽ mở rộng ví dụ trên theo cách thứ hai. Excel sẽ liên kết với DLL và DLL sẽ liên kết trở lại với Excel. Tiếp theo chúng ta sẽ nghiên cứu cách sử dụng Form của VB 6.0 như là UserForm sẵn có trong Excel.
vâng, thế mà tôi chả chịu đọc. cám ơn bạn nha.

nhân tiện, bạn có thể cho tôi 1 ví dụ nổi bật tính tiện lợi khi excel liên kết với dll chứ? nói thật, tôi vẫn còn mù mờ :(.

1. khả năng bảo mật code. dll không thể bảo mật được, không thiếu chương trình decompiler.
2. sử dụng forms nâng cao. để hỗ trợ cho excel?
3. hỗ trợ điểu khiển ActiveX. cái này tôi chịu, chưa thể mường tượng được.

thảo luận nào.
 
Sao em làm giống như Bác Huong chỉ để sử dụng .dll
1. Tool/Add-Ins .....
2. Chọn Automation
3. Chọn Browse
Sau đó chọn file .ddl
thì bị báo lỗi là :
The file you selected does not contain a new Automation Server, or you do ...
bị báo lỗi như vầy là sao ? Xin giải thích giúp ! Xin cám ơn
C:%5Ct.bmp
 
Lần chỉnh sửa cuối:
Web KT
Back
Top Bottom