Bài tập về ADO căn bản.

Liên hệ QC
Hic. Nhiều dữ liệu quá... chỉ là bảng chấm công.
Nhiều là số liệu lộ cộ, chồng chéo, cái có cái không, nên khó kiểm soát nếu không phải chủ nhân của nó - nên tôi không kiểm soát là đã đủ dữ liệu lấy như bạn mong muộn, do vậy không test tốt được.
 
Nguyên nhân là ADO là ứng với kiểu xử lý database thường ưa thích là database chuẩn có tiêu đề, dữ liệu cùng 1 cột phải cùng kiểu dữ liệu
Trường hợp vấn đề ở đây là chương trình sẽ dò tìm 8 dòng đầu để dịnh kiểu datatype) cho field (column) tương ứng, vì dữ liệu trống nên nó sẽ CÓ THỂ định kiểu sai, dẫn đến hiểu lầm dữ liệu time sau... nên bỏ qua
...

Đã lỡ chỉ đến đây rồi thì chỉ luôn cách vượt qua vấn đề này luôn đi.
 
Ở đây vấn đề đáng nói là dữ liệu kiểu text cũng thiếu, kiểu number cũng thiếu, kiểu time cũng thiếu, file nguồn nếu mở cho kết quả khác, nếu đóng cho kết quả khác. Anh ADO này khó nhằn thật.
Nếu đã chấp nhận dùng ADO thì phải chấp nhận việc xây dựng CSDL đúng chuẩn. Còn nếu dữ liệu không đúng chuẩn thì ta không nên dùng nó. Bởi vì ta sẽ không chắc chắn rằng khi sử dụng sẽ không gặp phải vấn đề.
 
Nếu đã chấp nhận dùng ADO thì phải chấp nhận việc xây dựng CSDL đúng chuẩn. Còn nếu dữ liệu không đúng chuẩn thì ta không nên dùng nó. Bởi vì ta sẽ không chắc chắn rằng khi sử dụng sẽ không gặp phải vấn đề.
Đây là dữ liệu chấm công nên trong 1 trường nó có đầy đủ các loại dữ liệu text, time, number, không thể khác. Nếu theo như anh nói ở trên có nghĩa không áp dụng ADO cho bài toán này. Vậy ta giải thích sao khi dữ liệu nguồn mở thì kết quả lại đúng. Khi đóng dữ liệu nguồn thì kết quả lại sai.
Và với bài toán này khi vùng dữ liệu nguồn ta chọn có dòng đầu tiên là text ở tất cả các trường dữ liệu thì kết quả ok(Dựa trên góp ý của Nguyễn Duy Tuân). Phương án em lựa chọn là thiết kế lại dòng đầu tiên của vùng dữ liệu nguồn và tạm hài lòng kết quả.
 
Đây là dữ liệu chấm công nên trong 1 trường nó có đầy đủ các loại dữ liệu text, time, number, không thể khác. Nếu theo như anh nói ở trên có nghĩa không áp dụng ADO cho bài toán này. Vậy ta giải thích sao khi dữ liệu nguồn mở thì kết quả lại đúng. Khi đóng dữ liệu nguồn thì kết quả lại sai.
Và với bài toán này khi vùng dữ liệu nguồn ta chọn có dòng đầu tiên là text ở tất cả các trường dữ liệu thì kết quả ok(Dựa trên góp ý của Nguyễn Duy Tuân). Phương án em lựa chọn là thiết kế lại dòng đầu tiên của vùng dữ liệu nguồn và tạm hài lòng kết quả.

Có mấy vấn đề về bài toán của bạn cần phải xem lại.
- Chắc bạn chưa hiểu CSDL đúng chuẩn như bác HLMT đã nói nên mới đem ra so sánh với cái file dữ liệu chấm công Excel của bạn. CSDL chuẩn cơ bản là: (nói riêng cho file excel)
+ "Kiểu dữ liệu" cột nào ra cột đó. Cột này có thể "Text", cột kia "Date", cột khác dạng "Number"... nhưng bắt buộc không có kiểu trộn lẫn các loại dữ liệu vô cùng 1 cột.
+ Tiêu đề cột phải đầy đủ cho các cột nếu dùng "HDR=Yes".
- File chấm công của bạn không phải là CSDL chuẩn vì vi phạm nguyên tắc trên. Một cột dạng DateTime mà có thêm Text.
- File chấm công của bạn không phải là file dữ liệu gốc (thô) mà là dữ liệu đã qua xử lý để báo cáo (thêm các ký hiệu chấm công) nên để dùng ADO đọc dữ liệu thì kết quả trả về không tin tưởng được. Lập trình code, xử lý, đúng là đúng, sai là sai, không thể tạm hài lòng vì hên kết quả lần này ra đúng.
Cách nên làm là xử lý từ file dữ liệu thô của máy chấm công (máy có thể xuất dạng Excel, text cũng được). Thêm dữ liệu nghỉ phép, dùng công thức tính toán giờ vào ra v.v.. để xử lý bài toán chấm công.
Còn việc ADO đọc dữ liệu Excel khi file đóng hay mở cho kết quả khác nhau đó là một cái lỗi mà chính Microsoft đã thông báo rồi. "Việc Query một file Excel đang mở bằng ADO trong VBA có thể gây rò rỉ bộ nhớ (memory leak), các tham chiếu trong bộ nhớ không được giải phóng nên có thể làm kết quả sai".
 
Có mấy vấn đề về bài toán của bạn cần phải xem lại.
- Chắc bạn chưa hiểu CSDL đúng chuẩn như bác HLMT đã nói nên mới đem ra so sánh với cái file dữ liệu chấm công Excel của bạn. CSDL chuẩn cơ bản là: (nói riêng cho file excel)
+ "Kiểu dữ liệu" cột nào ra cột đó. Cột này có thể "Text", cột kia "Date", cột khác dạng "Number"... nhưng bắt buộc không có kiểu trộn lẫn các loại dữ liệu vô cùng 1 cột.
+ Tiêu đề cột phải đầy đủ cho các cột nếu dùng "HDR=Yes".
- File chấm công của bạn không phải là CSDL chuẩn vì vi phạm nguyên tắc trên. Một cột dạng DateTime mà có thêm Text.
- File chấm công của bạn không phải là file dữ liệu gốc (thô) mà là dữ liệu đã qua xử lý để báo cáo (thêm các ký hiệu chấm công) nên để dùng ADO đọc dữ liệu thì kết quả trả về không tin tưởng được. Lập trình code, xử lý, đúng là đúng, sai là sai, không thể tạm hài lòng vì hên kết quả lần này ra đúng.
Cách nên làm là xử lý từ file dữ liệu thô của máy chấm công (máy có thể xuất dạng Excel, text cũng được). Thêm dữ liệu nghỉ phép, dùng công thức tính toán giờ vào ra v.v.. để xử lý bài toán chấm công.
Còn việc ADO đọc dữ liệu Excel khi file đóng hay mở cho kết quả khác nhau đó là một cái lỗi mà chính Microsoft đã thông báo rồi. "Việc Query một file Excel đang mở bằng ADO trong VBA có thể gây rò rỉ bộ nhớ (memory leak), các tham chiếu trong bộ nhớ không được giải phóng nên có thể làm kết quả sai".
Cám ơn ý kiến của bạn. Hiểu thêm chút kiến thức.
 
Nếu đã chấp nhận dùng ADO thì phải chấp nhận việc xây dựng CSDL đúng chuẩn. Còn nếu dữ liệu không đúng chuẩn thì ta không nên dùng nó. Bởi vì ta sẽ không chắc chắn rằng khi sử dụng sẽ không gặp phải vấn đề.
Anh ơi cho em hỏi là.Bây giờ mình muốn lấy dữ liệu ở file đóng dùng ADO.Nhưng lấy vào mảng và chỉ lấy dòng dữ liệu cuối cùng thì làm thế nào vậy anh.
 

File đính kèm

  • Book1.xlsm
    10.7 KB · Đọc: 4
Anh ơi cho em hỏi là.Bây giờ mình muốn lấy dữ liệu ở file đóng dùng ADO.Nhưng lấy vào mảng và chỉ lấy dòng dữ liệu cuối cùng thì làm thế nào vậy anh.
File đóng, là sao? có nghĩa là còn file nữa, vậy post lên (lưu ý không bao giờ lấy dữ liệu từ file đóng được, mà khi đó chỉ nói là không mở ở excel và kết nối lấy dữ liệu qua ADO)
Và bạn chỉ nhờ riêng, nên thôi đợi người nhờ vậy
 
Chắc từ nay hông keo lấy Dữ Liệu File đóng nữa mà keo là: Sử dụng ADO lấy dữ liệu file Excel khác hay lấy dữ Liệu Database.accdb ..........he -0-0-0-===\.
Còn keo cô next hay Cnn khó nhớ thấy bà ....
 
...Nhưng lấy vào mảng và chỉ lấy dòng dữ liệu cuối cùng thì làm thế nào vậy anh.
1. Hàm GetRows() của RecordSet lấy dữ liệu vào mảng. Nếu không có tham số thì nó đổ cả RecordSet vào 1 mảng 2 chiều. Từ đó, mò đến dòng cuối cùng của mảng.
2. Hàm MoveLast đi đến dòng cuối của RecordSet. Hàm GetRows(1, 0) đọc dòng này
Thực ra thì GetRows(1, 2) cũng đọc được dòng cuối của RecordSet mà không cần MoveLast.
 
Chắc từ nay hông keo lấy Dữ Liệu File đóng nữa mà keo là: Sử dụng ADO lấy dữ liệu file Excel khác hay lấy dữ Liệu Database.accdb ..........he -0-0-0-===\.
Còn keo cô next hay Cnn khó nhớ thấy bà ....
Túm lại: là file không thể đóng, khi có nhu cầu lấy dữ liệu, nếu ai viết hay nói vậy, là chỉ đúng 1 nửa
 
Em xin chào cả nhà
Em có 2 File "Input" và "Output" :

-File "Input" : Sheet"Input" Chứa dữ liệu nhập
-File "Output" Sheet"Output" Chứa tiêu đề giống với "Input"
=>Em muốn thiết kế 2 nút bấm "GetData" và "Update"

1/ Nút "GetData" => Sẽ lấy tất dữ liệu (trừ dòng tiêu đề) từ Sheet "Input" sang "Output" với điều kiện Sheet "Output" đang đóng/mở đều sẽ thao tác được & Nếu đã "GetData" được tất cả dữ liệu từ "Input" rồi thì khi Click "GetData" lần n+1 dữ liệu sẽ không đổ thêm vào nữa tránh bị Double, hoặc khi Click "GetData" các dòng dữ liệu tại Sheet"Ouuput được xóa đi và ghi lại (Theo hướng sử dụng ADODB)

2/ Nút "Update" => Sẽ cập nhật dữ liệu được sửa đổi từ Sheet"Input" sang "Output" với điều kiện dữ liệu "SoTicket" on "Input" = "SoTicket" on "Output" (Ví dụ: chỉ Update được khi TM41055001 ở "Input" = TM41055001 ở "Output")

*Note : Có thể Bonus giúp em thêm kết hợp ADO và ARRAY
*Note 2: Cả nhà nếu có phương án hoặc giải pháp nào tốt hơn thì em cũng rất mong được tư vấn ạ

Mong cả nhà giúp đỡ em, em vừa gia nhập VBA không được bao lâu và thật sự rất tâm đắc với các nghiên cứu của các bậc tiền bối, nhưng vì kiến thức ADO và VBA còn có giới hạn nên chỉ có thể Edit và tùy biến theo mô hình làm việc của riêng mình. Rất cám ơn cả nhà
 

File đính kèm

  • ADODB.rar
    48.3 KB · Đọc: 9
Em sorry anh , anh download file đính kèm về xem giúp em, em đã sửa lại Tiếng Việt . Vì tên file em đặt là tiếng anh nên có vẻ hơm rườm rà một chút => Mong cả nhà hỗ trợ
Em có 2 File "Input" và "Output" :

-File "Input" : Sheet"Input" Chứa dữ liệu nhập
-File "Output" Sheet"Output" Chứa tiêu đề giống với "Input"
=>Em muốn thiết kế 2 nút bấm "GetData" và "Update"

1/ Nút "Gửi dữ liệu (Insert)" => Sẽ lấy tất dữ liệu (trừ dòng tiêu đề) từ Sheet "Input" sang "Output" với điều kiện Sheet "Output" đang đóng/mở đều sẽ thao tác được & Nếu đã "Gửi dữ liệu (Insert)" được tất cả dữ liệu từ "Input" rồi thì khi Click "Gửi dữ liệu (Insert)" lần n+1 dữ liệu sẽ không đổ thêm vào nữa tránh bị trùng và sinh ra nhiều dòng hàng giống nhau, hoặc khi bấm "Gửi dữ liệu (Insert)" các dòng dữ liệu tại Sheet"Output" được xóa đi và ghi lại (Theo hướng sử dụng ADODB)

2/ Nút "Cập nhật (Update)" => Sẽ cập nhật dữ liệu được sửa đổi từ Sheet"Input" sang "Output" với điều kiện dữ liệu "SoTicket" trong file "Input" = "SoTicket" trong file "Output" (Ví dụ: chỉ Cập nhật (Update) được khi TM41055001 ở "Input" = TM41055001 ở "Output")

*Note : Có thể theme giúp em kết hợp ADO và ARRAY
*Note 2: Cả nhà nếu có phương án hoặc giải pháp nào tốt hơn thì em cũng rất mong được tư vấn ạ

Mong cả nhà giúp đỡ em, em vừa gia nhập VBA không được bao lâu và thật sự rất tâm đắc với các nghiên cứu của các bậc tiền bối, nhưng vì kiến thức ADO và VBA còn có giới hạn nên chỉ có thể Edit và tùy biến theo mô hình làm việc của riêng mình. Rất cám ơn cả nhà
 

File đính kèm

  • ADODB.rar
    48.3 KB · Đọc: 5
Em sorry anh , anh download file đính kèm về xem giúp em, em đã sửa lại Tiếng Việt . Vì tên file em đặt là tiếng anh nên có vẻ hơm rườm rà một
..

*Note : Có thể theme giúp em kết hợp ADO và ARRAY
*Note 2: Cả nhà nếu có phương án hoặc giải pháp nào tốt hơn thì em cũng rất mong được tư vấn ạ

Ý là diễn giải yêu cầu bằng tiếng Việt đừng chen tiếng Anh vô. Ở môi trường cty bạn, bạn có thể nói chuyện chen Anh VIệt gì đó thì tùy nhưng ở các diễn đàn, môi trường công cộng nên dùng thuần Việt giao tiếp thì hay hơn. :)
 
... ở các diễn đàn, môi trường công cộng nên dùng thuần Việt giao tiếp thì hay hơn. :)
Việc tôi không thích dùng tiếng Anh Việt lẫn lộn là vì lý do cá nhân. Giản dị hơn là tôi không muốn con tôi "Hai Đét" mỗi sáng gặp mặt.

Ở diễn đàn, tiếng Anh Việt lẫn lộn gây khó hiểu. Điển hình là từ "theme" ở trên. Nó là tiếng Anh hay tiếng Việt gõ sai? "Note" ở trên là "yêu cầu" hay "phụ chú"?

Ở môi trường công cộng, tiếng Anh Việt lẫn lộn còn liên quan đến vấn đề ngữ cảnh. Có nhiều lúc nghe thấy giọng mỉa mai châm biếm nhưng lại không biết người dùng cố tình hay do dốt tiếng Anh mà còn ráng rặn.

Vì vậy tôi có nói, "muốn dùng tiếng Anh thì dùng luôn cả bài". Khi ấy mình biết rõ chủ đích người viết.
 
em thì lại thích các bạn dùng tiếng Anh lẫn tiếng Việt luôn , vì nó cũng là 1 cách học mà ^^

(Em sorry anh , anh download file đính kèm về xem giúp em, em đã sửa lại Tiếng Việt)
như câu này thì bạn này hơi lười , hàm lượng đầu tư cho tiếng Anh chưa cao nên cũng ko học đc gì nhiều từ bạn

nếu bạn ghi theo cú pháp !

Em xin lỗi anh , anh tải tập tin đính kèm về xem giúp em, em đã sửa lại tiếng Việt
(i'm sorry , please download the attached file and help me to check it, i already revise Vietnamese)

thì mình nghĩ là có đóng góp cho cộng đồng hơn ^^
 
em thì lại thích các bạn dùng tiếng Anh lẫn tiếng Việt luôn , vì nó cũng là 1 cách học mà ^^
...
Bạn muốn học theo cách gì thì cũng là quyền tự do cá nhân. Nhưng tôi khuyến cáo cho các bạn khác còn phân vân:
- Dùng 2 thứ tiếng lẫn lộn là cách học không tốt. Tiếng Anh khó nhất không phải là từ vựng, mà nó khó ở câu cú - nhất là thành ngữ. Vì vậy, lúc học tiếng Anh, đầu óc phải hoàn toàn suy nghĩ theo văn hoá Anh.

Điển hình, một bạn nọ viết:
"Sau một time tìm hiểu về..."
time ở đây là cái gì? Tiếng Anh từ time có hai nghĩa, "thời gian" và "lượt". Cả hai nghĩa ấy đưa vào câu trên đều có thể dịch được, tuy rằng ra hai nghĩa khác nhau hoàn toàn.
 
Các anh cho em hỏi là em viết code lấy dữ liệu vào mảng bằng ADO nhưng nó chỉ lấy được 255 ký tự vào mảng.Có cách nào lấy được toàn bộ dữ liệu không nhỉ.
Mã:
Sub tonghop()
     Application.ScreenUpdating = False
     Application.AskToUpdateLinks = False
     Application.DisplayAlerts = False
     Dim cn As Object, sqlStr As String, i As Long, lr As Long, k, rst As Object, Pro As String, ext As String, arr(1 To 1000, 1 To 14), a As Long
     Dim sarr, j As Long, b As Long
     Set cn = CreateObject("ADODB.Connection")
     Set rst = CreateObject("ADODB.recordset")
     With Application.FileDialog(msoFileDialogFilePicker)
         .AllowMultiSelect = True
    If Not .Show = -1 Then Exit Sub
    For Each k In .SelectedItems
       Pro = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
       ext = ";Extended Properties=""Excel 12.0;HDR=yes;IMEX= 1"";"
       cn.Open (Pro & k & ext)
       sqlStr = "Select * From [sheet1$a1:e30]"
       sarr = cn.Execute(sqlStr).GetRows
       a = a + 1
       b = Len(sarr(1, 24))
       arr(a, 1) = a
       arr(a, 2) = sarr(1, 3)
       arr(a, 3) = sarr(1, 0)
       arr(a, 4) = sarr(1, 2)
       arr(a, 5) = sarr(1, 1)
       arr(a, 9) = sarr(4, 7)
       arr(a, 10) = sarr(4, 8)
       arr(a, 11) = sarr(4, 9)
       arr(a, 12) = sarr(4, 10)
       arr(a, 13) = sarr(4, 11)
       arr(a, 14) = sarr(1, 24)
       For j = 25 To 28
          If sarr(1, j) <> Empty Then arr(a, 14) = arr(a, 14) & Chr(10) & sarr(1, j)
       Next j
       cn.Close
    Next
    End With
    With Sheets("sheet1")
         lr = .Range("A" & Rows.Count).End(xlUp).Row
         If lr > 12 Then .Range("A13:N" & lr).ClearContents
         If a Then .Range("A13:N13").Resize(a).Value = arr
     End With
End Sub
 
Web KT
Back
Top Bottom