Giúp mình code VBA lọc dữ liệu có điều kiện và tổng hợp

Liên hệ QC

nguyenkhoadng

Thành viên hoạt động
Tham gia
15/6/11
Bài viết
179
Được thích
30
Nhờ các bạn giúp mình đoạn code VBA lọc dữ liệu có điều kiện, sau đó tổng hợp chúng lại. cụ thể như sau:
- ở sheet THONG-KE mình có 2 cấu kiện AA1 Và AA2, dữ liệu thống kê như trong file ví dụ đính kèm.
Mình muốn nhờ các bạn giúp mình đoạn vba tạo 1 sheet PHAN-TICH, trong đó có 2 bảng (BẢNG LỌC DỮ LIỆU và BẢNG TỔNG HỢP) cụ thể:
- ở bảng LỌC DỮ LIỆU sẽ lọc tất cả dữ liệu bên sheet THONG-KE dựa vào điều kiện là cột D và E. dữ liệu nào có cột D và E giống nhau thì cộng lại, còn lại khác nhau thì giữ nguyên. và vẫn giữ lại 2 cấu kiện AA1, AA2 như trong file ví dụ đính kèm.
- ở bảng TỔNG HỢP sẽ tổng hợp lại từ bảng LỌC DỮ LIỆU.

Nhờ các bạn giúp cho.
Cụ thể mình có ghi trong file đính kèm.
Mình cảm ơn!
 

File đính kèm

Có phải bạn chưa lưu file? Bạn nên lưu cái file Book1 đó vào ổ đĩa nó mới chạy được.
 
Upvote 0
Đúng là chưa lưu file nên ko chạy được code.
vậy để chạy code mà ko phải lưu file thì làm như thế nào?

ADO sẽ không chạy được nếu như bạn không lưu file, còn muốn chạy được mà không cần lưu file thì bạn dùng VBA, các cao thủ VBA khác sẽ giúp bạn.
 
Upvote 0
ADO sẽ không chạy được nếu như bạn không lưu file, còn muốn chạy được mà không cần lưu file thì bạn dùng VBA, các cao thủ VBA khác sẽ giúp bạn.

Mình hiểu rồi, vậy mình sẽ tạo thêm cho nó chức năng báo lưu file khi tạo file thống kê mới là ổn. :)
Chúc bạn vui vẻ!
 
Upvote 0
ADO sẽ không chạy được nếu như bạn không lưu file, còn muốn chạy được mà không cần lưu file thì bạn dùng VBA, các cao thủ VBA khác sẽ giúp bạn.

Thì Hai Lúa viết thêm 1 code Save tạm file ở đâu đó
Để kiểm tra xem đó có phải là file trắng mới tạo hay không, có thể dùng Activeworkbook.Path ---> Kết quả này = rổng nghĩa là file chưa lưu
 
Upvote 0
Thì Hai Lúa viết thêm 1 code Save tạm file ở đâu đó
Để kiểm tra xem đó có phải là file trắng mới tạo hay không, có thể dùng Activeworkbook.Path ---> Kết quả này = rổng nghĩa là file chưa lưu

Mình đang dùng tạm code sau để lưu khi tao file mới. có như vậy thì khi chạy tổng hợp sẽ ko bị báo lỗi chưa lưu file.

Mã:
Sub ModBTK_moi()Dim Num As Integer
Dim Sh As Worksheet
For Each Sh In ActiveWorkbook.Worksheets
   If InStr(1, Sh.Name, "BTK") Then
      Num = Num + 1
   End If
Next
ThisWorkbook.Sheets("BTK").Copy Before:=ActiveWorkbook.ActiveSheet
With ActiveWorkbook.ActiveSheet
  .Name = "BTK-" & Format(Num + 1, "00")
  .Visible = True
End With
    WbN = ThisWorkbook.Name
    anser = MsgBox("Kich 'OK' = Luu BTK moi")
    FileSaveAs = Application.GetSaveAsFilename("BTK moi.xls", "ExcelFiles (*.xls), *.xls", , "Chon thu muc va ten tap tin")
    If FileSaveAs = False Then 'neu kich 'Cancel'
        MsgBox "Ban vua huy bo.", , "!!!"
        ActiveWorkbook.Close False
        Exit Sub
    End If
    ActiveWorkbook.SaveAs FileSaveAs
    ActiveWorkbook.Save
    MsgBox "Da co the bat dau thong ke thep !", , "OK"
End Sub

hơi bất tiện chút vì nó bắt lưu ngay lúc ban đầu. nếu như khi chạy tổng hợp mới bắt lưu với bảng thông báo "Để đảm bảo an toàn, Bạn nên lưu bảng thống kê trước khi tiếp tục công việc" thì hay hơn.
 
Lần chỉnh sửa cuối:
Upvote 0
Với đoạn code của bạn Hai Lúa thì hôm nay mình dùng khá ổn. có điều mình chuyển bảng thống kê của mình sang add-ins để dùng nên mỗi lần tạo 1 bảng thống kê mới lại phải lưu mới chạy được nên hơi bất tiện.
Nên mình lại tiếp tục lên topic này để nhờ các bạn nào có thể giúp hiệu chỉnh lại đoạn code tổng hợp thép ở #5 sao cho khi chạy code thì sẽ hiện thông báo "Để đảm bảo an toàn, Bạn nên lưu bảng thống kê trước khi tiếp tục công việc" và tiến hành save lại. công tác save chỉ 1 lần đầu thôi, lần tạo bảng thống kê mới tiếp theo nếu kiểm tra save rồi thì thôi, nếu chưa save thì lại hiện thông báo như lúc ban đầu.
- Nếu bạn nào có thể giúp mình mà lại chuyên bên mảng VBA hơn thì nhờ giúp mình đoạn code VBA với nội dung như đoạn code ADO ở bài #5 với. (Vì nghe bạn Hai Lúa nói nếu dùng VBA thì sẽ bỏ qua đc bước save)
Mình cảm ơn!
 
Upvote 0
Với đoạn code của bạn Hai Lúa thì hôm nay mình dùng khá ổn. có điều mình chuyển bảng thống kê của mình sang add-ins để dùng nên mỗi lần tạo 1 bảng thống kê mới lại phải lưu mới chạy được nên hơi bất tiện.
Nên mình lại tiếp tục lên topic này để nhờ các bạn nào có thể giúp hiệu chỉnh lại đoạn code tổng hợp thép ở #5 sao cho khi chạy code thì sẽ hiện thông báo "Để đảm bảo an toàn, Bạn nên lưu bảng thống kê trước khi tiếp tục công việc" và tiến hành save lại. công tác save chỉ 1 lần đầu thôi, lần tạo bảng thống kê mới tiếp theo nếu kiểm tra save rồi thì thôi, nếu chưa save thì lại hiện thông báo như lúc ban đầu.
- Nếu bạn nào có thể giúp mình mà lại chuyên bên mảng VBA hơn thì nhờ giúp mình đoạn code VBA với nội dung như đoạn code ADO ở bài #5 với. (Vì nghe bạn Hai Lúa nói nếu dùng VBA thì sẽ bỏ qua đc bước save)
Mình cảm ơn!
Kiểm tra nếu file chưa được lưu vào ổ đĩa thì lưu vào ổ C với tên tương ứng của WB đó, ngược lại sẽ lưu file rồi mới chạy code.

[GPECODE=sql]Sub ModTongHopThepHinh()
On Error Resume Next
Dim adoConn As Object, adoRS As Object, fld, i As Integer, eR As Integer
Set adoConn = CreateObject("ADODB.Connection")
Set adoRS = CreateObject("ADODB.Recordset")
If InStr(ActiveWorkbook.FullName, ":\") = 0 Then
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs "C:\" & ActiveWorkbook.Name
Else
ActiveWorkbook.Save
Application.DisplayAlerts = True
End If
With adoConn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ActiveWorkbook.FullName & _
";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
.Open
End With
With adoRS
.ActiveConnection = adoConn
.Open "select CK,CLT,QCT,sum(CD) as [TCD],sum(TL) as [TTL],sum(DTS) as [TDTS] " _
& "from [" & ActiveSheet.Name & "$A10:R500] " _
& "group by CK,CLT,QCT " _
& "having CK is not null"
End With
With ActiveSheet
.Range("U11:AF500").ClearContents
For Each fld In adoRS.Fields
i = i + 1
.Cells(10, i + 20) = fld.Name
Next
.[U11].CopyFromRecordset adoRS
End With
adoRS.Close
With adoRS
.ActiveConnection = adoConn
.Open "select '' as STT,CLT,QCT,sum(CD) as [TCD],sum(TL) as [TTL] " _
& "from [" & ActiveSheet.Name & "$A10:R500] " _
& "group by CLT,QCT " _
& "having CLT is not null " _
& "order by right(QCT,1),CLT"
End With
i = 0
With ActiveSheet
For Each fld In adoRS.Fields
i = i + 1
.Cells(10, i + 27) = fld.Name
Next
.[AB11].CopyFromRecordset adoRS
End With
adoRS.Close
With adoRS
.ActiveConnection = adoConn
.Open "select sum(DTS) as [TDTS] " _
& "from [" & ActiveSheet.Name & "$A10:R500]"
End With
With ActiveSheet
eR = .Range("AC65000").End(xlUp).Row + 1
.Range("AC" & eR) = "T" & ChrW(7892) & "NG C" & ChrW(7896) & "NG"
.Range("AC" & eR + 1) = "T" & ChrW(7892) & "NG DI" & ChrW(7878) & "N TÍCH S" & ChrW(416) & "N"
.Range("AE" & eR).FormulaR1C1 = "=SUM(R[-" & eR - 11 & "]C:R[-1]C)"
.Range("AF" & eR).FormulaR1C1 = "=SUM(R[-" & eR - 11 & "]C:R[-1]C)"
.Range("AE" & eR + 1).CopyFromRecordset adoRS
' .Cells.EntireColumn.AutoFit
.Range("AB11:AB" & eR - 1).FormulaR1C1 = "=ROW()-10"
End With
adoRS.Close: Set adoRS = Nothing
adoConn.Close: Set adoConn = Nothing

End Sub

[/GPECODE]

Em làm theo cách này mà ko được bác ạ
bác có yahoo ko ạ
Bạn làm như thế nào mà không được?
 
Upvote 0
mình gặp lỗi như hình dưới. nhờ bạn xem giúp.

w1_zps58964dc5.png


w2_zpsf6de065d.png
 
Upvote 0
Chán vãi mấy chứ này
Làm gần hết cả rồi, chỉ còn có tí xíu ---> Nhìn vào cái dòng báo lỗi màu vàng cũng đoán được chứ

Những thành viên lên diễn đàn để hỏi hoặc để nhờ sự giúp đỡ gồm có 3 phần:
1. Biết nhiều (Dĩ nhiên những thành viên này thì ít khi hỏi mà chủ yếu là hỗ trợ các thành viên khác)
1. Biết ít
2. Không biết (và Dĩ nhiên đây là phần hỏi cực kỳ nhiều và đếm đến ko ít phiền toái, vì đơn giản họ không biết gì về cái họ muốn tìm hiểu, nhưng được cái họ rất muốn tìm hiểu)
Nếu như một người không biết chút gì về code thử hỏi họ có thể can thiệp vào được không? vì trước mắt họ như 1 đám rừng.
Hy vọng bạn hiểu.
Cảm ơn vì góp ý của bạn!
Chúc vui!
 
Upvote 0
Những thành viên lên diễn đàn để hỏi hoặc để nhờ sự giúp đỡ gồm có 3 phần:
1. Biết nhiều (Dĩ nhiên những thành viên này thì ít khi hỏi mà chủ yếu là hỗ trợ các thành viên khác)
1. Biết ít
2. Không biết (và Dĩ nhiên đây là phần hỏi cực kỳ nhiều và đếm đến ko ít phiền toái, vì đơn giản họ không biết gì về cái họ muốn tìm hiểu, nhưng được cái họ rất muốn tìm hiểu)
Nếu như một người không biết chút gì về code thử hỏi họ có thể can thiệp vào được không? vì trước mắt họ như 1 đám rừng.
Hy vọng bạn hiểu.
Cảm ơn vì góp ý của bạn!
Chúc vui!

Tôi học VBA cũng bắt đầu từ con số 0... Tôi kém thông minh nhưng được cái tôi "chịu cày"
Những cái nhỏ nhỏ thì cứ tự nghiên cứu ---> Suy đoán, chính sửa, thí nghiệm và rút ra kết luận
Visual Basic được cái là thân thiện với người dùng, lỗi ở đâu nó chỉ chính xác tại đó, đồng thời có câu thông báo lỗi ----> Đọc xem nó nói gì để mà sửa. Thế thôi
Cái quỷ gì cũng hỏi thì đến kiếp nào mới mong tự mình làm được đây
-------------
Tôi nói thế không có ý phê phán gì bạn mà để bạn rút kinh nghiệm... Bạn cứ tự mình chỉnh sửa code, chỉnh lung tung gì đó (theo suy đoán) dù chẳng chạy được thì ít ra bạn cũng không thẹn với lòng vì mình đã làm hết khả năng... Thêm nữa, nếu tự sửa mà chưa chạy thì vẫn còn các thành viên khác trợ giúp
(oải nhất là cái gì lỗi cũng la làng)
 
Upvote 0
Tôi học VBA cũng bắt đầu từ con số 0... Tôi kém thông minh nhưng được cái tôi "chịu cày"
Những cái nhỏ nhỏ thì cứ tự nghiên cứu ---> Suy đoán, chính sửa, thí nghiệm và rút ra kết luận
Visual Basic được cái là thân thiện với người dùng, lỗi ở đâu nó chỉ chính xác tại đó, đồng thời có câu thông báo lỗi ----> Đọc xem nó nói gì để mà sửa. Thế thôi
Cái quỷ gì cũng hỏi thì đến kiếp nào mới mong tự mình làm được đây
-------------
Tôi nói thế không có ý phê phán gì bạn mà để bạn rút kinh nghiệm... Bạn cứ tự mình chỉnh sửa code, chỉnh lung tung gì đó (theo suy đoán) dù chẳng chạy được thì ít ra bạn cũng không thẹn với lòng vì mình đã làm hết khả năng... Thêm nữa, nếu tự sửa mà chưa chạy thì vẫn còn các thành viên khác trợ giúp
(oải nhất là cái gì lỗi cũng la làng)

Cảm ơn bạn!
Mình sẽ rút kinh nghiệm.
 
Upvote 0
Kiểm tra nếu file chưa được lưu vào ổ đĩa thì lưu vào ổ C với tên tương ứng của WB đó, ngược lại sẽ lưu file rồi mới chạy code.

[GPECODE=sql]Sub ModTongHopThepHinh()
On Error Resume Next
Dim adoConn As Object, adoRS As Object, fld, i As Integer, eR As Integer
Set adoConn = CreateObject("ADODB.Connection")
Set adoRS = CreateObject("ADODB.Recordset")
If InStr(ActiveWorkbook.FullName, ":\") = 0 Then
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs "C:\" & ActiveWorkbook.Name
Else
ActiveWorkbook.Save
Application.DisplayAlerts = True
End If
With adoConn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ActiveWorkbook.FullName & _
";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
.Open
End With
With adoRS
.ActiveConnection = adoConn
.Open "select CK,CLT,QCT,sum(CD) as [TCD],sum(TL) as [TTL],sum(DTS) as [TDTS] " _
& "from [" & ActiveSheet.Name & "$A10:R500] " _
& "group by CK,CLT,QCT " _
& "having CK is not null"
End With
With ActiveSheet
.Range("U11:AF500").ClearContents
For Each fld In adoRS.Fields
i = i + 1
.Cells(10, i + 20) = fld.Name
Next
.[U11].CopyFromRecordset adoRS
End With
adoRS.Close
With adoRS
.ActiveConnection = adoConn
.Open "select '' as STT,CLT,QCT,sum(CD) as [TCD],sum(TL) as [TTL] " _
& "from [" & ActiveSheet.Name & "$A10:R500] " _
& "group by CLT,QCT " _
& "having CLT is not null " _
& "order by right(QCT,1),CLT"
End With
i = 0
With ActiveSheet
For Each fld In adoRS.Fields
i = i + 1
.Cells(10, i + 27) = fld.Name
Next
.[AB11].CopyFromRecordset adoRS
End With
adoRS.Close
With adoRS
.ActiveConnection = adoConn
.Open "select sum(DTS) as [TDTS] " _
& "from [" & ActiveSheet.Name & "$A10:R500]"
End With

With ActiveSheet
eR = .Range("AC65000").End(xlUp).Row + 1
.Range("AC" & eR) = "T" & ChrW(7892) & "NG C" & ChrW(7896) & "NG"
.Range("AC" & eR + 1) = "T" & ChrW(7892) & "NG DI" & ChrW(7878) & "N TÍCH S" & ChrW(416) & "N"
.Range("AE" & eR).FormulaR1C1 = "=SUM(R[-" & eR - 11 & "]C:R[-1]C)"
.Range("AF" & eR).FormulaR1C1 = "=SUM(R[-" & eR - 11 & "]C:R[-1]C)"
.Range("AE" & eR + 1).CopyFromRecordset adoRS
' .Cells.EntireColumn.AutoFit
.Range("AB11:AB" & eR - 1).FormulaR1C1 = "=ROW()-10"
End With
adoRS.Close: Set adoRS = Nothing
adoConn.Close: Set adoConn = Nothing

End Sub

[/GPECODE]

E mò mẫm phân tích đoạn code của a Hai Lúa, người biết nhìn qua là rõ ngay, còn e ko biết ngồi mò cái đoạn code này hơn nữa giờ mới rõ được chút chút :)
e có 2 vấn đề nhờ các a nào biết giúp e:
1. Vấn đề là ở phần code tô màu đỏ là đoạn tính tổng diện tích sơn, vậy cho e hỏi giờ e muốn khai báo thêm phần tính tổng khối lượng que hàn (ví dụ cột que hàn nằm ở cột L bên bảng thống kê, còn diện tích sơn nằm ở cột M) thì e phải thêm đoạn code như thế nào?
2. Khi chạy đoạn code này nếu bên bảng thống kê ko có dữ liệu thì nó sẽ báo lỗi, nhờ các a sửa lại giúp e nếu chạy đoạn code này mà bên bảng thống kê ko có dữ liệu thì vẫn không báo lỗi và hiện ra 1 bảng thông báo "Chưa có dữ liệu ở bảng thống kê"
e cảm ơn!
 
Lần chỉnh sửa cuối:
Upvote 0
E mò mẫm phân tích đoạn code của a Hai Lúa, người biết nhìn qua là rõ ngay, còn e ko biết ngồi mò cái đoạn code này hơn nữa giờ mới rõ được chút chút :)
e có 2 vấn đề nhờ các a nào biết giúp e:
1. Vấn đề là ở phần code tô màu đỏ là đoạn tính tổng diện tích sơn, vậy cho e hỏi giờ e muốn khai báo thêm phần tính tổng khối lượng que hàn (ví dụ cột que hàn nằm ở cột L bên bảng thống kê, còn diện tích sơn nằm ở cột M) thì e phải thêm đoạn code như thế nào?
2. Khi chạy đoạn code này nếu bên bảng thống kê ko có dữ liệu thì nó sẽ báo lỗi, nhờ các a sửa lại giúp e nếu chạy đoạn code này mà bên bảng thống kê ko có dữ liệu thì vẫn không báo lỗi và hiện ra 1 bảng thông báo "Chưa có dữ liệu ở bảng thống kê"
e cảm ơn!

Cho cái file mới + kèm với code của bạn lên mình test thử nhé.
 
Upvote 0
Phần ô màu vàng là phần e muốn bổ sung thêm, và có phần comment kèm theo để a dễ hình dung
a xem giúp e
e cảm ơn!
Bạn dùng code sau thử nhé.

[GPECODE=sql]Sub ModTongHopThepHinh()
On Error Resume Next
Dim adoConn As Object, adoRS As Object, fld, i As Integer, eR As Integer
Set adoConn = CreateObject("ADODB.Connection")
Set adoRS = CreateObject("ADODB.Recordset")
With adoConn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ActiveWorkbook.FullName & _
";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
.Open
End With
With adoRS
.ActiveConnection = adoConn
.Open "select CK,CLT,QCT,sum(CD) as [TCD],sum(TL) as [TTL],sum(qh) as TQH,sum(DTS) as [TDTS] " _
& "from [" & ActiveSheet.Name & "$A10:T500] " _
& "group by CK,CLT,QCT " _
& "having CK is not null"
End With
With ActiveSheet
.Range("U11:AF500").ClearContents
For Each fld In adoRS.Fields
i = i + 1
.Cells(10, i + 20) = fld.Name
Next
.[U11].CopyFromRecordset adoRS
End With
adoRS.Close
With adoRS
.ActiveConnection = adoConn
.Open "select '' as STT,CLT,QCT,sum(CD) as [TCD],sum(TL) as [TTL] " _
& "from [" & ActiveSheet.Name & "$A10:T500] " _
& "group by CLT,QCT " _
& "having CLT is not null " _
& "order by right(QCT,1),CLT"
End With
i = 0
With ActiveSheet
For Each fld In adoRS.Fields
i = i + 1
.Cells(10, i + 27) = fld.Name
Next
.[AB11].CopyFromRecordset adoRS
End With
adoRS.Close
With adoRS
.ActiveConnection = adoConn
.Open "select sum(DTS) as [TDTS] " _
& "from [" & ActiveSheet.Name & "$A10:T500]"
End With

With ActiveSheet
eR = .Range("AC65000").End(xlUp).Row + 1
.Range("AC" & eR) = "T" & ChrW(7892) & "NG C" & ChrW(7896) & "NG"
.Range("AC" & eR + 1) = "T" & ChrW(7892) & "NG DI" & ChrW(7878) & "N TÍCH S" & ChrW(416) & "N"
.Range("AC" & eR + 2) = "T" & ChrW(7892) & "NG C" & ChrW(7896) & "NG QUE HÀN"
.Range("AE" & eR).FormulaR1C1 = "=SUM(R[-" & eR - 11 & "]C:R[-1]C)"
.Range("AF" & eR).FormulaR1C1 = "=SUM(R[-" & eR - 11 & "]C:R[-1]C)"
.Range("AE" & eR + 1).CopyFromRecordset adoRS
' .Cells.EntireColumn.AutoFit
.Range("AB11:AB" & eR - 1).FormulaR1C1 = "=ROW()-10"
adoRS.Close
With adoRS
.ActiveConnection = adoConn
.Open "select sum(QH) as [TQH] " _
& "from [" & ActiveSheet.Name & "$A10:T500]"
End With
.Range("AE" & eR + 2).CopyFromRecordset adoRS
End With
adoRS.Close: Set adoRS = Nothing
adoConn.Close: Set adoConn = Nothing

End Sub

[/GPECODE]
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom