I'm trying to create an array of cell entries (e.g. A6,B6, etc) that populates in a for loop.
However the array
MyArray
is always empty and I can't figure out why its not being populated within the for loop. Below is (the appropriate part of-the code is doing other stuff to) my code:
Sub ListSheets()
' Defining all variables (objects) used within the code, establishing their
'classes
Dim i As Integer
Dim array_size As Integer
Dim MyArray() As String
array_size = 26
ReDim MyArray(array_size) As String
For intLoop = 1 To 26
MyArray(intLoop, 1) = Chr$(64 + intLoop) + "6"
Next
Set CopyFrom = MyArray
Sheets("vba_deposit").Range("A1").Resize(CopyFrom.Rows.Count).Value = CopyFrom.Value
End Sub
Any ideas?
Many thanks in advance.
Try this one:
Sub ListSheets()
Dim i As Integer
Dim array_size As Integer
Dim MyArray() As String
array_size = 26
ReDim MyArray(1 To array_size, 1 To 1)
For intLoop = 1 To 26
MyArray(intLoop, 1) = Chr$(64 + intLoop) + "6"
Next
Sheets("vba_deposit").Range("A1").Resize(UBound(MyArray)).Value = MyArray
End Sub
Your first idea to use MyArray(intLoop, 1) was good - because in that case there is no need to use Transpose (which not always working since it has limitation on number of elements in array) here: Range(...).Value = MyArray. However I've made little changes in your code:
redim array as 2D: ReDim MyArray(1 To array_size, 1 To 1)
use direct Range(...).Value = MyArray
Sub ListSheets()
' Defining all variables (objects) used within the code, establishing their
'classes
Dim i As Integer
Dim array_size As Integer
Dim MyArray() As String
array_size = 26
ReDim MyArray(array_size) As String
For intloop = 1 To 26
MyArray(intloop) = Chr$(64 + intloop) + "6"
Sheets(1).Range("A1").Offset(intloop - 1).Value = MyArray(intloop)
Next
'An array is not an object, you can't use SET with them.
'Your array is 1-dimensional, MyArray(1,1) won't work as that's 2-dimensional, just
'MyArray(1) = "whatever1" MyArray(2) = "whatever2" etc. etc.
End Sub
Related
I am trying to create a TextSplit function in Excel that can accept either a single reference or a range.
If it is a single string it returns an array of sub strings.
If it is a range it should return an array of sub string arrays.
A single string works but when I pass it a single column range it give me a #VALUE! error.
The commented lines work.
If I store the result of Array to arr Excel displays a grid of "test" strings.
If instead I set TextSplit to just arr(1) I get a single array of substrings similar to the single string version.
Function TextSplit(text, delimiter)
If IsArray(text) Then
Dim arr() As Variant: ReDim arr(0 To text.Count - 1)
For i = 1 To text.Count
arr(i-1) = Split(text(i), delimiter)
'arr(i-1) = Array("test", "test")
Next
TextSplit = arr
'TextSplit = arr(1)
Else
TextSplit = Split(text, delimiter)
End If
With the help of a different question Array and Split commands to create a 2 dimensional array
I was able to work your question out a bit, however I'm still unable to fill out the array from the cell where you'd call the function like with your single string which fills out in the columns next to it.
If it's for a column, you could just autofill text.split(cell,delimiter) if you're working from Excel.
If you're working from out vba and want to return the split array (2D like #Tim said) back to a sub:
Sub testingTextSplitter()
Dim arr As Variant, tArr As Variant
Dim testStr As String
testStr = Range("A1").Value 'Testing single cell
Range("G2").Value = TextSplit(testStr, "-")
arr = Range("A1:A8").Value
tArr = TextSplit(arr, "-")
For i = 0 To UBound(tArr, 1)
For j = 0 To UBound(tArr, 2)
Cells(i + 3, j + 3).Value = "'" & tArr(i, j) 'fills out from Range("C3"), adjust as needed
' This writing out is basically the same as fillingdown the formule of text.split() btw
Next j
Next i
End Sub
With the Function
Function TextSplit(tArray As Variant, delimiter As String) As String()
If IsArray(tArray) Then
Dim uBoundInput As Long, uBoundCells As Long 'I couldn't get your arr.Count to work on my end so gotta use the UBound
Dim arr() As String, testArr() As String
Dim i As Long, j As Long, maxColumns As Long
uBoundInput = UBound(tArray)
maxColumns = 0
For i = 0 To uBoundInput - 1
Debug.Print (tArray(i + 1, 1))
testArr = Split(tArray(i + 1, 1), "-")
uBoundCells = UBound(testArr)
If maxColumns < uBoundCells Then
maxColumns = uBoundCells
End If
Next i
ReDim arr(0 To uBoundInput - 1, 0 To maxColumns)
For i = 0 To uBoundInput - 1
testArr = Split(tArray(i + 1, 1), "-")
For j = 0 To UBound(testArr)
arr(i, j) = testArr(j)
Next j
Next i
TextSplit = arr()
Else
TextSplit = Split(tArray, delimiter)
End If
End Function
I'm quite new to VBA as well so apologies in advance for redundancies like not filling testArray when figuring out the maxColumns, I couldn't figure that one out. First time working with 2D arrays.
Other question that might help:
VBA UDF Return Array
(I tried using the array formulay with {} but got same Value error as before)
Hope this helps.
I don't know what happened, but the array branch of my code is now working. I have been messing with a few things, but I am not sure why it is working. The "As Variant()" declaration is new from the above code, but that may have been omitted before. (This code is on my work machine but I wrote the original post from my personal computer so I couldn't copy and paste. I am on my work computer now.)
The only other change that I made was to the index values of the arr array.
Thanks for your help, not sure what was wrong or how it got fixed though.
Function TextSplit(text, delimiter) As Variant()
If IsArray(text) Then
Dim arr() As Variant: ReDim arr(1 To text.Count)
For i = 1 To text.Count
arr(i) = Split(text(i), delimiter, -1, 1)
Next
TextSplit = arr
Else
TextSplit = Split(text, delimiter, -1, 1)
End If
End Function
I have 2 arrays taken from 2 ranges in a sheet. I'm trying to create a third array that contains only the values contained in array 1 that are missing in array 2 (I found this code online).
Array 2´s size will vary and depends on this code:
Dim iListaIncompleta() As Variant
Dim iCountLI As Long
Dim iElementLI As Long
iCountLI = Range("B1").End(xlDown).Row
ReDim iListaIncompleta(iCountLI)
For iElementLI = 1 To iCountLI
iListaIncompleta(iElementLI - 1) = Cells(iElementLI, 2).Value
Next iElementLI
and Array 1's size is always from A1:A7, and I use this code to create it:
Dim iListaCompleta() As Variant
Dim iElementLC As Long
iListaCompleta = Range("A1:A7")
This is the original code I found online to extract missing values:
Dim v1 As Variant, v2 As Variant, v3 As Variant
Dim coll As Collection
Dim i As Long
'Original Arrays from the code:
v1 = Array("Bob", "Alice", "Thor", "Anna") 'Complete list
v2 = Array("Bob", "Thor") 'Incomplete list
Set coll = New Collection
For i = LBound(v1) To UBound(v1)
If v1(i) <> 0 Then
coll.Add v1(i), v1(i) 'Does not add value if it's 0
End If
Next i
For i = LBound(v2) To UBound(v2)
On Error Resume Next
coll.Add v2(i), v2(i)
If Err.Number <> 0 Then
coll.Remove v2(i)
End If
If coll.Exists(v2(i)) Then
coll.Remove v2(i)
End If
On Error GoTo 0
Next i
ReDim v3(LBound(v1) To (coll.Count) - 1)
For i = LBound(v3) To UBound(v3)
v3(i) = coll(i + 1) 'Collections are 1-based
Debug.Print v3(i)
Next i
End Sub
However, this code has arrays defined like this:
v1 = Array("Bob", "Alice", "Thor", "Anna")
And the actual arrays I wanna use are defined differently (as you can see in the first two pieces of code). When I try to run the code with them, it displays
Error 9: Subscript out of range.
The code works well as it originally is, but when I try to use MY arrays, it's when I get this error.
Obviously, I've tried it changing the names of the variables (v1 and v2) to my own 2 arrays (iListaCompleta and iListaIncompleta), and still doesn't work.
Any ideas??
Thank you in advance!
Here's a function that can be used to compare arrays of any dimension size to pull out differences and put only the differences in a one-dimensional array:
Public Function ArrayDifference(ByVal arg_Array1 As Variant, ByVal arg_array2 As Variant) As Variant
If Not IsArray(arg_Array1) Or Not IsArray(arg_array2) Then Exit Function 'Arguments provided were not arrays
Dim vElement As Variant
Dim hDifference As Object: Set hDifference = CreateObject("Scripting.Dictionary")
For Each vElement In arg_Array1
If Not hDifference.exists(vElement) Then hDifference.Add vElement, vElement
Next vElement
For Each vElement In arg_array2
If hDifference.exists(vElement) Then
hDifference.Remove vElement
Else
hDifference.Add vElement, vElement
End If
Next vElement
ArrayDifference = hDifference.Keys
End Function
Here's how you would call the function to compare two different arrays. It also includes how to populate the initial arrays using your provided setup:
Sub arrays()
Dim ws As Worksheet: Set ws = ActiveWorkbook.ActiveSheet
Dim rList1 As Range: Set rList1 = ws.Range("A1", ws.Cells(ws.Rows.Count, "A").End(xlUp))
Dim rList2 As Range: Set rList2 = ws.Range("B1", ws.Cells(ws.Rows.Count, "B").End(xlUp))
Dim aList1 As Variant
If rList1.Cells.Count = 1 Then
ReDim aList1(1 To 1, 1 To 1)
aList1(1, 1) = rList1.Value
Else
aList1 = rList1.Value
End If
Dim aList2 As Variant
If rList2.Cells.Count = 1 Then
ReDim aList2(1 To 1, 1 To 1)
aList2(1, 1) = rList2.Value
Else
aList2 = rList2.Value
End If
Dim aList3 As Variant
aList3 = ArrayDifference(aList1, aList2)
MsgBox Join(aList3, Chr(10))
End Sub
I have 2 arrays that I want to combine into a single array of all possible combinations. I then need to loop through all of the combinations and popular arguments for a function. My arrays are not equal in size, and my attempts so far have resulted in a combined array only having 1 pair of values. This is VBA in PowerPoint, not Excel, if that makes a difference to available syntax.
How can I go from this:
arrayColor = Array("Blue","Green","Red")
arraySize = Array("XS","S","M","L","XL")
To this:
arrayCombo(0,0) = "Blue"
arrayCombo(0,1) = "XS"
arrayCombo(1,0) = "Blue"
arrayCombo(1,1) = "S"
...
arrayCombo(15,0) = "Red"
arrayCombo(15,1) = "XL"
And then use a loop to call each pair of values and populate argument values. This code just to illustrate the concept; it's certainly not legit. Pretty sure I need a nested loop here?
For i = 0 To UBound(arrayCombo(i))
nextSubToFire(color, size)
Next i
This is what I've got so far, but it only results in a single pair in my combined array. It's based on this question, but I think I'm either missing something or the sole answer there isn't quite correct. I've looked at other similar questions, but can't wrap my head around doing this with an array compiled in the code rather than the other examples all tailored to Excel.
Option Explicit
Dim arrayColorSize, arrayCombo
Sub CoreRoutine()
Dim arrayColor, arraySize
arrayColor = Array("Blue","Green","Red")
arraySize = Array("XS","S","M","L","XL")
arrayColorSize = Array(arrayColor, arraySize)
arrayCombo = Array(0, 0)
DoCombinations (0)
Dim a As Integer
Dim b As Integer
'For loop comes next once I figure out how to populate the full arrayCombo
End Sub
Sub DoCombinations(ia)
Dim i
For i = 0 To UBound(arrayColorSize(ia)) ' for each item
arrayCombo(ia) = arrayColorSize(ia)(i) ' add this item
If ia = UBound(arrayColorSize) Then
Else
DoCombinations (ia + 1)
End If
Next i
End Sub
Using the Locals window, I see arrayCombo exists, but it only has 1 pair of values in it, which is the last set of pairing options. I see that arrayColorSize has the 2 array sets as I'd expect, so I suspect the DoCombinations sub is missing something.
Any guidance much appreciated!
One way of doing this is to combine the two 1D arrays into a 2D array with 2 columns (as in your example):
Private Function Combine1DArrays(ByRef arr1 As Variant, ByRef arr2 As Variant) As Variant
If GetArrayDimsCount(arr1) <> 1 Or GetArrayDimsCount(arr2) <> 1 Then
Err.Raise 5, "Combine1DArrays", "Expected 1D arrays"
End If
'
Dim count1 As Long: count1 = UBound(arr1) - LBound(arr1) + 1
Dim count2 As Long: count2 = UBound(arr2) - LBound(arr2) + 1
Dim i As Long, j As Long, r As Long
Dim result() As Variant
'
ReDim result(0 To count1 * count2 - 1, 0 To 1)
r = 0
For i = LBound(arr1) To UBound(arr1)
For j = LBound(arr2) To UBound(arr2)
result(r, 0) = arr1(i)
result(r, 1) = arr2(j)
r = r + 1
Next j
Next i
Combine1DArrays = result
End Function
Public Function GetArrayDimsCount(ByRef arr As Variant) As Long
Const MAX_DIMENSION As Long = 60
Dim dimension As Long
Dim tempBound As Long
'
On Error GoTo FinalDimension
For dimension = 1 To MAX_DIMENSION
tempBound = LBound(arr, dimension)
Next dimension
FinalDimension:
GetArrayDimsCount = dimension - 1
End Function
You can use it like this for example:
Sub CoreRoutine()
Dim arrayColorSize As Variant
Dim i As Long
Dim color As String
Dim size As String
'
arrayColorSize = Combine1DArrays(Array("Blue", "Green", "Red") _
, Array("XS", "S", "M", "L", "XL"))
For i = LBound(arrayColorSize, 1) To UBound(arrayColorSize, 1)
color = arrayColorSize(i, 0)
size = arrayColorSize(i, 1)
NextSubToFire color, size
Next i
End Sub
Sub NextSubToFire(ByVal color As String, ByVal size As String)
Debug.Print color, size
End Sub
I have create the following code. I want verify if my arry1 is equal to "Gi0". If is correct then copy to a new arry2, but then appear the following error:
Subscript out of range
Can someone explain me what is wrong?
with :
arry2(k, 1) = arry1(i, 1)
Private Sub CommandButton1_Click()
Dim arry1() As Variant
ReDim arry2(1 To 20, 1 To 1)
arry1 = Sheets("Sheet1").Range("B2:B65").Value
k = 1
For i = 1 To UBound(ar1)
If Left(arry1(i, 1), 3) = "Gi0" Then
arry2(k, 1) = arry1(i, 1)
k = k + 1
Else
End If
Next i
End Sub
You have Ubound(ar1) and your array is called arry1.
Also, you don't need an ELSE statement in your IF.
And is that a good way to dim or redim an array? I don't think so.
If I want arry2 to be a 21 by 2 array then I say
dim arry2(20,1) as double.
If you want to dim in terms of variables I say:
dim arry2() as double
redim arry2(x,y)
I need to declare variant variables from the elements of a dynamic array.
I have an array (arrWS) which contains the names of specific sheets which is populated manually, and I want to declare "N" range objects where "N" is the number of worksheets.
Sequence:
1- Declare an array containing some worksheet names ==> varAAA = Array("Sheet1", "Sheet3", "Sheet4", ...)
2- Get the number of elements in this array
3- Then like that if possible:
Dim varBBB(1 To N)
For i = 1 to N
varBBB(i) = Sheets(varAAA(i)).UsedRange
Next N
Thank you so much in advance.
Your main problem is that you must Set object variables:
'1- Declare an array containing some worksheet names
' ==> varAAA = Array("Sheet1", "Sheet3", "Sheet4", ...)
Dim VarAAAA
varAAA = Array("Sheet1", "Sheet3", "Sheet4")
'2- Get the number of elements in this array
Dim N As Long
N = UBound(varAAA) - LBound(varAAA) + 1
'3- Then like that if possible:
'Dim varBBB(1 To N)
Dim varBBB() As Range
ReDim varBBB(1 To N)
'For i = 1 to N
For i = 1 To N
'varBBB(i) = Sheets(varAAA(i)).UsedRange
Set varBBB(i) = Sheets(varAAA(i - 1 + LBound(varAAA))).UsedRange
'Confirm that ranges have been correctly set
Debug.Print i, varAAA(i - 1 + LBound(varAAA)), varBBB(i).Address
'Next N
Next
Maybe you are looking for something like,
Dim arrWS() As String
Dim iLoop As Integer
With ThisWorkbook
ReDim arrWS(1 To .Sheets.Count)
For iLoop = 1 To .Sheets.Count
arrWS(iLoop) = .Sheets(iLoop).Name
Next
End With
then you can use Ubound(arrWWS) to get the last index of the array.
You can now use this code to store each usedrange in the sheet,
Dim arrBB() As Variant
Dim arrHolder() As Variant
ReDim arrBB(1 To UBound(arrWS))
For iLoop = LBound(arrWS) To UBound(arrWS)
arrHolder() = Sheets(arrWS(iLoop)).UsedRange.Value
arrBB(iLoop) = arrHolder()
Next
End Sub
You could do this:
Dim varBBB()
Redim varBBB(LBound(varAAA) to UBound(varAAA))
For i = LBound(varAAA) to UBound(varAAA)
varBBB(i) = Sheets(varAAA(i)).UsedRange
Next i