So I have an Array called TagOptions - it contains numeric values according to a pervious if statement. In order to take out values I didn't want I gave the undesired values a place holder value of 0. I am now trying to filter out this value but can't find anything online that is helpful.
Will paste the entire function for context but more interested in just filtering out the placeholder zeros from my array.
Sorry if this is novice but I am very new to this:
Private Sub CommandButton4_Click()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("TEST")
lrow = sh.Cells(Rows.count, 1).End(xlUp).Row
Dim splitstring As String
Dim holder As String
Dim myarray() As String
Dim strArrayNumber() As Integer
Dim strArrayTag() As String
Dim TagOptions() As Integer
Dim TagOptions2() As Integer
ReDim strArrayNumber(1 To lrow) As Integer
ReDim strArrayTag(1 To lrow) As String
'Initial for loop splitting tags and removing any tags with text (MV-4005A)
'Transfering those remaining tag numbers into array if they match equip selected
For a = 1 To lrow
If sh.Cells(a, 1).Value <> vbNullString Then
splitstring = sh.Cells(a, 1).Value
myarray = Split(splitstring, "-")
strArrayTag(a) = myarray(0)
End If
If IsNumeric(myarray(1)) = False Then
myarray(1) = 0
End If
If strArrayTag(a) = TagNumber1.Value Then 'Only stored if has selected Equipment tag
strArrayNumber(a) = myarray(1)
End If
Next a
'Sort Created Array
Quicksort strArrayNumber, LBound(strArrayNumber), UBound(strArrayNumber)
ReDim TagOptions(1000 To 2000) As Integer
Dim j As Integer
For j = 1000 To 2000
For b = 1 To UBound(strArrayNumber)
If strArrayNumber(b) = j Then
TagOptions(j) = 0
Exit For
Else
TagOptions(j) = j
End If
Next b
sh.Cells(j, 8) = TagOptions(j)
Next j
Quicksort TagOptions, LBound(TagOptions), UBound(TagOptions)
For f = LBound(TagOptions) To UBound(TagOptions)
sh.Cells(f, 9) = TagOptions(f)
Next f
**TagOptions2 = Filter(TagOptions, "0", False, vbDatabaseCompare)**
Me.ComboBox1.List = TagOptions
End Sub
Thnak you in advance for any help.
tl;dr entire code, just note that VBA's Filter() function applied on a "flat" 1-dim array only executes a partial character search finding "0" also in strings like e.g. "10" or "205", what definitely isn't what you want to do :-;
Btw, if your initial array is a 2-dim array, there are number of answers at SO how to slice data from a 2-dim array and transpose or double transpose them to a 1-dim array needed as starting point.
Solving the actual core question how to filter out zero-digits
To succeed in filtering out zeros in a 1-dim array, simply use the following function via the Worksheetfunction FilterXML (available since vers. 2013+):
tagOptions = WorksheetFunction.FilterXML("<t><s>" & _
Join(tagOptions, "</s><s>") & "</s></t>", _
"//s[not(.='0')]")
resulting in a 1-based 2-dim array.
If you prefer, however to get a resulting 1-dim array instead, simply transpose it via tagOptions = Application.Transpose(tagOptions) or tagOptions = WorkSheetFunction.Transpose(tagOptions).
You can find an excellent overview at Extract substrings ... from FilterXML
Is it possible to create multi dimensional array with different element types (string and integer)?
I tried like this but wan't work
BT = Range("A12")
ReDim IT(BT) As String
ReDim RBT(BT) As Integer
ReDim IT_RBT(IT, RBT) as ???? how to create multi dim array with different variables type
Range("B2").Select
i = 0
Do
i = i + 1
IT(i) = ActiveCell
RBT(i) = i
IT_RBT(i, i) = ???? how to enter values in such array ????
ActiveCell.Offset(1, 0).Select
Loop While ActiveCell <> ""
Thank you
Use a Variant array.
Dim values() As Variant
Now, your code is making assumptions that should be removed.
BT = Range("A12") '<~ implicit: ActiveSheet.Range("A12").Value
If you mean to pull the value of A12 from a particular specific worksheet, then you should qualify that Range member call with a proper Worksheet object. See CodeName: Sheet1 for more info, but long story short if that sheet is in ThisWorkbook you can do this:
BT = Sheet1.Range("A12").Value
And now assumptions are gone. Right? Wrong. BT isn't declared (at least not here). If it's declared and it's not a Variant, then there's a potential type mismatch error with that assignment. In fact, the only data type that can accept any cell value, is Variant:
Dim BT As Variant
BT = Sheet1.Range("A12").Value
Here, we're assuming BT is a numeric value:
ReDim IT(BT) As String
That's another assumption. We don't know that BT is numeric. We don't even know that it's a value that can be coerced into a numeric data type: we should bail out if that's not the case:
If Not IsNumeric(BT) Then
MsgBox "Cell A12 contains a non-numeric value; please fix & try again."
Exit Sub
End If
ReDim IT(BT) As String
Now that will work... but then, only the upper bound is explicit; is this a 0-based or a 1-based array? If the module says Option Base 1, then it's 1-based. Otherwise, it's 0-based - implicit array lower bounds are an easy source of "off-by-one" bugs (like how you're populating the arrays starting at index 1, leaving index 0 empty). Always make array bounds explicit:
ReDim IT(1 To BT) As String
Unclear why you need 3 arrays at all, and why you're only populating (i,i) in the 3rd one - you cannot populate a 2D array with a Do...Loop structure; you need every value of y for each value of x, and unless you hard-code the width of the array, that's a nested loop.
Moreover, looping on the ActiveCell and Selecting an Offset is making the code 1) very hard to follow, and 2) incredibly inefficient.
Consider:
Dim lastRow As Long
lastRow = Sheet1.Range("B" & Sheet1.Rows).End(xlUp).Row
ReDim values(1 To lastRow, 1 To 2) As Variant
Dim currentRow As Long
For currentRow = 2 To lastRow
Dim currentColumn As Long
For currentColumn = 1 To 2
values(currentRow, currentColumn) = Sheet1.Cells(currentRow, currentColumn).Value
Next
Next
Now, if we don't need any kind of logic in that loop and all we want is to grab a 2D variant array that contains every cell in B2:B???, then we don't need any loops:
Dim values As Variant
values = Sheet1.Range("A2:B" & lastRow).Value
And done: values is a 1-based (because it came from a Range), 2D variant array that contains the values of every cell in A2:B{lastRow}.
Note, code that consumes this array will need to avoid assumptions about the data types in it.
As #SJR has said, variant will allow for this. The below example is a easy example how to add different types to an array. Instead of x or y you can have a cell on a worksheet.
Dim array1() As Variant, i As Long
Dim x As String, y As Long
x = "5"
y = 1
For i = 1 To 10
ReDim Preserve array1(1 To 2, 1 To i)
array1(1, i) = x
array1(2, i) = y
y = y + 1
Debug.Print array1(1, i) & "," & array1(2, i) ' This is where you insert output
Next
You can do this:
BT = Range("A12")
ReDim IT(BT) As String
ReDim RBT(BT) As Integer
Dim IT_RBT(1 to 2) 'variant
IT_RBT(1) = IT 'add String array
IT_RBT(2) = RBT 'add Integer array
... this will keep your typed arrays functional but it's not a 2D array and you'd need to use notation like
IT_RBT(1)(1) 'String type
IT_RBT(2)(1) 'Integer type
I'm working with arrays and I'm sorry but I'm a bit new to it and still confused. I have already this code to store the values in a range in an array and if I run it, it is empty.
attPresent = ws.Range("H4:H" & lastrow)
ReDim attPresent(1 To UBound(attPresent))
For k = LBound(attPresent) To UBound(attPresent)
MsgBox attPresent(k)
Next
Can someone please tell me where I'm wrong? I've read any other posts and gather some ideas, but still not working.
You can go like this
Dim attPresent as Variant
attPresent = ws.Range("H4:H" & lastrow).Value '<-- this will automatically size the array to a 2dimensional array of as many rows as the range ones and one column
For k = LBound(attPresent,1) To UBound(attPresent,1)
MsgBox attPresent(k,1)
Next
Or
Dim attPresent as Variant
attPresent=Application.Transpose(Range("H4:H" & lastrow).Value) '<-- this will automatically size the array to a 1dimensional array of as many elements as the range
For k = LBound(attPresent) To UBound(attPresent)
MsgBox attPresent(k)
Next
Reference MSDN: ReDim Statement (Visual Basic)
When you Redim the array you are erasing all the values. Use ReDim Preserve to resize the last dimension of the Array and still preserve the values of the array.
After the dynamic array has been allocated(the first time Redim is used) you can only resize the last dimension of a array and you cannot change the number of dimensions. In your code you are trying to convert a 2 Dimensional array to a 1 Dimensional array, you can not do that.
You should watch this complete series: Excel VBA Introduction. This is the relevant video: Excel VBA Introduction Part 25 - Arrays
'Try this code example to suit your case
Sub StoreRangeofCellsToAnArray()
'presumes optionbase=0
'presume Range("a1:c3") contain number 1 to 9
Dim MyRange, MyArray(9), n
n = 0
For Each c In Range("a1:c3")
MyArray(n) = c
n = n + 1
Next
'testing: reprint array
For n = 0 To 8
Debug.Print MyArray(n)
Next
End Sub
I'm using VB6 and I need to do a ReDim Preserve to a Multi-Dimensional Array:
Dim n, m As Integer
n = 1
m = 0
Dim arrCity() As String
ReDim arrCity(n, m)
n = n + 1
m = m + 1
ReDim Preserve arrCity(n, m)
Whenever I do it as I have written it, I get the following error:
runtime error 9: subscript out of range
Because I can only change the last array dimension, well in my task I have to change the whole array (2 dimensions in my example) !
Is there any workaround or another solution for this?
As you correctly point out, one can ReDim Preserve only the last dimension of an array (ReDim Statement on MSDN):
If you use the Preserve keyword, you can resize only the last array
dimension and you can't change the number of dimensions at all. For
example, if your array has only one dimension, you can resize that
dimension because it is the last and only dimension. However, if your
array has two or more dimensions, you can change the size of only the
last dimension and still preserve the contents of the array
Hence, the first issue to decide is whether 2-dimensional array is the best data structure for the job. Maybe, 1-dimensional array is a better fit as you need to do ReDim Preserve?
Another way is to use jagged array as per Pieter Geerkens's suggestion. There is no direct support for jagged arrays in VB6. One way to code "array of arrays" in VB6 is to declare an array of Variant and make each element an array of desired type (String in your case). Demo code is below.
Yet another option is to implement Preserve part on your own. For that you'll need to create a copy of data to be preserved and then fill redimensioned array with it.
Option Explicit
Public Sub TestMatrixResize()
Const MAX_D1 As Long = 2
Const MAX_D2 As Long = 3
Dim arr() As Variant
InitMatrix arr, MAX_D1, MAX_D2
PrintMatrix "Original array:", arr
ResizeMatrix arr, MAX_D1 + 1, MAX_D2 + 1
PrintMatrix "Resized array:", arr
End Sub
Private Sub InitMatrix(a() As Variant, n As Long, m As Long)
Dim i As Long, j As Long
Dim StringArray() As String
ReDim a(n)
For i = 0 To n
ReDim StringArray(m)
For j = 0 To m
StringArray(j) = i * (m + 1) + j
Next j
a(i) = StringArray
Next i
End Sub
Private Sub PrintMatrix(heading As String, a() As Variant)
Dim i As Long, j As Long
Dim s As String
Debug.Print heading
For i = 0 To UBound(a)
s = ""
For j = 0 To UBound(a(i))
s = s & a(i)(j) & "; "
Next j
Debug.Print s
Next i
End Sub
Private Sub ResizeMatrix(a() As Variant, n As Long, m As Long)
Dim i As Long
Dim StringArray() As String
ReDim Preserve a(n)
For i = 0 To n - 1
StringArray = a(i)
ReDim Preserve StringArray(m)
a(i) = StringArray
Next i
ReDim StringArray(m)
a(n) = StringArray
End Sub
Since VB6 is very similar to VBA, I think I might have a solution which does not require this much code to ReDim a 2-dimensional array - using Transpose, if you are working in Excel.
The solution (Excel VBA):
Dim n, m As Integer
n = 2
m = 1
Dim arrCity() As Variant
ReDim arrCity(1 To n, 1 To m)
m = m + 1
ReDim Preserve arrCity(1 To n, 1 To m)
arrCity = Application.Transpose(arrCity)
n = n + 1
ReDim Preserve arrCity(1 To m, 1 To n)
arrCity = Application.Transpose(arrCity)
What is different from OP's question: the lower bound of arrCity array is not 0, but 1. This is in order to let Application.Transpose do it's job.
Note that Transpose is a method of the Excel Application object (which in actuality is a shortcut to Application.WorksheetFunction.Transpose). And in VBA, one must take care when using Transpose as it has two significant limitations: If the array has more than 65536 elements, it will fail. If ANY element's length exceed 256 characters, it will fail. If neither of these is an issue, then Transpose will nicely convert the rank of an array form 1D to 2D or vice-versa.
Unfortunately there is nothing like 'Transpose' build into VB6.
In regards to this:
"in my task I have to change the whole array (2 dimensions"
Just use a "jagged" array (ie an array of arrays of values). Then you can change the dimensions as you wish. You can have a 1-D array of variants, and the variants can contain arrays.
A bit more work perhaps, but a solution.
I haven't tested every single one of these answers but you don't need to use complicated functions to accomplish this. It's so much easier than that! My code below will work in any office VBA application (Word, Access, Excel, Outlook, etc.) and is very simple. Hope this helps:
''Dimension 2 Arrays
Dim InnerArray(1 To 3) As Variant ''The inner is for storing each column value of the current row
Dim OuterArray() As Variant ''The outer is for storing each row in
Dim i As Byte
i = 1
Do While i <= 5
''Enlarging our outer array to store a/another row
ReDim Preserve OuterArray(1 To i)
''Loading the current row column data in
InnerArray(1) = "My First Column in Row " & i
InnerArray(2) = "My Second Column in Row " & i
InnerArray(3) = "My Third Column in Row " & i
''Loading the entire row into our array
OuterArray(i) = InnerArray
i = i + 1
Loop
''Example print out of the array to the Intermediate Window
Debug.Print OuterArray(1)(1)
Debug.Print OuterArray(1)(2)
Debug.Print OuterArray(2)(1)
Debug.Print OuterArray(2)(2)
I know this is a bit old but I think there might be a much simpler solution that requires no additional coding:
Instead of transposing, redimming and transposing again, and if we talk about a two dimensional array, why not just store the values transposed to begin with. In that case redim preserve actually increases the right (second) dimension from the start. Or in other words, to visualise it, why not store in two rows instead of two columns if only the nr of columns can be increased with redim preserve.
the indexes would than be 00-01, 01-11, 02-12, 03-13, 04-14, 05-15 ... 0 25-1 25 etcetera instead of 00-01, 10-11, 20-21, 30-31, 40-41 etcetera.
As long as there is only one dimension that needs to be redimmed-preserved the approach would still work: just put that dimension last.
As only the second (or last) dimension can be preserved while redimming, one could maybe argue that this is how arrays are supposed to be used to begin with.
I have not seen this solution anywhere so maybe I'm overlooking something?
(Posted earlier on similar question regarding two dimensions, extended answer here for more dimensions)
You can use a user defined type containing an array of strings which will be the inner array. Then you can use an array of this user defined type as your outer array.
Have a look at the following test project:
'1 form with:
' command button: name=Command1
' command button: name=Command2
Option Explicit
Private Type MyArray
strInner() As String
End Type
Private mudtOuter() As MyArray
Private Sub Command1_Click()
'change the dimensens of the outer array, and fill the extra elements with "1"
Dim intOuter As Integer
Dim intInner As Integer
Dim intOldOuter As Integer
intOldOuter = UBound(mudtOuter)
ReDim Preserve mudtOuter(intOldOuter + 2) As MyArray
For intOuter = intOldOuter + 1 To UBound(mudtOuter)
ReDim mudtOuter(intOuter).strInner(intOuter) As String
For intInner = 0 To UBound(mudtOuter(intOuter).strInner)
mudtOuter(intOuter).strInner(intInner) = "1"
Next intInner
Next intOuter
End Sub
Private Sub Command2_Click()
'change the dimensions of the middle inner array, and fill the extra elements with "2"
Dim intOuter As Integer
Dim intInner As Integer
Dim intOldInner As Integer
intOuter = UBound(mudtOuter) / 2
intOldInner = UBound(mudtOuter(intOuter).strInner)
ReDim Preserve mudtOuter(intOuter).strInner(intOldInner + 5) As String
For intInner = intOldInner + 1 To UBound(mudtOuter(intOuter).strInner)
mudtOuter(intOuter).strInner(intInner) = "2"
Next intInner
End Sub
Private Sub Form_Click()
'clear the form and print the outer,inner arrays
Dim intOuter As Integer
Dim intInner As Integer
Cls
For intOuter = 0 To UBound(mudtOuter)
For intInner = 0 To UBound(mudtOuter(intOuter).strInner)
Print CStr(intOuter) & "," & CStr(intInner) & " = " & mudtOuter(intOuter).strInner(intInner)
Next intInner
Print "" 'add an empty line between the outer array elements
Next intOuter
End Sub
Private Sub Form_Load()
'init the arrays
Dim intOuter As Integer
Dim intInner As Integer
ReDim mudtOuter(5) As MyArray
For intOuter = 0 To UBound(mudtOuter)
ReDim mudtOuter(intOuter).strInner(intOuter) As String
For intInner = 0 To UBound(mudtOuter(intOuter).strInner)
mudtOuter(intOuter).strInner(intInner) = CStr((intOuter + 1) * (intInner + 1))
Next intInner
Next intOuter
WindowState = vbMaximized
End Sub
Run the project, and click on the form to display the contents of the arrays.
Click on Command1 to enlarge the outer array, and click on the form again to show the results.
Click on Command2 to enlarge an inner array, and click on the form again to show the results.
Be careful though: when you redim the outer array, you also have to redim the inner arrays for all the new elements of the outer array
I stumbled across this question while hitting this road block myself. I ended up writing a piece of code real quick to handle this ReDim Preserve on a new sized array (first or last dimension). Maybe it will help others who face the same issue.
So for the usage, lets say you have your array originally set as MyArray(3,5), and you want to make the dimensions (first too!) larger, lets just say to MyArray(10,20). You would be used to doing something like this right?
ReDim Preserve MyArray(10,20) '<-- Returns Error
But unfortunately that returns an error because you tried to change the size of the first dimension. So with my function, you would just do something like this instead:
MyArray = ReDimPreserve(MyArray,10,20)
Now the array is larger, and the data is preserved. Your ReDim Preserve for a Multi-Dimension array is complete. :)
And last but not least, the miraculous function: ReDimPreserve()
'redim preserve both dimensions for a multidimension array *ONLY
Public Function ReDimPreserve(aArrayToPreserve,nNewFirstUBound,nNewLastUBound)
ReDimPreserve = False
'check if its in array first
If IsArray(aArrayToPreserve) Then
'create new array
ReDim aPreservedArray(nNewFirstUBound,nNewLastUBound)
'get old lBound/uBound
nOldFirstUBound = uBound(aArrayToPreserve,1)
nOldLastUBound = uBound(aArrayToPreserve,2)
'loop through first
For nFirst = lBound(aArrayToPreserve,1) to nNewFirstUBound
For nLast = lBound(aArrayToPreserve,2) to nNewLastUBound
'if its in range, then append to new array the same way
If nOldFirstUBound >= nFirst And nOldLastUBound >= nLast Then
aPreservedArray(nFirst,nLast) = aArrayToPreserve(nFirst,nLast)
End If
Next
Next
'return the array redimmed
If IsArray(aPreservedArray) Then ReDimPreserve = aPreservedArray
End If
End Function
I wrote this in like 20 minutes, so there's no guarantees. But if you would like to use or extend it, feel free. I would've thought that someone would've had some code like this up here already, well apparently not. So here ya go fellow gearheads.
This is more compact and respect the intial first position in array and just use the inital bound to add old value.
Public Sub ReDimPreserve(ByRef arr, ByVal size1 As Long, ByVal size2 As Long)
Dim arr2 As Variant
Dim x As Long, y As Long
'Check if it's an array first
If Not IsArray(arr) Then Exit Sub
'create new array with initial start
ReDim arr2(LBound(arr, 1) To size1, LBound(arr, 2) To size2)
'loop through first
For x = LBound(arr, 1) To UBound(arr, 1)
For y = LBound(arr, 2) To UBound(arr, 2)
'if its in range, then append to new array the same way
arr2(x, y) = arr(x, y)
Next
Next
'return byref
arr = arr2
End Sub
I call this sub with this line to resize the first dimension
ReDimPreserve arr2, UBound(arr2, 1) + 1, UBound(arr2, 2)
You can add an other test to verify if the initial size is not upper than new array. In my case it's not necessary
Easiest way to do this in VBA is to create a function that takes in an array, your new amount of rows, and new amount of columns.
Run the below function to copy in all of the old data back to the array after it has been resized.
function dynamic_preserve(array1, num_rows, num_cols)
dim array2 as variant
array2 = array1
reDim array1(1 to num_rows, 1 to num_cols)
for i = lbound(array2, 1) to ubound(array2, 2)
for j = lbound(array2,2) to ubound(array2,2)
array1(i,j) = array2(i,j)
next j
next i
dynamic_preserve = array1
end function
Function Redim2d(ByRef Mtx As Variant, ByVal QtyColumnToAdd As Integer)
ReDim Preserve Mtx(LBound(Mtx, 1) To UBound(Mtx, 1), LBound(Mtx, 2) To UBound(Mtx, 2) + QtyColumnToAdd)
End Function
'Main Code
sub Main ()
Call Redim2d(MtxR8Strat, 1) 'Add one column
end sub
'OR
sub main2()
QtyColumnToAdd = 1 'Add one column
ReDim Preserve Mtx(LBound(Mtx, 1) To UBound(Mtx, 1), LBound(Mtx, 2) To UBound(Mtx, 2) + QtyColumnToAdd)
end sub
If you not want include other function like 'ReDimPreserve' could use temporal matrix for resizing. On based to your code:
Dim n As Integer, m As Integer, i as Long, j as Long
Dim arrTemporal() as Variant
n = 1
m = 0
Dim arrCity() As String
ReDim arrCity(n, m)
n = n + 1
m = m + 1
'VBA automatically adapts the size of the receiving matrix.
arrTemporal = arrCity
ReDim arrCity(n, m)
'Loop for assign values to arrCity
For i = 1 To UBound(arrTemporal , 1)
For j = 1 To UBound(arrTemporal , 2)
arrCity(i, j) = arrTemporal (i, j)
Next
Next
If you not declare of type VBA assume that is Variant.
Dim n as Integer, m As Integer
Is there any way to return the value of an entire row of a multidimensional array to a one dimensional array In VBA?
Something like, arr_1dim = arr_2dim(3,:) is a matlab expression for assigning the row 3 of arr_2dim array to arr_1dim in one single stretch.
Is there any similar less expensive method in Excel VBA?
There is a simple way to get a column or a row of a two-dimensional array. Assign a zero to column to get the row, or assign a zero to row to get the column, thus:
Application.WorksheetFunction.Index(array, 0, columnyouwant) /* or */
Application.WorksheetFunction.Index(array, rowyouwant, 0)
See here:
How do I slice an array in Excel VBA?
No there is no VBA-function to get a row or column. You can only write it yourself, or take a look here:
http://www.cpearson.com/excel/vbaarrays.htm
This is what I do to easily print out one dimension of a multidimensional array.
Basically, I define a new, 1D array and stuff it with the values from the bigger array.
Example (3D to 1D to Printout):
Sub PrintItOut()
ReDim big_array(10,5,n) as Variant, small_array(n) as Variant
'use multidimensional array
'place multi-dimensional values into the 1D array
For i = 0 to n
small_array(i) = big_array(0, 0, i)
Next
Range(Cells(1, 1), Cells(1, n + 1)) = small_array
End Sub
That's how I do it. I hope that makes sense to whoever may be reading it. I think it's a very simple way to do it.
Matlab is such an awesome application to work when it comes to matrices, arrays, vectors... ;) But Excel is not that bad, it too is matrix based.
So Assuming you do not want to loop through. You may simply ouput your multi-D array into a worksheet using Transpose function.
Then pull a Row to your desired range size into an array using Transpose.
Dim vArr as Variant
'--output multi-D array into worksheet
Sheets(2).Range("E2").Resize(UBound(multiDArray) + 1, _
UBound(Application.Transpose(multiDArray))) = multiDArray
'--pull back the row you need: we double transpose here to get 1D. Coz single transpose
'-- results in 2D array..
vArr = WorksheetFunctions.Transpose( _
WorksheetFunctions.Transpose(Sheets(1).Range("A2:G2").Value))
To be absolutely dynamic, you may resize your range A2:G2 with a dynamic row count using the multi-D array row upperbound :)
Since I had this question by myself recently, I want to share my code. I wrote a ready-to-use function where you can choose if you want a column or a row to be extracted:
'*** Modul 1, define function ***
Function getOneLine(array2D As Variant, lineIndex As Integer, choice As String) As Variant
' returning one column or row of a 2D array
' array2D: 2 dimensional Array
' lineIndex: the index of column or row, starting at 0
' choice: "c" for column or "r" for row
Dim i, n As Integer
Dim oneLine As Variant
If choice = "c" Then
n = UBound(array2D, 2)
ReDim oneLine(n)
For i = 0 To n
oneLine(i) = array2D(lineIndex, i)
Next
getOneLine = oneLine
End If
If choice = "r" Then
n = UBound(array2D, 1)
ReDim oneLine(n)
For i = 0 To n
oneLine(i) = array2D(i, lineIndex)
Next
getOneLine = oneLine
End If
End Function
'*** Modul 2, call function ***
Sub SomeProcess()
' Creating a 3x2 Matrix
' (In VBA-arrays the column is indexed before the rows
' starting at 0. So 3x2 looks like 1x2)
Dim SomeArray(1, 2) As Variant
SomeArray(0, 0) = 1
SomeArray(0, 1) = 2
SomeArray(0, 2) = 3
SomeArray(1, 0) = 4
SomeArray(1, 1) = 5
SomeArray(1, 2) = 6
Dim oneLine As Variant
oneLine = getOneLine(SomeArray, 1, "c")
Debug.Print oneLine(2)
' prints 6
End Sub
A way to do something close:
ReDim TwoDim(10) As Variant
TwoDim(2) = Array("a", "b")
Debug.Print TwoDim(2)(1) 'Shows "a"
Debug.Print Join(TwoDim(2), "") 'Shows "ab"