Greetings,
If I understand correctly...
- We have a bunch of case numbers in one column.
- Some are listed once, some a few times, etc.
- This list continues to grow.
- We cannot sort the list, it is probably added to as billings or outlays or whatever occur.
- We'd like to be able to beat the boss stupid, but in lieu of that, we'd settle for pushing a button and a listing of all cases and ea case's current total monies should be produced.
- We'd still like to smack the boss around though, if only those pesky bills didn't keep showing up in the mail.
Would this work?
In a Standard Module:
Option Explicit
Sub exa()
Dim _
rngData As Range, _
i As Long, _
aryCollection As Variant
'// set a reference to the range containing Case Numbers. Change sheetname, //
'// column, and first cell (if no header row) to suit. //
With ThisWorkbook.Worksheets("Sheet1")
Set rngData = Range(.Range("A2"), _
RangeFound(.Range(.Range("A2"), .Cells(Rows.Count, 1))))
End With
'// Return an array of unique case numbers. //
aryCollection = RetCollection(rngData)
'// SAA, change dest sheet, col, start row to suit. //
With ThisWorkbook.Worksheets("Sheet2") _
.Range("A2").Resize(UBound(aryCollection) - LBound(aryCollection) + 1)
'// Plunk the array of case numbers in. //
.Value = Application.Transpose(aryCollection)
'// Plunk in the SUMIF formula... //
.Offset(, 1).Formula = _
"=SUMIF(" & rngData.Parent.Name & "!" & rngData.Address(True, True) & _
",A2," & rngData.Parent.Name & "!" & _
rngData.Offset(, 2).Address(True, True) & ")"
'// ...and optionally, overwrite it. //
.Offset(, 1).Value = .Offset(, 1).Value
'// If your boss changes sheetnames, beat him/her stupid. //
End With
End Sub
Function RetCollection(DataRange As Range) As Variant
Dim CaseNo As Variant
With CreateObject("Scripting.Dictionary")
For Each CaseNo In DataRange.Value
.Item(CaseNo) = CaseNo
Next
RetCollection = .Items
End With
End Function
Function RangeFound(SearchRange As Range, _
Optional FindWhat As String = "*", _
Optional StartingAfter As Range, _
Optional LookAtTextOrFormula As XlFindLookIn = xlValues, _
Optional LookAtWholeOrPart As XlLookAt = xlPart, _
Optional SearchRowCol As XlSearchOrder = xlByRows, _
Optional SearchUpDn As XlSearchDirection = xlPrevious, _
Optional bMatchCase As Boolean = False) As Range
If StartingAfter Is Nothing Then
Set StartingAfter = SearchRange(1)
End If
Set RangeFound = SearchRange.Find(What:=FindWhat, _
After:=StartingAfter, _
LookIn:=LookAtTextOrFormula, _
LookAt:=LookAtWholeOrPart, _
SearchOrder:=SearchRowCol, _
SearchDirection:=SearchUpDn, _
MatchCase:=bMatchCase)
End Function
Hope that helps,
Mark