Assigning an array to another array in one line - arrays

I'm new to VBA, and I can't seem to work out a very simple concept - assigning one array to another, both being of equal size and type. Like in this example:
Option Explicit
Sub main()
Dim arr1(2), arr2(2) As Double
arr1(0) = 5
arr1(1) = 10
arr2 = arr1 'error here
Debug.Print arr2(0)
Debug.Print arr2(0)
End Sub
Running this returns an error
"Can't assign to array"
Now, I know I can iterate through every element with a For loop, but in some advanced cases, it is impractical to use - for example, I have a slow-loading function that returns an array, and because of that, I'd like to run it only once, taking it's whole return value and assigning to some other array, like this:
arr1 = Very_Slow_Function_That_Returns_An_Array()
But obviously, this won't work either, and will produce the same error. So, what can be done? Can someone give some advice on how to assign a whole array to another array without having to iterate through every element?

You can assign an array to another in VBA like this:
Option Explicit
Sub main()
Dim arr1 As Variant
Dim arr2 As Variant
arr1 = Array(5, 10)
'Assign array1 to array2
arr2 = arr1
Debug.Print arr1(0)
Debug.Print arr2(0)
End Sub

These variations work:
Sub main()
Dim arr1() As Double, arr2() As Double
ReDim arr1(0 To 1)
arr1(0) = 5
arr1(1) = 10
arr2 = arr1
End Sub
or
Sub main()
Dim arr1() As Variant, arr2() As Variant
arr1 = Array(5, 10)
arr2 = arr1
End Sub
Third variation which is closest to OP code:
Sub main()
Dim arr1(0 To 1) As Double, arr2() As Double
arr1(0) = 5
arr1(1) = 10
arr2 = arr1 'no error here now.
End Sub

Related

Populating a dynamic array with cellvalues from one column VBA

I have the following problem: I imported a .csv file with my data into a separate worksheet called "Import".
In this QueryTable, I have the second column called "KW", which indicates the weeknumber for every row.
Now I wanted to populate an array with the cell values from the second column.
I need to make it dynamic, because the length of the array changes with each import.
So far I made the code below:
Sub PopulatingArrayVariable()
Dim myArray() As Variant
Dim TempArray() As Variant
Dim myTable As ListObject
Dim x As Long
Sheets("Import").Activate
Set myTable = ActiveSheet.ListObjects("database_all")
TempArray = myTable.DataBodyRange.Columns(2)
myArray = Application.Transpose(TempArray)
For x = LBound(myArray) To UBound(myArray)
Debug.Print myArray(x)
Next x
End Sub
I get the "runtime error 13": types not compatible
I get the error, but I don't know what exactly I need to change. Can someone please help me solve this?
Fix the Dim and use Set:
Sub PopulatingArrayVariable()
Dim myArray() As Variant '*** will be a 1D VBA array
Dim TempArray As Range '*** typical 2D range variable as part of a column
Dim myTable As ListObject
Dim x As Long
Sheets("Import").Activate
Set myTable = ActiveSheet.ListObjects("database_all")
Set TempArray = myTable.DataBodyRange.Columns(2)
myArray = Application.Transpose(TempArray)
For x = LBound(myArray) To UBound(myArray)
Debug.Print myArray(x)
Next x
End Sub
I would use an arraylist instead as it provides more flexibility. For example you can do something like this:
Sub test()
Dim arr As Object
Dim i As Long
Dim j As Long
Dim lastRow As Long
Set arr = CreateObject("System.Collections.ArrayList")
lastRow = Cells(Rows.Count, 2).End(xlUp).Row
j = 2
'Filling arrayLists
For i = 2 To lastRow
arr.Add ActiveSheet.Cells(i, 2)
Next i
'Read from arrayLists
For i = 0 To arr.Count - 1
Cells(j, 3) = arr(i)
j = j + 1
Next i
End Sub
Customize the code as required. It should resolve your issue.

Passing Array to Sub ByRef in Excel VBA

I am currently working on a project for my job. I have two Subs and want to fill an array with one of those and want to use it in the other Sub. Its hard to explain but here is the code so far:
Private Sub Find_CHNO(name As String, ByRef Myarray() As String)
Dim filter As String
Dim ws As Worksheet
Dim rng As Range
Dim i, j As Long
Set ws = Sheets("Stoffdatenbank")
Set rng = ws.Range("A1").CurrentRegion
filter = name
ReDim Myarray(4)
For i = 1 To rng.Rows.count
If InStr(1, rng.Cells(i, 2), filter) > 0 Then
For j = 1 To 4
Myarray(j) = rng.Cells(i, j + 2)
Next
End If
Next
End Sub
And
Private Sub b_heizwert_calculate_Click()
Dim wC, wH, wN, wO, Hi As Double
Dim arr1(0 To 4), arr2(0 To 4), arr3(0 To 4) As String
If arrL3(0) = "" Then
Call Find_CHNO(arrL1(0), arr1)
Call Find_CHNO(arrL2(0), arr2)
MsgBox arr1(0)
'wC = arrL1(1) * arr1(1)
Else
End If
End Sub
Whenever I press on the Button that triggers the second Sub I get the following error:
Compile Error: Incompatible Type: Data field or user-defined type expected
The following is marked blue when the error occurs: The "arr1" in the following line:
Call Find_CHNO(arrL1(0), arr1)
When you Dim arr1(0 To 4), arr2(0 To 4), arr3(0 To 4) As String only the last is a string array. The first two are variant arrays.
Define each definitively.
Dim arr1(0 To 4) As String, arr2(0 To 4) As String, arr3(0 To 4) As String
You are also defining arr1, arr2 and arr3 but using arrL1, arrL2 and arrL3 but I'll assume that is just a typo or they are publicly declared elsewhere.

How do I split the string into a long() type array in Excel VBA?

Let's say I have something like "1-34-52", I want to split them into an array, however, while Test1 works, it gives me an String() type array. How do I put the numbers in "1-34-52" into a Long() type array? Can I redim type of an array in VBA?
Sub Test1()
Dim arr As Variant
arr = Split("1-34-52", "-")
Debug.Print TypeName(arr), TypeName(arr(0))
End Sub
Sub Test2()
Dim arr() As Long
arr = Split("1-34-52") 'You get type mismatch error
End Sub
You can Redim an array of Variants. Since Variants can hold integer values, there is no problem:
Sub dural()
ary = Split("1-34-52", "-")
ReDim lary(0 To UBound(ary))
For i = 0 To UBound(ary)
lary(i) = CLng(ary(i))
Next i
End Sub
Note:
Sub dural()
ary = Split("1-34-52", "-")
Dim lary() As Long
ReDim lary(0 To UBound(ary))
For i = 0 To UBound(ary)
lary(i) = CLng(ary(i))
Next i
End Sub
will also work.
You can loop through the array and populate a new one:
Sub Test1()
Dim arr As Variant, LongArr() As Long, X As Long
arr = Split("1-34-52", "-")
ReDim LongArr(UBound(arr))
For X = LBound(arr) To UBound(arr)
LongArr(X) = CLng(arr(X))
Next
Debug.Print TypeName(arr), TypeName(arr(0))
Debug.Print TypeName(LongArr), TypeName(LongArr(0))
End Sub

Excel VBA Pass Cell Array into Function

I'm trying to write a simple VBA Function like this:
Public Function ReturnMMult(Arr1() As Variant, Arr2() As Variant) As Variant
ReturnMMult = WorksheetFunction.MMult(Arr1,Arr2)
End Function
But it always gives me #VALUE! I've tried changing the Arr's to Ranges, but that doesn't work either. I basically want to be able to write functions that can take ranges like $A1:$A10 or something like that. Looked in a lot of places, and can't figure it out. What am I doing wrong?
something like
Public Function M(a As Excel.Range, b As Excel.Range) As Variant()
Dim a1() As Variant
Dim a2() As Variant
a1 = a.value
a2 = b.value
M = Application.WorksheetFunction.MMult(a1, a2)
End Function
You need to bring them in as ranges then shift them to arrays:
Public Function ReturnMMult(Arr1rng As Range, Arr2rng As Range) As Variant
Dim Arr1() As Variant: Arr1 = Arr1rng.Value
Dim Arr2() As Variant: Arr2 = Arr2rng.Value
ReturnMMult = WorksheetFunction.MMult(Arr1, Arr2)
End Function
This is an example of usage of MMult worksheet function. Please adopt it to your situation.
Sub test()
Dim xArray As Variant, yArray As Variant, zArray As Variant
Dim Fn As Object
Set Fn = Application.WorksheetFunction
xArray = Range("A1:B2").Value
yArray = Range("D1:E2").Value
zArray = Fn.MMult(xArray, yArray)
ActiveCell.Resize(2, 2).Value = zArray
End Sub
MMult returns the #VALUE! error when:
Any cells are empty or contain text.
The number of columns in array1 is different from the number of rows in array2.
The size of the resulting array is equal to or greater than a total of 5,461 cells. Reference WorksheetFunction.MMult method

Array not populating from For Loop VBA

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

Resources