How to define the Array Size in variable - vba

my array size is decided by the some other function. but when i tried to define the size of the array using the variable i am getting the error "Constant Expression Required"
i would like define the size of the array
Option Explicit
Sub Abcd()
Dim n_variables As Integer
n_variables = def()
MsgBox "n_variables" & n_variables
Dim abc(1 To n_variables) As Integer
End Sub
Function def()
def = 100
End Function
is there any way i can define the array size in variable format?
Any one help me please.

Use the Redim statement:
Dim n_variables As Integer
n_variables = def()
MsgBox "n_variables" & n_variables
Dim abc() As Integer
Redim abc(1 To n_variables) As Integer

Related

two-dimensional array to an array in visual basic

I've got a question about using two-dimensional array.
Public twolist(,) As String
For i As Integer = 0 To twolist.length()-1
If Func(twolist(i, )) Then 'this part is hard for me
'doing something
End If
Public Function Func(ByVal CancelInput() As String) As Boolean
What i want to do is Passing two-dimensional array to an array.
I want to read one row in two-dimensional array and pass to function(Func), which is using an array.
Hope You can understand my question... and Thank you!
As an alternative to the For Next Loop, you could use Linq (if you are confortable with it) to perform the same task.
This transforms each element of the source array to a String, groups them in an IEnumerable(Of String) and the result is converted to an unidimensional Array of Strings:
Dim twolist(N, N) As String
Dim CancelInput() As String = twolist.Cast(Of String).Select(Function(str) str).ToArray()
Dim result As Boolean = Func(CancelInput)
I have just used an arbitrary size for your array. You need nested For loops to iterate through a 2 dimensional array. The outer loop goes through the rows and the inner loop adds the value in each field to another array that you are passing to your Function. Each row is passed individually as a single dimension array.
Private Sub TwoDimensionalArray()
Dim twolist(,) As String
ReDim twolist(10, 5)
'First you will need to add data to your array
For x As Integer = 0 To 10
Dim arrayRow(5) As String
For y As Integer = 0 To 5
arrayRow(y) = twolist(x, y)
Next
If Func(arrayRow) Then 'this part is hard for me
'doing something
End If
Next
End Sub
Public Function Func(ByVal CancelInput() As String) As Boolean
Return True
End Function
Mary's answer is good, but assumes you know the length of each dimension.
I have changed it slightly to use the Array.GetLength function:
Private Sub TwoDimensionalArray()
Dim twolist(,) As String
ReDim twolist(10, 5)
'First you will need to add data to your array
For x As Integer = 0 To 10
'Fetch the length of this dimension:
Dim i As Integer = twolist.GetLength(x)
Dim arrayRow(i) As String
For y As Integer = 0 To i - 1
arrayRow(y) = twolist(x, y)
Next
If Func(arrayRow) Then
'do something
End If
Next
End Sub
Public Function Func(ByVal CancelInput() As String) As Boolean
Return True
End Function
Note:
In VB.Net, ReDim twoList(10,5) actually gives you an array of (11,6).
Array.GetLength(0) will return 6 (0,1,2,3,4,5).
In short, Dim specifies the maximum index in each dimension, Length & GetLength return the count of elements.

Excel vba percentile worksheetfunction function with collection argument

Is there a way to call Application.Worksheetfunction.Percentile(resultColl) where resultColl is a Collection?
I tried it and it returns a Unable to get Percentile property of the WorksheetFunction class error.
EDIT:
I tried to first convert that collection to array:
Function convertToArray(resultColl As Collection)
Dim resultArray() As Variant
ReDim resultArray(1 To resultColl.Count)
Dim i As Long
For i = 1 To resultColl.Count
resultArray(i) = resultColl.Item(i)
Next
convertToArray = resultArray
End Function
and use that array inside Percentile function:
Application.WorksheetFunction.Percentile( _
convertToArray(clientsColl.Item(1).getSumLosses), 0.99)
But now it returns a wrong number of arguments or invalid property assignment error at convertToArray function, even though in this test example I created, the function works fine:
Sub testConvert() 'this works fine
Dim testColl As Collection
Set testColl = New Collection
testColl.Add "apple"
testColl.Add "orange"
testColl.Add "pineapple"
Dim tempArray() As Variant
tempArray = convertToArray(testColl)
MsgBox (tempArray(1))
End Sub
clientsColl.Item(1).getSumLosses is a Collection:
inside Client class:
Private sumLosses As Collection 'the collection of numbers, a percentile of which I need to calculate
Private Sub Class_Initialize()
Set sumLosses = New Collection
End Sub
Public Property Get getSumLosses()
Set getSumLosses = sumLosses
End Property
EDIT2:
Changed the Percentile function call to this:
Dim tempArray() As Variant
tempArray = convertToArray(clientsColl.Item(1).getSumLosses)
resultDict.Add "UL: " & _
Application.WorksheetFunction.Percentile(tempArray, 0.99)
the error occurs on the line with resultDict.
Figured it out. The adding to the dictionary was done in a wrong way:
resultDict.Add "UL: " & _
Application.WorksheetFunction.Percentile(tempArray, 0.99)
instead of
resultDict.Add "UL: ", _
Application.WorksheetFunction.Percentile(tempArray, 0.99)

Error dimensioning an array to a dynamic size

The following code:
Sub mySub()
Dim s As String
s = "jdsjakfjdaskl"
Dim a(Len(s)) As String
End Sub
Gives an error
"Compile error: Constant expression required".
I would really appreciate any advice on how to fix this, thanks!
You have to use ReDim if you wish the size of an array to be set at run-time:
Sub mySub()
Dim s As String
Dim a() As String
s = "jdsjakfjdaskl"
ReDim a(1 To Len(s)) As String
'The "As String" in the above statement is optional as it already knows
'it is of type String, so you can simplify that if you like to:
'ReDim a(1 To Len(s))
End Sub

calling a function to return an array - type mismatch

I have a custom type as shown below,
Public Type TypeFieldColumn
iCol As Integer
dRow As Double
End Type
I then have the following sub routine
Private Sub PopulateWorksheet()
Dim wsTS As Worksheet
Dim clsData As New clsDatabase
Dim rsTS As New ADODB.Recordset
Dim Fields() As TypeFieldColumn
Set wsTS = ThisWorkbook.Sheets(SomeName)
Set rsTS = clsData.SomeMethod()
Fields = FindFactorColumns(rsTS, wsTS)
End Sub
which calls the function below
Private Function FindFactorColumns(rsTS As ADODB.Recordset, wsTS As Worksheets) As TypeFieldColumn()
Dim i As Integer
Dim index As Integer
Dim FactorName As String
Dim Flds() As TypeFieldColumn
ReDim Flds(1 To rsTS.Fields.Count - 1)
For i = 1 To rsTS.Fields.Count - 1
FactorName = rsTS.Fields(i).Name
index = MapBloombergIndexToFactorName(FactorName)
If index > 0 Then FactorName = pMap(index).MapName
Flds(i).iCol = Application.WorksheetFunction.Match(FactorName, wsTS.Range("1:1"), 0)
Next
FindFactorColumns = Flds
End Function
I get a run time error of type mismatch on the line Fields = FindFactorColumns(rsTS, wsTS) - I don't understand why though?
Only writing this up to save #Rory time, it is his answer.
The type mismatch occurred because wsTS, which was saved as a single worksheet in the Populate Worksheet Sub, was declared as multiple worksheets in the FindFactorColumn function.
Because the error line occured at the function call, #Rory was able to determine the type mismatch by looking at the type of the variables used in the Function and comparing them to the type of those same variables when saved in the Sub.

Array one dimensional. Why does split work and not Array()

Got a simple question. The Array() function in VBA does return a two dimensional array? I'm trying to create a one dimensional array with this function and use it in the filter() function but it says "type mismatch". And if that's the case, how can I force Array() to create a one dimensional array?
Sub tester()
Dim xWorkb As Excel.Workbook
Dim xFiles_target() As String
Dim file_path As String
xFiles_target = Array("Bella.xls", "Fizz.xls", "Milo.xls")
file_path = Dir("C:\Users\hans\Desktop\")
Do While Len(file_path) > 0
Debug.Print file_path
If UBound(Filter(xFiles_target, file_path)) >= 0 Then
Debug.Print "found " & file_path
End If
file_path = Dir
Loop
End Sub
Array function does create a 1D Array. However the function requires the variable you are assigning to, to be of Variant type. It cannot be String/Number.
Dim tmpArr() As String
tmpArr = Array("Hello", "World")
The above is likely to throw Type mismatch error. However,
Dim tmpArr()
tmpArr = Array("Hello", "World")
The above will take it as such. That is no error will be thrown but the tmpArray now has two elements to it.
The Split function will result in a String array. Although Variant type can take in String, a Number array cannot take in the Split function.
More information about this neatly organized here : http://patorjk.com/programming/tutorials/vbarrays.htm
Hope this helps.