• Thứ Bảy, 20/11/2010 07:52 (GMT+7)

    Xuất dữ liệu từ Foxpro sang Excel và chuyển mã Unicode

    Câu hỏi :

    Xin hướng dẫn sử dụng Foxpro for dos xuất dữ liệu dùng font VNI-DOS sang Excel và chuyển sang mã Unicode.



    Trả lời :

    Yêu cầu của bạn gồm 2 vấn đề chính cần giải quyết:

    1. Copy các record dữ liệu từ file *.dbf sang 1 worksheet Excel. File *.dbf là 1 bảng (table) dữ liệu, worksheet Excel cũng là 1 bảng dữ liệu. Do đó việc chuyển thông tin từ file *.dbf sang worksheet Excel là hoạt động copy dữ liệu từ table này sang table khác. Bạn có thể lập trình dùng các đối tượng ADO để thực hiện hoạt động này. Cách đơn giản nhất là dùng trực tiếp Excel như sau: chạy Excel, chọn menu File.Open để mở file *.dbf và hiển thị lên 1 worksheet Excel. Sau đó, chọn menu File.Save As để lưu lại theo định dạng *.xls.

    2. Chuyển mã các chuỗi văn bản trong bảng dữ liệu từ bảng mã này sang bảng mã khác (cụ thể là từ VNI 1 byte sang Unicode). Bạn có thể dùng các ứng dụng chuyển mã tiếng Việt sẵn có trên thị trường để chuyển mã tiếng Việt trực tiếp trong worksheet Excel.

    Lưu ý, do bảng mã tiếng Việt VNI-DOS (và một số bảng mã tiếng Việt cũ khác) có dùng một số mã ký tự điều khiển làm ký tự tiếng Việt nên một số ứng dụng bị xử lý sai. Do đó để giải quyết tổng quát và triệt để vấn đề chuyển mã tiếng Việt, chúng tôi có viết 1 đối tượng COM cung cấp các hàm chức năng để chuyển mã tiếng Việt từ bất kỳ bảng mã nào sang một bảng mã khác. Bạn có thể liên hệ với tòa soạn để copy đối tượng này (file bktrans.dll) về cài vào máy và sử dụng. Qui trình cài đặt đối tượng COM vào máy như sau:

    - Copy file bktrans.dll vào thư mục thích hợp (thí dụ c:\MyCOM).

    - Tạo icon shortcut trên màn hình desktop của trình đăng ký components bằng cách ấn phải chuột trên màn hình desktop, chọn option New.Shortcut, duyệt và chọn file c:\windows\system32\regsvr32.exe để tạo icon shortcut cho nó.

    - Chạy tiện ích duyệt hệ thống file, tìm và hiển thị nội dung thư mục c:\MyCOM, thay đổi kích thước/dời vị trí cửa sổ hiển thị thư mục sao cho thấy được icon shortcut của trình đăng ký component, chọn file bktrans.dll, drag nó vào icon shortcut của trình đăng ký để đăng ký nó vào Windows.

    - Sau khi đã đăng ký thành công, bạn có thể dùng bất kỳ môi trường lập trình nào (VB, VC++,...) để lập trình ứng dụng và dùng đối tượng Bktrans vừa đăng ký y như dùng các đối tượng COM khác.

    Sau đây chúng tôi xin trình bày qui trình điển hình để xây dựng 1 ứng dụng bằng VB 6.0 đọc bảng dữ liệu từ file *.dbf, chuyển mã tiếng Việt từ mã VNI-DOS sang mã Unicode cho bất kỳ field chuỗi nào rồi ghi kết quả lên 1 worksheet Excel:

    1. Chạy VB 6.0, tạo Project mới thuộc loại "Standard EXE" (loại Project mặc định có 1 Form giao diện rỗng ban đầu).

    2. Chọn menu Project.References để hiển thị cửa sổ References. Duyệt tìm và chọn mục BkTrans 1.0 Type Library để "add" thành phần COM phục vụ chuyển mã tiếng Việt vào Project. Tương tự, duyệt tìm và chọn mục Microsoft ActiveX Data Objects 2.x Library để "add" thành phần COM phục vụ truy xuất database vào Project.

    3. Chọn menu Project.Components để hiển thị cửa sổ Components. Duyệt tìm và chọn mục Microsoft Common Dialog Control 6.0 để "add" điều khiển phục vụ duyệt hệ thống file vào Project.

    4. Thiết kế Form ứng dụng theo hình sau, gồm có 5 label, 3 textbox, 2 combobox, 3 button và 1 CommonDialog:

    Đặt tên cho 3 textbox là txtDBFFile, txtExcelFile, txtWorksheet, tên cho 3 button là btnDBFFile, btnExcelFile, btnStart, tên cho 2 combobox là cbSourceCode, cbDestCode, tên cho CommonDialog là FileDialog.

    5. Ấn kép chuột vào button btnDBFFile để tạo thủ tục xử lý sự kiện Click chuột trên nó, tương tự tạo thủ tục xử lý Click chuột cho 2 button còn lại và cho 2 Combobox rồi viết code VB 6.0 sau đây:

    Option Explicit
    'khai báo các biến cần dùng
    Private srcid As Integer
    Private dstid As Integer
    Private VietLibCOM As New BKTRANSLib.BKTRANSLib

    'thủ tục Click button chọn file DBF
    Private Sub btnDBFFile_Click()
    FileDialog.ShowOpen
    txtDBFFile.Text = FileDialog.FileName
    End Sub

    'thủ tục Click button chọn file Excel
    Private Sub btnExcelFile_Click()
    FileDialog.ShowOpen
    txtExcelFile.Text = FileDialog.FileName
    End Sub

    'thủ tục Click button bắt đầu chuyển mã & chuyển định dạng
    Private Sub btnStart_Click()
    'khai báo các biến cần dùng
    Dim Connection1 As ADODB.Connection
    Dim RecordSet1 As ADODB.Recordset
    Dim Connection2 As ADODB.Connection
    Dim RecordSet2 As ADODB.Recordset
    Dim Command2 As ADODB.Command
    Dim path As String, TableName As String
    Dim strSQL As String, strbuf As String
    Dim sfldbuf As String, dfldbuf As String
    Dim i As Integer, j As Integer
    Dim fStart As Integer, kq As Long
    Dim fld As Variant
    'xác định đường dẫn và file DBF
    i = 1
    Do
    j = InStr(i, txtDBFFile.Text, "\", vbBinaryCompare)
    If (j <> 0) Then
    i = j + 1
    End If
    Loop While j <> 0
    'xác định đường dẫn
    path = Mid(txtDBFFile.Text, 1, i - 1)
    'xác định tên file DBF
    TableName = Mid(txtDBFFile.Text, i)
    'Tạo connection tới database nguồn
    Set Connection1 = New ADODB.Connection
    Connection1.Open "Provider=MSDASQL;DRIVER=Microsoft FoxPro VFP Driver (*.dbf);SourceType=DBF;SourceDB=" & path & ";"
    'Tạo recordset chứa các record của table nguồn
    Set RecordSet1 = New ADODB.Recordset
    RecordSet1.Open TableName, Connection1, adOpenStatic, adLockReadOnly, adCmdTable
    'Tạo connection tới database đích
    Set Connection2 = New ADODB.Connection
    Connection2.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & txtExcelFile.Text & ";Extended Properties=Excel 8.0;"
    'Tạo command làm việc với database đích
    Set Command2 = New ADODB.Command
    Command2.ActiveConnection = Connection2
    'xây dựng lệnh SQL tạo Table đích
    strSQL = "CREATE TABLE " & txtWorksheet.Text & " ("
    'duyệt tìm từng field của table nguồn
    fStart = 1
    For Each fld In RecordSet1.Fields
    'tìm tên và kiểu của field
    Select Case fld.Type
    Case 2
    strbuf = "Integer"
    Case 3
    strbuf = "Long"
    Case 5
    strbuf = "Currency"
    Case 6
    strbuf = "Double"
    Case 11
    strbuf = "Logical"
    Case 202
    strbuf = "Text"
    Case 203
    strbuf = "Text"
    Case 7
    strbuf = "Date"
    Case 135
    strbuf = "Date"
    Case 129
    strbuf = "Text"
    Case 131
    strbuf = "Integer"
    Case 133
    strbuf = "Date"
    Case Else
    MsgBox "Type với mã " & fld.Type & " chưa được xử lý!!!"
    End Select
    If fStart Then
    strSQL = strSQL & fld.Name & " " & strbuf
    fStart = 0
    Else
    strSQL = strSQL & ", " & fld.Name & " " & strbuf
    End If
    Next fld
    strSQL = strSQL & ")"
    'Xóa table trên database đích nếu có rồi
    'Command2.CommandText = "DROP TABLE " & txtWorksheet.Text
    'Command2.Execute
    'Tạo mới table trên database đích
    Command2.CommandText = strSQL
    Command2.Execute
    'Tạo recordset chứa các record của table đích
    Set RecordSet2 = New ADODB.Recordset
    RecordSet2.Open txtWorksheet.Text, Connection2, adOpenKeyset, adLockOptimistic, adCmdTable
    'duyệt chuyển mã và copy từng record
    While Not RecordSet1.EOF
    'tạo mới record
    RecordSet2.AddNew
    For i = 0 To RecordSet1.Fields.Count - 1
    'nếu field i là chuỗi thì chuyển mã
    If (RecordSet1.Fields(i).Type = 129) Or (RecordSet1.Fields(i).Type = 202) Or (RecordSet1.Fields(i).Type = 203) Then
    On Error GoTo AssignIt
    sfldbuf = RecordSet1.Fields(i).Value
    If Len(sfldbuf) <> 0 Then
    kq = VietLibCOM.TransStr(srcid, dstid, sfldbuf, dfldbuf)
    RecordSet2.Fields(i).Value = dfldbuf
    Else: GoTo AssignIt
    End If
    Else
    'nếu không thì chỉ copy dữ liệu
    AssignIt:
    RecordSet2.Fields(i).Value = RecordSet1.Fields(i).Value
    End If
    Next i
    'lưu lại record lên table đích
    RecordSet2.Update
    'di chuyển đến record kế tiếp
    RecordSet1.MoveNext
    Wend
    'đóng các đối tượng sử dụng lại
    RecordSet1.Close
    Connection1.Close
    Connection2.Close
    End Sub

    'thủ tục Click chọn mã tiếng Việt đích
    Private Sub cbDestCode_Click()
    dstid = cbDestCode.ListIndex
    End Sub

    'thủ tục Click chọn mã tiếng Việt gốc
    Private Sub cbSourceCode_Click()
    srcid = cbSourceCode.ListIndex
    End Sub

    'thủ tục khởi tạo ban đầu cho ứng dụng
    Private Sub Form_Load()
    Dim i As Integer
    Dim s As String
    Dim ret As Integer
    Dim cnt As Integer
    'xóa trắng nội dung các đối tượng hiển thị
    txtDBFFile.Text = ""
    txtExcelFile.Text = ""
    txtWorksheet.Text = ""
    cbSourceCode.Clear
    cbDestCode.Clear
    'khởi động đối tượng chuyển mã
    ret = VietLibCOM.Init()
    'tìm số bảng mã được phép xử lý
    cnt = VietLibCOM.GetCodeCount()
    'hiển thị chúng vào 2 combox để user chọn lựa
    For i = 0 To cnt - 1
    VietLibCOM.GetCodeName i, s
    cbSourceCode.AddItem s
    cbDestCode.AddItem s
    Next i
    End Sub

    6. Chọn menu Run.Start để chạy thử ứng dụng, chọn file DBF gốc, chọn file Excel chứa kết quả, chọn mã tiếng Việt gốc, chọn mã tiếng Việt đích, nhập tên worksheet chứa kết quả, chọn button "Bắt đầu copy và chuyển mã file DBF". Sau đó chạy Excel và mở xem thử nội dung file Excel kết quả.

    Lưu ý chương trình trên có thể truy xuất bảng dữ liệu của bất kỳ database server nào (FoxPro, Access, Excel, MySQL, SQL, Oracle,...). Bạn chỉ cần hiệu chỉnh chuỗi ConnectionString miêu tả database cần truy xuất cho phù hợp với định dạng database cần truy xuất.

    Bạn có thể liên hệ với tòa soạn để copy Project VB 6.0 của ứng dụng chuyển mã (có tên là VBTransDataTable) và file bktrans.dll chứa đối tượng COM phục vụ chuyển mã tiếng Việt.

    Chuyên mục: Lập trình