Tổng hợp số lượng theo từng ký hiệu mã sản phẩm..!

shnhatha

Yêu THVBA
Nhờ anh chi em diễn đàn trợ giúp..!Mình có file dữ liệu
- Tại sheet (DL_N) có 9 cột mã, mỗi cột có nhiều mã sản phẩm khác nhau bao gồm số lượng theo từng tháng.Mình đã lọc riêng từng mã sản phẩm sang sheet(T_H) muốn nhờ anh chị em giúp code tổng hợp số lượng theo từng mã sản phẩm đó điền vào cột tháng tại sheet (T_H)...Rất mong được sự quan tâm giúp đỡ anh chị em diễn đàn..!
 

CRV

SMod
Thành viên BQT
Bạn tham khảo, nếu bạn cảm thấy hứng thú với đoạn code này rất mong bạn ủng hộ diễn đàn:
Mã:
Option Explicit
Public Sub THVBA_CRV___()
    '//Khai bao tham so
    Dim dic As Object, sheet As Worksheet, cell As Range
    Dim data As Variant, result As Variant, key As Variant
    Dim i As Long, j As Long, k As Long, r As Long
    Dim c As Integer
    '// Tang toc code
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    '// Xac dinh mang du lieu dau vao & kich thuoc mang ket qua dau ra
    Set sheet = ThisWorkbook.Worksheets("DL_N")
    data = sheet.Range("C3").CurrentRegion.Value
    r = UBound(data, 1) * 9:    c = 2:  k = 1
    ReDim result(1 To r, 1 To c)
    result(1, 1) = "Ma":    result(1, 2) = "Phan Loai"
    '// Khoi tao Dictionary
    Set dic = CreateObject("Scripting.Dictionary")
    dic.CompareMode = vbTextCompare
    '// Lay ten tieu de cot la thang roi gan vao Dic
    For j = 10 To UBound(data, 2)
        key = "Month|" & data(1, j)
        If Not dic.Exists(key) Then
            c = c + 1:  dic.Add key, c
            ReDim Preserve result(1 To r, 1 To c + 2)
            result(1, c + 0) = data(1, j)
            result(1, c + 1) = "Tong_SN"
            result(1, c + 2) = "T_B"
            c = c + 2
        End If
    Next j
    '// Xu ly du lieu
    For i = 2 To UBound(data, 1)
        For j = 1 To 9
            key = data(1, j) & "|" & data(i, j)
            If Not dic.Exists(key) Then
                k = k + 1:          dic.Add key, k
                result(k, 1) = data(1, j)
                result(k, 2) = data(i, j)
                If Not IsEmpty(data(i, j)) Then
                    For c = 10 To UBound(data, 2)
                        key = "Month|" & data(1, c)
                        result(k, dic.Item(key)) = result(k, dic.Item(key)) + data(i, c)
                    Next c
                End If
            Else
                r = dic.Item(key)
                If Not IsEmpty(data(i, j)) Then
                    For c = 10 To UBound(data, 2)
                        key = "Month|" & data(1, c)
                        result(r, dic.Item(key)) = result(r, dic.Item(key)) + data(i, c)
                    Next c
                End If
            End If
        Next j
    Next i
    '// Tao sheet moi
    c = ThisWorkbook.Sheets.Count: r = UBound(result, 2)
    Set sheet = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(c))
    '/// Gan ket qua vao sheet moi & ke khung
    With sheet
        .Name = "T_H_" & c + 1
        Set cell = .Cells(3, 1)
        cell.Resize(k, r).Value = result
        cell.Resize(k, 2).Font.Bold = True
        cell.Resize(k, 2).Font.Color = RGB(100, 0, 200)
        cell.Resize(k, 2).Interior.Color = RGB(204, 255, 255)
        cell.Resize(k, 2).Font.Size = 10
        cell.Resize(k, 2).Borders(xlEdgeRight).LineStyle = 1
        With cell.CurrentRegion
            .Cells.Sort Key1:=cell, Order1:=xlAscending, _
                        Key2:=cell.Offset(, 1), Order2:=xlAscending, _
                        Orientation:=xlTopToBottom, Header:=xlYes
        End With
        With .Cells.Font
            .Name = "Times New Roman": .Size = 11
        End With
        cell.Resize(, r).Font.Bold = True
        .Cells.EntireColumn.AutoFit
        .Tab.Color = 255
        j = cell.Column
        i = cell.Row + 1
        k = k + i
        Do While i <= k
            If .Cells(i, j).Value <> key Then
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).LineStyle = xlContinuous
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).Weight = xlThick
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).Color = RGB(121, 121, 121)
                key = .Cells(i, j).Value:   i = i + 1
            Else
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).LineStyle = xlDot
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).Weight = xlThin
                .Cells(i, j).Value = Empty: i = i + 1
            End If
        Loop
    End With
    '//Tra lai trang thai ban dau - ket thuc tang toc
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    '//Thong bao ket thuc
    MsgBox "Done and success !", vbInformation + vbOKOnly, "https://tuhocvba.net/"
End Sub
 

Đính kèm

shnhatha

Yêu THVBA
Bạn tham khảo, nếu bạn cảm thấy hứng thú với đoạn code này rất mong bạn ủng hộ diễn đàn:
Mã:
Option Explicit
Public Sub THVBA_CRV___()
    '//Khai bao tham so
    Dim dic As Object, sheet As Worksheet, cell As Range
    Dim data As Variant, result As Variant, key As Variant
    Dim i As Long, j As Long, k As Long, r As Long
    Dim c As Integer
    '// Tang toc code
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    '// Xac dinh mang du lieu dau vao & kich thuoc mang ket qua dau ra
    Set sheet = ThisWorkbook.Worksheets("DL_N")
    data = sheet.Range("C3").CurrentRegion.Value
    r = UBound(data, 1) * 9:    c = 2:  k = 1
    ReDim result(1 To r, 1 To c)
    result(1, 1) = "Ma":    result(1, 2) = "Phan Loai"
    '// Khoi tao Dictionary
    Set dic = CreateObject("Scripting.Dictionary")
    dic.CompareMode = vbTextCompare
    '// Lay ten tieu de cot la thang roi gan vao Dic
    For j = 10 To UBound(data, 2)
        key = "Month|" & data(1, j)
        If Not dic.Exists(key) Then
            c = c + 1:  dic.Add key, c
            ReDim Preserve result(1 To r, 1 To c + 2)
            result(1, c + 0) = data(1, j)
            result(1, c + 1) = "Tong_SN"
            result(1, c + 2) = "T_B"
            c = c + 2
        End If
    Next j
    '// Xu ly du lieu
    For i = 2 To UBound(data, 1)
        For j = 1 To 9
            key = data(1, j) & "|" & data(i, j)
            If Not dic.Exists(key) Then
                k = k + 1:          dic.Add key, k
                result(k, 1) = data(1, j)
                result(k, 2) = data(i, j)
                If Not IsEmpty(data(i, j)) Then
                    For c = 10 To UBound(data, 2)
                        key = "Month|" & data(1, c)
                        result(k, dic.Item(key)) = result(k, dic.Item(key)) + data(i, c)
                    Next c
                End If
            Else
                r = dic.Item(key)
                If Not IsEmpty(data(i, j)) Then
                    For c = 10 To UBound(data, 2)
                        key = "Month|" & data(1, c)
                        result(r, dic.Item(key)) = result(r, dic.Item(key)) + data(i, c)
                    Next c
                End If
            End If
        Next j
    Next i
    '// Tao sheet moi
    c = ThisWorkbook.Sheets.Count: r = UBound(result, 2)
    Set sheet = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(c))
    '/// Gan ket qua vao sheet moi & ke khung
    With sheet
        .Name = "T_H_" & c + 1
        Set cell = .Cells(3, 1)
        cell.Resize(k, r).Value = result
        cell.Resize(k, 2).Font.Bold = True
        cell.Resize(k, 2).Font.Color = RGB(100, 0, 200)
        cell.Resize(k, 2).Interior.Color = RGB(204, 255, 255)
        cell.Resize(k, 2).Font.Size = 10
        cell.Resize(k, 2).Borders(xlEdgeRight).LineStyle = 1
        With cell.CurrentRegion
            .Cells.Sort Key1:=cell, Order1:=xlAscending, _
                        Key2:=cell.Offset(, 1), Order2:=xlAscending, _
                        Orientation:=xlTopToBottom, Header:=xlYes
        End With
        With .Cells.Font
            .Name = "Times New Roman": .Size = 11
        End With
        cell.Resize(, r).Font.Bold = True
        .Cells.EntireColumn.AutoFit
        .Tab.Color = 255
        j = cell.Column
        i = cell.Row + 1
        k = k + i
        Do While i <= k
            If .Cells(i, j).Value <> key Then
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).LineStyle = xlContinuous
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).Weight = xlThick
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).Color = RGB(121, 121, 121)
                key = .Cells(i, j).Value:   i = i + 1
            Else
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).LineStyle = xlDot
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).Weight = xlThin
                .Cells(i, j).Value = Empty: i = i + 1
            End If
        Loop
    End With
    '//Tra lai trang thai ban dau - ket thuc tang toc
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    '//Thong bao ket thuc
    MsgBox "Done and success !", vbInformation + vbOKOnly, "https://tuhocvba.net/"
End Sub
Đầu tiên mình xin cảm ơn bạn bạn đã rất tận tình giúp đỡ mình giải đáp thắc mắc trong nhiều bài viết..
Sau đó mình cũng rất vui với ý kiến đóng góp một phần nhỏ cho diễn đàn vì cộng đồng mang lại kiến thức hiểu biết chung.
Mong được anh chi em bạn bè chỉ bảo giúp đỡ...!
 
  • Love
Reactions: CRV

CRV

SMod
Thành viên BQT
Vậy code trên chạy đúng ý bạn chưa?
Bạn còn thắc mắc điều gì nữa không vậy?
 

shnhatha

Yêu THVBA
Bạn tham khảo, nếu bạn cảm thấy hứng thú với đoạn code này rất mong bạn ủng hộ diễn đàn:
Mã:
Option Explicit
Public Sub THVBA_CRV___()
    '//Khai bao tham so
    Dim dic As Object, sheet As Worksheet, cell As Range
    Dim data As Variant, result As Variant, key As Variant
    Dim i As Long, j As Long, k As Long, r As Long
    Dim c As Integer
    '// Tang toc code
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    '// Xac dinh mang du lieu dau vao & kich thuoc mang ket qua dau ra
    Set sheet = ThisWorkbook.Worksheets("DL_N")
    data = sheet.Range("C3").CurrentRegion.Value
    r = UBound(data, 1) * 9:    c = 2:  k = 1
    ReDim result(1 To r, 1 To c)
    result(1, 1) = "Ma":    result(1, 2) = "Phan Loai"
    '// Khoi tao Dictionary
    Set dic = CreateObject("Scripting.Dictionary")
    dic.CompareMode = vbTextCompare
    '// Lay ten tieu de cot la thang roi gan vao Dic
    For j = 10 To UBound(data, 2)
        key = "Month|" & data(1, j)
        If Not dic.Exists(key) Then
            c = c + 1:  dic.Add key, c
            ReDim Preserve result(1 To r, 1 To c + 2)
            result(1, c + 0) = data(1, j)
            result(1, c + 1) = "Tong_SN"
            result(1, c + 2) = "T_B"
            c = c + 2
        End If
    Next j
    '// Xu ly du lieu
    For i = 2 To UBound(data, 1)
        For j = 1 To 9
            key = data(1, j) & "|" & data(i, j)
            If Not dic.Exists(key) Then
                k = k + 1:          dic.Add key, k
                result(k, 1) = data(1, j)
                result(k, 2) = data(i, j)
                If Not IsEmpty(data(i, j)) Then
                    For c = 10 To UBound(data, 2)
                        key = "Month|" & data(1, c)
                        result(k, dic.Item(key)) = result(k, dic.Item(key)) + data(i, c)
                    Next c
                End If
            Else
                r = dic.Item(key)
                If Not IsEmpty(data(i, j)) Then
                    For c = 10 To UBound(data, 2)
                        key = "Month|" & data(1, c)
                        result(r, dic.Item(key)) = result(r, dic.Item(key)) + data(i, c)
                    Next c
                End If
            End If
        Next j
    Next i
    '// Tao sheet moi
    c = ThisWorkbook.Sheets.Count: r = UBound(result, 2)
    Set sheet = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(c))
    '/// Gan ket qua vao sheet moi & ke khung
    With sheet
        .Name = "T_H_" & c + 1
        Set cell = .Cells(3, 1)
        cell.Resize(k, r).Value = result
        cell.Resize(k, 2).Font.Bold = True
        cell.Resize(k, 2).Font.Color = RGB(100, 0, 200)
        cell.Resize(k, 2).Interior.Color = RGB(204, 255, 255)
        cell.Resize(k, 2).Font.Size = 10
        cell.Resize(k, 2).Borders(xlEdgeRight).LineStyle = 1
        With cell.CurrentRegion
            .Cells.Sort Key1:=cell, Order1:=xlAscending, _
                        Key2:=cell.Offset(, 1), Order2:=xlAscending, _
                        Orientation:=xlTopToBottom, Header:=xlYes
        End With
        With .Cells.Font
            .Name = "Times New Roman": .Size = 11
        End With
        cell.Resize(, r).Font.Bold = True
        .Cells.EntireColumn.AutoFit
        .Tab.Color = 255
        j = cell.Column
        i = cell.Row + 1
        k = k + i
        Do While i <= k
            If .Cells(i, j).Value <> key Then
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).LineStyle = xlContinuous
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).Weight = xlThick
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).Color = RGB(121, 121, 121)
                key = .Cells(i, j).Value:   i = i + 1
            Else
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).LineStyle = xlDot
                .Cells(i, j).Resize(, r).Borders(xlEdgeTop).Weight = xlThin
                .Cells(i, j).Value = Empty: i = i + 1
            End If
        Loop
    End With
    '//Tra lai trang thai ban dau - ket thuc tang toc
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    '//Thong bao ket thuc
    MsgBox "Done and success !", vbInformation + vbOKOnly, "https://tuhocvba.net/"
End Sub
Về nội dung đoạn code..bạn giúp mình chỉnh sửa Tổng hợp trực tiếp số lượng sang sheet (T_H) mình đã xắp xếp...!Trong trường hợp mình muốn Insert thêm cột vào giữa các tháng thì số lượng tại côt tháng cũng thay đổi.Coi các tháng (từ T9-....đến T8) là một điều kiện..
Xin cảm ơn bạn
 

shnhatha

Yêu THVBA
Vậy code trên chạy đúng ý bạn chưa?
Bạn còn thắc mắc điều gì nữa không vậy?
Cảm ơn bạn ..!mục đích 2 dòng trống để lập dữ liệu tính toán phụ dựa vào số lượng tổng hợp.Trong trường hợp phải bổ xung thêm cột tính toán vào các tháng..Nhờ bạn chỉnh sửa code theo nội dung diễn giải trên giúp mình..!
 
  • Like
Reactions: CRV

CRV

SMod
Thành viên BQT
Mình đã sửa code đưa kết quả theo dữ liệu sheet "T_H", bạn kiểm tra lại xem đúng chưa?
Mã:
Option Explicit
Const CRV__ As String = "https://tuhocvba.net/"

Public Sub THVBA_CRV___2()

    '//Khai bao tham so
    Dim dic As Object, sheet As Worksheet, cell As Range
    Dim data As Variant, result As Variant, ma As Variant, key As Variant
    Dim i As Long, j As Long, k As Long, n As Long, r As Long
    Dim c As Integer, colMa As Integer, Tmr As Double
    Tmr = Timer()

    '// Xac dinh mang du lieu dau vao & kich thuoc mang ket qua dau ra
    Set sheet = ThisWorkbook.Worksheets("DL_N")
    If sheet.AutoFilterMode Then sheet.AutoFilterMode = False
    data = sheet.Range("C3").CurrentRegion.Value
    
    Set sheet = ThisWorkbook.Worksheets("T_H")
    If sheet.AutoFilterMode Then sheet.AutoFilterMode = False
    r = sheet.Cells(sheet.Rows.Count, 2).End(xlUp).Row
    c = sheet.Cells(3, sheet.Columns.Count).End(xlToLeft).Column
    If (r < 4) Or (c < 3) Then Exit Sub
    sheet.Range("C4").Resize(10000, 100).ClearContents
    '// Khoi tao Dictionary
    Set dic = CreateObject("Scripting.Dictionary")
    dic.CompareMode = vbTextCompare
    result = sheet.Range("A3:A" & r).Resize(, c).Value
    For j = 3 To c Step 3
        key = CRV__ & result(1, j)
        If Not dic.Exists(key) Then dic.Add key, j
    Next j
    For i = 2 To UBound(result, 1)
        If Len(result(i, 1)) > 0 Then ma = result(i, 1)
        key = ma & CRV__ & result(i, 2)
        If Not dic.Exists(key) Then dic.Add key, i
    Next i
    
    n = UBound(data, 2): colMa = 9
    '// Xu ly tong hop du lieu theo ma & phan loai ma
    For i = 2 To UBound(data, 1)
        For j = 1 To colMa
            key = data(1, j) & CRV__ & data(i, j)
            If dic.Exists(key) Then
                r = dic.Item(key)
                For c = colMa + 1 To n
                    key = CRV__ & data(1, c)
                    If dic.Exists(key) Then
                        result(r, dic.Item(key)) = _
                        result(r, dic.Item(key)) + data(i, c)
                    End If
                Next c
            End If
        Next j
    Next i
    r = UBound(result, 1): c = UBound(result, 2)
    sheet.Range("A3").Resize(r, c).Value = result
    '//Thong bao ket thuc
    Tmr = WorksheetFunction.Round(Timer() - Tmr, 2)
    MsgBox "Done and success, " & vbNewLine & "processing time is: " & Tmr & " seconds.", _
        vbInformation + vbOKOnly, CRV__
End Sub
 

Đính kèm

Sửa lần cuối:
.Rất mong được sự quan tâm giúp đỡ anh chị em diễn đàn..!
Thao khảo thêm 1 cách khác:
Mã:
Sub ABC()
    Dim Dic As Object, Arr(), sArr(), Res(), i&, Key$, j&, Tmp$
    Dim S, r&, sR&, iC&, Tmr As Double
    Tmr = Timer()
    Application.ScreenUpdating = 0
    Set Dic = CreateObject("Scripting.dictionary")
    With Sheets("DL_N")
        Arr = .Range("C3").CurrentRegion.Value
        For j = 1 To UBound(Arr, 2)
            If j < 10 Then
                For i = 2 To UBound(Arr)
                    If Arr(i, j) <> Empty Then
                        Key = Arr(1, j) & "|" & Arr(i, j)
                        Dic(Key) = Dic(Key) & "," & i
                    End If
                Next
            Else
                Dic.Add Arr(1, j), j
            End If
        Next
    End With
    With Sheets("T_H")
        iC = .Cells(3, Columns.Count).End(1).Column - 2
        sArr = .Range("A3").Resize(.Range("B" & Rows.Count).End(3).Row - 2, iC + 2).Value
        ReDim Res(1 To UBound(sArr) - 1, 1 To iC)
        For i = 2 To UBound(sArr)
            If sArr(i, 1) <> Empty Then Tmp = sArr(i, 1) Else sArr(i, 1) = Tmp
            Key = sArr(i, 1) & "|" & sArr(i, 2)
            If Dic.Exists(Key) = True Then
                S = Split(Dic.Item(Key), ",")
                For j = 3 To iC Step 3
                    For r = 1 To UBound(S)
                        Res(i - 1, j - 2) = Res(i - 1, j - 2) + Arr(S(r), Dic(sArr(1, j)))
                    Next
                Next
            End If
        Next
        .Range("C4").Resize(UBound(sArr) - 1, UBound(sArr, 2) - 2).Value = Res
    End With
    Application.ScreenUpdating = 1
    MsgBox "Hoàn thành: " & Timer() - Tmr
End Sub
 

shnhatha

Yêu THVBA
Mình đã sửa code đưa kết quả theo dữ liệu sheet "T_H", bạn kiểm tra lại xem đúng chưa?
Mã:
Option Explicit
Const CRV__ As String = "https://tuhocvba.net/"

Public Sub THVBA_CRV___2()

    '//Khai bao tham so
    Dim dic As Object, sheet As Worksheet, cell As Range
    Dim data As Variant, result As Variant, ma As Variant, key As Variant
    Dim i As Long, j As Long, k As Long, n As Long, r As Long
    Dim c As Integer, colMa As Integer, Tmr As Double
    Tmr = Timer()

    '// Xac dinh mang du lieu dau vao & kich thuoc mang ket qua dau ra
    Set sheet = ThisWorkbook.Worksheets("DL_N")
    If sheet.AutoFilterMode Then sheet.AutoFilterMode = False
    data = sheet.Range("C3").CurrentRegion.Value
  
    Set sheet = ThisWorkbook.Worksheets("T_H")
    If sheet.AutoFilterMode Then sheet.AutoFilterMode = False
    r = sheet.Cells(sheet.Rows.Count, 2).End(xlUp).Row
    c = sheet.Cells(3, sheet.Columns.Count).End(xlToLeft).Column
    If (r < 4) Or (c < 3) Then Exit Sub
    sheet.Range("C4").Resize(10000, 100).ClearContents
    '// Khoi tao Dictionary
    Set dic = CreateObject("Scripting.Dictionary")
    dic.CompareMode = vbTextCompare
    result = sheet.Range("A3:A" & r).Resize(, c).Value
    For j = 3 To c Step 3
        key = CRV__ & result(1, j)
        If Not dic.Exists(key) Then dic.Add key, j
    Next j
    For i = 2 To UBound(result, 1)
        If Len(result(i, 1)) > 0 Then ma = result(i, 1)
        key = ma & CRV__ & result(i, 2)
        If Not dic.Exists(key) Then dic.Add key, i
    Next i
  
    n = UBound(data, 2): colMa = 9
    '// Xu ly tong hop du lieu theo ma & phan loai ma
    For i = 2 To UBound(data, 1)
        For j = 1 To colMa
            key = data(1, j) & CRV__ & data(i, j)
            If dic.Exists(key) Then
                r = dic.Item(key)
                For c = colMa + 1 To n
                    key = CRV__ & data(1, c)
                    If dic.Exists(key) Then
                        result(r, dic.Item(key)) = _
                        result(r, dic.Item(key)) + data(i, c)
                    End If
                Next c
            End If
        Next j
    Next i
    r = UBound(result, 1): c = UBound(result, 2)
    sheet.Range("A3").Resize(r, c).Value = result
    '//Thong bao ket thuc
    Tmr = WorksheetFunction.Round(Timer() - Tmr, 2)
    MsgBox "Done and success, " & vbNewLine & "processing time is: " & Tmr & " seconds.", _
        vbInformation + vbOKOnly, CRV__
End Sub
Mình đã chạy thử code..Rất cảm ơn bạn và nhờ bạn xem lại giúp .Để bạn dễ hiểu hơn mình xin trình bày lại nội dung..
Thực tế mình muốn đoạn code thay hàm sumifs với điều là các mã nhỏ tại cột B và mã tháng (từ T9-....đến T8) ,để khi phải bổ xung thêm cột tính toán tại mỗi tháng,thì số liệu tổng vẫn được điền vào cột tháng. (Dữ liệu mã cột A mình để trình bày cho dễ hiểu )
Mình cũng nghĩ đến sử dụng Dic để duyệt so sánh các mã (không thay đổi) tại cột B với bản DL_N nếu giống nhau thì sẽ gộp số lượng ứng với từng tháng.
Do khả năng hiểu biết về VBA quá ít mong học hỏi nhiều hơn.!
 
  • Love
Reactions: CRV

CRV

SMod
Thành viên BQT
Nghĩa là kết quả chưa đúng ý bạn à?
Vậy bạn làm công thức sumifs ra rồi gửi lại file lên đây mình xem thế nào?
 

shnhatha

Yêu THVBA
Thao khảo thêm 1 cách khác:
Mã:
Sub ABC()
    Dim Dic As Object, Arr(), sArr(), Res(), i&, Key$, j&, Tmp$
    Dim S, r&, sR&, iC&, Tmr As Double
    Tmr = Timer()
    Application.ScreenUpdating = 0
    Set Dic = CreateObject("Scripting.dictionary")
    With Sheets("DL_N")
        Arr = .Range("C3").CurrentRegion.Value
        For j = 1 To UBound(Arr, 2)
            If j < 10 Then
                For i = 2 To UBound(Arr)
                    If Arr(i, j) <> Empty Then
                        Key = Arr(1, j) & "|" & Arr(i, j)
                        Dic(Key) = Dic(Key) & "," & i
                    End If
                Next
            Else
                Dic.Add Arr(1, j), j
            End If
        Next
    End With
    With Sheets("T_H")
        iC = .Cells(3, Columns.Count).End(1).Column - 2
        sArr = .Range("A3").Resize(.Range("B" & Rows.Count).End(3).Row - 2, iC + 2).Value
        ReDim Res(1 To UBound(sArr) - 1, 1 To iC)
        For i = 2 To UBound(sArr)
            If sArr(i, 1) <> Empty Then Tmp = sArr(i, 1) Else sArr(i, 1) = Tmp
            Key = sArr(i, 1) & "|" & sArr(i, 2)
            If Dic.Exists(Key) = True Then
                S = Split(Dic.Item(Key), ",")
                For j = 3 To iC Step 3
                    For r = 1 To UBound(S)
                        Res(i - 1, j - 2) = Res(i - 1, j - 2) + Arr(S(r), Dic(sArr(1, j)))
                    Next
                Next
            End If
        Next
        .Range("C4").Resize(UBound(sArr) - 1, UBound(sArr, 2) - 2).Value = Res
    End With
    Application.ScreenUpdating = 1
    MsgBox "Hoàn thành: " & Timer() - Tmr
End Sub
Tốc độ code thật tuyệt vời ..
 

shnhatha

Yêu THVBA
Nghĩa là kết quả chưa đúng ý bạn à?
Vậy bạn làm công thức sumifs ra rồi gửi lại file lên đây mình xem thế nào?
Bạn xem giúp mình..

Nếu sử dụng công thức mình sẽ phải sửa công thức tham chiếu các cột khác nhau ứng với từng mã sản phẩm.Mình tổng hợp dữ liệu T9 nhờ bạn xem giúp .!Về nội dung code của bạn khá tốt..Mình muốn nhờ bạn chỉ giúp không cần điều kiện cột A ,chỉ sử dụng điều kiện cột B.và khi mình muốn thêm cột tại giữa các tháng thì chỉnh sửa thế nào để code vẫn trả giá trị đúng tương ứng với từng tháng
 
Sửa lần cuối:
Nếu sử dụng công thức mình sẽ phải sửa công thức tham chiếu các cột khác nhau ứng với từng mã sản phẩm.Mình tổng hợp dữ liệu T9 nhờ bạn xem giúp .!Về nội dung code của bạn khá tốt..Mình muốn nhờ bạn chỉ giúp không cần điều kiện cột A ,chỉ sử dụng điều kiện cột B.và khi mình muốn thêm cột tại giữa các tháng thì chỉnh sửa thế nào để code vẫn trả giá trị đúng tương ứng với từng tháng
Với code trên bạn cũng có thể sửa được mà. Không lẽ phải chỉ bạn xíu 1. Cộng với với bạn hỏi bạn kia mình trả lời cũng hơi kỳ. Thôi để smod giải quyết cho bạn cũng được. Hihi
 

shnhatha

Yêu THVBA
Với code trên bạn cũng có thể sửa được mà. Không lẽ phải chỉ bạn xíu 1. Cộng với với bạn hỏi bạn kia mình trả lời cũng hơi kỳ. Thôi để smod giải quyết cho bạn cũng được. Hihi
Vâng..mình cũng đang gồi học hỏi và tìm hiểu từng câu mã lệnh ..cảm ơn sự quan tâm trợ giúp của anh chị em thành viên..Đúng là tuhocVBA :) ..nên nhiều khi toàn chắp vá..mong được các thành viên góp ý chỉ bảo nhiều.!
 

CRV

SMod
Thành viên BQT
Vậy không hiểu cột mã đầu tiên có tác dụng gì nữa, ban đầu thì mình nghĩ theo mã + phân loại (2 điều kiện).
Còn công thức của bạn chỉ có một điều kiện phân loai, từ đầu bạn đưa công thức & nói rõ ràng hơn thì có lẽ bạn & mình không phải mất nhiều thời gian với nhau.

Code bài 7 của mình bạn chỉ cần, sửa 2 chỗ sau.
1.sửa đoạn:
Mã:
        If Len(result(i, 1)) > 0 Then ma = result(i, 1)
        key = ma & CRV__ & result(i, 2)
Thành:
Mã:
key = CRV__ & result(i, 2)
2.Sửa đoạn:
Mã:
key = data(1, j) & CRV__ & data(i, j)
Thành:
Mã:
key = CRV__ & data(i, j)
Code hoàn chỉnh:
Mã:
Option Explicit
Const CRV__ As String = "https://tuhocvba.net/"
Public Sub THVBA_CRV___3()
    '//Khai bao tham so
    Dim dic As Object, sheet As Worksheet, cell As Range
    Dim data As Variant, result As Variant, ma As Variant, key As Variant
    Dim i As Long, j As Long, k As Long, n As Long, r As Long
    Dim c As Integer, colMa As Integer, Tmr As Double
    Tmr = Timer()

    '// Xac dinh mang du lieu dau vao & kich thuoc mang ket qua dau ra
    Set sheet = ThisWorkbook.Worksheets("DL_N")
    If sheet.AutoFilterMode Then sheet.AutoFilterMode = False
    data = sheet.Range("C3").CurrentRegion.Value
    
    Set sheet = ThisWorkbook.Worksheets("T_H")
    If sheet.AutoFilterMode Then sheet.AutoFilterMode = False
    r = sheet.Cells(sheet.Rows.Count, 2).End(xlUp).Row
    c = sheet.Cells(3, sheet.Columns.Count).End(xlToLeft).Column
    If (r < 4) Or (c < 3) Then Exit Sub
    sheet.Range("C4").Resize(10000, 100).ClearContents
    '// Khoi tao Dictionary
    Set dic = CreateObject("Scripting.Dictionary")
    dic.CompareMode = vbTextCompare
    result = sheet.Range("A3:A" & r).Resize(, c).Value
    For j = 3 To c Step 3
        key = CRV__ & result(1, j)
        If Not dic.Exists(key) Then dic.Add key, j
    Next j
    For i = 2 To UBound(result, 1)
        key = CRV__ & result(i, 2)
        If Not dic.Exists(key) Then dic.Add key, i
    Next i
    
    n = UBound(data, 2): colMa = 9
    '// Xu ly tong hop du lieu theo ma & phan loai ma
    For i = 2 To UBound(data, 1)
        For j = 1 To colMa
            key = CRV__ & data(i, j)
            If dic.Exists(key) Then
                r = dic.Item(key)
                For c = colMa + 1 To n
                    key = CRV__ & data(1, c)
                    If dic.Exists(key) Then
                        result(r, dic.Item(key)) = _
                        result(r, dic.Item(key)) + data(i, c)
                    End If
                Next c
            End If
        Next j
    Next i
    r = UBound(result, 1): c = UBound(result, 2)
    sheet.Range("A3").Resize(r, c).Value = result
    '//Thong bao ket thuc
    Tmr = WorksheetFunction.Round(Timer() - Tmr, 2)
    MsgBox "Done and success, " & vbNewLine & "processing time is: " & Tmr & " seconds.", _
        vbInformation + vbOKOnly, CRV__
End Sub
 

CRV

SMod
Thành viên BQT
Cách làm của bạn @Binana trong bài #8 rất hay để tối ưu tốc độ, tuy nhiên để cho người mới hiểu được thì có thể sẽ khó hiểu hơn.
Nếu tốc độ chỉ hơn kém nhau có tý xíu thì đối với cá nhân mình thấy không quan trọng mà nên chọn giải pháp (cách làm) mà bản thân người dùng dễ hiểu và có thể tùy biến chỉnh sửa được.
Còn đối với mình đọc hiểu được code của bạn @Binana thì sẽ chọn cách nào tối ưu vê tốc độ nên đuơng nhiên mình thích cách làm của @Binana
 

shnhatha

Yêu THVBA
Vậy không hiểu cột mã đầu tiên có tác dụng gì nữa, ban đầu thì mình nghĩ theo mã + phân loại (2 điều kiện).
Còn công thức của bạn chỉ có một điều kiện phân loai, từ đầu bạn đưa công thức & nói rõ ràng hơn thì có lẽ bạn & mình không phải mất nhiều thời gian với nhau.

Code bài 7 của mình bạn chỉ cần, sửa 2 chỗ sau.
1.sửa đoạn:
Mã:
        If Len(result(i, 1)) > 0 Then ma = result(i, 1)
        key = ma & CRV__ & result(i, 2)
Thành:
Mã:
key = CRV__ & result(i, 2)
2.Sửa đoạn:
Mã:
key = data(1, j) & CRV__ & data(i, j)
Thành:
Mã:
key = CRV__ & data(i, j)
Code hoàn chỉnh:
Mã:
Option Explicit
Const CRV__ As String = "https://tuhocvba.net/"
Public Sub THVBA_CRV___3()
    '//Khai bao tham so
    Dim dic As Object, sheet As Worksheet, cell As Range
    Dim data As Variant, result As Variant, ma As Variant, key As Variant
    Dim i As Long, j As Long, k As Long, n As Long, r As Long
    Dim c As Integer, colMa As Integer, Tmr As Double
    Tmr = Timer()

    '// Xac dinh mang du lieu dau vao & kich thuoc mang ket qua dau ra
    Set sheet = ThisWorkbook.Worksheets("DL_N")
    If sheet.AutoFilterMode Then sheet.AutoFilterMode = False
    data = sheet.Range("C3").CurrentRegion.Value
   
    Set sheet = ThisWorkbook.Worksheets("T_H")
    If sheet.AutoFilterMode Then sheet.AutoFilterMode = False
    r = sheet.Cells(sheet.Rows.Count, 2).End(xlUp).Row
    c = sheet.Cells(3, sheet.Columns.Count).End(xlToLeft).Column
    If (r < 4) Or (c < 3) Then Exit Sub
    sheet.Range("C4").Resize(10000, 100).ClearContents
    '// Khoi tao Dictionary
    Set dic = CreateObject("Scripting.Dictionary")
    dic.CompareMode = vbTextCompare
    result = sheet.Range("A3:A" & r).Resize(, c).Value
    For j = 3 To c Step 3
        key = CRV__ & result(1, j)
        If Not dic.Exists(key) Then dic.Add key, j
    Next j
    For i = 2 To UBound(result, 1)
        key = CRV__ & result(i, 2)
        If Not dic.Exists(key) Then dic.Add key, i
    Next i
   
    n = UBound(data, 2): colMa = 9
    '// Xu ly tong hop du lieu theo ma & phan loai ma
    For i = 2 To UBound(data, 1)
        For j = 1 To colMa
            key = CRV__ & data(i, j)
            If dic.Exists(key) Then
                r = dic.Item(key)
                For c = colMa + 1 To n
                    key = CRV__ & data(1, c)
                    If dic.Exists(key) Then
                        result(r, dic.Item(key)) = _
                        result(r, dic.Item(key)) + data(i, c)
                    End If
                Next c
            End If
        Next j
    Next i
    r = UBound(result, 1): c = UBound(result, 2)
    sheet.Range("A3").Resize(r, c).Value = result
    '//Thong bao ket thuc
    Tmr = WorksheetFunction.Round(Timer() - Tmr, 2)
    MsgBox "Done and success, " & vbNewLine & "processing time is: " & Tmr & " seconds.", _
        vbInformation + vbOKOnly, CRV__
End Sub
Thực sự xin lỗi đã để bạn mất quá nhiều thời gian..!mong bạn thông cảm
 
  • Love
Reactions: CRV
Cách làm của bạn @Binana trong bài #8 rất hay để tối ưu tốc độ, tuy nhiên để cho người mới hiểu được thì có thể sẽ khó hiểu hơn.
Nếu tốc độ chỉ hơn kém nhau có tý xíu thì đối với cá nhân mình thấy không quan trọng mà nên chọn giải pháp (cách làm) mà bản thân người dùng dễ hiểu và có thể tùy biến chỉnh sửa được.
Còn đối với mình đọc hiểu được code của bạn @Binana thì sẽ chọn cách nào tối ưu vê tốc độ nên đuơng nhiên mình thích cách làm của @Binana
Hihi. Cám ơn anh đã giành lời khen. Thực ra em viết không phải là để đọ tốc độ với code của anh hay bất kì ai đâu. Viết thì viết được mà bảo diễn giải logic thành ra em rất đần cái đoạn này luôn ấy. Chênh nhau vài phần trăm giây thì đâu có đáng gì chứ ạ
 

shnhatha

Yêu THVBA
Hihi. Cám ơn anh đã giành lời khen. Thực ra em viết không phải là để đọ tốc độ với code của anh hay bất kì ai đâu. Viết thì viết được mà bảo diễn giải logic thành ra em rất đần cái đoạn này luôn ấy. Chênh nhau vài phần trăm giây thì đâu có đáng gì chứ ạ
Chào bạn..bạn có thể dành chút thời gian giúp mình chỉnh sửa nội dung code theo bài #15 để mình tham khảo học hỏi thêm..!xin cảm ơn rất nhiều ..!
 
Sửa lần cuối:

shnhatha

Yêu THVBA
Chào bạn..bạn có thể dành chút thời gian giúp mình chỉnh sửa nội dung code theo bài #15 để mình tham khảo học hỏi thêm..!xin cảm ơn rất nhiều ..!
Mình đã chỉnh sửa được đoạn code..!nhưng phát sinh 2 vấn đề nhờ 2 bạn @Binana@CRV giải đáp giúp..!
Thức nhất khi thực chạy lại code sẽ chỉ làm(Xóa giá trị )tại cột tháng những cột khác không bị ảnh hưởng..
Thứ 2 sảy ra vấn đề khi mình xóa một giá trị mã nhỏ tại cột B để dòng trống.Khi thực hiện code thì tự resize số lượng vào dòng đó .!
(Nội dung code của bạn @CRV cũng bị như thế...Xin lỗi bạn @CRV đã gắn thẻ bạn vào bài viết)

Mã:
Sub ABC()
    Dim Dic As Object, Arr(), sArr(), Res(), i&, Key$, j&, Tmp$
    Dim S, r&, sR&, iC&, Tmr As Double
    Tmr = Timer()
    Application.ScreenUpdating = 0
    Set Dic = CreateObject("Scripting.dictionary")
    With Sheets("DL_N")
        Arr = .Range("C3").CurrentRegion.Value
        For j = 1 To UBound(Arr, 2)
            If j < 10 Then
                For i = 1 To UBound(Arr)
                    If Arr(i, j) <> Empty Then
                        Key = Arr(i, j)
                        Dic(Key) = Dic(Key) & "," & i
                    End If
                Next
            Else
                Dic.Add Arr(1, j), j
            End If
        Next
    End With
    With Sheets("T_H")
        iC = .Cells(3, Columns.Count).End(1).Column - 2
     
        sArr = .Range("B3").Resize(.Range("B" & Rows.Count).End(3).Row - 2, iC + 1).Value
        ReDim Res(1 To UBound(sArr), 1 To iC)
        For i = 1 To UBound(sArr)
            If sArr(i, 1) <> Empty Then Tmp = sArr(i, 1) Else sArr(i, 1) = Tmp
            Key = sArr(i, 1)
            If Dic.Exists(Key) = True Then
                S = Split(Dic.Item(Key), ",")
                For j = 2 To iC Step 3
                    For r = 1 To UBound(S)
                        Res(i - 1, j - 1) = Res(i - 1, j - 1) + Arr(S(r), Dic(sArr(1, j)))
                    Next
                Next
            End If
        Next
        .Range("C4").Resize(UBound(sArr), UBound(sArr, 2) - 1).Value = Res
       
    End With
    Application.ScreenUpdating = 1
    MsgBox "Hoàn thành: " & Timer() - Tmr
End Sub
 
Top