问题
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