Hoàng Nhật Phương
Thành viên gắn bó
![](/diendan/data/PhoToDanhHieu/pip.gif)
![](/diendan/data/PhoToDanhHieu/pip.gif)
![](/diendan/data/PhoToDanhHieu/pip.gif)
- Tham gia
- 5/11/15
- Bài viết
- 1,895
- Được thích
- 1,219
chạy thử codeXin chào các bạn,
Vì tập tin rất nhiều dữ liệu vì vậy mà tôi muốn sử dụng code thay cho công thức.
Bài toán và kết quả mong muốn tôi xin được nêu trong tập tin đính kèm.
Nhờ các bạn xem giúp ạ.
Sub GPE()
Dim Darr As Variant, Sarr As Variant, S As Variant, i As Long, j As Long, k As Byte, n As Double, Dtmp As Variant, Tmp As Variant
With Sheets("Sheet2")
Sarr = .Range("D1", Cells(.Range("D1").End(xlDown).Row, .Range("D1").End(xlToRight).Column)).Value
End With
With Sheets("Sheet1")
Darr = .Range("C2:E" & .Range("E65500").End(xlUp).Row).Value
End With
ReDim Arr(1 To UBound(Darr, 1))
With CreateObject("scripting.dictionary")
For i = 1 To UBound(Darr, 1)
Dtmp = Darr(i, 1)
If Dtmp <> "" Then
If IsNumeric(Dtmp) Then
Tmp = Dtmp & "#" & Darr(i, 3)
If Not .exists(Tmp) Then .Add Tmp, 1 Else .Item(Tmp) = .Item(Tmp) + 1
Else
S = Split(Replace(Dtmp, " ", ""), "&")
For k = 0 To UBound(S)
n = 1 / (UBound(S) + 1)
Tmp = S(k) & "#" & Darr(i, 3)
If Not .exists(Tmp) Then .Add Tmp, n Else .Item(Tmp) = .Item(Tmp) + n
Next k
End If
End If
Next i
For i = 2 To UBound(Sarr, 1)
For j = 2 To UBound(Sarr, 2)
Tmp = Sarr(i, 1) & "#" & Sarr(1, j)
If .exists(Tmp) Then Sarr(i, j) = .Item(Tmp)
Next j
Next i
End With
Sheets("Sheet2").Range("D1").Resize(UBound(Sarr, 1), UBound(Sarr, 2)) = Sarr
End Sub
Xin chào các bạn,
Vì tập tin rất nhiều dữ liệu vì vậy mà tôi muốn sử dụng code thay cho công thức.
Bài toán và kết quả mong muốn tôi xin được nêu trong tập tin đính kèm.
Nhờ các bạn xem giúp ạ.
Xin chào các bạn,
Vì tập tin rất nhiều dữ liệu vì vậy mà tôi muốn sử dụng code thay cho công thức.
Bài toán và kết quả mong muốn tôi xin được nêu trong tập tin đính kèm.
Nhờ các bạn xem giúp ạ.
Sub Main()
Dim lR1 As Long, lC1 As Long, lR2 As Long, lC2 As Long, lR As Long, lC As Long
Dim dic1 As Object, dic2 As Object
Dim aData1, aData2, aSummary, aTarget, Target As Range
Dim vDate, tmp, sID
Set dic1 = CreateObject("Scripting.Dictionary")
Set dic2 = CreateObject("Scripting.Dictionary")
aData1 = Worksheets("Sheet1").Range("E2:E10000").Value
aData2 = Worksheets("Sheet1").Range("I2:AA10000").Value
aSummary = Worksheets("Sheet1").Range("H2:H10000").Value
Set Target = Worksheets("Sheet2").Range("D1:G10000")
aTarget = Target.Value
ReDim aDes(2 To UBound(aTarget, 1), 2 To UBound(aTarget, 2))
Intersect(Target.Offset(1, 1), Target).ClearContents
tmp = Empty
On Error Resume Next
''Nạp mã hàng vào dic1
For lR1 = 2 To UBound(aTarget, 1)
tmp = aTarget(lR1, 1)
If tmp <> Empty Then
If Not dic1.Exists(tmp) Then dic1.Add tmp, lR1
End If
Next
tmp = Empty
''Nạp các cột ngày tháng vào dic2
For lC1 = 2 To UBound(aTarget, 2)
tmp = aTarget(1, lC1)
If tmp <> Empty Then
If Not dic2.Exists(tmp) Then dic2.Add tmp, lC1
End If
Next
Dim n As Long
For lR2 = 1 To UBound(aData2, 1)
For lC2 = 1 To UBound(aData2, 2)
sID = aData2(lR2, lC2)
vDate = aData1(lR2, 1)
If dic1.Exists(sID) Then
If dic2.Exists(vDate) Then
n = n + 1
lR = dic1.Item(sID): lC = dic2.Item(vDate) ''xác định vị trí dòng, cột trong kết quả
aDes(lR, lC) = aDes(lR, lC) + aSummary(lR2, 1)
End If
End If
Next
Next
If n Then
Intersect(Target.Offset(1, 1), Target).Value = aDes
MsgBox "Found " & n & " values", , dic1.Count & " - " & dic2.Count
End If
End Sub
hình như ở sheet1, cột H trở đi là tài sản riêng quí giá nên chủ topic không cho đụng tới, chỉ được dùng 3 cột C,D,E thôiXài tạm:
Code tuy dài nhưng tôi nghĩ sẽ dễ hiểuMã:Sub Main() Dim lR1 As Long, lC1 As Long, lR2 As Long, lC2 As Long, lR As Long, lC As Long Dim dic1 As Object, dic2 As Object Dim aData1, aData2, aSummary, aTarget, Target As Range Dim vDate, tmp, sID Set dic1 = CreateObject("Scripting.Dictionary") Set dic2 = CreateObject("Scripting.Dictionary") aData1 = Worksheets("Sheet1").Range("E2:E10000").Value aData2 = Worksheets("Sheet1").Range("I2:AA10000").Value aSummary = Worksheets("Sheet1").Range("H2:H10000").Value Set Target = Worksheets("Sheet2").Range("D1:G10000") aTarget = Target.Value ReDim aDes(2 To UBound(aTarget, 1), 2 To UBound(aTarget, 2)) Intersect(Target.Offset(1, 1), Target).ClearContents tmp = Empty On Error Resume Next ''Nạp mã hàng vào dic1 For lR1 = 2 To UBound(aTarget, 1) tmp = aTarget(lR1, 1) If tmp <> Empty Then If Not dic1.Exists(tmp) Then dic1.Add tmp, lR1 End If Next tmp = Empty ''Nạp các cột ngày tháng vào dic2 For lC1 = 2 To UBound(aTarget, 2) tmp = aTarget(1, lC1) If tmp <> Empty Then If Not dic2.Exists(tmp) Then dic2.Add tmp, lC1 End If Next Dim n As Long For lR2 = 1 To UBound(aData2, 1) For lC2 = 1 To UBound(aData2, 2) sID = aData2(lR2, lC2) vDate = aData1(lR2, 1) If dic1.Exists(sID) Then If dic2.Exists(vDate) Then n = n + 1 lR = dic1.Item(sID): lC = dic2.Item(vDate) ''xác định vị trí dòng, cột trong kết quả aDes(lR, lC) = aDes(lR, lC) + aSummary(lR2, 1) End If End If Next Next If n Then Intersect(Target.Offset(1, 1), Target).Value = aDes MsgBox "Found " & n & " values", , dic1.Count & " - " & dic2.Count End If End Sub
hình như ở sheet1, cột H trở đi là tài sản riêng quí giá nên chủ topic không cho đụng tới, chỉ được dùng 3 cột C,D,E thôi
Xài tạm:
Code tuy dài nhưng tôi nghĩ sẽ dễ hiểuMã:Sub Main() Dim lR1 As Long, lC1 As Long, lR2 As Long, lC2 As Long, lR As Long, lC As Long Dim dic1 As Object, dic2 As Object Dim aData1, aData2, aSummary, aTarget, Target As Range Dim vDate, tmp, sID Set dic1 = CreateObject("Scripting.Dictionary") [COLOR=#0000ff] Set dic2 = CreateObject("Scripting.Dictionary") aData1 = Worksheets("Sheet1").Range("E2:E10000").Value aData2 = Worksheets("Sheet1").Range("I2:AA10000").Value aSummary = Worksheets("Sheet1").Range("H2:H10000").Value Set Target = Worksheets("Sheet2").Range("D1:G10000")[/COLOR] aTarget = Target.Value ReDim aDes(2 To UBound(aTarget, 1), 2 To UBound(aTarget, 2)) Intersect(Target.Offset(1, 1), Target).ClearContents tmp = Empty On Error Resume Next ''Nạp mã hàng vào dic1 For lR1 = 2 To UBound(aTarget, 1) tmp = aTarget(lR1, 1) If tmp <> Empty Then If Not dic1.Exists(tmp) Then dic1.Add tmp, lR1 End If Next tmp = Empty ''Nạp các cột ngày tháng vào dic2 For lC1 = 2 To UBound(aTarget, 2) tmp = aTarget(1, lC1) If tmp <> Empty Then If Not dic2.Exists(tmp) Then dic2.Add tmp, lC1 End If Next Dim n As Long For lR2 = 1 To UBound(aData2, 1) For lC2 = 1 To UBound(aData2, 2) sID = aData2(lR2, lC2) vDate = aData1(lR2, 1) If dic1.Exists(sID) Then If dic2.Exists(vDate) Then n = n + 1 lR = dic1.Item(sID): lC = dic2.Item(vDate) ''xác định vị trí dòng, cột trong kết quả aDes(lR, lC) = aDes(lR, lC) + aSummary(lR2, 1) End If End If Next Next If n Then Intersect(Target.Offset(1, 1), Target).Value = aDes MsgBox "Found " & n & " values", , dic1.Count & " - " & dic2.Count End If End Sub
Ahihi, thật tuyệt vời)
Xin cảm ơn các bạn: HieuCD, Ba Tê, ndu96081631 nhiều ạ.
Cả 3 code đều cho ra kết quả đúng với mong muốn của tôi rồi.
Code của bạn Ba Tê còn lấy luôn dữ liệu cho cả cột D nữa, chú chuột thật đáng yêu quá!
Tới đây thì ngon lành rồi.
Nhưng vẫn còn 1 bước nữa nhờ các bạn xem và giúp cho ạ:
Hiện tại tập tin đính kèm đang tổng hợp từ Sheet1 sang sheet2
Nhưng tập tin thực tế là có nhiều sheet có cấu trúc giống như sheet1 (10 sheet dữ liệu), và 1sheet tổng hợp.
10sheet dữ liệu này có tên là: a,b,....,j giống như sheet1 trong tập tin gửi kèm tại bài 1.
và 1sheet Tổng hợp có tên là: Tonghop giống như sheet2 trong tập tin gửi kèm.
Xin chào ndu96081631,
Bài viết của bạn đối với tôi có phần dễ áp dung và tùy biến hơn ở các dòng bôi màu.
Với cách làm này sẽ dựa vào các cột dữ liệu phụ sau khi tách các mã hàng ra.
Bạn có thể sửa lại code giúp tôi tổng hợp theo bài 6 vẫn theo cách làm này của bạn được không ạ.
Đó là 1 cách làm để tôi có thể tham khảo và để ứng dụng.
''Hằng số SHEETNAME này bạn có thể thay đổi cho phù hợp
Const SHEETNAME = "TONGHOP"
Sub Main()
Dim lR As Long, lC As Long, lRow As Long, lCol As Long, n As Long
Dim dic1 As Object, dic2 As Object
Dim aData
Dim vDate, sTmp As String, sID, aTmp
Dim wks As Worksheet
Set dic1 = CreateObject("Scripting.Dictionary")
Set dic2 = CreateObject("Scripting.Dictionary")
On Error Resume Next
lR = 1: lC = 1
ReDim aDes(1 To 10000, 1 To 1)
Worksheets(SHEETNAME).Range("D1:G10000").Clear
''Duyệt qua các sheet, ngoại trừ SHEETNAME
For Each wks In ThisWorkbook.Worksheets
If UCase(wks.Name) <> SHEETNAME Then
aData = wks.Range("C2:E10000").Value
For n = 1 To UBound(aData, 1)
sTmp = aData(n, 1)
vDate = aData(n, 3)
If (sTmp <> Empty) And (vDate <> Empty) Then
aTmp = Split(sTmp, "&")
''Nạp mã hàng vào cột cột 1 của kết quả
For Each sID In aTmp
If Not dic1.Exists(CStr(sID)) Then
lR = lR + 1
dic1.Add CStr(sID), lR
aDes(lR, 1) = CStr(sID)
End If
''Nạp tháng vào dòng 1 của kết quả
If Not dic2.Exists(vDate) Then
lC = lC + 1
dic2.Add vDate, lC
ReDim Preserve aDes(1 To 10000, 1 To lC)
aDes(1, lC) = "'" & vDate
End If
''xác định vị trí dòng cột của kết quả để cộng dồn
lRow = dic1.Item(sID): lCol = dic2.Item(vDate)
aDes(lRow, lCol) = aDes(lRow, lCol) + aData(n, 2) / (UBound(aTmp) + 1)
Next
End If
Next
End If
Next
''Đưa kết quả xuống sheet đồng thời format bảng tính
With Worksheets(SHEETNAME).Range("D1").Resize(lR, lC)
.Value = aDes
.Interior.ColorIndex = 6
.Resize(1).Font.Bold = True
.Resize(, 1).Font.Bold = True
Intersect(.Offset(1, 1), .Cells).NumberFormat = "0.00"
.Borders.LineStyle = 1
.Cells(1, 1) = "M" & ChrW(195) & " HÀNG"
End With
End Sub
Sub GPE()
Dim Sh As Worksheet, dArr As Variant, TD As Variant, S As Variant, Tmp As Variant
Dim Arr(1 To 10000, 1 To 1000), jC(1 To 1000) As Boolean, iR(1 To 10000) As Boolean
Dim LastR As Long, I As Long, si As Long, J As Long, C As Long, sj As Long, K As Long, N As Double
For Each Sh In ActiveWorkbook.Sheets
LastR = Sh.Range("C" & Rows.Count).End(xlUp).Row
If Sh.Name <> "TongHop" And LastR > 1 Then
dArr = Sh.Range("C2:E" & LastR).Value
For I = 1 To UBound(dArr, 1)
Tmp = dArr(I, 1)
If Tmp <> "" And dArr(I, 3) <> "" Then
C = CLng(CDate(dArr(I, 3))) - 42735
If jC(C) = False Then jC(C) = True: sj = sj + 1
If IsNumeric(Tmp) Then
If iR(Tmp) = False Then iR(Tmp) = True: si = si + 1
Arr(Tmp, C) = Arr(Tmp, C) + 1
Else
S = Split(Replace(Tmp, " ", ""), "&")
N = dArr(I, 2) / (UBound(S) + 1)
For K = 0 To UBound(S)
Tmp = CLng(S(K))
If iR(Tmp) = False Then iR(Tmp) = True: si = si + 1
Arr(Tmp, C) = Arr(Tmp, C) + N
Next K
End If
End If
Next I
End If
Next Sh
ReDim dArr(1 To si, 1 To sj + 1)
K = 0
ReDim S(1 To sj): ReDim TD(1 To sj)
For J = 1 To 1000
If jC(J) = True Then
K = K + 1: S(K) = J
TD(K) = Month(CDate(J + 42735)) & "/" & Year(CDate(J + 42735))
End If
Next J
K = 0
For I = 1 To 10000
If iR(I) = True Then
K = K + 1
dArr(K, 1) = I
For J = 1 To sj
dArr(K, J + 1) = Arr(I, S(J))
Next J
End If
Next I
Sheets("TongHop").Range("E1").Resize(, sj) = TD
Sheets("TongHop").Range("D2").Resize(si, sj + 1) = dArr
End Sub
Sub GPE_Hieu()
Dim Sh As Worksheet, dArr As Variant, S As Variant, Tmp As Variant
Dim Arr(1 To 10000, 1 To 24), TD(1 To 1, 1 To 24)
Dim LastR As Long, I As Long, si As Long, J As Long, C As Long, Mc As Long, K As Long, N As Double
Const Mfist = 1: Const Yfist = 2017
For Each Sh In ActiveWorkbook.Sheets
LastR = Sh.Range("C" & Rows.Count).End(xlUp).Row
If Sh.Name <> "TongHop" And LastR > 1 Then
dArr = Sh.Range("C2:E" & LastR).Value
For I = 1 To UBound(dArr, 1)
Tmp = dArr(I, 1)
If Tmp <> "" And dArr(I, 3) <> "" Then
C = Month(CDate(dArr(I, 3))) - Mfist + 2 + (Year(CDate(dArr(I, 3))) - Yfist) * 12
If C > Mc Then Mc = C
If TD(1, C - 1) = "" Then TD(1, C - 1) = dArr(I, 3)
If IsNumeric(Tmp) Then
Arr(Tmp, 1) = Tmp: Arr(Tmp, C) = Arr(Tmp, C) + dArr(I, 2)
Else
S = Split(Replace(Tmp, " ", ""), "&")
N = dArr(I, 2) / (UBound(S) + 1)
For K = 0 To UBound(S)
Tmp = CLng(S(K))
Arr(Tmp, 1) = Tmp: Arr(Tmp, C) = Arr(Tmp, C) + N
Next K
End If
End If
Next I
End If
Next Sh
ReDim dArr(1 To 10000, 1 To Mc + 1)
K = 0
For I = 1 To 10000
If Arr(I, 1) > 0 Then
K = K + 1
For J = 1 To Mc
dArr(K, J) = Arr(I, J)
Next J
End If
Next I
Sheets("TongHop").Range("E1").Resize(, Mc - 1) = TD
Sheets("TongHop").Range("D2").Resize(K, Mc) = dArr
Macro3
End Sub
Không hiểu sao dài thế... mà không biết đúng không...Nhưng hiện tôi đang phát sinh thêm một vấn đề (Sếp yêu cầu thêm)
Sub abxy()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Const wsTonghop As String = "Tonghop*"
Dim ws As Worksheet, lR As Long, r As Long, i As Long
Dim DL(), Ma As String, m As Long, tmpMa, iMa
Dim sArr(1 To 10 ^ 6, 1 To 4)
For Each ws In ThisWorkbook.Worksheets
If Not ws.Name Like wsTonghop Then
lR = ws.Range("C" & ws.Rows.Count).End(xlUp).Row
If lR = 1 Then GoTo 1
DL = ws.Range("C2:H" & lR): lR = UBound(DL, 1)
For r = 1 To lR
If DL(r, 1) <> Empty And DL(r, 2) <> Empty Then
If DL(r, 3) <> Empty And DL(r, 6) <> Empty Then
Ma = DL(r, 1): m = Month(CDate(DL(r, 3)))
If IsNumeric(Ma) Then
i = i + 1
sArr(i, 1) = CLng(Ma): sArr(i, 2) = DL(r, 2)
sArr(i, 3) = m: sArr(i, 4) = DL(r, 6)
If VBA.UCase(DL(r, 6)) Like "SPECIAL" Then sArr(i, 4) = 6
Else
tmpMa = Split(Replace(Ma, " ", ""), "&")
For Each iMa In tmpMa
If i > 10 ^ 6 Then GoTo 2:
i = i + 1
sArr(i, 1) = CLng(iMa): sArr(i, 2) = DL(r, 2) / (UBound(tmpMa) + 1)
sArr(i, 3) = m: sArr(i, 4) = DL(r, 6)
If VBA.UCase(DL(r, 6)) Like "SPECIAL" Then sArr(i, 4) = 6
Next iMa
End If
End If
End If
Next r
End If
1:
Next ws
2:
If i Then
Dim MH(), maxMH As Long, j As Long, k As Long, iDG As Long
[COLOR=#0000ff]MH = Sheets("Tonghop2").Range("C7:C5592").Value[/COLOR]: maxMH = UBound(MH, 1)
ReDim KQ(1 To maxMH, 1 To (13 * 6 + 5))
For j = 1 To maxMH
For r = 1 To i '
If sArr(r, 1) = MH(j, 1) Then
iDG = sArr(r, 4)
iDG = (iDG - 1) * 14 + 1
KQ(j, iDG + sArr(r, 3)) = KQ(j, iDG + sArr(r, 3)) + sArr(r, 2)
End If
Next r
For k = 1 To 6
KQ(j, (k - 1) * 14 + 1) = MH(j, 1)
Next k
Next j
End If
Sheets("Tonghop2").Range("C7").Resize(maxMH, UBound(KQ, 2)) = KQ
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Sub GPE_3()
Dim Sh As Worksheet, Darr As Variant, Arr As Variant, S As Variant, Tmp As Variant
Dim LastR As Long, i As Long, iRow As Long, j As Long, C As Long, jCol As Long, Dg As Byte, k As Long, N As Double
iRow = Sheets("Tonghop2").Range("C" & Rows.Count).End(xlUp).Value
jCol = Sheets("Tonghop2").Cells(6, Columns.Count).End(xlToLeft).Column - 2
ReDim Arr(1 To iRow, 1 To jCol)
For Each Sh In ActiveWorkbook.Sheets
LastR = Sh.Range("C" & Rows.Count).End(xlUp).Row
If Not (Sh.Name = "Tonghop" Or Sh.Name = "Tonghop2" Or LastR < 2) Then
Darr = Sh.Range("C2:H" & LastR).Value
For i = 1 To UBound(Darr, 1)
If Darr(i, 1) <> "" And Darr(i, 2) <> "" And Darr(i, 3) <> "" And Darr(i, 6) <> "" Then
Tmp = Darr(i, 1)
If IsNumeric(Darr(i, 6)) Then Dg = Darr(i, 6) Else Dg = 6
C = Month(CDate(Darr(i, 3))) + (Dg - 1) * 14 + 1
If IsNumeric(Tmp) Then
Arr(Tmp, C) = Arr(Tmp, C) + Darr(i, 2)
Else
S = Split(Replace(Tmp, " ", ""), "&")
N = Darr(i, 2) / (UBound(S) + 1)
For k = 0 To UBound(S)
Tmp = CLng(S(k))
Arr(Tmp, C) = Arr(Tmp, C) + N
Next k
End If
End If
Next i
End If
Next Sh
For i = 1 To iRow
For j = 1 To jCol
If j Mod 14 = 1 Then Arr(i, j) = i
Next j
Next i
Sheets("Tonghop2").Range("C7").Resize(iRow, jCol) = Arr
End Sub
Đã sửa lại lỗi ở bài trên.Xin chào befaint ,HieuCD
Cảm ơn 2 bạn rất nhiều vì đã hỗ trợ cho tôi.
Vâng vấn đề kiểm tra kết quả là trách nhiệm của Oanh Thơ, khi nào có kết quả tôi sẽ thông tin lại ạ.
@ befaint
Nhờ Code bị lỗi như ảnh đính kèm, nhờ bạn xử lý giúp ạ.
p/s: lâu lâu mới lại thấy bạn, bạn vẫn khỏe chứ.