Nhờ Anh Chị hỗ trợ sửa code lọc dữ liệu bằng VBA

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

dinhquang042000

Thành viên chính thức
Tham gia
16/12/15
Bài viết
76
Được thích
4
Xin chào Anh Chị,
Em đang làm file lọc dữ liệu tự động bằng VBA. File em sử dụng 3 sub.
Sub Copy_data để copy toàn bộ dữ liệu từ file DU LIEU qua file chính tạo các sheet mới giống sheet dữ liệu
Sub TaoSheetBangKe để tự động tạo tạo sheet BANG KE cho mỗi sheet dữ liệu vừa tạo ở trên theo mẫu sheet "BANG KE" (VD SITC LIAONING 2318S sẽ tự tạo BANG KE SITC LIAONING 2318S
Sub TAOBANGKE1 sẽ duyệt qua từng sheet dữ liệu (VD sheet "SITC LIAONING 2318S" ) và copy dữ liệu qua sheet BANG KE tương ứng ("BANG KE SITC LIAONING 2318S") các cột dữ liệu chỉ định trước là (1, 2, 3, 4, 5, 6, 9, 7, 14, 15, 16, 19, 20). Nhưng khi em chạy chỉ 1 sheet dữ liệu chạy được rùi báo lỗi run-time error '9'.
Em gửi file + bảng dữ liệu, Mong Anh Chị bớt chút thời gian xem xét, hỗ trợ em sửa lại code này với ạ.
Em xin cảm ơn!
 

File đính kèm

Xin chào Anh Chị,
Em đang làm file lọc dữ liệu tự động bằng VBA. File em sử dụng 3 sub.
Sub Copy_data để copy toàn bộ dữ liệu từ file DU LIEU qua file chính tạo các sheet mới giống sheet dữ liệu
Sub TaoSheetBangKe để tự động tạo tạo sheet BANG KE cho mỗi sheet dữ liệu vừa tạo ở trên theo mẫu sheet "BANG KE" (VD SITC LIAONING 2318S sẽ tự tạo BANG KE SITC LIAONING 2318S
Sub TAOBANGKE1 sẽ duyệt qua từng sheet dữ liệu (VD sheet "SITC LIAONING 2318S" ) và copy dữ liệu qua sheet BANG KE tương ứng ("BANG KE SITC LIAONING 2318S") các cột dữ liệu chỉ định trước là (1, 2, 3, 4, 5, 6, 9, 7, 14, 15, 16, 19, 20). Nhưng khi em chạy chỉ 1 sheet dữ liệu chạy được rùi báo lỗi run-time error '9'.
Em gửi file + bảng dữ liệu, Mong Anh Chị bớt chút thời gian xem xét, hỗ trợ em sửa lại code này với ạ.
Em xin cảm ơn!
Nếu tôi hiểu đúng y bạn thì
Theo tôi :
1/Bạn không cần Dùng Sub Copy_data mà dùng code lấy luôn dữ liệu từ file DuLieu. (khi duyệt đến sheet nào thì lấy luôn dữ liệu của sheet đó và khi đó code sẽ là
Mã:
Sub CopyData()
Dim ifile As Variant
Dim i, s As Integer
Dim wb As Workbook
Dim ws As Worksheet
Dim star_cell As Range
Dim start_cell_temp As Range

Dim start_cell As Range

ifile = Application.GetOpenFilename(Filefilter:="Excel File (*.xlsx), *xls", MultiSelect:=True)
For i = 1 To UBound(ifile)
    Set wb = Workbooks.Open(ifile(i))
        For s = 1 To wb.Sheets.Count
  '          ThisWorkbook.Worksheets.Add
  '          ThisWorkbook.ActiveSheet.Name = wb.Sheets(s).Name
  '          Set start_cell_temp = wb.Sheets(s).Range("A1")
  '          start_cell_temp.CurrentRegion.Copy
  '          ThisWorkbook.ActiveSheet.Range("A1").PasteSpecial xlPasteAll
      Call  Sub TAOBANGKE(wb.Sheets(s).Name)
        Next s
    wb.Close
Next i
End Sub

Mã:
Sub TAOBANGKE(Byval wsheet as String)

  Dim sArr, Res(), colArr As Variant
  Dim i As Long, k As Long, j, ws As Integer
  Dim tmq, vessel, date_vessel As String
  Dim wb As Workbook, Sh As Worksheet
  Dim dk As Boolean
  Const cateString = "D"
  colArr = Array(0, 1, 2, 3, 4, 5, 6, 9, 7, 14, 15, 16, 19, 20)
 
 ' For Each wsheet In Worksheets
  '      If Left(wsheet.Name, 4) <> "BANG" Then
 k = 0
         With wsheet
           i = .Range("A" & Rows.Count).End(xlUp).Row
           If i < 4 Then MsgBox ("VUI LONG CAP NHAT DU LIEU TRUOC"): Exit Sub
           sArr = .Range("A2:T" & i).Value
         End With
      
         ReDim Res(1 To UBound(sArr) * 2, 1 To 13)
           For i = 1 To UBound(sArr)
           dk = False
           If i = 1 Then
             dk = True
           Else
             tmq = sArr(i, 3)
             vessel = sArr(2, 17)
             date_vessel = sArr(2, 18)

           If tmq <> "" Then dk = True
           End If
           If dk Then
             k = k + 1
             For j = 1 To 13
                If j = 1 And k = 1 Then Res(k, j) = 1 Else Res(k, j) = sArr(i, colArr(j))
             Next j
'           End If
'         Next i
      
'         With Sheets("BANG KE " & wsheet.Name)
Call TaoSheetBangKe(wsheet)
Set Sh = ActiveSheet
           Sh.Range("A5:M1000").ClearContents
           Sh.Range("C2").ClearContents
           Sh.Range("C3").ClearContents
           Sh.Range("C2") = vessel
           Sh.Range("C3") = date_vessel
           If k > 0 Then Sh.Range("A5").Resize(k, 13) = Res
'        End With
        End If
     Next
End Sub

2/Còn vì 1 lý do nào đó mà vẫn dùng sub Copy_data thì :
Sửa lại Sub TaoSheetBangKe() thành :
Mã:
Sub TaoSheetBangKe(ByVal ShName As String)
  Dim wsheet As Worksheet
  Dim sArr, Res(), colArr As Variant
  Dim i, k, j As Integer
'  For Each wsheet In Worksheets
'    If Left(wsheet.Name, 4) <> "BANG" Then
        Sheets("BANG KE").Copy after:=Sheets("BANG KE")
        ActiveSheet.Name = "BANG KE " & ShName 'wsheet.Name
'    End If
'  Next wsheet
End Sub
Và sửa lại sub TAOBANGKE1() thành
Mã:
Sub TAOBANGKE1()

  Dim sArr, Res(), colArr As Variant
  Dim i As Long, k As Long, j, ws As Integer
  Dim tmq, vessel, date_vessel As String
  Dim wb As Workbook, Sh As Worksheet     ' thêm biến Sh
  Dim dk As Boolean
  Const cateString = "D"
  colArr = Array(0, 1, 2, 3, 4, 5, 6, 9, 7, 14, 15, 16, 19, 20)
 
  For Each wsheet In Worksheets
        If Left(wsheet.Name, 4) <> "BANG" Then
 k = 0
         With wsheet
           i = .Range("A" & Rows.Count).End(xlUp).Row
           If i < 4 Then MsgBox ("VUI LONG CAP NHAT DU LIEU TRUOC"): Exit Sub
           sArr = .Range("A2:T" & i).Value
         End With
      
         ReDim Res(1 To UBound(sArr) * 2, 1 To 13)
           For i = 1 To UBound(sArr)
           dk = False
           If i = 1 Then
             dk = True
           Else
             tmq = sArr(i, 3)
             vessel = sArr(2, 17)
             date_vessel = sArr(2, 18)

           If tmq <> "" Then dk = True
           End If
           If dk Then
             k = k + 1
             For j = 1 To 13
                If j = 1 And k = 1 Then Res(k, j) = 1 Else Res(k, j) = sArr(i, colArr(j))
             Next j
           End If
         Next i
      
'         With Sheets("BANG KE " & wsheet.Name)   bo dòng này mà chạy dong tao sh mới
Call TaoSheetBangKe(wsheet.Name)
Set Sh = ActiveSheet
           Sh.Range("A5:M1000").ClearContents
           Sh.Range("C2").ClearContents
           Sh.Range("C3").ClearContents
           Sh.Range("C2") = vessel
           Sh.Range("C3") = date_vessel
           If k > 0 Then Sh.Range("A5").Resize(k, 13) = Res
'        End With
        End If
     Next
End Sub
Hy vọng là đúng ý.
Chú: Bạn phải xóa bỏ các sheets("BANGKE .....") trước khi chạy code.
Nhớ test kỹ .
Chúc thành công.
 
Nếu tôi hiểu đúng y bạn thì
Theo tôi :
1/Bạn không cần Dùng Sub Copy_data mà dùng code lấy luôn dữ liệu từ file DuLieu. (khi duyệt đến sheet nào thì lấy luôn dữ liệu của sheet đó và khi đó code sẽ là
Mã:
Sub CopyData()
Dim ifile As Variant
Dim i, s As Integer
Dim wb As Workbook
Dim ws As Worksheet
Dim star_cell As Range
Dim start_cell_temp As Range

Dim start_cell As Range

ifile = Application.GetOpenFilename(Filefilter:="Excel File (*.xlsx), *xls", MultiSelect:=True)
For i = 1 To UBound(ifile)
    Set wb = Workbooks.Open(ifile(i))
        For s = 1 To wb.Sheets.Count
  '          ThisWorkbook.Worksheets.Add
  '          ThisWorkbook.ActiveSheet.Name = wb.Sheets(s).Name
  '          Set start_cell_temp = wb.Sheets(s).Range("A1")
  '          start_cell_temp.CurrentRegion.Copy
  '          ThisWorkbook.ActiveSheet.Range("A1").PasteSpecial xlPasteAll
      Call  Sub TAOBANGKE(wb.Sheets(s).Name)
        Next s
    wb.Close
Next i
End Sub

Mã:
Sub TAOBANGKE(Byval wsheet as String)

  Dim sArr, Res(), colArr As Variant
  Dim i As Long, k As Long, j, ws As Integer
  Dim tmq, vessel, date_vessel As String
  Dim wb As Workbook, Sh As Worksheet
  Dim dk As Boolean
  Const cateString = "D"
  colArr = Array(0, 1, 2, 3, 4, 5, 6, 9, 7, 14, 15, 16, 19, 20)
 
 ' For Each wsheet In Worksheets
  '      If Left(wsheet.Name, 4) <> "BANG" Then
 k = 0
         With wsheet
           i = .Range("A" & Rows.Count).End(xlUp).Row
           If i < 4 Then MsgBox ("VUI LONG CAP NHAT DU LIEU TRUOC"): Exit Sub
           sArr = .Range("A2:T" & i).Value
         End With
    
         ReDim Res(1 To UBound(sArr) * 2, 1 To 13)
           For i = 1 To UBound(sArr)
           dk = False
           If i = 1 Then
             dk = True
           Else
             tmq = sArr(i, 3)
             vessel = sArr(2, 17)
             date_vessel = sArr(2, 18)

           If tmq <> "" Then dk = True
           End If
           If dk Then
             k = k + 1
             For j = 1 To 13
                If j = 1 And k = 1 Then Res(k, j) = 1 Else Res(k, j) = sArr(i, colArr(j))
             Next j
'           End If
'         Next i
    
'         With Sheets("BANG KE " & wsheet.Name)
Call TaoSheetBangKe(wsheet)
Set Sh = ActiveSheet
           Sh.Range("A5:M1000").ClearContents
           Sh.Range("C2").ClearContents
           Sh.Range("C3").ClearContents
           Sh.Range("C2") = vessel
           Sh.Range("C3") = date_vessel
           If k > 0 Then Sh.Range("A5").Resize(k, 13) = Res
'        End With
        End If
     Next
End Sub

2/Còn vì 1 lý do nào đó mà vẫn dùng sub Copy_data thì :
Sửa lại Sub TaoSheetBangKe() thành :
Mã:
Sub TaoSheetBangKe(ByVal ShName As String)
  Dim wsheet As Worksheet
  Dim sArr, Res(), colArr As Variant
  Dim i, k, j As Integer
'  For Each wsheet In Worksheets
'    If Left(wsheet.Name, 4) <> "BANG" Then
        Sheets("BANG KE").Copy after:=Sheets("BANG KE")
        ActiveSheet.Name = "BANG KE " & ShName 'wsheet.Name
'    End If
'  Next wsheet
End Sub
Và sửa lại sub TAOBANGKE1() thành
Mã:
Sub TAOBANGKE1()

  Dim sArr, Res(), colArr As Variant
  Dim i As Long, k As Long, j, ws As Integer
  Dim tmq, vessel, date_vessel As String
  Dim wb As Workbook, Sh As Worksheet     ' thêm biến Sh
  Dim dk As Boolean
  Const cateString = "D"
  colArr = Array(0, 1, 2, 3, 4, 5, 6, 9, 7, 14, 15, 16, 19, 20)
 
  For Each wsheet In Worksheets
        If Left(wsheet.Name, 4) <> "BANG" Then
 k = 0
         With wsheet
           i = .Range("A" & Rows.Count).End(xlUp).Row
           If i < 4 Then MsgBox ("VUI LONG CAP NHAT DU LIEU TRUOC"): Exit Sub
           sArr = .Range("A2:T" & i).Value
         End With
    
         ReDim Res(1 To UBound(sArr) * 2, 1 To 13)
           For i = 1 To UBound(sArr)
           dk = False
           If i = 1 Then
             dk = True
           Else
             tmq = sArr(i, 3)
             vessel = sArr(2, 17)
             date_vessel = sArr(2, 18)

           If tmq <> "" Then dk = True
           End If
           If dk Then
             k = k + 1
             For j = 1 To 13
                If j = 1 And k = 1 Then Res(k, j) = 1 Else Res(k, j) = sArr(i, colArr(j))
             Next j
           End If
         Next i
    
'         With Sheets("BANG KE " & wsheet.Name)   bo dòng này mà chạy dong tao sh mới
Call TaoSheetBangKe(wsheet.Name)
Set Sh = ActiveSheet
           Sh.Range("A5:M1000").ClearContents
           Sh.Range("C2").ClearContents
           Sh.Range("C3").ClearContents
           Sh.Range("C2") = vessel
           Sh.Range("C3") = date_vessel
           If k > 0 Then Sh.Range("A5").Resize(k, 13) = Res
'        End With
        End If
     Next
End Sub
Hy vọng là đúng ý.
Chú: Bạn phải xóa bỏ các sheets("BANGKE .....") trước khi chạy code.
Nhớ test kỹ .
Chúc thành công.
Dạ vâng ạ. Em cảm ơn Chị thật nhiều ạ.
 
Bài đăng lộn tiệm rồi
D92.jpg
 
Nếu tôi hiểu đúng y bạn thì
Theo tôi :
1/Bạn không cần Dùng Sub Copy_data mà dùng code lấy luôn dữ liệu từ file DuLieu. (khi duyệt đến sheet nào thì lấy luôn dữ liệu của sheet đó và khi đó code sẽ là
Mã:
Sub CopyData()
Dim ifile As Variant
Dim i, s As Integer
Dim wb As Workbook
Dim ws As Worksheet
Dim star_cell As Range
Dim start_cell_temp As Range

Dim start_cell As Range

ifile = Application.GetOpenFilename(Filefilter:="Excel File (*.xlsx), *xls", MultiSelect:=True)
For i = 1 To UBound(ifile)
    Set wb = Workbooks.Open(ifile(i))
        For s = 1 To wb.Sheets.Count
  '          ThisWorkbook.Worksheets.Add
  '          ThisWorkbook.ActiveSheet.Name = wb.Sheets(s).Name
  '          Set start_cell_temp = wb.Sheets(s).Range("A1")
  '          start_cell_temp.CurrentRegion.Copy
  '          ThisWorkbook.ActiveSheet.Range("A1").PasteSpecial xlPasteAll
      Call  Sub TAOBANGKE(wb.Sheets(s).Name)
        Next s
    wb.Close
Next i
End Sub

Mã:
Sub TAOBANGKE(Byval wsheet as String)

  Dim sArr, Res(), colArr As Variant
  Dim i As Long, k As Long, j, ws As Integer
  Dim tmq, vessel, date_vessel As String
  Dim wb As Workbook, Sh As Worksheet
  Dim dk As Boolean
  Const cateString = "D"
  colArr = Array(0, 1, 2, 3, 4, 5, 6, 9, 7, 14, 15, 16, 19, 20)
 
 ' For Each wsheet In Worksheets
  '      If Left(wsheet.Name, 4) <> "BANG" Then
 k = 0
         With wsheet
           i = .Range("A" & Rows.Count).End(xlUp).Row
           If i < 4 Then MsgBox ("VUI LONG CAP NHAT DU LIEU TRUOC"): Exit Sub
           sArr = .Range("A2:T" & i).Value
         End With
     
         ReDim Res(1 To UBound(sArr) * 2, 1 To 13)
           For i = 1 To UBound(sArr)
           dk = False
           If i = 1 Then
             dk = True
           Else
             tmq = sArr(i, 3)
             vessel = sArr(2, 17)
             date_vessel = sArr(2, 18)

           If tmq <> "" Then dk = True
           End If
           If dk Then
             k = k + 1
             For j = 1 To 13
                If j = 1 And k = 1 Then Res(k, j) = 1 Else Res(k, j) = sArr(i, colArr(j))
             Next j
'           End If
'         Next i
     
'         With Sheets("BANG KE " & wsheet.Name)
Call TaoSheetBangKe(wsheet)
Set Sh = ActiveSheet
           Sh.Range("A5:M1000").ClearContents
           Sh.Range("C2").ClearContents
           Sh.Range("C3").ClearContents
           Sh.Range("C2") = vessel
           Sh.Range("C3") = date_vessel
           If k > 0 Then Sh.Range("A5").Resize(k, 13) = Res
'        End With
        End If
     Next
End Sub
Em chào Chị Hương, Em cảm ơn sự trợ giúp nhiệt tình của Chị,
Nhưng khi em chạy theo cách 1 của Chị thì báo lỗi như hình.
Em chưa biết cách khắc phục lỗi này. Mong chỉ xem chỉ dẫn thêm giúp em ạ.
Em cảm ơn chị nhiều ạ
Bài đã được tự động gộp:

Dạ vâng ạ. Sorry Anh. Lần sau em sẽ chú ý khi đăng bài hơn ạ.
 

File đính kèm

  • LOI.jpg
    LOI.jpg
    12.8 KB · Đọc: 7
Lần chỉnh sửa cuối:
Thêm 1 cách khác tham khảo. Hi vọng đoán đúng ý
Mã:
Option Explicit
Sub ABC()
    Dim cn As Object, rs As Object
    Dim eRow&, Sql$, ws As Worksheet, wb As Workbook, i&, strFile$
    Dim WbN As Workbook
    Application.ScreenUpdating = 0
    Application.DisplayAlerts = 0
    Set WbN = ThisWorkbook
    For Each ws In WbN.Worksheets
        If ws.Name <> "BANG KE" Then
            ws.Delete
        End If
    Next
    With Application.FileDialog(msoFileDialogFilePicker)
        .Filters.Add "All Excel", "*.xls*"
        .AllowMultiSelect = False
        .Show
        If .SelectedItems.Count Then
            For i = 1 To .SelectedItems.Count
                strFile = .SelectedItems(i)
                Set wb = Workbooks.Open(strFile)
                Set cn = CreateObject("adodb.connection")
                cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile & ";Extended Properties=""Excel 12.0;HDR=NO"";"
                For Each ws In wb.Worksheets
                    WbN.Sheets("BANG KE").Copy after:=WbN.Sheets("BANG KE")
                    WbN.ActiveSheet.Name = "BANG KE " & ws.Name
                    Sql = "SELECT F1, F2, F3, F4, F5, F6, F9, F7, F14, F15, F16, F19, F20 FROM [" & ws.Name & "$A2:T65000] WHERE F3 IS NOT NULL"
                    Set rs = cn.Execute(Sql)
                    If Not rs.EOF Then ActiveSheet.Range("A5").CopyFromRecordset rs
                Next
                rs.Close
                cn.Close
                wb.Close False
                Set rs = Nothing
                Set cn = Nothing
            Next
        End If
    End With
    Application.ScreenUpdating = 1
    Application.DisplayAlerts = 1
End Sub
 
Lần chỉnh sửa cuối:
Thêm 1 cách khác tham khảo. Hi vọng đoán đúng ý
Mã:
Option Explicit
Sub ABC()
    Dim cn As Object, rs As Object
    Dim eRow&, Sql$, ws As Worksheet, wb As Workbook, i&, strFile$
    Dim WbN As Workbook
    Application.ScreenUpdating = 0
    Application.DisplayAlerts = 0
    Set WbN = ThisWorkbook
    For Each ws In WbN.Worksheets
        If ws.Name <> "BANG KE" Then
            ws.Delete
        End If
    Next
    With Application.FileDialog(msoFileDialogFilePicker)
        .Filters.Add "All Excel", "*.xls*"
        .AllowMultiSelect = False
        .Show
        If .SelectedItems.Count Then
            For i = 1 To .SelectedItems.Count
                strFile = .SelectedItems(i)
                Set wb = Workbooks.Open(strFile)
                Set cn = CreateObject("adodb.connection")
                cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile & ";Extended Properties=""Excel 12.0;HDR=NO"";"
                For Each ws In wb.Worksheets
                    WbN.Sheets("BANG KE").Copy after:=WbN.Sheets("BANG KE")
                    WbN.ActiveSheet.Name = "BANG KE " & ws.Name
                    Sql = "SELECT F1, F2, F3, F4, F5, F6, F9, F7, F14, F15, F16, F19, F20 FROM [" & ws.Name & "$A2:T65000] WHERE F3 IS NOT NULL"
                    Set rs = cn.Execute(Sql)
                    If Not rs.EOF Then ActiveSheet.Range("A5").CopyFromRecordset rs
                Next
                rs.Close
                cn.Close
                wb.Close False
                Set rs = Nothing
                Set cn = Nothing
            Next
        End If
    End With
    Application.ScreenUpdating = 1
    Application.DisplayAlerts = 1
End Sub
Dạ vâng ạ, Em cảm ơn Anh nhiều ạ
 
Em chào Chị Hương, Em cảm ơn sự trợ giúp nhiệt tình của Chị,
Nhưng khi em chạy theo cách 1 của Chị thì báo lỗi như hình.
Em chưa biết cách khắc phục lỗi này. Mong chỉ xem chỉ dẫn thêm giúp em ạ.
Em cảm ơn chị nhiều ạ
"Chị" chưa đi Thái Lan em ơi!
 
Web KT

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

Back
Top Bottom