23

I'm presently populating my array Securities with the following code:

Option Base 1 Securities = Array(Worksheets(3).Range("A8:A" & SymbolCount).Value) 

This produces a 2-dimensional array where every address is (1...1,1...N). I want a 1-dimensional array (1...N).

How can I either (a) populate Securities as a 1-dimensional array, or, (b) efficiently strip Securities to a 1-dimensional array (I'm stuck at a with each loop).

4 Answers 4

76

I know you already accepted an answer but here is simpler code for you:

If you are grabbing a singe row (with multiple columns) then use:

Securities = application.transpose(application.transpose _ (Worksheets(3).Range("A8:A" & SymbolCount).Value)) 

If you are grabbing a single column (with multiple rows) then use:

Securities = application.transpose(Worksheets(3).Range("A8:A" & SymbolCount).Value) 

So, basically you just transpose twice for rows and once for columns.

Update:

Large tables might not work for this solution (as noted in the comment below):

I used this solution in a large table, and I found that there is a limitation to this trick: Application.Transpose(Range("D6:D65541").Value) 'runs without error, but Application.Transpose(Range("D6:D65542").Value) 'run-time error 13 Type mismatch

Update 2:

Another problem you might have as mentioned in the comments:

If one exceeds 255 characters, the function fails.

It has been a long time since I worked with Excel VBA but this might be a general limitation of accessing the data this way?

Sign up to request clarification or add additional context in comments.

9 Comments

Agreed that this is by far the easiest way to convert a row of data into 1d array
@Emma, I don't recall where I picked that trick up. But all I am doing is changing a 1xn matrix to nx1 which is just an array of n units. Not sure why the behavior is built into Excel to work that way. Many things in Excel aren't documented very well, it's such a large program!
I used this solution in a large table, and I found that there is a limitation to this trick: Application.Transpose(Range("D6:D65541").Value) 'runs without error, but Application.Transpose(Range("D6:D65542").Value) 'run-time error 13 Type mismatch
Transpose() can only handle a 1D array with up to 65,536 elements for the Excel 2007 and later versions of Excel.
I know this post is a bit old but your answer helped me. Still the best solution I've seen to achieve this!
|
4
Sub test2() Dim arTmp Dim securities() Dim counter As Long, i As Long arTmp = Range("a1").CurrentRegion counter = UBound(arTmp, 1) ReDim securities(1 To counter) For i = 1 To counter securities(i) = arTmp(i, 1) Next i MsgBox "done" End Sub 

6 Comments

Option (a) simply does not work. Proposed code should be quite fast anyway.
Sorry, newish to VBA, could you explain line 5?
As a general rule: in VBE, click on the keyword and press F1 to get help. Ubound(arTmp, 2) returns the Upper Bound of arTemp, in the 2d dimension, which is the column dimension. And now I understand your question: I may have done a mistake there... :-/
I get a "subscript out of range" error for the UBound line. The line 5 reference was inquiring about the CurrentRegion line - why is that necessary?
Ah, ok. No, it's not necessary. You can use arTmp = Range("A8:A" & SymbolCount) as well
|
3

This will reflect the answer iDevlop gave, but I wanted to give you some additional information on what it does.

Dim tmpArray As Variant Dim Securities As Variant 'Dump the range into a 2D array tmpArray = Sheets(3).Range("A8:A" & symbolcount).Value 'Resize the 1D array ReDim Securities(1 To UBound(tmpArray, 1)) 'Convert 2D to 1D For i = 1 To UBound(Securities, 1) Securities(i) = tmpArray(i, 1) Next 

Probably the fastest way to get a 1D array from a range is to dump the range into a 2D array and convert it to a 1D array. This is done by declaring a second variant and using ReDim to re-size it to the appropriate size once you dump the range into the first variant (note you don't need to use Array(), you can do it as I have above, which is more clear).

The you just loop through the 2D array placing each element in the 1D array.

I hope this helps.

2 Comments

I like the idea of bulk dumping it to 2D array. Is the looping really necessary to get 1D array? Wouldn't it be possible to ReDim Preserve the original 2D matrix?
Are you sure (1) we need two variant arrays one for 1D and second for 2D, (2) the looping through all the variables is the fastest way? Can't we just slice or somehow ReDim the original array chopping off one dimension from it?
2

If you read values from a single column into an array as you have it then I do think you will end up with an array that needs to be accessed using array(1, n) syntax.

Alternatively, you can loop through all cells in your data and add them into an array:

Sub ReadIntoArray() Dim myArray(), myData As Range, cl As Range, cnt As Integer, i As Integer Set myData = Worksheets(3).Range("A8:A" & SymbolCount) //Not sure how you get SymbolCount ReDim myArray(myData.Count) cnt = 0 For Each cl In myData myArray(cnt) = cl cnt = cnt + 1 Next cl For i = 0 To UBound(myArray) //Print out the values in the array as check... Debug.Print myArray(i) Next i End Sub 

6 Comments

Looping through cells is slower and less efficient than dumping them into a 2D array first.
@Issun - I agree with you. From my understading if you read in a single column range as an array then it has to be accessed using array(1, n) notation whereas OP wanted to be able to use array(n) notation.
Yep, that's correct. The fastest way to do this is to dump the entire range into a 2D array then convert it to a 1D array (I also posted a solution on how to do this). I've tested this many times, and it's much faster than looping over cells (which I also use to do), even though looping seems to be more straight-forward. :)
@Issun - do you have a link to your solution of converting 2D to 1D array? It would be good a learning opportunity for me...
I posted it on this question!
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.