Option Explicit
Enum enProfile
All = 0
Site = 1
SiteBrand = 2
SiteGen = 3
End Enum
Dim lngProfile As Long
Dim aOut() As Variant
Dim aDataout() As Variant
Sub GetAmount()
Dim dic As Object, dicChild As Object
Dim aData(), dKey, cKey, aUser(4)
Dim strKey As String
Dim i As Long, j As Long
If Sheets("Sales Report").Range("B3").value = vbNullString Then
'validation of what the user entered
With Sheets("Sales Report")
'start date:
If IsDate(.Cells(5, 2).value) Then aUser(0) = .Cells(5, 2).value Else MsgBox "enter a date", vbOKOnly + vbExclamation, "Error": Exit Sub
'end date:
If IsDate(.Cells(6, 2).value) Then aUser(1) = .Cells(6, 2).value Else MsgBox "enter a date", vbOKOnly + vbExclamation, "Error": Exit Sub
End With
With Sheets("Formulas")
'Site:
aUser(2) = .Cells(1, 3).value
'Brand:
aUser(3) = .Cells(1, 6).value
'Gender
aUser(4) = .Cells(1, 15).value
End With
'set profile
If aUser(2) <> 0 And aUser(3) <> 0 And aUser(4) <> 0 Then
lngProfile = enProfile.All
ElseIf aUser(2) <> 0 And aUser(3) = 0 And aUser(4) = 0 Then
lngProfile = enProfile.Site
ElseIf aUser(2) <> 0 And aUser(3) <> 0 And aUser(4) = 0 Then
lngProfile = enProfile.SiteBrand
ElseIf aUser(2) <> 0 And aUser(3) = 0 And aUser(4) <> 0 Then
lngProfile = enProfile.SiteGen
Else
MsgBox "Please enter at least one restriction.", vbCritical + vbOKOnly, "Error"
Exit Sub
End If
aData = Sheets("Data").Cells(1, 1).CurrentRegion.value
Set dic = New Dictionary
For i = LBound(aData, 1) + 1 To UBound(aData, 1)
If ValidateRecord(aUser, aData, i) Then
strKey = GetDicKey(aUser, aData, i)
If Not dic.Exists(strKey) Then
Set dicChild = New Dictionary
dicChild.Add CStr(aData(1, 5)), 0
dicChild.Add CStr(aData(1, 7)), 0
dicChild.Add CStr(aData(1, 8)), 0
dic.Add strKey, dicChild
End If
dic.Item(strKey).Item(CStr(aData(1, 5))) = dic.Item(strKey).Item(CStr(aData(1, 5))) + aData(i, 5)
dic.Item(strKey).Item(CStr(aData(1, 7))) = dic.Item(strKey).Item(CStr(aData(1, 7))) + aData(i, 7)
dic.Item(strKey).Item(CStr(aData(1, 8))) = dic.Item(strKey).Item(CStr(aData(1, 8))) + aData(i, 8)
End If
Next i
Set dicChild = New Dictionary: Set dicChild = Nothing
If dic.Count = 0 Then
MsgBox "Nothing found", vbOKOnly + vbExclamation, "End"
ClearResult
Exit Sub
End If
PrepareOutputArray aData, dic.Count
i = 2
For Each dKey In dic.Keys
aDataout(i, 1) = Split(dKey, vbNullChar)(0)
Select Case lngProfile
Case enProfile.All
aOut = Array(Split(dKey, vbNullChar)(1), Split(dKey, vbNullChar)(3), Split(dKey, vbNullChar)(2))
Case enProfile.Site
aOut = Array(Split(dKey, vbNullChar)(1), Split(dKey, vbNullChar)(3), Split(dKey, vbNullChar)(2))
Case enProfile.SiteBrand
aOut = Array(Split(dKey, vbNullChar)(1), Split(dKey, vbNullChar)(3), Split(dKey, vbNullChar)(2))
Case enProfile.SiteGen
aOut = Array(Split(dKey, vbNullChar)(1), Split(dKey, vbNullChar)(3), Split(dKey, vbNullChar)(2))
End Select
aDataout(i, 2) = aOut(0)
aDataout(i, 3) = aOut(1)
aDataout(i, 4) = aOut(2)
For j = 5 To 7
aDataout(i, j) = dic.Item(CStr(dKey)).Item(CStr(aDataout(1, j)))
Next j
i = i + 1
Next dKey
ClearResult
ActiveSheet.Cells(10, 5).Resize(UBound(aDataout, 1), UBound(aDataout, 2)).value = aDataout
'ThisWorkbook.Worksheets.Add.Cells(1, 1).Resize(UBound(aDataout, 1), UBound(aDataout, 2)).Value = aDataout
Else
MsgBox ("In order to see a breakdown by style you must delete any data in cell B3")
End If
Set dic = Nothing
End Sub
Private Function ValidateRecord(aUser As Variant, aData As Variant, i As Long) As Boolean
Select Case lngProfile
Case enProfile.All
ValidateRecord = (aData(i, 1) >= aUser(0) And aData(i, 1) <= aUser(1) _
And aUser(2) = aData(i, 2) And aUser(3) = aData(i, 3) And aData(i, 6) = aUser(4))
Case enProfile.Site
ValidateRecord = (aData(i, 1) >= aUser(0) And aData(i, 1) <= aUser(1) _
And aUser(2) = aData(i, 2))
Case enProfile.SiteBrand
ValidateRecord = (aData(i, 1) >= aUser(0) And aData(i, 1) <= aUser(1) _
And aUser(2) = aData(i, 2) And aUser(3) = aData(i, 3))
Case enProfile.SiteGen
ValidateRecord = (aData(i, 1) >= aUser(0) And aData(i, 1) <= aUser(1) _
And aUser(2) = aData(i, 2) And aData(i, 6) = aUser(4))
End Select
End Function
Private Function GetDicKey(aUser As Variant, aData As Variant, i As Long) As String
Select Case lngProfile
Case enProfile.All
GetDicKey = CStr(aUser(2) & vbNullChar & aUser(3) & vbNullChar & aUser(4) & vbNullChar & aData(i, 4))
Case enProfile.Site
GetDicKey = CStr(aUser(2) & vbNullChar & aUser(3) & vbNullChar & aUser(4) & vbNullChar & aData(i, 4))
Case enProfile.SiteBrand
GetDicKey = CStr(aUser(2) & vbNullChar & aUser(3) & vbNullChar & aUser(4) & vbNullChar & aData(i, 4))
Case enProfile.SiteGen
GetDicKey = CStr(aUser(2) & vbNullChar & aUser(3) & vbNullChar & aUser(4) & vbNullChar & aData(i, 4))
End Select
End Function
Private Sub PrepareOutputArray(aData As Variant, lngCount As Long)
Dim i As Long, aIndex() As Variant
Select Case lngProfile
Case enProfile.All
aIndex = Array(2, 3, 4, 6, 5, 7, 8)
Case enProfile.Site
aIndex = Array(2, 3, 4, 6, 5, 7, 8)
Case enProfile.SiteBrand
aIndex = Array(2, 3, 4, 6, 5, 7, 8)
Case enProfile.SiteGen
aIndex = Array(2, 3, 4, 6, 5, 7, 8)
End Select
ReDim aDataout(1 To lngCount + 1, 1 To UBound(aIndex) + 1)
For i = 1 To UBound(aIndex) + 1
If aIndex(i - 1) <> 0 Then
aDataout(1, i) = aData(1, aIndex(i - 1))
Else
aDataout(1, i) = vbNullString
End If
Next i
End Sub
Private Sub ClearResult()
With ActiveSheet
.Cells(10, 5).Resize(.Rows.Count - 11, .Columns.Count - 6).ClearContents
End With
End Sub
Bookmarks