Я избегал использовать другую функцию для написания OutRange (это был бы лучший и более чистый код, но это не топи c)
Option Explicit
'Pages need to be in ASCendent order
Function GetPageRanges(Pages() As Variant, Exclusion() As Variant) As String
GetPageRanges = ""
'Dim Pages(), Exclusion As Variant
Dim OutRange(0 To 1) As Variant
Dim Page As Variant
Dim SExcl As String
' Pages = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
'Exclusion = Array(1, 1, 3, 3, 7)
SExcl = "," & Join(Exclusion, ",") & "," 'Every page is sorrounded by commas
OutRange(0) = Null
OutRange(1) = Null
For Each Page In Pages
'Comma-sorrounding is used in order to delimit page number
'(searching for "2" in a string will match even when it contains page "123").
'Searching for ",2," will not match with ",123,"
If InStr(SExcl, "," & Page & ",") Then
'Page is in Exclusion list
'Previous range, if existing, has to be written as range excluding this page.
'If previus range has only a left/lower bound than it has to be written as a single page.
'After that also this page has to be written as a single page
If Not IsNull(OutRange(0)) Then
'There was a range or a single page
GetPageRanges = GetPageRanges & OutRange(0)
If Not IsNull(OutRange(1)) Then GetPageRanges = GetPageRanges & "-" & OutRange(1)
GetPageRanges = GetPageRanges & ","
'Clean OutRange
OutRange(0) = Null
OutRange(1) = Null
End If
'Add this page (found in exclusion)
GetPageRanges = GetPageRanges & Page & ","
Else
'Page is NOT in Exclusion list
'If OutRange is not started I put page as left/lower bound
If (IsNull(OutRange(0))) Then
OutRange(0) = Page
Else
'If the range is the one following the left/lower bound then it's inside the same range
'If this page is the one following the previous right/upeer bound then it's inside the same range.
'If some page has been skipped the range has to be closed , written and a new open it's opened
If ((OutRange(0) + 1) = Page) Then
OutRange(1) = Page
ElseIf (CInt(OutRange(1) + 1) = Page) Then
'Same action of the if statement expression. We need to use else if in order to use
'CInt(OutRange(1)) only if we know that it's not null
OutRange(1) = Page
Else
'Like when an excluded page is found, we write down out range and clean it
GetPageRanges = GetPageRanges & OutRange(0)
If Not IsNull(OutRange(1)) Then GetPageRanges = GetPageRanges & "-" & OutRange(1)
GetPageRanges = GetPageRanges & ","
OutRange(0) = Null
OutRange(1) = Null
'This page is written for next range left/lower bound
OutRange(0) = Page
End If
End If
End If
Next Page
'If the last page was not in exclusion than we have to write down OutRange
GetPageRanges = GetPageRanges & OutRange(0)
If Not IsNull(OutRange(1)) Then GetPageRanges = GetPageRanges & "-" & OutRange(1)
GetPageRanges = GetPageRanges & ","
'Remove last character (is a comma)
If GetPageRanges <> "" Then GetPageRanges = Left(GetPageRanges, Len(GetPageRanges) - 1)
End Function
Sub Run()
Dim Pages() As Variant
Dim Exclusion() As Variant
Pages = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Exclusion = Array(1, 1, 3, 3, 7)
Debug.Print GetPageRanges(Pages, Exclusion)
End Sub