What I'm trying to do is populate an ArrayList with .AddRange() in VBA using the last binding in native C # ArrayList , but I cannot figure out how to pass an object other than another ArrayList as an argument ... what - Something else that I tried so far is not successful ...
So basically what I am doing now (Note: list is C # ArrayList via mscorlib.dll)
Dim list as Object Set list = CreateObject("System.Collections.ArrayList") Dim i As Long For i = 1 To 5 list.Add Range("A" & i).Value2 Next
But it is quite inefficient and ugly if, for example, i can be = 500K .
In VBA, this also works:
ArrayList1.AddRange ArrayList2
But I really need / need to pass an array instead of ArrayList2
So I heard that I can pass an array to the .AddRange() parameter in .NET. I tested it in a small C # console application and it seemed like everything was fine. The following works great in a clean C # console application.
ArrayList list = new ArrayList(); string[] strArr = new string[1]; strArr[0] = "hello"; list.AddRange(strArr);
Therefore, returning to the VBA module trying to do the same, it fails.
Dim arr(1) As Variant arr(0) = "WHY!?" Dim arrr As Variant arrr = Range("A1:A5").Value list.AddRange arr ' Fail list.AddRange arrr ' Fail list.AddRange Range("A1:A5").Value ' Fail
Note. I tried to pass my own VBA array of options and Collection , ranges - all but another ArrayList failed.
How to pass own VBA array as parameter in ArrayList ?
Or any alternative to create a collection from a range without a loop
Bonus question: * Or maybe there is another built-in .Net COM Visible Collection that can be populated from a VBA Range Object or Array without a loop and already has .Reverse ?
NOTE: I know that I can make a .dll shell for this, but I am interested in my own solutions - if any .
Update
To better illustrate why I want to completely avoid explicit iteration, here is an example (only one column is used for simplicity)
Sub Main() ' Initialize the .NET ArrayList Dim list As Object Set list = CreateObject("System.Collections.ArrayList") ' There are two ways to populate the list. ' I selected this one as it more efficient than a loop on a small set ' For details, see: http://www.dotnetperls.com/array-optimization list.Add Range("A1") list.Add Range("A2") list.Add Range("A3") list.Add Range("A4") list.Add Range("A5") ' It OK with only five values but not with 50K. ' Alternative way to populate the list ' According to the above link this method has a worse performance 'Dim i As Long 'Dim arr2 As Variant 'arr2 = Range("A1:A5").Value2 'For i = 1 To 5 ' list.Add arr2(i, 1) 'Next ' Call native ArrayList.Reverse ' Note: no looping required! list.Reverse ' Get an array from the list Dim arr As Variant arr = list.ToArray ' Print reversed to Immediate Window 'Debug.Print Join(arr, Chr(10)) ' Print reversed list to spreadsheet starting at B1 Range("B1").Resize(UBound(arr) + 1, 1) = Application.Transpose(arr) End Sub
Please note: the only time I have to loop around is to populate the list (ArrayList), what I would like to do is just find a way to load arr2 into an ArrayList or other .NET compatible type without a loop.
At this point, I see that there is no built-in / built-in way to do this, so I think that I will try to implement my own method, and maybe if it works, send an update to the Interop library.