阵列vba的最大填充维度

时间:2010-05-06 13:45:02

标签: arrays excel vba excel-vba

假设我有一个单维数组(为了保持简单)。有没有一种简单的方法来判断明确赋值的元素的最高索引是什么?除了循环和计数? 我知道Ubound找到了数组的最高维度,但这不是我需要的。是否有类似Ubound的东西,但它只计算数组的填充元素,或填充的最高索引?

我的数组包含字符串。 此外,如果数组是多维的,那该怎么办呢。

我在excel vba工作。

5 个答案:

答案 0 :(得分:4)

简而言之,没有内置机制可以做到这一点,但如果你正在寻找一种方法来破解它,那么请继续阅读。

这取决于你如何填充数组。如果它是顺序的,最简单的就是有一个计数器。

如果它是随机的,那么你找到最后一个元素的确切索引会遇到更大的挑战。一个想法是从最大值开始并开始倒计时。

如果数组已初始化,则可以计算默认值并从ubound中减去。

还有其他想法,但您需要更清楚地定义问题,以便给我们更好的回答机会。最好是一个例子。

答案 1 :(得分:2)

我建议在填充数组时使用ReDim Preserve。因此,UBound将很适合你。只有多维数组中的最后一个维度可以重新调整。

答案 2 :(得分:2)

数组中最高的填充元素

你可以倒退一个循环,直到找到第一个不空的数组元素 这相当于" last"填充元素。

简答:

Function HighestPopIdx(ByRef arr) As Long
    For HighestPopIdx = UBound(arr) To LBound(arr) Step -1
        If Not IsEmpty(arr(HighestPopIdx)) Then Exit Function
    Next
End Function

更长的回答:

要获取 数组中最高的填充元素 ,我会使用 For..Next 循环 { {1}} 功能。

(为了演示,这个例子过于复杂了。)

IsEmpty

...或反过来(第一个例子可能会更快,具体取决于你的情况。

其他说明:

除了@ jtolle' answer之外,Sub demo() '(Hit CTRL+G in the VBE to view the output in the Immediate window.) 'Make a test ARRAY of 5 elements: Dim arr(1 To 5) Erase arr '(just to make sure the test is starting 'fresh') arr(1) = "X" arr(2) = 99 arr(4) = "Y" '3 of the 5 elements have data (highest one is 4) Dim elIdx As Long, highestPopEl As Long For elIdx = LBound(arr) To UBound(arr) If Not IsEmpty(arr(elIdx)) Then highestPopEl = elIdx Next elIdx Debug.Print "The highest populated element index is " & highestPopEl 'Returns 4 End Sub Count工作表函数都不起作用:

CountA

...还有评论,显示数组&细胞范围的功能相似,但相同:

    With Application.WorksheetFunction
        Debug.Print "Array WS CountA", .CountA(arr) 'returns 5 (Counts cells)
        Debug.Print "Array WS Count", .Count(arr) 'returns 1 (Counts numbers)
    End With

另一方面,如果我的"实际"目标是对数组中的每个元素执行某些操作,我会将 'Make a test RANGE of 5 cells Dim rge As Range Set rge = Range("A1:A5") rge.Clear '(maker sure we're starting fresh) Range("A1") = "X" Range("A2") = 99 Range("A4") = "Y" '3 of the 5 cells have data With Application.WorksheetFunction Debug.Print "Range WS CountA", .CountA(rge) 'returns 3 (Counts values) Debug.Print "Range WS Count", .Count(rge) 'returns 1 (Counts numbers) End With '... and the VBA [Range.Count] method behaves differently: Debug.Print "Range VBA .Count", rge.Count 'returns 5 (Counts cells) 循环与 For..Each 函数一起使用。

IsEmpty

完成输出:

    'if my actual purpose is to ***do something*** to an ARRAY...
    Debug.Print: Debug.Print "Array [For..Next] :"
    Dim elCnt As Long, el

    For Each el In arr
        If Not IsEmpty(el) Then _
            elCnt = elCnt + 1: Debug.Print "#" & elCnt & ": Element value =", el
    Next el    ' (returns "X", 99, "Y")

    '...and the identical method can be used on a RANGE of cells
    Debug.Print: Debug.Print "Range [For..Next] :"
    Dim clCnt As Long, cl

    For Each cl In rge
        If Not IsEmpty(cl) Then _
            clCnt = clCnt + 1: Debug.Print "#" & clCnt & ": Cell value =", cl
    Next cl    ' (returns "X", 99, "Y")


End Sub

更多信息:

答案 3 :(得分:1)

您可以考虑使用包含数组变量的自定义类,将数据项添加到数组中的代码也会修改另一个变量以跟踪“已使用”的索引号。然后你可以包含一个函数来返回存储的“最高索引”数字。

答案 4 :(得分:-1)

2018年的注释:这在Excel 365中是错误的,在Excel 2000中可能是错误的。请参阅注释。但是我把它作为一个例子来说明如何使用VBA中的Application.WorksheetFunction()与使用工作表中的公式完全不同。


当然,循环确实没什么问题,但是......

说你有这个:

Public Sub test()
    Dim a(1 To 3)

    a(1) = 1
    a(2) = "stuff"

    Debug.Print Application.WorksheetFunction.CountA(a)
End Sub

这将打印'2' [ *不,它会打印3 - 请参阅注释***],因为第三个元素具有默认值'空'。 (请注意,您的数组必须声明为Variant类型才能工作,但它可以包含String类型的元素。如果您的数组类型为String,则没有任何空格!)当然,这假设您知道你的所有容器都在最后,因为它只是在计算,而不是实际返回一个索引。出于同样的原因,您必须知道二维数组中值的分布才有意义。

我认为这正是您所需要的,基于您的编辑。