Tạo báo cáo giống như Pivot Table.

Liên hệ QC

thang.phduy2

Thành viên mới
Tham gia
20/1/21
Bài viết
12
Được thích
0
Chào anh chị.

Em có thể xin code VBA có thể tạo báo cáo như sheet3 từ dữ liệu gốc ở sheet1. Hình thức báo cáo giống như pivot table.

Cảm ơn anh chị.
 

File đính kèm

  • pivot.xlsx
    45.3 KB · Đọc: 39
Sao bạn không Ghi lại Code của Pivot luôn
 
Chào anh chị.

Em có thể xin code VBA có thể tạo báo cáo như sheet3 từ dữ liệu gốc ở sheet1. Hình thức báo cáo giống như pivot table.

Cảm ơn anh chị.
Theo ví dụ kết quả
Mã:
Sub ABC()
  Dim sArr(), Res() As String, ResQt(), Dic As Object
  Dim i&, k&, iR&, sRow&, iKey$
 
  Set Dic = CreateObject("Scripting.Dictionary")
  With Sheets("Sheet1")
    sArr = .Range("A2", .Range("E" & Rows.Count).End(xlUp)).Value
  End With
  sRow = UBound(sArr)
  ReDim Res(1 To sRow, 1 To 4)
  ReDim ResQt(1 To sRow, 1 To 1)
  For i = 1 To sRow
    If sArr(i, 3) = 1 Then
      iKey = sArr(i, 1) & "|" & sArr(i, 4)
      If Not Dic.Exists(iKey) Then
        k = k + 1
        Dic.Add iKey, k
        Res(k, 1) = sArr(i, 4)
        Res(k, 2) = sArr(i, 5)
        Res(k, 4) = sArr(i, 1)
      End If
      iR = Dic.Item(iKey)
      ResQt(iR, 1) = ResQt(iR, 1) + 1
    End If
  Next i
  With Sheets("Sheet3")
    i = .Range("B" & Rows.Count).End(xlUp).Row
    If i > 1 Then .Range("B2:E" & i).ClearContents
    .Range("B2").Resize(k, 4) = Res
    .Range("D2").Resize(k, 1) = ResQt
    .Range("B2").Resize(k, 4).Sort .[E2], 1, .[B2], , 1
  End With
End Sub
 
Mình thấy phần Qty bạn điền tay đâu có đúng đâu nhỉ? Nó bằng 9 chứ sao bằng 7 được vậyView attachment 254270
Chia theo cột E ở E3 và E11.

Cảm ơn bạn đã reply.
Bài đã được tự động gộp:

Theo ví dụ kết quả
Mã:
Sub ABC()
  Dim sArr(), Res() As String, ResQt(), Dic As Object
  Dim i&, k&, iR&, sRow&, iKey$

  Set Dic = CreateObject("Scripting.Dictionary")
  With Sheets("Sheet1")
    sArr = .Range("A2", .Range("E" & Rows.Count).End(xlUp)).Value
  End With
  sRow = UBound(sArr)
  ReDim Res(1 To sRow, 1 To 4)
  ReDim ResQt(1 To sRow, 1 To 1)
  For i = 1 To sRow
    If sArr(i, 3) = 1 Then
      iKey = sArr(i, 1) & "|" & sArr(i, 4)
      If Not Dic.Exists(iKey) Then
        k = k + 1
        Dic.Add iKey, k
        Res(k, 1) = sArr(i, 4)
        Res(k, 2) = sArr(i, 5)
        Res(k, 4) = sArr(i, 1)
      End If
      iR = Dic.Item(iKey)
      ResQt(iR, 1) = ResQt(iR, 1) + 1
    End If
  Next i
  With Sheets("Sheet3")
    i = .Range("B" & Rows.Count).End(xlUp).Row
    If i > 1 Then .Range("B2:E" & i).ClearContents
    .Range("B2").Resize(k, 4) = Res
    .Range("D2").Resize(k, 1) = ResQt
    .Range("B2").Resize(k, 4).Sort .[E2], 1, .[B2], , 1
  End With
End Sub
Cảm ơn anh. Code chạy ngon lành.
 
Lần chỉnh sửa cuối:
Chào anh chị.

Em có thể xin code VBA có thể tạo báo cáo như sheet3 từ dữ liệu gốc ở sheet1. Hình thức báo cáo giống như pivot table.

Cảm ơn anh chị.
Thử bon chen với Bác @HieuCD , Bạn thử chạy 'Sub Tham_Khao_ForNext' bên dưới:

Mã:
Option Explicit

Private Function KeyExists(aExists, sKey, j, k) As Boolean
    For k = 1 To j
        If aExists(k) = sKey Then
            KeyExists = True
            Exit For
        End If
    Next k
End Function

Sub Tham_Khao_ForNext()
  
    Dim aExists, sKey As String, sArr(), Result()
    Dim r As Long, i As Long, j As Long, k As Long
    Dim shData  As Worksheet, shKQ As Worksheet
    
    Set shData = ThisWorkbook.Worksheets("Sheet1")
    Set shKQ = ThisWorkbook.Worksheets("Sheet3")
    
    r = shData.Range("A" & shData.Rows.Count).End(xlUp).Row
    If r < 2 Then Exit Sub
    
    shKQ.Range("A2").Resize(10000, 5).ClearContents
    sArr = shData.Range("A1").Resize(r, 5).Value2
    ReDim Result(1 To r, 1 To 5): ReDim aExists(1 To r)
    For i = 1 To r
        If sArr(i, 3) = 1 Then
            sKey = sArr(i, 1) & "|" & sArr(i, 4)
            If Not KeyExists(aExists, sKey, j, k) Then
                aExists(k) = sKey
                j = j + 1
                Result(j, 1) = j
                Result(j, 2) = sArr(i, 4)
                Result(j, 3) = sArr(i, 5)
                Result(j, 5) = sArr(i, 1)
            End If
            Result(k, 4) = Result(k, 4) + 1
        End If
    Next i
    
    shKQ.Range("A2").Resize(j, 5) = Result
    
End Sub
 
Chào anh chị.

Em có thể xin code VBA có thể tạo báo cáo như sheet3 từ dữ liệu gốc ở sheet1. Hình thức báo cáo giống như pivot table.

Cảm ơn anh chị.
Thêm cho bạn 1 cách dùng ADO:

Mã:
Sub GopDL()
    With CreateObject("ADODB.Recordset")
        .Open "Select [article_no],[Size],sum(Qty),[Carton] from [Sheet1$] where [Carton] is not null Group By [article_no],[Size],[Carton] order by [Carton]", "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
        Sheet2.Range("G2").CopyFromRecordset .DataSource
    End With
End Sub
 
Thêm cho bạn 1 cách dùng ADO:

Mã:
Sub GopDL()
    With CreateObject("ADODB.Recordset")
        .Open "Select [article_no],[Size],sum(Qty),[Carton] from [Sheet1$] where [Carton] is not null Group By [article_no],[Size],[Carton] order by [Carton]", "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
        Sheet2.Range("G2").CopyFromRecordset .DataSource
    End With
End Sub
Ta có thể thay thế đoạn truy vấn trên như sau:

Mã:
Select [article_no],[Size],sum(Qty),[Carton]
From [Sheet1$]
Where [Carton] is not null
Group By [Carton],[article_no],[Size]
 
Thử bon chen với Bác @HieuCD , Bạn thử chạy 'Sub Tham_Khao_ForNext' bên dưới:

Mã:
Option Explicit

Private Function KeyExists(aExists, sKey, j, k) As Boolean
    For k = 1 To j
        If aExists(k) = sKey Then
            KeyExists = True
            Exit For
        End If
    Next k
End Function

Sub Tham_Khao_ForNext()
 
    Dim aExists, sKey As String, sArr(), Result()
    Dim r As Long, i As Long, j As Long, k As Long
    Dim shData  As Worksheet, shKQ As Worksheet
   
    Set shData = ThisWorkbook.Worksheets("Sheet1")
    Set shKQ = ThisWorkbook.Worksheets("Sheet3")
   
    r = shData.Range("A" & shData.Rows.Count).End(xlUp).Row
    If r < 2 Then Exit Sub
   
    shKQ.Range("A2").Resize(10000, 5).ClearContents
    sArr = shData.Range("A1").Resize(r, 5).Value2
    ReDim Result(1 To r, 1 To 5): ReDim aExists(1 To r)
    For i = 1 To r
        If sArr(i, 3) = 1 Then
            sKey = sArr(i, 1) & "|" & sArr(i, 4)
            If Not KeyExists(aExists, sKey, j, k) Then
                aExists(k) = sKey
                j = j + 1
                Result(j, 1) = j
                Result(j, 2) = sArr(i, 4)
                Result(j, 3) = sArr(i, 5)
                Result(j, 5) = sArr(i, 1)
            End If
            Result(k, 4) = Result(k, 4) + 1
        End If
    Next i
   
    shKQ.Range("A2").Resize(j, 5) = Result
   
End Sub
Dùng Sub tốc độ nhanh hơn Function
 
Thử bon chen với Bác @HieuCD , Bạn thử chạy 'Sub Tham_Khao_ForNext' bên dưới:

Mã:
Option Explicit
Private Function KeyExists(aExists, sKey, j, k) As Boolean
    For k = 1 To j
        If aExists(k) = sKey Then
            KeyExists = True
            Exit For
        End If
    Next k
End Function
Viết ào ào thế mà có biết nguyên lý hoạt động của Function KeyExists hay không vậy nhóc? Tại sao k cứ thế mà tăng 1?
 
Viết ào ào thế mà có biết nguyên lý hoạt động của Function KeyExists hay không vậy nhóc? Tại sao k cứ thế mà tăng 1?
Chú vùi dập con cũng phải vừa phải thôi chú (@$%@
Không hiểu mà ra kết quả được, con làm gì mà may thế, k +1 là theo j+1 phải không chú Mỹ (hehe con cũng không chắc)
 
Web KT
Back
Top Bottom