Trích lọc dữ liệu từ 2 sheet để so sánh sự khác biệt

Liên hệ QC

kokano90

Thành viên hoạt động
Tham gia
10/8/19
Bài viết
117
Được thích
25
Chào các thầy cô ạ.
Em có file demo dữ liệu như file đính kèm.
Giờ muốn trích lọc dữ liệu từ nhiều sheet và sheet KQ theo 2 dạng để so sánh sự khác biệt.
Muôn sử dụng dictinonary nhưng lại không biết làm thế nào.
Nhờ các thầy cô giúp đỡ với ạ. Em có đính kèm kết quả mẫu tại sheet KQ.
Em xin cám ơn nhiều.
 

File đính kèm

  • demo.xlsb
    13.9 KB · Đọc: 27
Chào các thầy cô ạ.
Em có file demo dữ liệu như file đính kèm.
Giờ muốn trích lọc dữ liệu từ nhiều sheet và sheet KQ theo 2 dạng để so sánh sự khác biệt.
Muôn sử dụng dictinonary nhưng lại không biết làm thế nào.
Nhờ các thầy cô giúp đỡ với ạ. Em có đính kèm kết quả mẫu tại sheet KQ.
Em xin cám ơn nhiều.
2 sheet a và b, tên 1 và tên 2 luôn luôn giống nhau?
 
Upvote 0
2 sheet a và b, tên 1 và tên 2 luôn luôn giống nhau?
Cũng có lúc nó khác nhau thầy ạ. Chính vì thế nên em mới muốn đưa dữ liệu 2 sheets về để so sánh. Ý tưởng ban đầu là sử dụng dic. Key là tên 1&tên 2 ạ. Nếu 1 trong 2 sheet a hoặc b có thêm tên 1 thì ở sheet KQ sẽ gồm những cái chung của sheet a và b. Thêm cái ko chung nữa ạ
 
Lần chỉnh sửa cuối:
Upvote 0
Cũng có lúc nó khác nhau thầy ạ. Chính vì thế nên em mới muốn đưa dữ liệu 2 sheets về để so sánh. Ý tưởng ban đầu là sử dụng dic. Key là tên 1&tên 2 ạ. Nếu 1 trong 2 sheet a hoặc b có thêm tên 1 thì ở sheet KQ sẽ gồm những cái chung của sheet a và b. Thêm cái ko chung nữa ạ
Chạy code
Mã:
Sub ABC()
  Dim sArr(0 To 1), Arr(), Res(), sh
  Dim Dic As Object, iKey$, iKey2$
  Dim k&, k2&, iR&, iR2&
  Dim n&, i&, j&, sRow&, sCol&, jC&
 
  sh = Array("a", "b")
  For n = 0 To 1
    With Sheets(sh(n))
      sRow = .Range("A" & Rows.Count).End(xlUp).Row
      sCol = .Range("AAA1").End(xlToLeft).Column
      sArr(n) = .Range("A1", .Cells(sRow, sCol)).Value
    End With
  Next n
  ReDim Res(1 To UBound(sArr(0)) + UBound(sArr(1)), 1 To UBound(sArr(0), 2) + UBound(sArr(1), 2) + 2)
  ReDim Res2(1 To UBound(Res), 1 To UBound(Res, 2) + 1)
  Set Dic = CreateObject("scripting.dictionary")
 

  sCol = 2
  For n = 0 To 1
    Res(1, sCol + 1) = "Sheet " & sh(n)
    Res2(1, sCol + 2) = "Sheet " & sh(n)
    Arr = sArr(n)
    For j = 3 To UBound(Arr, 2)
      For i = 2 To UBound(Arr)
        If Arr(i, j) > 0 Then
          sCol = sCol + 1
          Dic.Item(Arr(1, j) & "Sheet " & sh(n)) = sCol  'Cot Res
          Res(2, sCol) = Arr(1, j)
          Res2(2, sCol + 1) = Arr(1, j)
          Exit For
        End If
      Next i
    Next j
  Next n
  k = 2: k2 = 2
  For n = 0 To 1
    Arr = sArr(n)
    For i = 2 To UBound(Arr)
      iKey = Arr(i, 1)
      If Dic.exists(iKey) = False Then
        k = k + 1
        Dic.Add iKey, k
        Res(k, 1) = k - 2
        Res(k, 2) = iKey
        Res2(k2 + 1, 1) = k - 2
      End If
      iR = Dic.Item(iKey)
      
      iKey2 = Arr(i, 1) & "|" & Arr(i, 2)
      If Dic.exists(iKey2) = False Then
        k2 = k2 + 1
        Dic.Add iKey2, k2
        Res2(k2, 2) = Arr(i, 1)
        Res2(k2, 3) = Arr(i, 2)
      End If
      iR2 = Dic.Item(iKey2)
      For j = 3 To UBound(Arr, 2)
        If Arr(i, j) > 0 Then
          jC = Dic.Item(Arr(1, j) & "Sheet " & sh(n))
          Res(iR, jC) = Res(iR, jC) + Arr(i, j)
          Res2(iR2, jC + 1) = Res2(iR2, jC + 1) + Arr(i, j)
        End If
      Next j
    Next i
  Next n
  With Sheets("KQ2")
    Res(2, 1) = .Range("A2").Value
    Res(2, 2) = .Range("B2").Value
    Res2(2, 1) = .Range("A2").Value
    Res2(2, 2) = .Range("B2").Value
    Res2(2, 3) = .Range("C2").Value
    .UsedRange.Clear
    .Range("B1").Resize(k2, 2).NumberFormat = "@"
    .Range("A1").Resize(k2, sCol + 1) = Res2
    .Range("A1").Resize(k2, sCol + 1).Borders.LineStyle = 1
  End With
  With Sheets("KQ1")
    .UsedRange.Clear
    .Range("B1").Resize(k).NumberFormat = "@"
    .Range("A1").Resize(k, sCol) = Res
    .Range("A1").Resize(k, sCol).Borders.LineStyle = 1
  End With
End Sub
 
Upvote 0
Cám ơn thầy nhiều. Mai em sẽ test lại rồi phản hồi thầy sau. Tại giờ tắt điện mất tiêu rồi ạ. Cảm ơn thầy lần nữa ạ
 
Upvote 0
@HieuCD : Thật tuyệt vời. Cám ơn Thầy. Code của thầy chạy trúng phóc luôn.
Phiền thầy 1 chút. Nếu như mà muốn mở rộng thêm phần chênh lệch trong 2 sheet KQ1, KQ2 thì phải sửa code thế nào ạ thầy?
Em cám ơn thầy nhiều
1591164432721.png
 
Upvote 0
Upvote 0
@HieuCD Việc các cột "Tiền..." ấy giống nhau như thầy hỏi ấy. Có thể sửa được trong code của thầy không thầy? Tại em thêm 1 modul thu lại macro xử lý bằng tay. Nhưng khi cái cột "Tiền..." ấy phát sinh thêm cột. Thì macro em thu nó lại trậc lấc. Kết quả không ra đúng ạ.
Cám ơn thầy về đoạn code trên kia rất nhiều ạ
 
Upvote 0
Các cột tiền ấy giống nhau thầy ạ
Thử code
Mã:
Sub ABC()
  Dim sArr(0 To 1), Arr(), Res(), sh
  Dim Dic As Object, iKey$, iKey2$
  Dim k&, k2&, iR&, iR2&
  Dim n&, i&, j&, sRow&, sCol&, jC&, eCol&, dCol&
 
  sh = Array("a", "b")
  For n = 0 To 1 'Tao Mang du lieu 2 sheet a, b
    With Sheets(sh(n))
      sRow = .Range("A" & Rows.Count).End(xlUp).Row
      sCol = .Range("AAA1").End(xlToLeft).Column
      sArr(n) = .Range("A1", .Cells(sRow, sCol)).Value
    End With
  Next n
 
  eCol = UBound(sArr(0), 2)
  For j = 3 To eCol 'Loc cac cot "Tien" co phat sinh
    For n = 0 To 1
      Arr = sArr(n)
      For i = 2 To UBound(Arr)
        If Arr(i, j) > 0 Then Exit For
      Next i
      If i <= UBound(Arr) Then Exit For
    Next n
    If n = 2 Then sArr(0)(1, j) = Empty Else dCol = dCol + 1 'Dem cot "tien" co phat sinh
  Next j
  ReDim Res(1 To UBound(sArr(0)) + UBound(sArr(1)), 1 To dCol * 3 + 2)
  ReDim Res2(1 To UBound(Res), 1 To UBound(Res, 2) + 1)
 
  Set Dic = CreateObject("scripting.dictionary")
  Arr = sArr(0)
  sCol = 2 'thu tu cot ket qua
  For n = 0 To 1 'Tao tieu de cot và thu tu cot ket qua
    Res(1, sCol + 1) = "Sheet " & sh(n) 'Tao tieu de cot
    Res2(1, sCol + 2) = "Sheet " & sh(n)
    For j = 3 To eCol
      If Arr(1, j) <> Empty Then
        sCol = sCol + 1 'thu tu cot ket qua
        Dic.Item(Arr(1, j) & "Sheet " & sh(n)) = sCol
        Res(2, sCol) = Arr(1, j) 'Tao tieu de cot
        Res2(2, sCol + 1) = Arr(1, j)
      End If
    Next j
  Next n
  Res(1, sCol + 1) = "Chenh Lech"
  Res2(1, sCol + 2) = "Chenh Lech"
  k = 2: k2 = 2
  For n = 0 To 1 'Gán ket qua tu du lieu cac sheet
    Arr = sArr(n)
    For i = 2 To UBound(Arr)
      iKey = Arr(i, 1)
      If Dic.exists(iKey) = False Then
        k = k + 1
        Dic.Add iKey, k
        Res(k, 1) = k - 2
        Res(k, 2) = iKey
        Res2(k2 + 1, 1) = k - 2
      End If
      iR = Dic.Item(iKey)
      
      iKey2 = Arr(i, 1) & "|" & Arr(i, 2)
      If Dic.exists(iKey2) = False Then
        k2 = k2 + 1
        Dic.Add iKey2, k2
        Res2(k2, 2) = Arr(i, 1)
        Res2(k2, 3) = Arr(i, 2)
      End If
      iR2 = Dic.Item(iKey2)
      For j = 3 To eCol
        If Arr(i, j) > 0 Then
          jC = Dic.Item(Arr(1, j) & "Sheet " & sh(n))
          Res(iR, jC) = Res(iR, jC) + Arr(i, j)
          Res2(iR2, jC + 1) = Res2(iR2, jC + 1) + Arr(i, j)
        End If
      Next j
    Next i
  Next n
 
  For j = 1 To dCol 'Cot ket qua chenh lech
    Res(2, sCol + j) = Res(2, sCol + j - dCol)
    For i = 3 To k
      Res(i, sCol + j) = Res(i, sCol + j - 2 * dCol) - Res(i, sCol + j - dCol)
    Next i
    Res2(2, sCol + j + 1) = Res2(2, sCol + j - dCol + 1)
    For i = 3 To k2
      Res2(i, sCol + j + 1) = Res2(i, sCol + j + 1 - 2 * dCol) - Res2(i, sCol + j + 1 - dCol)
    Next i
  Next j

  With Sheets("KQ2")
    Res(2, 1) = .Range("A2").Value
    Res(2, 2) = .Range("B2").Value
    Res2(2, 1) = .Range("A2").Value
    Res2(2, 2) = .Range("B2").Value
    Res2(2, 3) = .Range("C2").Value
    .UsedRange.Clear
    .Range("B1").Resize(k2, 2).NumberFormat = "@"
    .Range("A1").Resize(k2, sCol + dCol + 1) = Res2
    .Range("A1").Resize(k2, sCol + dCol + 1).Borders.LineStyle = 1
  End With
  With Sheets("KQ1")
    .UsedRange.Clear
    .Range("B1").Resize(k).NumberFormat = "@"
    .Range("A1").Resize(k, sCol + dCol) = Res
    .Range("A1").Resize(k, sCol + dCol).Borders.LineStyle = 1
  End With
End Sub
 
Upvote 0
@HieuCD Chao thầy ạ
Hiện tại sử dụng code tren của thầy ổn rồi.Thầy có thể cho em hỏi thêm 1 chút.
Tại sheet KQ2 ấy ạ. Khi em tạo Pivotable từ sheet KQ2 ấy. Nó bị vướng phần tên trùng nhau từ các tiền...
Có cách nào mà tách biệt được phần Tiền Tại cột sheet a là Tiền 1, Tiền 2,....
Sheet B Là Tiền 11 ,Tiền 21, Tiền 31....
Cột chênh lệch Tiền 12, Tiền 22, Tiền 32... không ạ
Trường hợp tạo được bảng Pivotable rồi. có cách nào mà thực hiện thao tác này:
1591888259318.png
cho ngắn gọn được không thầy? Tại thu macro mà thấy nó dài quá trong khi thêm đoạn code này
Mã:
ActiveSheet.PivotTables("PivotTable1").PivotFields.Subtotals = False
nó báo lỗi. Em cũng chưa biết lí do tại sao
Mong thầy giúp ạ. Cám ơn thầy
 

File đính kèm

  • 1591888233629.png
    1591888233629.png
    22.8 KB · Đọc: 4
Upvote 0
@HieuCD Chao thầy ạ
Hiện tại sử dụng code tren của thầy ổn rồi.Thầy có thể cho em hỏi thêm 1 chút.
Tại sheet KQ2 ấy ạ. Khi em tạo Pivotable từ sheet KQ2 ấy. Nó bị vướng phần tên trùng nhau từ các tiền...
Có cách nào mà tách biệt được phần Tiền Tại cột sheet a là Tiền 1, Tiền 2,....
Sheet B Là Tiền 11 ,Tiền 21, Tiền 31....
Cột chênh lệch Tiền 12, Tiền 22, Tiền 32... không ạ
Trường hợp tạo được bảng Pivotable rồi. có cách nào mà thực hiện thao tác này:
View attachment 239155
cho ngắn gọn được không thầy? Tại thu macro mà thấy nó dài quá trong khi thêm đoạn code này
Mã:
ActiveSheet.PivotTables("PivotTable1").PivotFields.Subtotals = False
nó báo lỗi. Em cũng chưa biết lí do tại sao
Mong thầy giúp ạ. Cám ơn thầy
Chỉnh tiêu đề "Tiền"
Mã:
Sub ABC()
  Dim sArr(0 To 1), Arr(), Res(), sh
  Dim Dic As Object, iKey$, iKey2$
  Dim k&, k2&, iR&, iR2&
  Dim n&, i&, j&, sRow&, sCol&, jC&, eCol&, dCol&
 
  sh = Array("a", "b")
  For n = 0 To 1 'Tao Mang du lieu 2 sheet a, b
    With Sheets(sh(n))
      sRow = .Range("A" & Rows.Count).End(xlUp).Row
      sCol = .Range("AAA1").End(xlToLeft).Column
      sArr(n) = .Range("A1", .Cells(sRow, sCol)).Value
    End With
  Next n
 
  eCol = UBound(sArr(0), 2)
  For j = 3 To eCol 'Loc cac cot "Tien" co phat sinh
    For n = 0 To 1
      Arr = sArr(n)
      For i = 2 To UBound(Arr)
        If Arr(i, j) > 0 Then Exit For
      Next i
      If i <= UBound(Arr) Then Exit For
    Next n
    If n = 2 Then sArr(0)(1, j) = Empty Else dCol = dCol + 1 'Dem cot "tien" co phat sinh
  Next j
  ReDim Res(1 To UBound(sArr(0)) + UBound(sArr(1)), 1 To dCol * 3 + 2)
  ReDim Res2(1 To UBound(Res), 1 To UBound(Res, 2) + 1)
 
  Set Dic = CreateObject("scripting.dictionary")
  Arr = sArr(0)
  sCol = 2 'thu tu cot ket qua
  For n = 0 To 1 'Tao tieu de cot và thu tu cot ket qua
    Res(1, sCol + 1) = "Sheet " & sh(n) 'Tao tieu de cot
    Res2(1, sCol + 2) = "Sheet " & sh(n)
    For j = 3 To eCol
      If Arr(1, j) <> Empty Then
        sCol = sCol + 1 'thu tu cot ket qua
        Dic.Item(Arr(1, j) & "Sheet " & sh(n)) = sCol
        Res(2, sCol) = Arr(1, j) 'Tao tieu de cot
        Res2(2, sCol + 1) = Arr(1, j)
      End If
    Next j
  Next n
  Res(1, sCol + 1) = "Chenh Lech"
  Res2(1, sCol + 2) = "Chenh Lech"
  k = 2: k2 = 2
  For n = 0 To 1 'Gán ket qua tu du lieu cac sheet
    Arr = sArr(n)
    For i = 2 To UBound(Arr)
      iKey = Arr(i, 1)
      If Dic.exists(iKey) = False Then
        k = k + 1
        Dic.Add iKey, k
        Res(k, 1) = k - 2
        Res(k, 2) = iKey
        Res2(k2 + 1, 1) = k - 2
      End If
      iR = Dic.Item(iKey)
      
      iKey2 = Arr(i, 1) & "|" & Arr(i, 2)
      If Dic.exists(iKey2) = False Then
        k2 = k2 + 1
        Dic.Add iKey2, k2
        Res2(k2, 2) = Arr(i, 1)
        Res2(k2, 3) = Arr(i, 2)
      End If
      iR2 = Dic.Item(iKey2)
      For j = 3 To eCol
        If Arr(i, j) > 0 Then
          jC = Dic.Item(Arr(1, j) & "Sheet " & sh(n))
          Res(iR, jC) = Res(iR, jC) + Arr(i, j)
          Res2(iR2, jC + 1) = Res2(iR2, jC + 1) + Arr(i, j)
        End If
      Next j
    Next i
  Next n
 
  For j = 1 To dCol 'Cot ket qua chenh lech
    Res(2, sCol + j) = Res(2, sCol + j - dCol) & 2
    Res(2, sCol + j - dCol) = Res(2, sCol + j - dCol) & 1
    For i = 3 To k
      Res(i, sCol + j) = Res(i, sCol + j - 2 * dCol) - Res(i, sCol + j - dCol)
    Next i
    Res2(2, sCol + j + 1) = Res2(2, sCol + j - dCol + 1) & 2
    Res2(2, sCol + j - dCol + 1) = Res2(2, sCol + j - dCol + 1) & 1
    For i = 3 To k2
      Res2(i, sCol + j + 1) = Res2(i, sCol + j + 1 - 2 * dCol) - Res2(i, sCol + j + 1 - dCol)
    Next i
  Next j

  With Sheets("KQ2")
    Res(2, 1) = .Range("A2").Value
    Res(2, 2) = .Range("B2").Value
    Res2(2, 1) = .Range("A2").Value
    Res2(2, 2) = .Range("B2").Value
    Res2(2, 3) = .Range("C2").Value
    .UsedRange.Clear
    .Range("B1").Resize(k2, 2).NumberFormat = "@"
    .Range("A1").Resize(k2, sCol + dCol + 1) = Res2
    .Range("A1").Resize(k2, sCol + dCol + 1).Borders.LineStyle = 1
  End With
  With Sheets("KQ1")
    .UsedRange.Clear
    .Range("B1").Resize(k).NumberFormat = "@"
    .Range("A1").Resize(k, sCol + dCol) = Res
    .Range("A1").Resize(k, sCol + dCol).Borders.LineStyle = 1
  End With
End Sub
Array(...) lấy từ bộ thu Macro chỉnh lại cho phù hợp
Mã:
Sub RemoveSubotals()
  With ActiveSheet.PivotTables("PivotTable1")
    For i = 0 To .PivotFields.Count - 1
      .PivotFields.Item(i).Subtotals = Array( False, False, False, False, False, False, False, False, False, False, False, False)
    Next i
  End With
End Sub
 
Upvote 0
Web KT

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

Back
Top Bottom