Nhờ viết code tổng hợp dữ liệu

Liên hệ QC

Erebus

Thành viên mới
Tham gia
30/10/16
Bài viết
41
Được thích
6
Em chào các bác ạ !
Em đang có một bài toán khó như sau, em có các sheet dữ liệu sheet1,sheet2,sheet3 và cần tổng hợp lại thành một báo cáo như tệp đính kèm.
Vì dữ liệu rất lớn lên đến mấy trăm nghìn dòng nên dùng sumifs cần chạy rất lâu
Nhờ các bác viết giúp em code tự động tổng hợp dữ liệu từ các sheet vào với ạ
 

File đính kèm

  • Example 1.xlsx
    14.6 KB · Đọc: 28
Em chào các bác ạ !
Em đang có một bài toán khó như sau, em có các sheet dữ liệu sheet1,sheet2,sheet3 và cần tổng hợp lại thành một báo cáo như tệp đính kèm.
Vì dữ liệu rất lớn lên đến mấy trăm nghìn dòng nên dùng sumifs cần chạy rất lâu
Nhờ các bác viết giúp em code tự động tổng hợp dữ liệu từ các sheet vào với ạ
Lớn vậy không nên dùng code có công cụ mới của excel mà anh @VetMini hay giới thiệu ấy nhỉ.
 
Upvote 0
Đúng như anh dự đoán, nhất nhất là phải "BMP" (bấm một phát).
Thêm một cách lấy cớ mới (ngoài cách thông dụng nhất: dữ kiệu vài trăm nghìn dòng)
<< máy công ty nên hạn chế nhiều thứ >>
Công ty này không biết tự trọng. Hạn chế công cụ để mặc nhân viên đi nhờ người ta làm giùm.

Tôi làm việc với nhiều công ty có luật "không nhận hàng giúp đỡ (we dont take charity)". Nếu công ty thấy phần mềm nào cần cho công việc thì họ mua, không cho phép đi xin.
 
Upvote 0
Thêm một cách lấy cớ mới (ngoài cách thông dụng nhất: dữ kiệu vài trăm nghìn dòng)
<< máy công ty nên hạn chế nhiều thứ >>
Công ty này không biết tự trọng. Hạn chế công cụ để mặc nhân viên đi nhờ người ta làm giùm.
Tôi làm việc với nhiều công ty có luật "không nhận hàng giúp đỡ (we dont take charity)". Nếu công ty thấy phần mềm nào cần cho công việc thì họ mua, không cho phép đi xin.
Em thấy chủ bài cũng đâu có hỏi "công cụ mới" là công cụ gì đâu, chỉ nói là máy công ty nên hạn chế, cũng không biết là hạn chế cái gì. Nếu chịu khó hỏi thì có khi trong máy cũng đã có sẵn rồi cũng nên.
 
Upvote 0
Em thấy chủ bài cũng đâu có hỏi "công cụ mới" là công cụ gì đâu, chỉ nói là máy công ty nên hạn chế, cũng không biết là hạn chế cái gì. Nếu chịu khó hỏi thì có khi trong máy cũng đã có sẵn rồi cũng nên.
43 phút trước
Thớt có hàm SumIfs nên có lẽ lẽ đời 2010 trở lên. Mà phiên bản này thì có Data Model rồi. Tuy nhiên, muốn Power Query cho êm thì phải 2013 trở lên.
Việc hạn chế có thể là công ty hạn chế tư duy phát triển của nhân viên. Vì phát triển hạn chế cho nên tin rằng Excel chỉ có hàm. Tháy GPE nhiều người sẵn sàng làm giùm cho nên lên đây vòi VBA. Phát triển thêm nữa chi cho mệt.
 
Upvote 0
Em chào các bác ạ !
Em đang có một bài toán khó như sau, em có các sheet dữ liệu sheet1,sheet2,sheet3 và cần tổng hợp lại thành một báo cáo như tệp đính kèm.
Vì dữ liệu rất lớn lên đến mấy trăm nghìn dòng nên dùng sumifs cần chạy rất lâu
Nhờ các bác viết giúp em code tự động tổng hợp dữ liệu từ các sheet vào với ạ
Bạn xem bài này của thầy Mỹ, dùng power query tổng hợp tất cả các sheet lại thành 1 file data tổng, sau đó pivot là có kết quả mong muốn. Còn nếu có mấy sheet thôi thì cứ copy paste bằng tay cho khỏe. Chúc bạn thành công.

 
Upvote 0
Viết theo iêu cầu của chủ bài đăng:
PHP:
Dim Sh As Worksheet
Sub TongHop()
 Dim aIT(), Arr()
 Dim Rws As Long, J As Long, W As Integer, Z As Long, Col As Integer, Tmr As Double
 Dim iTm As String, Typ As String
 
XoaDLTrung:                                 Tmr = Timer()
 Rws = [U2].CurrentRegion.Rows.Count
 aIT() = [U2].Resize(Rws).Value
 ReDim aKQ(1 To Rws, 1 To 1 + [s2].CurrentRegion.Rows.Count)
 For J = 2 To [U2].End(xlDown).Row
    W = W + 1:                              iTm = Cells(J, "U").Value
    aKQ(W, 1) = iTm
    For Each Sh In ThisWorkbook.Worksheets
        If Sh.Name <> "Report" Then
            Rws = Sh.[B3].CurrentRegion.Rows.Count
            Arr() = Sh.[B3].Resize(Rws, 3).Value
            For Z = 1 To UBound(Arr())
                If Arr(Z, 1) = iTm Then
                    Typ = Arr(Z, 3)
                    Col = Switch(Typ = "IOT-D", 2, Typ = "ISD", 3, Typ = "IAI", _
                        4, Typ = "IAR", 5, Typ = "ITN", 6, Typ = "GPE.COM", 9)
                    aKQ(W, Col) = Arr(Z, 2)
                End If
            Next Z
        End If
    Next Sh
 Next J
 [W3].Resize(41, 6).Value = aKQ():              MsgBox Timer() - Tmr
End Sub
Mã:
Sub XoaDLTrung()
 Dim Rng As Range
 Dim Rws As Long
 
 Sheets("Report").Select
 Union([S1].Resize(99999), [U1].Resize(99999)).Value = ""
 For Each Sh In ThisWorkbook.Worksheets
    If Sh.Name <> "Report" Then
        Rws = Sh.[A3].CurrentRegion.Rows.Count
        Sh.[B3].Resize(Rws).Copy Destination:=[U99999].End(xlUp).Offset(1)
        Sh.[D3].Resize(Rws).Copy Destination:=[S99999].End(xlUp).Offset(1)
    End If
 Next Sh
 Set Rng = [s2].CurrentRegion:      LapDSDN Rng
 Set Rng = [U2].CurrentRegion:      LapDSDN Rng
End Sub
PHP:
Sub LapDSDN(Rng As Range)
    Rng.RemoveDuplicates Columns:=1, Header:=xlNo
End Sub
 
Upvote 0
Em chào các bác ạ !
Em đang có một bài toán khó như sau, em có các sheet dữ liệu sheet1,sheet2,sheet3 và cần tổng hợp lại thành một báo cáo như tệp đính kèm.
Vì dữ liệu rất lớn lên đến mấy trăm nghìn dòng nên dùng sumifs cần chạy rất lâu
Nhờ các bác viết giúp em code tự động tổng hợp dữ liệu từ các sheet vào với ạ
Code theo kiểu 1+1=2
Bạn xem thử dùng được không
PHP:
Option Explicit
Sub GPE()
    Dim Ws As Worksheet, Lr As Long, i As Long, k As Long, Lr1 As Long
    Dim Arr(), Res(1 To 100000, 1 To 100), j As Long, Res0(1 To 100000, 1 To 3)
    Dim l As Long, m As Long, ii As Long, jj As Long
    Dim Rng1 As Range, Rng2 As Range, Rng3 As Range, Lr2 As Long, Arr1(), Lc As Long
    Application.ScreenUpdating = False
    On Error Resume Next
    Sheets("Report").Columns("J:AA").Delete shift:=xlToLeft
    For Each Ws In Worksheets
        If Ws.Name <> "Report" Then
            Lr = Ws.Range("B" & Rows.Count).End(xlUp).Row
            Arr = Ws.Range("B3:D" & Lr).Value
            For i = 1 To UBound(Arr)
                If Arr(i, 1) <> "" Then
                    m = m + 1
                    For j = 1 To 3
                        Res0(m, j) = Arr(i, j)
                    Next j
                End If
            Next i
        End If
    Next Ws
    With Sheets("Report")
        .Range("J3").Resize(m, 3) = Res0
        .Range("J3").CurrentRegion.Copy .Range("R3")
        Lr2 = .Range("R" & Rows.Count).End(xlUp).Row
        Lc = .Cells(2, Columns.Count).End(xlToLeft).Column
        Set Rng1 = .Range("R3:R" & Lr2)
        Set Rng2 = .Range("S3:S" & Lr2)
        Set Rng3 = .Range("T3:T" & Lr2)
        .Range("J3:J" & Lr2).RemoveDuplicates Columns:=1, Header:=xlNo
        .Range("L3:L" & Lr2).RemoveDuplicates Columns:=1, Header:=xlNo
        Lr1 = .Range("J" & Rows.Count).End(xlUp).Row
        .Range("L3").Select
        .Range(Selection, Selection.End(xlDown)).Copy
        .Range("K2").PasteSpecial Transpose:=True
        .Range("K3:L10000").ClearContents
        Arr1 = .Range("J2").CurrentRegion.Value
        For ii = 2 To UBound(Arr1, 1)
            For jj = 2 To UBound(Arr1, 2)
                Res(ii - 1, jj - 1) = Application.SumIfs(Rng2, Rng1, Arr1(ii, 1), Rng3, Arr1(1, jj))
            Next jj
        Next ii
        .Range("K3").Resize(ii, jj).Value = Res
        .Range("K3").CurrentRegion.Borders.LineStyle = 1
        .Range("J2") = "ITEM"
        .Columns("J:AA").AutoFit
        .Range("R3").CurrentRegion.Delete
        End With
    Application.ScreenUpdating = True
    MsgBox "Xong"
End Sub
 

File đính kèm

  • Example 1.xlsb
    27.8 KB · Đọc: 13
Upvote 0
1666502365080.png

Trong quản trị, như bạn nói 1 + 1 = ý của sếp (bao nhiêu thì bao, miễn sếp gật đầu.)

Đó là quản trị loại đã trên "trình độ vỡ lòng [sic]"

Đây là cách của dân quản lý không có trình độ:
Người kế toán bình thường phải đối diện với hai mặt:
- Đối nội: sếp biết kế toán của mình cho nên không cần phải gật hay lắc đầu. Lính của kế toán biết GPE nên chỉ cần lên hỏi cách "phân bổ ngẫu nhiên" một con số ra nhiều nơi.
- Đối ngoại: với kiểm toán, kế toán biết phải tránh các con số 1. (kiểm toán thấy nhiều số 1's là chúng nghi ngờ)
.
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn xem bài này của thầy Mỹ, dùng power query tổng hợp tất cả các sheet lại thành 1 file data tổng, sau đó pivot là có kết quả mong muốn. Còn nếu có mấy sheet thôi thì cứ copy paste bằng tay cho khỏe. Chúc bạn thành công.

Cảm ơn bác, em sẽ nghiên cứu xem sao
Bài đã được tự động gộp:

Viết theo iêu cầu của chủ bài đăng:
PHP:
Dim Sh As Worksheet
Sub TongHop()
 Dim aIT(), Arr()
 Dim Rws As Long, J As Long, W As Integer, Z As Long, Col As Integer, Tmr As Double
 Dim iTm As String, Typ As String
 
XoaDLTrung:                                 Tmr = Timer()
 Rws = [U2].CurrentRegion.Rows.Count
 aIT() = [U2].Resize(Rws).Value
 ReDim aKQ(1 To Rws, 1 To 1 + [s2].CurrentRegion.Rows.Count)
 For J = 2 To [U2].End(xlDown).Row
    W = W + 1:                              iTm = Cells(J, "U").Value
    aKQ(W, 1) = iTm
    For Each Sh In ThisWorkbook.Worksheets
        If Sh.Name <> "Report" Then
            Rws = Sh.[B3].CurrentRegion.Rows.Count
            Arr() = Sh.[B3].Resize(Rws, 3).Value
            For Z = 1 To UBound(Arr())
                If Arr(Z, 1) = iTm Then
                    Typ = Arr(Z, 3)
                    Col = Switch(Typ = "IOT-D", 2, Typ = "ISD", 3, Typ = "IAI", _
                        4, Typ = "IAR", 5, Typ = "ITN", 6, Typ = "GPE.COM", 9)
                    aKQ(W, Col) = Arr(Z, 2)
                End If
            Next Z
        End If
    Next Sh
 Next J
 [W3].Resize(41, 6).Value = aKQ():              MsgBox Timer() - Tmr
End Sub
Mã:
Sub XoaDLTrung()
 Dim Rng As Range
 Dim Rws As Long
 
 Sheets("Report").Select
 Union([S1].Resize(99999), [U1].Resize(99999)).Value = ""
 For Each Sh In ThisWorkbook.Worksheets
    If Sh.Name <> "Report" Then
        Rws = Sh.[A3].CurrentRegion.Rows.Count
        Sh.[B3].Resize(Rws).Copy Destination:=[U99999].End(xlUp).Offset(1)
        Sh.[D3].Resize(Rws).Copy Destination:=[S99999].End(xlUp).Offset(1)
    End If
 Next Sh
 Set Rng = [s2].CurrentRegion:      LapDSDN Rng
 Set Rng = [U2].CurrentRegion:      LapDSDN Rng
End Sub
PHP:
Sub LapDSDN(Rng As Range)
    Rng.RemoveDuplicates Columns:=1, Header:=xlNo
End Sub
Em cảm ơn bác rất nhiều ạ
Bài đã được tự động gộp:

Code theo kiểu 1+1=2
Bạn xem thử dùng được không
PHP:
Option Explicit
Sub GPE()
    Dim Ws As Worksheet, Lr As Long, i As Long, k As Long, Lr1 As Long
    Dim Arr(), Res(1 To 100000, 1 To 100), j As Long, Res0(1 To 100000, 1 To 3)
    Dim l As Long, m As Long, ii As Long, jj As Long
    Dim Rng1 As Range, Rng2 As Range, Rng3 As Range, Lr2 As Long, Arr1(), Lc As Long
    Application.ScreenUpdating = False
    On Error Resume Next
    Sheets("Report").Columns("J:AA").Delete shift:=xlToLeft
    For Each Ws In Worksheets
        If Ws.Name <> "Report" Then
            Lr = Ws.Range("B" & Rows.Count).End(xlUp).Row
            Arr = Ws.Range("B3:D" & Lr).Value
            For i = 1 To UBound(Arr)
                If Arr(i, 1) <> "" Then
                    m = m + 1
                    For j = 1 To 3
                        Res0(m, j) = Arr(i, j)
                    Next j
                End If
            Next i
        End If
    Next Ws
    With Sheets("Report")
        .Range("J3").Resize(m, 3) = Res0
        .Range("J3").CurrentRegion.Copy .Range("R3")
        Lr2 = .Range("R" & Rows.Count).End(xlUp).Row
        Lc = .Cells(2, Columns.Count).End(xlToLeft).Column
        Set Rng1 = .Range("R3:R" & Lr2)
        Set Rng2 = .Range("S3:S" & Lr2)
        Set Rng3 = .Range("T3:T" & Lr2)
        .Range("J3:J" & Lr2).RemoveDuplicates Columns:=1, Header:=xlNo
        .Range("L3:L" & Lr2).RemoveDuplicates Columns:=1, Header:=xlNo
        Lr1 = .Range("J" & Rows.Count).End(xlUp).Row
        .Range("L3").Select
        .Range(Selection, Selection.End(xlDown)).Copy
        .Range("K2").PasteSpecial Transpose:=True
        .Range("K3:L10000").ClearContents
        Arr1 = .Range("J2").CurrentRegion.Value
        For ii = 2 To UBound(Arr1, 1)
            For jj = 2 To UBound(Arr1, 2)
                Res(ii - 1, jj - 1) = Application.SumIfs(Rng2, Rng1, Arr1(ii, 1), Rng3, Arr1(1, jj))
            Next jj
        Next ii
        .Range("K3").Resize(ii, jj).Value = Res
        .Range("K3").CurrentRegion.Borders.LineStyle = 1
        .Range("J2") = "ITEM"
        .Columns("J:AA").AutoFit
        .Range("R3").CurrentRegion.Delete
        End With
    Application.ScreenUpdating = True
    MsgBox "Xong"
End Sub
Em cảm ơn bác rất nhiều ạ
 
Upvote 0
Em chào các bác ạ !
Em đang có một bài toán khó như sau, em có các sheet dữ liệu sheet1,sheet2,sheet3 và cần tổng hợp lại thành một báo cáo như tệp đính kèm.
Vì dữ liệu rất lớn lên đến mấy trăm nghìn dòng nên dùng sumifs cần chạy rất lâu
Nhờ các bác viết giúp em code tự động tổng hợp dữ liệu từ các sheet vào với ạ
Bạn thử code sau:

Mã:
Sub TrichLoc_HLMT()
    Dim cn As String, strSQL As String, i As Integer
    strSQL = "Select [DATE],[ITEM],[Qty],[Type] From [Jan$] Where [Qty] is not null"
    strSQL = strSQL & " Union All Select [DATE],[ITEM],[Qty],[Type] From [Mar$] Where [Qty] is not null"
    strSQL = strSQL & " Union All Select [DATE],[ITEM],[Qty],[Type] From [May$] Where [Qty] is not null"
    cn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0 Xml;"
    With CreateObject("ADODB.Recordset")
        .Open ("TRANSFORM SUM([Qty]) Select [ITEM], Sum(Qty) As Total From (" & strSQL & ") GROUP BY  [ITEM] PIVOT [Type]"), cn
        For i = 0 To .Fields.Count - 1
            Sheet4.Cells(2, i + 12) = .Fields(i).Name
        Next
        Sheet4.Range("L3").CopyFromRecordset .DataSource
    End With
End Sub

Cột 'Total' của bạn phải bằng các cột cộng lại chứ bạn?
 
Upvote 0
Code theo kiểu 1+1=2
Bạn xem thử dùng được không
PHP:
Option Explicit
Sub GPE()
    Dim Ws As Worksheet, Lr As Long, i As Long, k As Long, Lr1 As Long
    Dim Arr(), Res(1 To 100000, 1 To 100), j As Long, Res0(1 To 100000, 1 To 3)
    Dim l As Long, m As Long, ii As Long, jj As Long
    Dim Rng1 As Range, Rng2 As Range, Rng3 As Range, Lr2 As Long, Arr1(), Lc As Long
    Application.ScreenUpdating = False
    On Error Resume Next
    Sheets("Report").Columns("J:AA").Delete shift:=xlToLeft
    For Each Ws In Worksheets
        If Ws.Name <> "Report" Then
            Lr = Ws.Range("B" & Rows.Count).End(xlUp).Row
            Arr = Ws.Range("B3:D" & Lr).Value
            For i = 1 To UBound(Arr)
                If Arr(i, 1) <> "" Then
                    m = m + 1
                    For j = 1 To 3
                        Res0(m, j) = Arr(i, j)
                    Next j
                End If
            Next i
        End If
    Next Ws
    With Sheets("Report")
        .Range("J3").Resize(m, 3) = Res0
        .Range("J3").CurrentRegion.Copy .Range("R3")
        Lr2 = .Range("R" & Rows.Count).End(xlUp).Row
        Lc = .Cells(2, Columns.Count).End(xlToLeft).Column
        Set Rng1 = .Range("R3:R" & Lr2)
        Set Rng2 = .Range("S3:S" & Lr2)
        Set Rng3 = .Range("T3:T" & Lr2)
        .Range("J3:J" & Lr2).RemoveDuplicates Columns:=1, Header:=xlNo
        .Range("L3:L" & Lr2).RemoveDuplicates Columns:=1, Header:=xlNo
        Lr1 = .Range("J" & Rows.Count).End(xlUp).Row
        .Range("L3").Select
        .Range(Selection, Selection.End(xlDown)).Copy
        .Range("K2").PasteSpecial Transpose:=True
        .Range("K3:L10000").ClearContents
        Arr1 = .Range("J2").CurrentRegion.Value
        For ii = 2 To UBound(Arr1, 1)
            For jj = 2 To UBound(Arr1, 2)
                Res(ii - 1, jj - 1) = Application.SumIfs(Rng2, Rng1, Arr1(ii, 1), Rng3, Arr1(1, jj))
            Next jj
        Next ii
        .Range("K3").Resize(ii, jj).Value = Res
        .Range("K3").CurrentRegion.Borders.LineStyle = 1
        .Range("J2") = "ITEM"
        .Columns("J:AA").AutoFit
        .Range("R3").CurrentRegion.Delete
        End With
    Application.ScreenUpdating = True
    MsgBox "Xong"
End Sub
Em chào bác, bác ơi em có thể xin liên hệ bác được không ah, em có chút việc nhờ bác xem qua ạ
 
Upvote 0
Em chào bác, bác ơi em có thể xin liên hệ bác được không ah, em có chút việc nhờ bác xem qua ạ
Bạn có thắc mắc gì cứ hỏi tại đây cũng được nhé. Vì nếu hỏi riêng tôi nhiều cái tôi không biết thì không còn có nhiều người trả lời giúp nhé.
 
Upvote 0
Web KT

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

Back
Top Bottom