<% Class PurpleEnvelopeReportHelper_Class Public Function FormatElectionLabel(ByVal rawValue) FormatElectionLabel = Trim(rawValue & "") If Len(FormatElectionLabel) = 0 Then Exit Function On Error Resume Next dim parsedDate : parsedDate = CDate(rawValue) If Err.Number = 0 Then FormatElectionLabel = MonthName(Month(parsedDate), True) & "-" & CStr(Year(parsedDate)) Else Err.Clear End If On Error GoTo 0 End Function Public Function SortPrecinctColorRows(ByVal rs) dim list : set list = new LinkedList_Class If rs.EOF Then set SortPrecinctColorRows = list Exit Function End If dim items() dim itemCount : itemCount = -1 Do Until rs.EOF itemCount = itemCount + 1 ReDim Preserve items(itemCount) dim row : set row = new PrecinctColorRow_ViewModel_Class row.PRECINCT = rs("PRECINCT") If IsNull(rs("ColorId")) Then row.ColorId = "" Else row.ColorId = rs("ColorId") End If Set items(itemCount) = row rs.MoveNext Loop SortPrecinctItems items dim i For i = 0 To UBound(items) list.Push items(i) Next set SortPrecinctColorRows = list End Function Public Function SortPrecinctBallotRangeRows(ByVal rs) dim list : set list = new LinkedList_Class If rs.EOF Then set SortPrecinctBallotRangeRows = list Exit Function End If dim items() dim itemCount : itemCount = -1 Do Until rs.EOF itemCount = itemCount + 1 ReDim Preserve items(itemCount) dim row : set row = new PrecinctBallotRangeRow_ViewModel_Class row.PRECINCT = rs("PRECINCT") row.LowBallotNumber = rs("LowBallotNumber") row.HighBallotNumber = rs("HighBallotNumber") Set items(itemCount) = row rs.MoveNext Loop SortPrecinctItems items dim i For i = 0 To UBound(items) list.Push items(i) Next set SortPrecinctBallotRangeRows = list End Function Public Function BuildBallotRangesWithMissing(ByVal rs) ' Groups raw PRECINCT/BALLOT_NUMBER rows by precinct, strips non-digits from each ' ballot number, 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 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) > 0 Then If precinctNums.Exists(precinct) Then precinctNums(precinct) = precinctNums(precinct) & "," & digits Else precinctNums.Add precinct, digits 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 dim i, j For i = 0 To UBound(items) - 1 For j = i + 1 To UBound(items) If PrecinctSortsBefore(items(j).PRECINCT, items(i).PRECINCT) Then dim temp : set temp = items(i) Set items(i) = items(j) Set items(j) = temp End If Next Next End Sub Private Function PrecinctSortsBefore(ByVal leftPrecinct, ByVal rightPrecinct) dim leftType, leftNumber, leftSuffix, leftNormalized dim rightType, rightNumber, rightSuffix, rightNormalized ParsePrecinctSortParts leftPrecinct, leftType, leftNumber, leftSuffix, leftNormalized ParsePrecinctSortParts rightPrecinct, rightType, rightNumber, rightSuffix, rightNormalized If leftType <> rightType Then PrecinctSortsBefore = (leftType < rightType) Exit Function End If If leftType = 0 Then If leftNumber <> rightNumber Then PrecinctSortsBefore = (leftNumber < rightNumber) Exit Function End If If leftSuffix <> rightSuffix Then PrecinctSortsBefore = (leftSuffix < rightSuffix) Exit Function End If End If If leftNormalized <> rightNormalized Then PrecinctSortsBefore = (leftNormalized < rightNormalized) Else PrecinctSortsBefore = (UCase(Trim(leftPrecinct & "")) < UCase(Trim(rightPrecinct & ""))) End If End Function Private Sub ParsePrecinctSortParts(ByVal precinct, ByRef precinctType, ByRef numericPart, ByRef suffixPart, ByRef normalizedText) dim rawPrecinct : rawPrecinct = Trim(precinct & "") dim leadingDigits : leadingDigits = "" dim i, currentChar For i = 1 To Len(rawPrecinct) currentChar = Mid(rawPrecinct, i, 1) If currentChar >= "0" And currentChar <= "9" Then leadingDigits = leadingDigits & currentChar Else Exit For End If Next If Len(leadingDigits) > 0 Then precinctType = 0 numericPart = CLng(leadingDigits) suffixPart = UCase(Trim(Mid(rawPrecinct, Len(leadingDigits) + 1))) normalizedText = CStr(numericPart) & "|" & suffixPart Else precinctType = 1 numericPart = 0 suffixPart = UCase(rawPrecinct) normalizedText = suffixPart End If End Sub End Class dim PurpleEnvelopeReportHelper__Singleton Function PurpleEnvelopeReportHelper() If IsEmpty(PurpleEnvelopeReportHelper__Singleton) Then set PurpleEnvelopeReportHelper__Singleton = new PurpleEnvelopeReportHelper_Class End If set PurpleEnvelopeReportHelper = PurpleEnvelopeReportHelper__Singleton End Function %>