Trong thực tế, dù ở môi trường lập trình Chuyên nghiệp hay ứng dụng văn phòng, chúng ta đều thường xuyên thao tác trên các dạng cơ sở dữ liệu. Việc ghi dữ liệu ra các định dạng dữ liệu đã có là một công việc khá thường xuyên và tương đối nhàm chán. Trong bài viết này tôi xin giới thiệu một phương pháp tương đối đặc biệt cho phép chúng ta nhanh chóng nhập dữ liệu vào các định dạng của các ứng dụng có hỗ trợ ngôn ngữ macro VBA của Microsoft như Excel, Access, Word...
Có rất nhiều kỹ thuật để ghi dữ liệu vào các định dạng dữ liệu chuẩn, với định dạng MDB của Access có thể sử dụng DAO đi kèm với bất kì bộ phát triển nào của Microsoft; với các định dạng chuẩn cơ sở dữ liệu như DBF (DBase, FoxPro), MDB (Access), DB (Paradox)... chúng ta có thể sử dụng giao tiếp ODBC hoặc hiện đại hơn là OLE-DB; ngoài ra có thể sử dụng các kĩ thuật khác kém phổ biến hơn như OLE Automation hoặc tự xây dựng thư viện xuất dữ liệu. Mỗi phương pháp đều có những điểm mạnh yếu riêng, không có phương pháp nào tốt cho mỗi nhu cầu của các lập trình viên. Việc sử dụng các thư viện tự viết chỉ thích hợp với các loại cơ sở dữ liệu đã quá cổ điển, không còn được hỗ trợ trong môi trường hiện tại; đối nghịch với nó, nếu bạn sử dụng thư viện CSDL đã có, ứng dụng của bạn sẽ "nở" to đến độ không ngờ, bạn sẽ phải đối phó những vấn đề nhức đầu có thể có trong quá trình cài đặt và vận hành ứng dụng, từ việc sai hỏng version trong quá trình cài đặt, đến các lỗi bất ngờ xảy ra do tranh chấp file dữ liệu, vân vân và vân vân. Đứng trên tất cả các vấn đề đó là việc bạn phải bỏ ra khá nhiều thời gian quý báu của mình để cài đặt các thủ tục đọc ghi/xử lý lỗi khi xuất dữ liệu.
Tôi muốn giới thiệu với các bạn một cách đơn giản, tương đối hiệu quả và đặc biệt là tốn rất ít thời gian để cài đặt việc nhập dữ liệu tự động vào các file cơ sở dữ liệu. Đó là việc sử dụng các Macro VBA được bạn viết sẵn ngay trong các file cơ sở dữ liệu. Với cách này bạn không cần quan tâm đến các cơ chế giao tiếp của ngôn ngữ lập trình với các cơ sở dữ liệu. Hơn nữa, đây lại là một cách đảm bảo tính độc lập dữ liệu cao đồng thời nó không phụ thuộc vào các Version của cơ sở dữ liệu. Bây giờ, chúng ta hãy xem xét cách thức tiến hành của phương pháp này.
Vấn đề: Chúng ta tưởng tượng một lập trình viên A đã có một chương trình xử lý dữ liệu viết trong Visual C++, dữ liệu do chương trình tạo ra cần được xuất ra nhiều dạng để nhiều chương trình khác xử lý, chẳng hạn cần xuất ra 3 dạng Access, Word và Excel, vấn đề ở đây là A cần phải hoàn thành công việc trong thời gian ngắn, chẳng hạn 1 ngày. Thay vì viết các hàm xuất dữ liệu trong Visual C++, công việc mà không chắc có thể 1 ngày làm xong được. A bèn làm như sau:
1. Xuất dữ liệu của chương trình ra file text theo một định dạng tự quy ước.
2. Viết các hàm bằng macro VBA trong Access, Word và Excel để khi các file này mở ra thì các macro tự động chạy và nạp dữ liệu từ file text đã có vào chính bản thân nó. Cơ chế này tương tự các virus macro trong Word.
3. Mỗi lần người sử dụng xuất dữ liệu, chương trình sẽ xuất ra một file dữ liệu trống chứa sẵn các macro mà A đã xây dựng, kèm theo một file text trùng tên. Khi người dùng mở file dữ liệu, dữ liệu từ file text sẽ được nhập vào trong quá trình mở file.
Như các bạn có thể thấy, thay vì phải viết/kiểm tra các hàm xuất dữ liệu cho từng loại CSDL, A chỉ phải xuất ra dạng text và viết vài macro VBA đơn giản.
Chúng ta hãy xem xét việc tạo một macro chạy tự động trong Microsoft Excel.
Trước tiên, nếu bạn đang làm việc với Office 97 hay Office 2000, bạn tìm đến và click vào biểu tượng của Visual Basic Editor trên Toolbar (biểu tượng này nằm trên Toolbar "Visual Basic" hoặc chọn mục "Tools.Macro.Visual Basic Editor" trên menu chính, lúc này bạn sẽ có một cửa sổ làm việc.
ở đây, bạn có thể viết các macro cho workbook hay các sheet. Trong phần này tôi sẽ giới thiệu cách cài đặt macro cho một workbook. Macro nhập dữ liệu tự động từ một file Text vào trong file Excel khi file này được mở. Để đơn giản, ta nên đặt tên file text trùng với tên file excel và định dạng file text này, chẳng hạn file text của tôi được định dạng như sau:
Dòng đầu tiên là số cột cần xuất vào file.
Dòng thứ 2 đến dòng thứ n+ 1 là tên của n cột.
Dòng thứ n + 2 là số dòng sẽ được xuất vào file.
Dòng thứ n+3 trở đi là nội dung của các Ô (nội dung mỗi Ô ghi trên 1 dòng), lần lượt theo các dòng từ trên xuống dưới và các cột từ trái sang phải.
Ví dụ cụ thể, tôi có một file example.txt được định dạng như sau:
4
Họ và tên
ngày sinh
Quê quán
Nghề nghiệp
2
Nguyễn Văn A
01-01-1970
Hà Nội
Kế toán
Nguyễn Thị B
30-10-1976
Hà Tây
Giáo viên
Bây giờ bạn bắt đầu viết Macro để thực hiện công việc nhập dữ liệu tự động. Để đảm bảo là dữ liệu được nhập vào ngay khi file được mở, chúng ta phải xử lý ở sự kiện Open workbook.
Trước tiên, ta đưa các khai báo sau vào sau phần Option Explicit: Option Explicit
Public NumCol As Integer
Public Numrow As Integer
Dim Columns (1 To 300 ) As String
Chúng ta đưa vào sự kiện Workbook- Open() đoạn mã sau đây:
Private Sub workbook-open ( )
On Error Goto FALL
Dim fileNum As Integer, I As Integer, J As Integer
Dim str As String, fileName As String
Dim wb As Workbook
Dim index As Integer
Set wb = Thisworkbook
fileName - Left (wb.FullName,
Len(wb . FullName) - 3)' & "txt"
fileNum = FreeFile
Open fileName For Input AB #fileNum
Input #fileNum, NumCo1
index = 1
For I = 1 To NumCo1
Line Input#fileMum, str
Woksheets ("Sheet1"), Range (Columns (I) &CStr (index)). Value = str
Next I
Input#fileNum, NumRow
For J = 1 To NumRow
index = index + 1
For I = 1 To NumCol
Line Input #fileNum, str
If (str <>"") Then
Worksheets ("Sheet1"). Range (Columns (I) & CStr (index). Value=str
End If
Next I
Next J
Close #fileNum
Kill fileName
wb.Save
End
FALL:
End
End Sub
Trong đoạn mã trên, columns là một mảng ký hiệu các cột của Excel (A...Z, AA...). Ta có thể tạo ra mảng một cách đơn giản bằng thủ tục sau đây:
Sub SetNameColumn()
Dim I As Integer
Columns (1) = "A"
For I = 2 To 26
Columns (I) = NextColumn (Columns (I-1))
Next I
Columns (27) = "AA"
For I = 28 To 300
Columns (I) = NextColumn (Columns (I-1))
Next I
End Sub
Trong đó NextColumn (Columns (i)) là hàm trả về tên cột tiếp theo cột i. Hàm này được viết như sau:
Function NextColumn (s As String) As String
If Len (s)=1 Then
NextColumn=Chr (Asc(s)+1)
Else
If Asc (Mid(s, Len(s)))=90 Then
NextColumn=Chr(Asc(s)+1)&"A"
Else
NextColumn=Chr(Asc(s) & Chr (Asc(Mid(s, Len(s))) +1)
End If
End If
End Function
Hoạt động của macro rất đơn giản, đầu tiên nó đọc dữ liệu từ file, đọc được số cột và đặt tên cho các cột của sheet, sau đó nó đọc xem dữ liệu xuất có bao nhiều hàng và lần lượt đọc/ghi thông tin vào các ô của sheet.
Việc viết macro cho Word và Access cũng không khác là bao, nắm được ý tưởng trên cộng với một chút kiến thức về VB là các bạn có thể dễ dàng thành công. Sau đây chúng ta hãy thử đánh giá phương pháp này một chút.
Nhược điểm
- Đôi khi có thể mất dữ liệu do người dùng đã có thao tác với file được xuất ra (chẳng hạn: move nó sang thư mục khác). Nhưng vấn đề này có thể được giải quyết trọn vẹn bằng một vài kỹ thuật VB tinh tế hơn.
- Chỉ chạy được với các ứng dụng hỗ trợ VBA, vấn đề này tương tự như việc các trang web có java script chỉ chạy được trên các trình duyệt hỗ trợ js vậy.
- Các macro có thể bị nhận lầm là virus (nhất là với các chương trình diệt virus của Việt Nam), vì kỹ thuật của chương trình sử dụng tương tự các kỹ thuật của virus.
Ưu điểm:
- Chương trình nhỏ gọn, chẳng dính dáng gì đến cơ sở dữ liệu (Cũng có nghĩa là không phải lo lắng gì về xử lý lỗi cài đặt, lỗi đọc dữ liệu...).
- Các macro được viết bằng VBA, dễ dàng bảo trì và phát triển hơn các đoạn mã viết bằng ngôn ngữ khác.
- Có thể xuất dữ liệu vào các ứng dụng rất đặc thù, không thể làm bằng các phương pháp xuất dữ liệu thông thường, ví dụ: xuất dữ liệu vào các file định dạng của Word, của PowerPoint, của Microsoft Project, của Visio... Đây là lợi thế độc nhất vô nhị của phương pháp này.
- Thời gian chi phí cho việc phát triển phần xuất dữ liệu là rất ngắn so với các phương pháp khác.
Trên đây là một cách sử dụng macro tự động nhập dữ liệu vào các file cơ sở dữ liệu. Việc viết macro rất đơn giản mà nhiều khi lại rất hiệu quả. Hy vọng các nhập dữ liệu này sẽ giúp bạn cảm thấy thú vị hơn khi làm việc với các cơ sở dữ liệu.
Có rất nhiều kỹ thuật để ghi dữ liệu vào các định dạng dữ liệu chuẩn, với định dạng MDB của Access có thể sử dụng DAO đi kèm với bất kì bộ phát triển nào của Microsoft; với các định dạng chuẩn cơ sở dữ liệu như DBF (DBase, FoxPro), MDB (Access), DB (Paradox)... chúng ta có thể sử dụng giao tiếp ODBC hoặc hiện đại hơn là OLE-DB; ngoài ra có thể sử dụng các kĩ thuật khác kém phổ biến hơn như OLE Automation hoặc tự xây dựng thư viện xuất dữ liệu. Mỗi phương pháp đều có những điểm mạnh yếu riêng, không có phương pháp nào tốt cho mỗi nhu cầu của các lập trình viên. Việc sử dụng các thư viện tự viết chỉ thích hợp với các loại cơ sở dữ liệu đã quá cổ điển, không còn được hỗ trợ trong môi trường hiện tại; đối nghịch với nó, nếu bạn sử dụng thư viện CSDL đã có, ứng dụng của bạn sẽ "nở" to đến độ không ngờ, bạn sẽ phải đối phó những vấn đề nhức đầu có thể có trong quá trình cài đặt và vận hành ứng dụng, từ việc sai hỏng version trong quá trình cài đặt, đến các lỗi bất ngờ xảy ra do tranh chấp file dữ liệu, vân vân và vân vân. Đứng trên tất cả các vấn đề đó là việc bạn phải bỏ ra khá nhiều thời gian quý báu của mình để cài đặt các thủ tục đọc ghi/xử lý lỗi khi xuất dữ liệu.
Tôi muốn giới thiệu với các bạn một cách đơn giản, tương đối hiệu quả và đặc biệt là tốn rất ít thời gian để cài đặt việc nhập dữ liệu tự động vào các file cơ sở dữ liệu. Đó là việc sử dụng các Macro VBA được bạn viết sẵn ngay trong các file cơ sở dữ liệu. Với cách này bạn không cần quan tâm đến các cơ chế giao tiếp của ngôn ngữ lập trình với các cơ sở dữ liệu. Hơn nữa, đây lại là một cách đảm bảo tính độc lập dữ liệu cao đồng thời nó không phụ thuộc vào các Version của cơ sở dữ liệu. Bây giờ, chúng ta hãy xem xét cách thức tiến hành của phương pháp này.
Vấn đề: Chúng ta tưởng tượng một lập trình viên A đã có một chương trình xử lý dữ liệu viết trong Visual C++, dữ liệu do chương trình tạo ra cần được xuất ra nhiều dạng để nhiều chương trình khác xử lý, chẳng hạn cần xuất ra 3 dạng Access, Word và Excel, vấn đề ở đây là A cần phải hoàn thành công việc trong thời gian ngắn, chẳng hạn 1 ngày. Thay vì viết các hàm xuất dữ liệu trong Visual C++, công việc mà không chắc có thể 1 ngày làm xong được. A bèn làm như sau:
1. Xuất dữ liệu của chương trình ra file text theo một định dạng tự quy ước.
2. Viết các hàm bằng macro VBA trong Access, Word và Excel để khi các file này mở ra thì các macro tự động chạy và nạp dữ liệu từ file text đã có vào chính bản thân nó. Cơ chế này tương tự các virus macro trong Word.
3. Mỗi lần người sử dụng xuất dữ liệu, chương trình sẽ xuất ra một file dữ liệu trống chứa sẵn các macro mà A đã xây dựng, kèm theo một file text trùng tên. Khi người dùng mở file dữ liệu, dữ liệu từ file text sẽ được nhập vào trong quá trình mở file.
Như các bạn có thể thấy, thay vì phải viết/kiểm tra các hàm xuất dữ liệu cho từng loại CSDL, A chỉ phải xuất ra dạng text và viết vài macro VBA đơn giản.
Chúng ta hãy xem xét việc tạo một macro chạy tự động trong Microsoft Excel.
Trước tiên, nếu bạn đang làm việc với Office 97 hay Office 2000, bạn tìm đến và click vào biểu tượng của Visual Basic Editor trên Toolbar (biểu tượng này nằm trên Toolbar "Visual Basic" hoặc chọn mục "Tools.Macro.Visual Basic Editor" trên menu chính, lúc này bạn sẽ có một cửa sổ làm việc.
ở đây, bạn có thể viết các macro cho workbook hay các sheet. Trong phần này tôi sẽ giới thiệu cách cài đặt macro cho một workbook. Macro nhập dữ liệu tự động từ một file Text vào trong file Excel khi file này được mở. Để đơn giản, ta nên đặt tên file text trùng với tên file excel và định dạng file text này, chẳng hạn file text của tôi được định dạng như sau:
Dòng đầu tiên là số cột cần xuất vào file.
Dòng thứ 2 đến dòng thứ n+ 1 là tên của n cột.
Dòng thứ n + 2 là số dòng sẽ được xuất vào file.
Dòng thứ n+3 trở đi là nội dung của các Ô (nội dung mỗi Ô ghi trên 1 dòng), lần lượt theo các dòng từ trên xuống dưới và các cột từ trái sang phải.
Ví dụ cụ thể, tôi có một file example.txt được định dạng như sau:
4
Họ và tên
ngày sinh
Quê quán
Nghề nghiệp
2
Nguyễn Văn A
01-01-1970
Hà Nội
Kế toán
Nguyễn Thị B
30-10-1976
Hà Tây
Giáo viên
Bây giờ bạn bắt đầu viết Macro để thực hiện công việc nhập dữ liệu tự động. Để đảm bảo là dữ liệu được nhập vào ngay khi file được mở, chúng ta phải xử lý ở sự kiện Open workbook.
Trước tiên, ta đưa các khai báo sau vào sau phần Option Explicit: Option Explicit
Public NumCol As Integer
Public Numrow As Integer
Dim Columns (1 To 300 ) As String
Chúng ta đưa vào sự kiện Workbook- Open() đoạn mã sau đây:
Private Sub workbook-open ( )
On Error Goto FALL
Dim fileNum As Integer, I As Integer, J As Integer
Dim str As String, fileName As String
Dim wb As Workbook
Dim index As Integer
Set wb = Thisworkbook
fileName - Left (wb.FullName,
Len(wb . FullName) - 3)' & "txt"
fileNum = FreeFile
Open fileName For Input AB #fileNum
Input #fileNum, NumCo1
index = 1
For I = 1 To NumCo1
Line Input#fileMum, str
Woksheets ("Sheet1"), Range (Columns (I) &CStr (index)). Value = str
Next I
Input#fileNum, NumRow
For J = 1 To NumRow
index = index + 1
For I = 1 To NumCol
Line Input #fileNum, str
If (str <>"") Then
Worksheets ("Sheet1"). Range (Columns (I) & CStr (index). Value=str
End If
Next I
Next J
Close #fileNum
Kill fileName
wb.Save
End
FALL:
End
End Sub
Trong đoạn mã trên, columns là một mảng ký hiệu các cột của Excel (A...Z, AA...). Ta có thể tạo ra mảng một cách đơn giản bằng thủ tục sau đây:
Sub SetNameColumn()
Dim I As Integer
Columns (1) = "A"
For I = 2 To 26
Columns (I) = NextColumn (Columns (I-1))
Next I
Columns (27) = "AA"
For I = 28 To 300
Columns (I) = NextColumn (Columns (I-1))
Next I
End Sub
Trong đó NextColumn (Columns (i)) là hàm trả về tên cột tiếp theo cột i. Hàm này được viết như sau:
Function NextColumn (s As String) As String
If Len (s)=1 Then
NextColumn=Chr (Asc(s)+1)
Else
If Asc (Mid(s, Len(s)))=90 Then
NextColumn=Chr(Asc(s)+1)&"A"
Else
NextColumn=Chr(Asc(s) & Chr (Asc(Mid(s, Len(s))) +1)
End If
End If
End Function
Hoạt động của macro rất đơn giản, đầu tiên nó đọc dữ liệu từ file, đọc được số cột và đặt tên cho các cột của sheet, sau đó nó đọc xem dữ liệu xuất có bao nhiều hàng và lần lượt đọc/ghi thông tin vào các ô của sheet.
Việc viết macro cho Word và Access cũng không khác là bao, nắm được ý tưởng trên cộng với một chút kiến thức về VB là các bạn có thể dễ dàng thành công. Sau đây chúng ta hãy thử đánh giá phương pháp này một chút.
Nhược điểm
- Đôi khi có thể mất dữ liệu do người dùng đã có thao tác với file được xuất ra (chẳng hạn: move nó sang thư mục khác). Nhưng vấn đề này có thể được giải quyết trọn vẹn bằng một vài kỹ thuật VB tinh tế hơn.
- Chỉ chạy được với các ứng dụng hỗ trợ VBA, vấn đề này tương tự như việc các trang web có java script chỉ chạy được trên các trình duyệt hỗ trợ js vậy.
- Các macro có thể bị nhận lầm là virus (nhất là với các chương trình diệt virus của Việt Nam), vì kỹ thuật của chương trình sử dụng tương tự các kỹ thuật của virus.
Ưu điểm:
- Chương trình nhỏ gọn, chẳng dính dáng gì đến cơ sở dữ liệu (Cũng có nghĩa là không phải lo lắng gì về xử lý lỗi cài đặt, lỗi đọc dữ liệu...).
- Các macro được viết bằng VBA, dễ dàng bảo trì và phát triển hơn các đoạn mã viết bằng ngôn ngữ khác.
- Có thể xuất dữ liệu vào các ứng dụng rất đặc thù, không thể làm bằng các phương pháp xuất dữ liệu thông thường, ví dụ: xuất dữ liệu vào các file định dạng của Word, của PowerPoint, của Microsoft Project, của Visio... Đây là lợi thế độc nhất vô nhị của phương pháp này.
- Thời gian chi phí cho việc phát triển phần xuất dữ liệu là rất ngắn so với các phương pháp khác.
Trên đây là một cách sử dụng macro tự động nhập dữ liệu vào các file cơ sở dữ liệu. Việc viết macro rất đơn giản mà nhiều khi lại rất hiệu quả. Hy vọng các nhập dữ liệu này sẽ giúp bạn cảm thấy thú vị hơn khi làm việc với các cơ sở dữ liệu.