|
|
|
@@ -80,6 +80,101 @@ Class PurpleEnvelopeReportHelper_Class |
|
|
|
set SortPrecinctBallotRangeRows = list |
|
|
|
End Function |
|
|
|
|
|
|
|
Public Function BuildBallotRangesWithMissing(ByVal rs) |
|
|
|
' Groups raw PRECINCT/BALLOT_NUMBER rows by precinct, extracts last 4 digits of |
|
|
|
' the numeric portion (matching the PowerShell InkjetRecords analysis script), |
|
|
|
' computes min/max and any missing numbers in that range, then returns rows |
|
|
|
' sorted by precinct in descending order. |
|
|
|
dim precinctNums : set precinctNums = CreateObject("Scripting.Dictionary") |
|
|
|
dim precinct, rawNum, digits, i, ch, last4Str |
|
|
|
|
|
|
|
Do Until rs.EOF |
|
|
|
precinct = Trim(rs("PRECINCT") & "") |
|
|
|
rawNum = rs("BALLOT_NUMBER") & "" |
|
|
|
|
|
|
|
digits = "" |
|
|
|
For i = 1 To Len(rawNum) |
|
|
|
ch = Mid(rawNum, i, 1) |
|
|
|
If ch >= "0" And ch <= "9" Then digits = digits & ch |
|
|
|
Next |
|
|
|
|
|
|
|
If Len(digits) >= 4 Then |
|
|
|
last4Str = Mid(digits, Len(digits) - 3, 4) |
|
|
|
If precinctNums.Exists(precinct) Then |
|
|
|
precinctNums(precinct) = precinctNums(precinct) & "," & last4Str |
|
|
|
Else |
|
|
|
precinctNums.Add precinct, last4Str |
|
|
|
End If |
|
|
|
End If |
|
|
|
rs.MoveNext |
|
|
|
Loop |
|
|
|
|
|
|
|
If precinctNums.Count = 0 Then |
|
|
|
set BuildBallotRangesWithMissing = new LinkedList_Class |
|
|
|
Exit Function |
|
|
|
End If |
|
|
|
|
|
|
|
dim keys : keys = precinctNums.Keys |
|
|
|
dim itemCount : itemCount = precinctNums.Count - 1 |
|
|
|
dim items() |
|
|
|
ReDim items(itemCount) |
|
|
|
|
|
|
|
dim k, j, n |
|
|
|
dim numStrs, numArr, minVal, maxVal, presenceDict, missingList, missingCount, row |
|
|
|
|
|
|
|
For k = 0 To itemCount |
|
|
|
precinct = keys(k) |
|
|
|
numStrs = Split(precinctNums(precinct), ",") |
|
|
|
|
|
|
|
ReDim numArr(UBound(numStrs)) |
|
|
|
For j = 0 To UBound(numStrs) |
|
|
|
numArr(j) = CLng(numStrs(j)) |
|
|
|
Next |
|
|
|
|
|
|
|
minVal = numArr(0) |
|
|
|
maxVal = numArr(0) |
|
|
|
For j = 1 To UBound(numArr) |
|
|
|
If numArr(j) < minVal Then minVal = numArr(j) |
|
|
|
If numArr(j) > maxVal Then maxVal = numArr(j) |
|
|
|
Next |
|
|
|
|
|
|
|
set presenceDict = CreateObject("Scripting.Dictionary") |
|
|
|
For j = 0 To UBound(numArr) |
|
|
|
If Not presenceDict.Exists(numArr(j)) Then |
|
|
|
presenceDict.Add numArr(j), True |
|
|
|
End If |
|
|
|
Next |
|
|
|
|
|
|
|
missingList = "" |
|
|
|
missingCount = 0 |
|
|
|
For n = minVal To maxVal |
|
|
|
If Not presenceDict.Exists(n) Then |
|
|
|
missingCount = missingCount + 1 |
|
|
|
If Len(missingList) > 0 Then missingList = missingList & ", " |
|
|
|
missingList = missingList & CStr(n) |
|
|
|
End If |
|
|
|
Next |
|
|
|
|
|
|
|
set row = new PrecinctBallotRangeRow_ViewModel_Class |
|
|
|
row.PRECINCT = precinct |
|
|
|
row.LowBallotNumber = minVal |
|
|
|
row.HighBallotNumber = maxVal |
|
|
|
row.MissingCount = missingCount |
|
|
|
row.MissingNumbers = missingList |
|
|
|
Set items(k) = row |
|
|
|
Next |
|
|
|
|
|
|
|
SortPrecinctItems items |
|
|
|
|
|
|
|
dim list : set list = new LinkedList_Class |
|
|
|
' Iterate in reverse for descending precinct order |
|
|
|
For k = UBound(items) To 0 Step -1 |
|
|
|
list.Push items(k) |
|
|
|
Next |
|
|
|
|
|
|
|
set BuildBallotRangesWithMissing = list |
|
|
|
End Function |
|
|
|
|
|
|
|
Private Sub SortPrecinctItems(ByRef items) |
|
|
|
If Not IsArray(items) Then Exit Sub |
|
|
|
|
|
|
|
|