Ghi Dữ Liệu Vào File Đóng Bằng ADO

Liên hệ QC

Kiều Mạnh

I don't program, I beat code into submission!!!
Tham gia
9/6/12
Bài viết
5,421
Được thích
4,033
Giới tính
Nam
Mình có viết một chương trình Bán hàng...sử dụng VBA để ghi dữ liệu từ file chuơngTrinh.xlsb vào File Data.xlsb hiện tại sử dụng tốt ...
Nhưng khi dữ liệu File Data càng lớn thì thấy nó hơi chậm lại...vì vậy mình muốn chuyển qua sử dụng ADO với code có chức năng tương tự nhưng kẹt chưa làm được ...Vậy úp lên nhờ các Bạn trợ giúp

1/ vùng dữ liệu cần ghi từ File chuongTrinh là [A6:J82]

2/ điều kiện ghi là từ [C6:C82] nếu Cells nào có dữ liệu thì lọc ghi theo dòng đó (khó khúc này ADO là mình Tịt...Nếu ghi nguyên vùng thì OK)

3/ Ghi vào Sheets("Data_Ban")File Data.xlsb nối tiếp xuống dưới tương tự như Code VBA mình viết....sau khi ghi xong thì chay Sub Auto_Open trong File Data.xlsb
Xin cảm ơn các Bạn đã trợ giúp...
Code VBA
PHP:
Public Sub LuuData_Ban()
Application.ScreenUpdating = False
Dim Nguon(), Kq(), i&, j&, k&
Nguon = ActiveSheet.Range("A6:J82").Value
ReDim Kq(1 To UBound(Nguon, 1), 1 To UBound(Nguon, 2))
For i = 1 To UBound(Nguon, 1)
    If Nguon(i, 3) <> "" Then 
       k = k + 1
        For j = 1 To UBound(Nguon, 2)
            Kq(k, j) = Nguon(i, j)
        Next
    End If
Next
With Workbooks.Open(ThisWorkbook.Path & "\Data.xlsb", 0)
    .Sheets("Data_Ban").Range("A65536").End(3)(2).Resize(k, UBound(Nguon, 2)) = Kq
    .RunAutoMacros (xlAutoOpen) ''Chay Sub Auto_Open Trong File Data
    .Close True
End With
Application.ScreenUpdating = True
End Sub
 

File đính kèm

  • Hoi Bai.rar
    38.8 KB · Đọc: 71
Theo tôi được biết thì ADO sẽ không làm được việc đó, nó chỉ sort dữ liệu theo dạng chuẩn. Nếu như theo ý bạn thì tôi nghĩ chỉ có cách là dùng update kết quả sang thôi.
Vậy thì nó Copy tên cột [B6:B82] qua ... xong Rồi Update số lượng theo tên hàng đó được không
Mong bạn giúp dùm
xin cảm ơn
 
Upvote 0
Vậy thì nó Copy tên cột [B6:B82] qua ... xong Rồi Update số lượng theo tên hàng đó được không
Mong bạn giúp dùm
xin cảm ơn
Chỉnh lại code khi mở workbook

Mã:
Option Explicit

Private Sub Workbook_Open()


    Sheet1.Range("A1") = "provider=Microsoft.ACE.OLEDB.12.0; data source=" & _
                   ThisWorkbook.Path & "\data.xlsb" & _
                  ";extended properties=""Excel 12.0;hdr=no"";"
    Sheet1.Range("A2") = "provider=Microsoft.ACE.OLEDB.12.0; data source=" & _
                   ThisWorkbook.FullName & _
                  ";extended properties=""Excel 12.0;hdr=no"";"
End Sub

Trong module

Mã:
Option Explicit

Dim cnn As Object, rst As Object


'Code ghi du lieu hang ban vao file data
Sub Ghi_Xuat_DuLieu()


    Set cnn = CreateObject("ADODB.Connection")
    cnn.Open (Sheet1.Range("A1"))
    cnn.Execute ("insert into [Data_Ban$] select * from [" & ThisWorkbook.FullName & ";hdr=no].[BanHang$A6:J] where F3 is not null")
    Lay_TonKho
End Sub
'Code tong hop nhap xuat ton tu file data
Sub Tong_Nhap_Xuat_Ton()


    Set cnn = CreateObject("ADODB.Connection")
    cnn.Open (Sheet1.Range("A1"))
    Set rst = cnn.Execute("select F2, sum(F3), Sum(F6),Sum(F12),Sum(F13),sum(F3)-sum(F12) from (select F2,F3,F6,0 as F12 ,0 as F13 from [Data_Nhap$] union all select F2,0,0,F3,F6 from [Data_Ban$]) group by F2 ")
    Sheet2.Range("a2").CopyFromRecordset rst
    
End Sub
'Code lay so luong ton kho tu file data
Sub Lay_TonKho()


    Set cnn = CreateObject("ADODB.Connection")
    With cnn
        .Open (Sheet1.Range("A1"))
        Set rst = .Execute("select F2, sum(F3)-sum(F12) from (select F2,F3,F6,0 as F12 ,0 as F13 from [Data_Nhap$] union all select F2,0,0,F3,F6 from [Data_Ban$]) group by F2 ")
        Sheet1.Range("M6").CopyFromRecordset rst
        .Close
        .Open (Sheet1.Range("A2"))
        .Execute ("UPDATE [BanHang$M6:N] a INNER JOIN [BanHang$A6:K] b ON a.F1=b.F2  SET b.F11=a.F2")
    End With
End Sub

Xem thêm file đính kèm.
 

File đính kèm

  • Hoi Bai.rar
    115.7 KB · Đọc: 39
Upvote 0
lấy hàng Tồn lên Gán vào Cột K là chính xác Theo cột B rồi đó ..sao Không Gán qua Cột N và cột M là tên hàng giống cột B
 
Upvote 0
lấy hàng Tồn lên Gán vào Cột K là chính xác Theo cột B rồi đó ..sao Không Gán qua Cột N và cột M là tên hàng giống cột B
Sau này bạn có thể tự tìm được câu trả lời này, với trình độ cùi bắp của tôi không chắc giải thích được.
 
Upvote 0
Sau này bạn có thể tự tìm được câu trả lời này, với trình độ cùi bắp của tôi không chắc giải thích được.
Mình xử lý bằng cách cực kỳ Cùi bắp là ....
PHP:
Sub Lay_TonKho()
    Set cnn = CreateObject("ADODB.Connection")
    With cnn
        .Open (Sheet1.Range("A1"))
        Set rst = .Execute("select F2, sum(F3)-sum(F12) from (select F2,F3,F6,0 as F12 ,0 as F13 from [Data_Nhap$] union all select F2,0,0,F3,F6 from [Data_Ban$]) group by F2 ")
        Sheet1.Range("M6").CopyFromRecordset rst
        .Close
        .Open (Sheet1.Range("A2"))
       .Execute ("UPDATE [BanHang$M6:N] a INNER JOIN [BanHang$A6:K] b ON a.F1=b.F2  SET b.F11=a.F2")
    End With     
    Range("M6:M82").Value = Range("B6:B82").Value
    Range("N6:N82").Value = Range("K6:K82").Value
    Range("K6:K82").ClearContents
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Mình xử lý bằng cách cực kỳ Cùi bắp là ....
PHP:
Sub Lay_TonKho()
    Set cnn = CreateObject("ADODB.Connection")
    With cnn
        .Open (Sheet1.Range("A1"))
        Set rst = .Execute("select F2, sum(F3)-sum(F12) from (select F2,F3,F6,0 as F12 ,0 as F13 from [Data_Nhap$] union all select F2,0,0,F3,F6 from [Data_Ban$]) group by F2 ")
        Sheet1.Range("M6").CopyFromRecordset rst
        .Close
        .Open (Sheet1.Range("A2"))
       .Execute ("UPDATE [BanHang$M6:N] a INNER JOIN [BanHang$A6:K] b ON a.F1=b.F2  SET b.F11=a.F2")
    End With     
    Range("M6:M82").Value = Range("B6:B82").Value
    Range("N6:N82").Value = Range("K6:K82").Value
    Range("K6:K82").ClearContents
End Sub
Tôi gửi bạn ví dụ về cập nhật trên range để phần nào bạn hiểu được cách thức, bạn tự nghiên cứu và tìm giải pháp tốt hơn nhé.

Mã:
'Code lay so luong ton kho tu file data

Sub Lay_TonKho()
    Dim strTen As String
    Set cnn = CreateObject("ADODB.Connection")
    cnn.Open (Sheet1.Range("A1"))
    Set rst = cnn.Execute("select F2, sum(F3)-sum(F12) as F10 from (select F2,F3,F6,0 as F12 ,0 as F13 from [Data_Nhap$] union all select F2,0,0,F3,F6 from [Data_Ban$]) group by F2 ")
    Application.ScreenUpdating = False
    Sheet1.Range("M6").Activate
    Do While Not IsEmpty(ActiveCell)
        strTen = ActiveCell.Value
        rst.Filter = "F2='" & strTen & "'"
        If rst.EOF Then
            rst.Filter = ""
            ActiveCell.Offset(0, 1) = "Khong Co"
        Else
            ActiveCell.Offset(0, 1) = rst("F10").Value
        End If
        ActiveCell.Offset(1, 0).Activate
    Loop
    Application.ScreenUpdating = True
End Sub
 

File đính kèm

  • Chuongtrinh.xlsb
    31.8 KB · Đọc: 20
Lần chỉnh sửa cuối:
Upvote 0
Tôi gửi bạn ví dụ về cập nhật trên range để phần nào bạn hiểu được cách thức, bạn tự nghiên cứu và tìm giải pháp tốt hơn nhé.

Mã:
'Code lay so luong ton kho tu file data

Sub Lay_TonKho()
    Dim strTen As String
    Set cnn = CreateObject("ADODB.Connection")
    cnn.Open (Sheet1.Range("A1"))
    Set rst = cnn.Execute("select F2, sum(F3)-sum(F12) as F10 from (select F2,F3,F6,0 as F12 ,0 as F13 from [Data_Nhap$] union all select F2,0,0,F3,F6 from [Data_Ban$]) group by F2 ")
    Application.ScreenUpdating = False
    Sheet1.Range("M6").Activate
    Do While Not IsEmpty(ActiveCell)
        strTen = ActiveCell.Value
        rst.Filter = "F2='" & strTen & "'"
        If rst.EOF Then
            rst.Filter = ""
            ActiveCell.Offset(0, 1) = "Khong Co"
        Else
            ActiveCell.Offset(0, 1) = rst("F10").Value
        End If
        ActiveCell.Offset(1, 0).Activate
    Loop
    Application.ScreenUpdating = True
End Sub
Thay vì viết như vậy thì mình copy Qua File nào cũng chạy được
PHP:
Sub Ghi_Xuat_DuLieu2()
    Dim Cnn As Object
    Set Cnn = CreateObject("ADODB.Connection")
    Cnn.Open ("provider=Microsoft.ACE.OLEDB.12.0; data source=" & _ 
           ThisWorkbook.Path & "\data.xlsb" & _
            ";extended properties=""Excel 12.0;hdr=no"";")
    Cnn.Execute ("insert into [Data_Ban$A2:J] select * from [" & ThisWorkbook.FullName & ";hdr=no].[BanHang$A6:J82] where F3 is not null")
    Set Cnn = Nothing
End Sub
Thì lại viết khó như sau và thêm Private Sub Workbook_Open() làm cho mình mò một hồi cũng ra.....qua mấy Bài viết của bạn hóa cái đầu của mình nó to thêm một tí Về ADO cảm ơn Bạn rất nhiều--=0
PHP:
Sub Ghi_Xuat_DuLieu()
    Set Cnn = CreateObject("ADODB.Connection")
    Cnn.Open (Sheet1.Range("A1"))
    Cnn.Execute ("insert into [Data_Ban$] select * from [" & ThisWorkbook.FullName & ";hdr=no].[BanHang$A6:J] where F3 is not null")
    End Sub
 
Upvote 0
Có một điều mình mong muốn là cải thiện được tốc độ xử lý .... nhưng cuối cùng tốc lại chậm hơn so với VBA .... tại Sao ?????????

Mà hàng ngày mình bán hàng liên tục phải ghi liên tục ....mà ADO xử lý chậm hơn VBA
các bạn Có thể tải File về Test bấm vào Ghi VBA xong Bấm Ghi ADO chờ kết quả....
Xin cảm Ơn
 

File đính kèm

  • Hoi Bai2.rar
    432.9 KB · Đọc: 31
Upvote 0
Có một điều mình mong muốn là cải thiện được tốc độ xử lý .... nhưng cuối cùng tốc lại chậm hơn so với VBA .... tại Sao ?????????

Mà hàng ngày mình bán hàng liên tục phải ghi liên tục ....mà ADO xử lý chậm hơn VBA
các bạn Có thể tải File về Test bấm vào Ghi VBA xong Bấm Ghi ADO chờ kết quả....
Xin cảm Ơn

thay Sub Lay_TonKho() cũ bằng Sub này xem mèo nào cắn miu nào ?
Mã:
Sub Lay_TonKho()
    Dim strTen As String, arr As Variant, r As Long, Dic As Object, dArr As Variant
    Set Cnn = CreateObject("ADODB.Connection")
    Set Dic = CreateObject("Scripting.Dictionary")
    Cnn.Open (Sheet1.Range("A1"))
    Set rst = Cnn.Execute("select f1, sum(f6)-sum(f12) from (select f1,f2 as f6,0 as f12 from [Data_Nhap$B2:C] union all select f1,0 as f6,f2 as f12 from [Data_Ban$B2:C]) group by f1 ")
    dArr = rst.GetRows
    Application.ScreenUpdating = False
    arr = Sheet1.Range("M6:M" & Sheet1.[M6].End(xlDown).Row).Value
    For r = 0 To UBound(dArr, 2) Step 1
        Dic(dArr(0, r)) = dArr(1, r)
    Next
    For r = 1 To UBound(arr) Step 1
        If Dic.exists(arr(r, 1)) Then
            arr(r, 1) = Dic(arr(r, 1))
        Else
            arr(r, 1) = "khong co dau Kieu Manh oi"
        End If
    Next
    Sheet1.Range("N6:N" & Sheet1.[M6].End(xlDown).Row).Value = arr
    Application.ScreenUpdating = True
    Set Cnn = Nothing
    Set rst = Nothing
End Sub
 
Upvote 0
Tôi gửi bạn ví dụ về cập nhật trên range để phần nào bạn hiểu được cách thức, bạn tự nghiên cứu và tìm giải pháp tốt hơn nhé.

Mã:
'Code lay so luong ton kho tu file data

Sub Lay_TonKho()
    Dim strTen As String
    Set cnn = CreateObject("ADODB.Connection")
    cnn.Open (Sheet1.Range("A1"))
    Set rst = cnn.Execute("select F2, sum(F3)-sum(F12) as F10 from (select F2,F3,F6,0 as F12 ,0 as F13 from [Data_Nhap$] union all select F2,0,0,F3,F6 from [Data_Ban$]) group by F2 ")
    Application.ScreenUpdating = False
    Sheet1.Range("M6").Activate
    Do While Not IsEmpty(ActiveCell)
        strTen = ActiveCell.Value
        rst.Filter = "F2='" & strTen & "'"
        If rst.EOF Then
            rst.Filter = ""
            ActiveCell.Offset(0, 1) = "Khong Co"
        Else
            ActiveCell.Offset(0, 1) = rst("F10").Value
        End If
        ActiveCell.Offset(1, 0).Activate
    Loop
    Application.ScreenUpdating = True
End Sub
Như tôi nói ở trên, tôi chỉ đưa ra ví dụ để hiểu cách thức vận dụng.

Có một điều mình mong muốn là cải thiện được tốc độ xử lý .... nhưng cuối cùng tốc lại chậm hơn so với VBA .... tại Sao ?????????

Mà hàng ngày mình bán hàng liên tục phải ghi liên tục ....mà ADO xử lý chậm hơn VBA
các bạn Có thể tải File về Test bấm vào Ghi VBA xong Bấm Ghi ADO chờ kết quả....
Xin cảm Ơn
Không hẳn thề đâu? Bạn nên cải biến nó nhé.
 
Lần chỉnh sửa cuối:
Upvote 0
cách trên của mình vẫn chưa đạt vì còn sử dụng mấy cái ngoài ADO . sub này sửa lại sử dụng ADO 100 %
Mã:
Sub Lay_TonKho()
    Dim strTen As String
    Set Cnn = CreateObject("ADODB.Connection")
    Cnn.Open (Sheet1.Range("A1"))
    Set rst = Cnn.Execute("select iif(a.f24 is null,0,a.f24) " & _
    "from (select f1, sum(f6)-sum(f12) as f24 from " & _
    "(select f1,f2 as f6,0 as f12 from [Data_Nhap$B2:C] " & _
    "union all select f1,0 as f6,f2 as f12 from [Data_Ban$B2:C]) group by f1) a " & _
    "right join [" & ThisWorkbook.FullName & ";hdr=no].[BanHang$M6:M] b on a.f1 = b.f1")
    Application.ScreenUpdating = False
    Sheet1.Range("N6").CopyFromRecordset rst
    Application.ScreenUpdating = True
    Set Cnn = Nothing
    Set rst = Nothing
End Sub
 
Upvote 0
cách trên của mình vẫn chưa đạt vì còn sử dụng mấy cái ngoài ADO . sub này sửa lại sử dụng ADO 100 %
Mã:
Sub Lay_TonKho()
    Dim strTen As String
    Set Cnn = CreateObject("ADODB.Connection")
    Cnn.Open (Sheet1.Range("A1"))
    Set rst = Cnn.Execute("select iif(a.f24 is null,0,a.f24) " & _
    "from (select f1, sum(f6)-sum(f12) as f24 from " & _
    "(select f1,f2 as f6,0 as f12 from [Data_Nhap$B2:C] " & _
    "union all select f1,0 as f6,f2 as f12 from [Data_Ban$B2:C]) group by f1) a " & _
    "right join [" & ThisWorkbook.FullName & ";hdr=no].[BanHang$M6:M] b on a.f1 = b.f1")
    Application.ScreenUpdating = False
    Sheet1.Range("N6").CopyFromRecordset rst
    Application.ScreenUpdating = True
    Set Cnn = Nothing
    Set rst = Nothing
End Sub
Hãy tối ưu thêm nữa, vẫn còn vài chổ chưa được như ý.
 
Upvote 0
anh làm mẫu luôn đi để em học tập với . sức em có vậy à
Gợi ý chút, hiện tại cái list dựa vào cột M, nếu cột M không có dữ liệu thì sao? Câu hỏi đặt ra là không cần cột M mà vẫn đưa ra dữ liệu cột M và N.
 
Upvote 0
Gợi ý chút, hiện tại cái list dựa vào cột M, nếu cột M không có dữ liệu thì sao? Câu hỏi đặt ra là không cần cột M mà vẫn đưa ra dữ liệu cột M và N.

ủa vậy là sao anh ? cột M Kiều Mạnh định nghĩa là cột làm mẫu về thứ tự và được copy từ cột B sang . như thế câu hỏi nếu như cột M không có dữ liệu là sao ? Kiều Mạnh đâu có ý định xóa cột M ?
 
Upvote 0
ủa vậy là sao anh ? cột M Kiều Mạnh định nghĩa là cột làm mẫu về thứ tự và được copy từ cột B sang . như thế câu hỏi nếu như cột M không có dữ liệu là sao ? Kiều Mạnh đâu có ý định xóa cột M ?
Đừng nóng, cái chuyện copy là chuyện của người ta. Theo yêu cầu của tác giả đến đây là ok, tuy nhiên giả sử cột M không có thì sao? Ta làm cách nào để được dữ liệu như tác giả yêu cầu?
 
Upvote 0
ủa vậy là sao anh ? cột M Kiều Mạnh định nghĩa là cột làm mẫu về thứ tự và được copy từ cột B sang . như thế câu hỏi nếu như cột M không có dữ liệu là sao ? Kiều Mạnh đâu có ý định xóa cột M ?
Thay vì nhìn từ cột B qua cũng được nhưng để lại Cột M nhìn kế Bên là Cột N thì dễ coi hơn
Càng về Sau code càng Xúc tích ngắn gọn mà Hay.......Cảm ơn Các Bạn nhiều .....khi nào rãnh qua Bình dương gọi cho Mạnh ta làm vài xị nha....Tel: 0929.555.666
sao code sau không viết thành một Function mà phải viết vậy thành ra mình cứ phải sửa lại Vì
[A1] là mình viết tên của hàng....ADO mình kém lắm Viết Function là thua
PHP:
Private Sub Workbook_Open()
    Sheet1.Range("A1") = "provider=Microsoft.ACE.OLEDB.12.0; data source=" & _
                   ThisWorkbook.Path & "\data.xlsb" & _ 
                 ";extended properties=""Excel 12.0;hdr=no"";"    
Sheet1.Range("A2") = "provider=Microsoft.ACE.OLEDB.12.0; data source=" & _
                   ThisWorkbook.FullName & _
                  ";extended properties=""Excel 12.0;hdr=no"";"
End Sub
 
Upvote 0
Đừng nóng, cái chuyện copy là chuyện của người ta. Theo yêu cầu của tác giả đến đây là ok, tuy nhiên giả sử cột M không có thì sao? Ta làm cách nào để được dữ liệu như tác giả yêu cầu?

không cho right join đến [BanHang$M6:M] thì right join đến [BanHang$B6:B] . nhưng chắc đây không phải ý anh . anh có thể nói rõ hơn không ?
 
Upvote 0
Upvote 0
Thay vì nhìn từ cột B qua cũng được nhưng để lại Cột M nhìn kế Bên là Cột N thì dễ coi hơn
Càng về Sau code càng Xúc tích ngắn gọn mà Hay.......Cảm ơn Các Bạn nhiều .....khi nào rãnh qua Bình dương gọi cho Mạnh ta làm vài xị nha....Tel: 0929.555.666
sao code sau không viết thành một Function mà phải viết vậy thành ra mình cứ phải sửa lại Vì
[A1] là mình viết tên của hàng....ADO mình kém lắm Viết Function là thua
PHP:
Private Sub Workbook_Open()
    Sheet1.Range("A1") = "provider=Microsoft.ACE.OLEDB.12.0; data source=" & _
                   ThisWorkbook.Path & "\data.xlsb" & _ 
                 ";extended properties=""Excel 12.0;hdr=no"";"    
Sheet1.Range("A2") = "provider=Microsoft.ACE.OLEDB.12.0; data source=" & _
                   ThisWorkbook.FullName & _
                  ";extended properties=""Excel 12.0;hdr=no"";"
End Sub
Có thể ghi vào chổ nào cũng được, tùy biến thôi mà bạn. Tôi chỉ ví dụ, bạn nên vận dụng để dể nhớ nhé.
 
Upvote 0
Web KT
Back
Top Bottom