【问题标题】:Simplest way to convert a number list to a readable string in VBA在 VBA 中将数字列表转换为可读字符串的最简单方法
【发布时间】:2016-09-07 21:35:39
【问题描述】:

给定一个数字数组:

[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 重写之前是否有人有更好的方法?

【问题讨论】:

  • 你确定你的输出吗?它的规则是什么?还是您的意思是输出为1-3,4,5-8,9-11
  • 是的,我确定,它不是 1-3,因为没有 2.. 它应该只连接相邻的数字
  • 哦,我明白了。在下面检查我的答案。

标签: vba


【解决方案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

希望有帮助:)

【讨论】:

  • 这比我的要短一点,但是我不得不对其进行一些更改,因为我只是为了唯一性而传入一个集合,当我尝试将最后一个数字与更高的数字进行测试时,它就崩溃了.
【解决方案2】:

好吧,我走了很长的路:

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

【讨论】:

    【解决方案3】:

    如果您曾经在 Excel 中使用 VBA,您可以让它为您完成如下工作

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-22
      • 2012-09-16
      • 1970-01-01
      • 2010-12-21
      • 2023-03-03
      • 2015-12-15
      • 2013-09-16
      • 2016-10-26
      相关资源
      最近更新 更多