2016-09-07 2 views
0

Дан массив чисел:Простейший способ для преобразования списка номеров в читаемую строку в VBA

[1,3,4,5,8,9,11]

Что это самый простой способ VBA для преобразования этого списка в читаемую строку, например:

1, 3-5, 8-9, 11

Я мог бы просто переписать мою функцию VB.net в VBA, но это уже довольно долго наматывается и закончится еще дольше в VBA.

Public Shared Function GroupedNumbers(nums As List(Of Long)) 

    If nums Is Nothing OrElse nums.Count = 0 Then Return "-" 

    If nums.Count = 1 Then Return nums(0) 

    Dim lNums = nums.Distinct().OrderBy(Function(m) m).ToList 

    Dim curPos As Long = 1 
    Dim lastNum As Long = lNums(0) 
    Dim i As Long = 0 
    Dim numStr As String = lNums(0) 
    Dim isGap As Boolean = False 

    Do Until i >= lNums.Count - 1 
     Do Until i >= lNums.Count - 1 OrElse lNums(i) + 1 <> lNums(i + 1) 
      i += 1 
      isGap = True 
     Loop 
     If isGap Then 
      numStr += "-" & lNums(i) 
     End If 
     If i <> lNums.Count - 1 Then 
      numStr += ", " & lNums(i + 1) 
      isGap = False 
      i += 1 
     End If 
    Loop 

    Return numStr 

End Function 

Просто интересно, есть ли у кого-нибудь лучший способ сделать это, прежде чем я переписал его для VBA?

+0

Вы уверены в своем выходе? каково правило для этого? или вы имели в виду, что выход будет «1-3,4,5-8,9-11'? –

+0

Да, я уверен, это не 1-3, потому что нет 2 .. он должен только присоединяться к смежным номерам –

+0

О, я получил вашу мысль. Проверьте мой ответ ниже. –

ответ

1

Если вы хотите простой метод, вы можете использовать что-то вроде следующего:

Function GroupedNumbers(nums() As Long) As String 
    SortMe (nums) 'No built-in sort method in VBA, 
        'so you need to implement one yourself (see links below). 
    Dim numStr As String 
    numStr = nums(0) 
    For i = 1 To UBound(nums) 
     If nums(i) = nums(i - 1) + 1 Then 
      numStr = numStr & IIf(nums(i) + 1 = nums(i + 1), "", "-" & nums(i)) 
     Else 
      numStr = numStr & ", " & nums(i) 
     End If 
    Next i 
    GroupedNumbers = numStr 
End Function 

Для сортировки массива вы можете обратиться к this question.

И если вам нужно что-то более простое, проверьте this answer, которые используют .NET-версию ArrayList для сортировки. Следовательно, вам нужно будет адаптировать вышеуказанную функцию для работы с ArrayList вместо Array.

Надежда, что помогает :)

+0

Это было немного короче, чем у меня, но мне пришлось внести некоторые изменения в него, поскольку я проходил коллекцию только для уникальности, и это упало, когда я попытался проверить последний номер на один выше. –

0

Ну я взял длинный маршрут:

Public Sub SortCollection(ByRef c As Collection) 
Dim tmp 
For i = 1 To c.Count - 1 
    For j = i + 1 To c.Count 
     If c(i) > c(j) Then 
      vTemp = c(j) 
      c.Remove j 
      c.Add tmp, tmp, i 
     End If 
    Next j 
Next i 
End Sub 


Public Function NumberListGrouped(cells As Range) As String 

    If cells.Count = 0 Then 
     AnimalIdListGrouped = "-" 
    ElseIf cells.Count = 1 Then 
     AnimalIdListGrouped = cells(1, 1) 
    End If 

    Dim c As New Collection 

    On Error Resume Next 
    For Each cell In cells 
     c.Add CInt(cell.Value), CStr(cell.Value) 
    Next cell 
    SortCollection c 
    On Error GoTo 0 

    Dim i As Long: i = 1 
    Dim numStr As String: numStr = c(1) 
    Dim isGap As Boolean: isGap = False 

    Do Until i >= c.Count 
     DoEvents 
     Do Until i >= c.Count Or c(i) + 1 <> c(i + 1) 
      i = i + 1 
      isGap = True 
      DoEvents 
     Loop 
     If isGap Then 
      numStr = numStr & "-" & c(i) 
     End If 
     If i <> c.Count Then 
      numStr = numStr & ", " & c(i + 1) 
      isGap = False 
      i = i + 1 
     End If 
    Loop 

    NumberListGrouped = numStr 

End Function 
0

Если вы когда-либо использовать VBA в Excel, вы могли бы это сделать для вас работу следующим образом

Function GroupedNumbers(nums() As Long) As String 
    Dim strng As String 
    Dim i As Long 

    For i = LBound(nums) To UBound(nums) - 1 
     strng = strng & CStr(nums(i)) & ",A" 
    Next i 
    strng = "A" & strng & CStr(nums(i)) 
    GroupedNumbers = Replace(Replace(Replace(Intersect(Columns(1), Range(strng)).Address(False, False), ",A", ", "), "A", ""), ":", "-") 
End Function 
Смежные вопросы