Force the creation and “looping” of single element arrays? (VBA)

℡╲_俬逩灬. 提交于 2021-02-10 17:58:54

问题


I hope to find a compressed solution to array handling over having to duplicate large sections of code only to handle lists of 1 element. (0 element is not a big problem because that needs no execution)

If I create

testRange As Variant 
testRange = .ListColumns(2).DataBodyRange.Value2 'Case only 1 row in list
IsArray(testRange) 'FALSE!

I have tried

testRange() As Variant
testRange() As String
...

Is there a way to force VBA to create Array also if only 1 elements are fed? After that is there a way to error-free use either:

For i = LBound(testRange) To UBound(testRange)

Or

For each i in testRange

With that 1 member Array, without writing a specific exception only for the sake of 1 member lists?

If none i might return to "good old" method:

For each cell in .ListColumns(2).DataBodyRange  

The only drawback to this is a bit slower execution, right?


EDIT: Nice ideas from @CallumDA
I need some more hints to understand this better, and make it work. I have tested with:

Public Sub Test2()
    Dim testRange As Variant
    With Sheet1.ListObjects(1).ListColumns(2).DataBodyRange
        testRange = IIf(.Count = 1, Array(.Value2), .Value2)
    End With
    For i = (LBound(testRange)) To (UBound(testRange))
        Debug.Print i & " : " ' & testRange(i, 1)
    Next
End Sub

Why is it so that when there is 1 element, i starts with 0, BUT when there are multiple elements, i starts with 1 ?

Also why is it so, that testRange(i, 1) gives a "Suscript out of range" error? (in case of the 1 element scenario) How should I test the values, that is accepted in both cases?


Sidenote: I have made a performance comparison between this array approach and the "each elements" approach to see if it is worth the effort at all. In case of a 3000 element table list the difference was 2ms vs. 10ms (So it really is a big difference in terms of multiplier, but luckily also the slower is fast enough for my scenario.)

For i = (LBound(testRange)) To (UBound(testRange))
         If testRange(i, 1) = "kaslkfjghh" Then 
VS.
For Each cell In Sheet1.ListObjects(2).ListColumns(1).DataBodyRange
         If cell.Value2 = "kaslkfjghh" Then 

回答1:


You can use Array to force the element into an array. If there's only ever one element in your ListColumn then use this:

Public Sub Test()
    Dim testRange As Variant
    testRange = Array(Sheet1.ListObjects(1).ListColumns(2).DataBodyRange.Value2)
    Debug.Print IsArray(testRange)
End Sub

If you sometimes have more than one in your ListColumn then use something like this instead:

Public Sub Test()
    Dim testRange As Variant
    With Sheet1.ListObjects(1).ListColumns(2).DataBodyRange
        testRange = IIf(.Count = 1, Array(.Value2), .Value2)
    End With
    Debug.Print IsArray(testRange)
End Sub


来源:https://stackoverflow.com/questions/48851472/force-the-creation-and-looping-of-single-element-arrays-vba

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!