WHOOSSHHHHH! That was the sound of that one going right over my head. ... let me have a look at that. Split(not used it, but doesn't look hard), Join(not used it, but doesn't look hard), Transpose(got that bit), ... I give up that formula looks a monster. I really need to go read about the Ubound and variants I think, sounds like i could do some fun things with it.
See if the following step-by-step explanation helps any...
This is the Excel formula to concatenate Column A values with a comma concatenated after it the number of times specified in Column B where I have used a # sign to stand in for the last row containing data...
Code:
Sub DistributeNumbers()
Dim Nums As Variant
Nums = Split(Join(Application.Transpose(Evaluate(Replace[COLOR=#000000]("IF(ROW(),[/COLOR][COLOR=#ff0000][B]REPT(A2:A#" & _
"&"","",B2:B#)[/B][/COLOR][COLOR=#000000])"[/COLOR], "#", Cells(Rows.Count, "A").End(xlUp).Row))), ""), ",")
Range("C2:C" & UBound(Nums)) = Application.Transpose(Nums)
End Sub
Functions that return text are not array-aware, so in order to make this an array formula we must embed the above formula in a structure that includes an array-aware function, so I use the ROW function inside an IF function (ROW always returns a values which IF sees as TRUE, so I did not include a FALSE section for the IF)...
Code:
Sub DistributeNumbers()
Dim Nums As Variant
Nums = Split(Join(Application.Transpose(Evaluate(Replace[COLOR=#000000]("[/COLOR][COLOR=#ff0000][B]IF(ROW(),[/B][/COLOR][COLOR=#000000]REPT(A2:A#" & _
"&"","",B2:B#)[/COLOR][COLOR=#ff0000][B])[/B][/COLOR][COLOR=#000000]", [/COLOR]"#", Cells(Rows.Count, "A").End(xlUp).Row))), ""), ",")
Range("C2:C" & UBound(Nums)) = Application.Transpose(Nums)
End Sub
The VB Replace function is used to change the # signs into the row number of the last data cell (the green part calculates the last row with data)...
Code:
Sub DistributeNumbers()
Dim Nums As Variant
Nums = Split(Join(Application.Transpose(Evaluate([COLOR=#ff0000][B]Replace("[/B][/COLOR][COLOR=#000000]IF(ROW(),REPT(A2:A#" & _
"&"","",B2:B#))[/COLOR][COLOR=#ff0000][B]", "#", [/B][/COLOR][COLOR=#008000][B]Cells(Rows.Count, "A").End(xlUp).Row[/B][/COLOR][COLOR=#ff0000][B])[/B][/COLOR])), ""), ",")
Range("C2:C" & UBound(Nums)) = Application.Transpose(Nums)
End Sub
The Evaluate function is used to process the text string representation of the resulting array formula...
Code:
Sub DistributeNumbers()
Dim Nums As Variant
Nums = Split(Join(Application.Transpose([COLOR=#ff0000][B]Evaluate([/B][/COLOR]Replace[COLOR=#000000]("IF(ROW(),REPT(A2:A#" & _
"&"","",B2:B#))", [/COLOR]"#", Cells(Rows.Count, "A").End(xlUp).Row)[COLOR=#ff0000][B])[/B][/COLOR]), ""), ",")
Range("C2:C" & UBound(Nums)) = Application.Transpose(Nums)
End Sub
We transpose this which turns it into a one-dimensional array because Join only works with one-dimensional arrays (Evaluate returns a two-dimensional array even for a single column of value)...
Code:
Sub DistributeNumbers()
Dim Nums As Variant
Nums = Split(Join([COLOR=#ff0000][B]Application.Transpose([/B][/COLOR]Evaluate(Replace[COLOR=#000000]("IF(ROW(),REPT(A2:A#" & _
"&"","",B2:B#))", [/COLOR]"#", Cells(Rows.Count, "A").End(xlUp).Row))[COLOR=#ff0000][B])[/B][/COLOR], ""), ",")
Range("C2:C" & UBound(Nums)) = Application.Transpose(Nums)
End Sub
We join the elements of the array into a text string using an empty string ("") as the delimiter (because the REPT function in the first explanation included the comma at the end)...
Code:
Sub DistributeNumbers()
Dim Nums As Variant
Nums = Split([COLOR=#ff0000][B]Join([/B][/COLOR]Application.Transpose(Evaluate(Replace[COLOR=#000000]("IF(ROW(),REPT(A2:A#" & _
"&"","",B2:B#))", [/COLOR]"#", Cells(Rows.Count, "A").End(xlUp).Row)))[COLOR=#ff0000][B], "")[/B][/COLOR], ",")
Range("C2:C" & UBound(Nums)) = Application.Transpose(Nums)
End Sub
We now split that long string into individual number by specifying the comma as the delimiter and assign the resulting one-dimensional array to a Variant variable ...
Code:
Sub DistributeNumbers()
Dim Nums As Variant
[COLOR=#ff0000][B]Nums = Split([/B][/COLOR]Join(Application.Transpose(Evaluate(Replace[COLOR=#000000]("IF(ROW(),REPT(A2:A#" & _
"&"","",B2:B#))", [/COLOR]"#", Cells(Rows.Count, "A").End(xlUp).Row))), "")[COLOR=#ff0000][B], ",")[/B][/COLOR]
Range("C2:C" & UBound(Nums)) = Application.Transpose(Nums)
End Sub
Next we transpose the one-dimensional array stored in Nums to make it a column oriented array...
Code:
Sub DistributeNumbers()
Dim Nums As Variant
Nums = Split(Join(Application.Transpose(Evaluate(Replace[COLOR=#000000]("IF(ROW(),REPT(A2:A#" & _
"&"","",B2:B#))", [/COLOR]"#", Cells(Rows.Count, "A").End(xlUp).Row))), ""), ",")
Range("C2:C" & UBound(Nums)) = [COLOR=#ff0000][B]Application.Transpose(Nums)[/B][/COLOR]
End Sub
And assign that to the output range. Note that Split produced a zero-based array, so theoretically there were UBound(Nums)+1 array elements in it, but we don't output the last element because it is always the empty string (Split created that empty element because the text string that was created by the Join function earlier ended with a comma which was the delimiter used to split the text)...
Code:
Sub DistributeNumbers()
Dim Nums As Variant
Nums = Split(Join(Application.Transpose(Evaluate(Replace[COLOR=#000000]("IF(ROW(),REPT(A2:A#" & _
"&"","",B2:B#))", [/COLOR]"#", Cells(Rows.Count, "A").End(xlUp).Row))), ""), ",")
[COLOR=#ff0000][B]Range("C2:C" & UBound(Nums))[/B][/COLOR] = Application.Transpose(Nums)
End Sub