How to get range of cells into a specific array dimension - vba
I need to get a range of cells into an array, which by itself is simple enough:
Dim matchArray As Variant
matchArray = Sheets(lookupSheet).Range("B2:B12000").Value2
This creates a two-dimensional array with one column as the second dimension and if you expand the range to include a second column it creates a two-dimensional array with two columns for the second dimension:
matchArray = Sheets(lookupSheet).Range("B2:C12000").Value2
But what if the two columns aren't next to each other and you don't want the one in the middle?
matchArray = Sheets(lookupSheet).Range("B2:B12000,D2:D12000").Value2
The above would be my best guess but it doesn't work, it only returns the first range specified.
So what I need is a way to return a range cell values into a specific dimension of the array.
I know I could do it by looping through the rows but that would take far too long with the number of rows I'm going to be working with.
You do need a loop -- but loop over VBA arrays rather than individual cells:
Sub Test()
Dim A As Variant, B As Variant, C As Variant
Dim i As Long
B = Sheets(lookupSheet).Range("B2:B12000").Value2
C = Sheets(lookupSheet).Range("D2:D12000").Value2
ReDim A(1 To 11999, 1 To 2)
For i = 1 To 11999
A(i, 1) = B(i, 1)
A(i, 2) = C(i, 2)
Next i
'do stuff with A
End Sub
This should only take a fraction of a second.
You can do it with a ragged array:
Dim var1(1 To 2) As Variant
Dim var As Variant
var = Range("A1:A10").Value2
var1(1) = var
var = Range("c1:c10").Value2
var1(2) = var
MsgBox var1(1)(3, 1)
Here are a couple more ways:
Sub Example1()
Const lookupSheet As String = "Sheet1"
Dim matchArray As Variant, arr1 As Variant, arr2 As Variant
With Sheets(lookupSheet)
arr1 = WorksheetFunction.Transpose(.Range("B2:B12000").Value2)
arr2 = WorksheetFunction.Transpose(.Range("D2:D12000").Value2)
matchArray = WorksheetFunction.Transpose(Array(arr1, arr2))
End With
End Sub
Sub Example2()
Const lookupSheet As String = "Sheet1"
Dim matchArray As Variant
Dim x As Long
With Sheets(lookupSheet)
matchArray = .Range("B2:B12000").Resize(, 2).Value2
For Each v In .Range("D2:D12000").Value2
x = x + 1
matchArray(x, 2) = v
Next
End With
End Sub
Probably no quicker than John Coleman's answer, but I think this does what you want.
Sub x()
Dim matchArray, r As Range
Set r = Sheets(lookupSheet).Range("B2:D12000")
matchArray = Application.Index(r, Evaluate("Row(1:" & r.Rows.Count & ")"), Array(1, 3))
End Sub
Related
Format cells with the same values split by a delimiter, but a different order in VBA
I am a VBA beginner, who cannot seem to find a solution to what seemed to be a very easy comparison to me at first. Basically, I have 2 columns where the values in the cells are split by a delimiter, however, not in the same order. eg. Range("A1").value = "1234|5678" Range("B1").value = "5678|1234" B1 should then be highlighted as a duplicate I am searching for some vba code which I can use to loop through the used range's in Columns A & B, to compare and highlight cells in column B that are duplicated, as per example above. Apologies if I missed any similar questions asked and answered previously, I have indeed conducted a search but perhaps my search criteria may have been out of bounds, and I simply did not come across the VBA solution. Regards, Enjay
Based on the little information given you could try the following code Sub Highlight() Const DELIMITER = "|" Dim rg As Range Dim a As Variant Dim b As Variant Dim sngCell As Range Set rg = Range("A1:A3") For Each sngCell In rg a = Split(sngCell.Value2, DELIMITER) b = Split(sngCell.Offset(, 1).Value2, DELIMITER) If isEqual(a, b) Then With sngCell.Offset(, 1).Interior .ThemeColor = xlThemeColorAccent6 End With End If Next sngCell End Sub with the following functions Function isEqual(a As Variant, b As Variant) As Boolean a = BubbleSort(a) b = BubbleSort(b) isEqual = True Dim i As Long For i = LBound(a) To UBound(a) If a(i) <> b(i) Then isEqual = False Exit For End If Next i End Function Function BubbleSort(ByRef strArray As Variant) As Variant 'sortieren von String Array 'eindimensionale Array 'Bubble-Sortier-Verfahren Dim z As Long Dim i As Long Dim strWert As Variant For z = UBound(strArray) - 1 To LBound(strArray) Step -1 For i = LBound(strArray) To z If LCase(strArray(i)) > LCase(strArray(i + 1)) Then strWert = strArray(i) strArray(i) = strArray(i + 1) strArray(i + 1) = strWert End If Next i Next z BubbleSort = strArray End Function
This will answer your question as-is. If the solution needs to be adjusted, I trust that you can fix it :) This uses StrComp to (in memory only) re-order the two string parts so that it can easily detect duplicate values. Option Explicit Sub DuplicateCheck() Dim delimiter As String delimiter = "|" Dim lastCol As Long lastCol = Cells(1, Columns.count).End(xlToLeft).Column Dim dict As Object Set dict = CreateObject("Scripting.Dictionary") Dim i As Long For i = 1 To lastCol Dim theSplit As Variant theSplit = Split(Cells(1, i), delimiter) Dim temp As String If StrComp(theSplit(0), theSplit(1), vbTextCompare) = 1 Then temp = theSplit(1) theSplit(1) = theSplit(0) theSplit(0) = temp End If temp = theSplit(0) & delimiter & theSplit(1) If Not dict.exists(temp) Then dict.Add (temp), 1 Else Cells(1, i).Interior.color = 65535 End If Next i End Sub
How do i dim values in an array as arrays?
just out of curiosity. is it possible to dim values in an array as their own individual array? Sub test() Dim ar(5) As Variant ar(1) = a ar(2) = b ar(3) = c ar(4) = d ar(5) = e For i = 1 To UBound(ar) Dim ar(i) As Variant '<---doesn't work :( Next i End Sub
If you're after a matrix style array, then you could just define a multi-dimensional array: Dim ar(5, x) As Variant But it seems as though you want a jagged array, ie an array of arrays. In that case you just assign an Array() Variant to each element of your array: Dim ar(5) As Variant ar(0) = Array(1, 2, 3) And the syntax to access the 'sub-elements' would be ar(x)(y): Debug.Print ar(0)(1)
You should be able to set one (or more) position of a Variant array to be an array: Sub test() Dim ar(5) As Variant Dim ar1(1 To 4) As Variant ar1(1) = 5 ar1(2) = "x" Set ar1(3) = ActiveSheet ar1(4) = 10 ar(1) = "a" ar(2) = "b" ar(3) = ar1 ar(4) = "d" ar(5) = "e" Debug.Print ar(1) Debug.Print ar(3)(1) Debug.Print ar(3)(3).Name End Sub
VBA to extract names from a list at random isn't working
I want to randomly extract 280 names from a list (dynamic range) of thousands of authors, then concatenate them into 1 string with each name separated by OR. So far I'm stuck at the first part. When I run the following code, nothing happens. Can anyone explain why? Thanks. Sub Authors() Dim InputRange As Range Dim AuthorCount As Long Dim AuthorRange As Excel.Range Set InputRange = Range("A:A") AuthorCount = Application.WorksheetFunction.CountA(InputRange) - 1 Set AuthorRange = ThisWorkbook.Worksheets("Sheet").Range("A2:A" & AuthorCount) Const nItemsToPick As Long = 280 Dim Authorlist As Variant Dim i As Long ReDim Authorlist(1 To nItemsToPick) For i = 1 To nItemsToPick Authorlist(i) = AuthorRange.Cells(Int(AuthorCount * Rnd + 1), 1) Next i End Sub
Using the below code Sub PickSample(intSampleSize As Integer, intPicks As Integer) Dim arr() As String Dim intCounter As Integer ReDim arr(intPicks) For intCounter = 0 To UBound(arr) arr(intCounter) = CStr(Int((intSampleSize - (i - 1)) * Rnd + 1) + (i - 1)) Next intCounter Debug.Print Join(arr(), ",") End Sub I ran this on the following, PickSample(10,5) and got the following, showing the duplicate possibilities, this will become less as the difference between picks and samples increases. 9,9,6,10,10,2 5,3,6,7,2,3 10,4,5,8,0,6 9,8,4,10,9,0 0,8,8,7,0,4 7,5,6,3,3,8 If your selection is 280, but the data set is only 300, dupes still arise PickSample 300,280 228,**92**,248,216,269,66,**107**,166,**107**,61,174,189,41,18,190,252,192,127,56,149,292,231,114,145,164,202,11,194,270,102,35,128,232,**107**,124,225,131,216,152,52,83,26,294,85,186,**92**,256,96,239,52,90,21,148,136,179,9,95,40,98,228,188,290,249,166,182,57,271,95,180,179,230,215,206,228,77,165,153,170,84,125,105,292,156,175,139,9,113,41,196,46,59,112,28,185,211,132,126,101,210,64,13,266,13,138,222,227,247,63,141,261,249,123,139,105,75,242,163,162,188,26,214,77,17,82,289,98,194,109,111,98,64,63,127,185,72,206,177,181,23,13,46,74,120,175,86,251,270,158,116,0,75,49,194,295,93,72,264,39,171,182,183,208,255,29,118,247,80,204,119,251,130,251,65,220,270,65,295,290,262,157,195,137,47,193,184,257,110,15,152,16,112,135,89,291,3,195,184,160,8,215,94,295,87,109,96,106,70,178,211,80,173,173,298,280,75,243,231,122,189,148,150,40,291,53,177,205,32,195,222,234,129,24,150,172,17,124,35,43,94,298,181,82,125,141,19,137,131,284,82,52,152,103,154,119,78,20,192,109,164,265,127,178,114,17,32,43,43,228,79,41,12,208,254,155,240,296,157,20,188,99,83 4,50,49,153,122,31,83,193,255,149,56,269,112,97,232,65,134,71,264,183,112,117,259,176,280,155,99,261,77,78,53,104,0,223,253,83,211,121,244,223,131,23,123,102,213,93,240,45,178,287,73,282,34,296,190,180,271,173,73,258,22,132,228,73,113,119,158,81,174,63,23,269,33,196,271,69,285,254,132,148,231,251,115,58,98,124,45,186,29,61,208,151,55,298,141,1,128,86,226,268,247,53,32,3,45,113,56,294,262,175,219,43,77,8,249,235,238,100,135,167,241,169,61,62,109,172,103,158,128,172,15,164,62,289,280,298,252,123,242,297,77,52,209,5,102,208,33,33,87,120,168,93,88,243,93,113,120,253,123,218,198,122,286,194,155,67,175,225,137,272,85,200,267,84,110,4,88,296,229,174,182,80,152,238,258,28,163,125,22,135,210,150,122,284,296,178,160,185,26,55,85,5,45,126,165,168,235,12,122,17,93,181,155,179,99,273,231,173,129,220,49,17,73,228,286,103,205,238,10,239,145,62,181,273,284,196,4,199,290,2,287,22,88,175,243,12,16,169,94,124,153,220,135,97,22,123,172,229,174,196,243,125,239,217,208,219,57,232,21,74,286,246,66,55,71,278,77,77,215,200,232 209,294,73,160,32,300,203,4,173,30,31,240,85,13,89,114,90,285,294,120,83,48,49,194,123,124,214,98,190,62,55,175,24,137,272,78,236,114,87,276,190,188,128,29,168,209,275,251,6,163,275,129,204,151,154,139,106,121,81,16,73,294,18,117,109,147,46,142,77,189,163,47,282,197,152,117,32,235,138,226,179,250,5,63,22,31,99,38,0,161,197,163,249,24,57,204,136,107,45,212,279,159,26,228,120,139,148,62,99,28,177,51,279,29,133,82,262,225,82,202,77,27,9,97,237,89,70,144,76,102,13,145,62,260,177,227,279,99,163,24,190,123,289,34,277,186,104,44,144,66,299,39,8,103,164,277,162,122,255,248,202,217,300,102,149,124,209,53,127,163,245,162,128,153,68,186,147,204,266,111,91,88,45,159,67,175,109,263,143,57,205,224,184,235,48,243,60,287,19,18,238,114,139,35,34,52,14,215,160,168,65,140,224,226,120,271,224,26,191,214,4,129,120,82,296,241,209,125,221,83,107,130,284,36,194,104,31,55,23,130,288,163,148,292,65,114,119,84,151,41,155,290,167,273,197,132,208,19,227,210,149,46,67,98,236,15,155,227,241,97,292,242,203,272,263,125,37,287,239,209,120 Using a dictionary to handle the dupes, using this code Sub PickSample(intSampleSize As Integer, intPicks As Integer) Dim dicPicked As New Scripting.Dictionary Dim arr() As String Dim intCounter As Integer Dim intPicked As Integer ReDim arr(intPicks) For intCounter = 0 To UBound(arr) RetryPick: intPicked = CStr(Int((intSampleSize - (i - 1)) * Rnd + 1) + (i - 1)) If dicPicked.Exists(CStr(intPicked)) Then GoTo RetryPick Else dicPicked.Add CStr(intPicked), 1 arr(intCounter) = intPicked End If Next intCounter Debug.Print Join(arr(), ",") dicPicked.RemoveAll Set dicPicked = Nothing End Sub Gives results, hopefully dupe free PickSample 300,280 203,125,69,114,26,208,39,219,36,174,220,113,24,74,104,282,128,112,223,205,200,147,44,143,152,162,157,300,70,54,108,177,13,276,153,91,7,168,89,145,127,12,16,257,187,229,61,213,117,214,254,171,59,242,23,51,224,52,185,165,193,189,21,296,63,173,160,280,190,232,235,141,256,56,87,98,32,5,267,195,77,120,197,82,288,68,57,136,132,182,122,15,47,48,261,96,110,258,49,105,155,86,186,97,225,80,264,140,11,46,199,230,275,19,34,83,222,66,116,294,298,259,292,271,272,84,115,101,124,43,183,71,289,291,25,188,55,158,150,216,243,92,58,0,290,148,255,149,250,167,27,233,228,265,9,299,65,283,62,88,207,240,109,179,161,178,268,278,175,139,237,234,169,297,269,281,184,262,270,164,202,279,253,295,196,212,8,274,159,75,172,163,130,38,154,73,99,247,249,263,273,67,40,20,221,138,14,33,218,286,227,251,94,166,209,156,211,37,137,90,131,111,107,2,215,85,146,100,293,204,231,285,79,53,126,60,239,260,248,78,4,217,29,64,121,226,201,210,45,206,134,17,1,192,246,3,35,191,236,93,28,41,244,287,129,277,142,118,6,81,18,135,181,241,180,103,50,252,31,95,30 44,278,132,10,232,56,146,193,284,276,236,155,79,117,102,61,119,200,229,131,138,133,235,173,204,34,7,98,3,202,167,143,130,30,126,206,13,262,221,166,174,298,111,116,39,288,263,76,47,170,89,268,154,253,52,91,217,148,12,22,83,33,77,264,85,214,55,127,279,251,101,86,230,35,172,59,198,62,286,296,220,29,191,242,271,5,54,84,297,158,38,270,231,107,95,110,57,129,9,273,53,269,68,4,234,228,211,207,70,153,151,194,179,128,169,63,142,109,145,58,186,24,245,60,87,0,17,246,225,222,218,184,258,26,161,226,247,31,144,178,223,122,88,124,137,210,293,94,99,213,190,281,80,72,104,40,6,123,290,259,254,45,78,66,227,289,261,141,65,135,8,274,69,257,203,168,196,42,248,67,73,125,37,11,287,181,92,291,238,108,212,1,118,28,216,244,164,249,240,150,46,74,277,36,189,188,255,224,195,260,15,175,267,280,49,180,27,165,50,113,243,201,237,149,205,156,199,292,136,48,71,75,285,41,81,239,209,185,266,160,176,152,171,163,100,2,32,183,16,97,19,294,187,20,282,272,157,182,121,140,106,112,265,295,51,21,256,64,241,114,162,90,252,115,25,82,103,23,299,120,197 57,241,105,1,247,289,284,72,89,68,101,225,295,242,290,5,291,217,267,87,62,80,24,106,103,38,285,197,286,300,151,222,219,254,201,113,195,245,243,15,179,98,145,192,74,118,142,109,70,58,11,4,154,277,129,115,250,202,293,163,181,168,288,268,281,112,79,49,60,175,236,23,266,186,59,167,190,187,41,228,174,157,48,231,165,253,227,171,66,176,135,238,120,258,19,110,194,164,131,296,91,206,159,255,8,189,124,148,114,13,75,121,95,272,119,214,50,117,279,213,205,133,96,196,137,173,246,218,233,77,27,264,141,184,193,263,102,83,244,210,78,127,36,63,188,42,0,152,198,271,169,298,207,111,3,158,182,282,30,226,199,17,273,297,191,166,46,144,252,55,25,26,200,86,162,237,211,299,212,287,161,12,40,45,69,216,54,125,71,47,132,93,22,20,76,126,51,262,107,229,234,257,2,39,278,235,84,37,280,208,153,251,67,136,104,28,221,149,248,276,170,140,14,269,180,16,108,34,94,43,92,52,204,65,134,85,183,7,146,143,97,270,64,259,139,160,260,223,32,81,177,33,178,185,90,292,9,232,209,265,10,88,283,147,123,99,261,240,6,138,274,122,61,203,249,155,256,44,294,116,35
this function picks nItemsToPick random elements up from arr array and returns them into an array: Function PickNRandomElementsFromArray(arr As Variant, nItemsToPick As Long) As Variant Dim arrSize As Long Dim i As Long, iPick As Long Dim temp As String arrSize = UBound(arr) '<--| count the values as the array size If nItemsToPick > arrSize Then nItemsToPick = arrSize '<--| the items to be picked cannot exceed array size For i = 1 To nItemsToPick iPick = Int((arrSize - (i - 1)) * Rnd + 1) + (i - 1) '<--| pick a random number between 'i' and 'arrSize' ' swap array elements in slots 'i' and 'iPick' temp = arr(iPick) arr(iPick) = arr(i) arr(i) = temp Next i ReDim Preserve arr(1 To nItemsToPick) '<--| resize the array to first picked items PickNRandomElementsFromArray = arr '<--| return the array End Function which you can exploit as follows: Option Explicit Sub Authors() Dim Authors As Variant, AuthorsList As Variant With ThisWorkbook.Worksheets("Sheet") '<--| reference your relevant worksheet Authors = Application.Transpose(.Range("A2", .Cells(.rows.count, 1).End(xlUp)).Value) '<--| fill 'Authors' array with its column "A" values from row 2 down to its last not empty one AuthorsList = PickNRandomElementsFromArray(Authors, 280) '<--| fill 'AuthorsList' array with a selection of 280 random elements of 'Authors' .Range("B1").Value = Join(AuthorsList, " OR ") '<--| fill cell "B1" with a string build by concatenating 'AuthorsList' values delimited with " OR " End With End Sub that can be quite contracted (and made as much less readable) to: Sub Authors() With ThisWorkbook.Worksheets("Sheet") '<--| reference your relevant worksheet .Range("B1").Value = Join(PickNRandomElementsFromArray(Application.Transpose(.Range("A2", .Cells(.rows.count, 1).End(xlUp)).Value), 280), " OR ") End With End Sub
From your comments, you seem to want to concatenate the array of strings, then put it back into excel. This, put just before the End Sub, will put it into cell B1 for example: ThisWorkbook.Worksheets("Sheet1").Range("B1").Value = Join(Authorlist, "OR")
Searching collections
I'm working with a rather large dataset (>100,000 rows) and trying to compare two lists to figure out which items in the new list are not already in the master list. In other words I want to find the new unique items. I have some VBA code that uses vlookup and arrays that works, but bombs out when the arrays get too big (~70,000). So I've turned to collections. However I'm having difficulty searching the collections using vlookup or match. Sub find_uniqueIDs() Dim a As Long Dim n As Long Dim m As Variant Dim oldnum As Long Dim oldIDs As Variant Dim oldcoll As New Collection Dim newnum As Long Dim newIDs As Variant Dim newcoll As New Collection oldnum = 75000 oldIDs = Range("A1", Range("A" & oldnum)) newnum = 45000 + 3 newIDs = Range("G3", Range("G" & newnum)) 'Using arrays to search, but bombs out when oldnum or newnum are ~70000 For n = 1 To newnum - 3 m = Application.VLookup(newIDs(n, 1), oldIDs, 1, False) If IsError(m) Then Range("E100000").End(xlUp).Offset(1, 0) = newIDs(n, 1) Next n 'Using collections to search For n = 1 To oldnum On Error Resume Next oldcoll.Add oldIDs(n, 1) On Error GoTo 0 Next n For m = 1 To newnum On Error Resume Next newcoll.Add newIDs(m, 1) On Error GoTo 0 Next m 'This bit of code doesn't work For a = 1 To newcoll.Count If Application.VLookup(newcoll(a), oldcoll, 1, False) = "#N/A" Then _ Range("E100000").End(xlUp).Offset(1, 0) = newcoll(a) Next a End Sub Any ideas how I can determine whether a particular item is in the master list using collections?
Here is a short sub demonstrating some of the scripting dictionary methods. Sub list_New_Unique() Dim dMASTER As Object, dNEW As Object, k As Variant Dim v As Long, vVALs() As Variant, vNEWs() As Variant Debug.Print "Start: " & Timer Set dMASTER = CreateObject("Scripting.Dictionary") Set dNEW = CreateObject("Scripting.Dictionary") dMASTER.comparemode = vbTextCompare dNEW.comparemode = vbTextCompare With Worksheets("Sheet7") vVALs = .Range("A2:A100000").Value2 vNEWs = .Range("C2:C100000").Value2 End With 'populate the dMASTER values For v = LBound(vVALs, 1) To UBound(vVALs, 1) dMASTER.Add Key:=vVALs(v, 1), Item:=vVALs(v, 1) Next v 'only populate dNEW with items not found in dMASTER For v = LBound(vNEWs, 1) To UBound(vNEWs, 1) If Not dMASTER.exists(vNEWs(v, 1)) Then If Not dNEW.exists(vNEWs(v, 1)) Then _ dNEW.Add Key:=vNEWs(v, 1), Item:=vNEWs(v, 1) End If Next v Debug.Print dNEW.Count For Each k In dNEW.keys 'Debug.Print k Next k Debug.Print "End: " & Timer dNEW.RemoveAll: Set dNEW = Nothing dMASTER.RemoveAll: Set dMASTER = Nothing End Sub With 99,999 unique entries in A2:A100000 and 89747 random entries in C2:C89747, this found 70,087 unique new entries not found in A2:A100000 in 9.87 seconds.
I would do it like this: Sub test() Dim newRow As Long, oldRow As Long Dim x As Long, Dim y As Long Dim checker As Boolean With ActiveSheet newRow = .Cells(.Rows.Count,7).End(xlUp).Row oldRow = .Cells(.Rows.Count,1).End(xlUp).Row checker = True for y = 1 To oldRow for x = 1 To newRow If .Cells(y,1).Value = .Cells(x,7).Value Then checker = False Exit For End If Next If checker Then Range("E10000").End(xlUp).Offset(1,0).Value = .Cells(y,1).Value End If checker = True Next End With End Sub
VLookup is a worksheet function, not a regular VBA function, thus it's for searching in Ranges, not Collections. Syntax: VLOOKUP (lookup_value, table_array, col_index_num, [range_lookup]) [...] table_array (required): the range of cells in which the VLOOKUP will search for the lookup_value and the return value. In order to search in other VBA data structures like arrays, collections etc you'll have to figure out some other way and maybe implement it manually.
While #Jeeped suggestion of a Scripting.Dictionary object might be the best one, you could also try using the Filter() function applied to your array.
Array to Excel Range
I'm new to VBA and trying to write an array to an excel range through an array UDF. I'm trying to output the array to a maximum number of rows that the formula was placed in. I am using the Microsoft Scripting Library for the dictionary, if that matters. With an array formula in excel (CTRL+Shift+Enter), how do I resize my array to the range that the formula was placed in and then place the array in the cells? I would like the formula on the cells to be =test("G1:J20") and the formula will be placed in the cells A1:B20. Code: Function test(ByVal inputRange As Range) As Variant Dim Cell As Variant Dim D As Dictionary Dim Arr() As Variant Dim i As Long Set D = New Dictionary ' Remove duplicates For Each Cell In inputRange If D.Exists(CStr(Cell.Value)) = False Then D.Add CStr(Cell.Value), 1 Else D.Exists (Cell.Value) D.Item(Cell.Value) = D.Item(Cell.Value) + 1 End If Next D.Remove vbNullString Redim Arr(0 To Application.Max(D.Count, Application.Caller.Cells.Count)) 'Fill the array with the keys from the Dictionary For i = 0 To D.Count - 1 Arr(i) = D.Keys(i) Next i test = Application.Transpose(Arr) End Function
To read and write arrays to cells you need a 2D array. For example: Dim data() as Variant, N as Long, M as Long ' Say you want a 100×50 array N = 100 : M = 50 ReDim data(1 to N, 1 to M) ' Fill data() Range("A1").Resize(N,M).Value = data Or to just read values Dim data() as Variant, N as Long, M as Long, i as Long, j as Long data = Range("A1:AX100").Value N = UBOUND(data,1) : M = UBOUND(data,2) For i = 1 to N For j = 1 to M Debug.Print(data(i,j)) Next j Next i Edit 1 I got rid of the evil Integer types and replaced them with Long, the native 32-bit integers in VBA.
Here is a method to put an array into a worksheet range, is this what you meant? Sub test() Dim v(0 To 2, 0 To 2) As Variant Dim r As Range 'fill the array with values populate v 'range must be same dimensions as array, in this case 3x3 Set r = ActiveSheet.Range("A1:C3") 'this simply puts array into range values r.Value2 = v End Sub Function populate(v As Variant) For i = 0 To 2 For j = 0 To 2 v(j, i) = i * j * j - i + 2 Next j Next i End Function However, since you're already looping through the dictionary for the values, why not just write the values directly to the worksheet? You can mimic the transpose by swapping your row and column indices Sub test() Dim dict As Dictionary Set dict = New Dictionary 'fill dictionary with values populate dict 'loop through dictionary, and add items to worksheet For i = 0 To dict.Count - 1 ActiveSheet.Cells(1, i + 1).Value = dict.Keys(i) ActiveSheet.Cells(2, i + 1).Value = dict.Items(i) Next i End Sub Function populate(dict As Dictionary) dict.Add "help", "me" dict.Add "I'm", "lost" dict.Add "everything", "1" dict.Add "or", "0" End Function