Tạo báo cáo giống như Pivot Table. (2 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

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

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

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

Back
Top Bottom