Getting the index of item in an array VBA - arrays

I am trying to get the index of the item in an array VBA, but I have issue getting it.
Const NoOfVol As Integer = 5
Dim vol(NoOfVol) As Integer
For Index = 1 To NoOfVol
vol(Index) = Cells(15 + Index, 8).Value
Next
The array looks like this: (-2500,-1250,0,1250,2500). I am calling the function this way.
Function Find(ByVal Value As Variant, arr As Variant) As Integer
Find = Application.Match(Value, arr, False)
End Function
posOfVol = Find(-1250, vol)
But the posOfVol = 3, when it should be 2. Not sure where my error is. Need some guidance on this.

Your array is actually effectively declared as:
Dim vol(0 to NoOfVol) As Integer
unless you have an Option Base 1 statement. Since your loop goes from 1 to 5, you never populate the first element of the array and it retains its default value of 0. Therefore your array is actually:
(0,-2500,-1250,0,1250,2500)
and since you are looking for an exact match, -1250 is found at the third position.

Related

VBA UDF multiple array arguments

I am trying to make a UDF in VBA that takes multiple arrays of equal size as an argument and then loops through them staying at the same index for each array.
I have set the code up as follows.
Public Function TwoArrays(TargetRange(), CriteriaRange())
dim value as range
for each value in TargetRange
next
end function
The issue is I can't get the index of the TargetRange to use in the CriteriaRange and even if I could for whatever reason whenever I put something like
CriteriaRange(2)
I get an error instead of what happens to be within that index.
Is there a way I can get the UDF to treat the array like a normal VBA array where I can do something along the lines of
Public Function TwoArrays(TargetRange(), CriteriaRange())
dim result as range
for i = lowerbound(TargetRange) to ubound(TargetRange)
If CriteriaRange(i) > 0 then
result = result + TargetRange(i)
end if
next i
end function
Thank you!
Like this:
Public Function TwoArrays(TargetRange As Range, CriteriaRange As Range)
Dim result, arrT, arrC, r As Long, c As Long
arrT = TargetRange.Value
arrC = CriteriaRange.Value
'probably should add some code here to check both ranges are the same size...
For r = 1 To UBound(arrT, 1)
For c = 1 To UBound(arrT, 2)
If arrC(r, c) > 0 Then result = result + arrT(r, c)
Next c
Next r
TwoArrays = result
End Function

How do I return a value from 2 overloaded functions with different return types?

I created two functions to import (make) an array from a text file. They have the same function names but different number of parameters. They also have return values which are different since one importArray function is returning a 1D array and the other is returning a 2D array.
Overloads Function importArray(fileName As String) As Array
Overloads Function importArray(fileName As String, splitter As Char) As Array
Sub Main()
Dim getArray As New MakeArray
Dim printArray() As String = getArray.importArray("array.txt")
For i = 0 To printArray.Length - 1
'printArray
Next
Console.ReadKey()
End Sub
I can't seem to wrap my head around this. I can enter 2 parameters when calling the function or 1 then it's fine, but I don't know how I could specify which function to call, because when I am printing the array I don't know whether to use the 1D or 2D array. I can't do 2 for loops since using one dimension or 2 throws an error "Expression is not a method" so I'm not sure how I can get around this.
Is there a way I could determine whether I am using a 1D or 2D array by reading the text file? I wanted to keep the code as efficient as possible.
Thank you!
Firstly, don't use the Array type that way. If the method return String array, that should be the return type. If it returns a 2D String array then that should be the return type.
Overloads Function ImportArray(fileName As String) As String()
Overloads Function ImportArray(fileName As String, splitter As Char) As String(,)
When you call one of the functions, you assign it to a variable of the appropriate type for the method you're calling. Just think of them as two different methods. Then, you either use a single loop of two nested loops to traverse the data.
Dim arr1 As String() = getArray.ImportArray(fileName)
For i = 0 To arr1.GetUpperBound(0)
'...
Next
Dim arr2 As String(,) = getArray.ImportArray(fileName, splitter)
For i = 0 To arr2.GetUpperBound(0)
For j = 0 To arr2.GetUpperBound(1)
'...
Next
Next

How to Pass an Array to and from a Function?

(Fair Warning, I am self taught on VBA so I apologize in advance for any cringe-worthy coding or notations.)
I have an estimating worksheet in excel. The worksheet will have a section for the user to input variables (which will be an array). The first input variable will "reset" the remaining input variables to a standard value when the first variable is changed. The standard values for the input variables are stored in a function in a module. I am attempting to fill the input variable array with the standard values from the function and then display those values on the sheet. I was easily able to do this without arrays but have had no luck in moving everything into arrays.
This is for excel 2010. I previously did not use arrays and created a new variable when needed, however the estimating sheet has grown much larger and it would be better to use arrays at this point. I have googled this question quite a bit, played around with removing and adding parenthesis, changing the type to Variant, trying to set the input variable array to be a variable that is an array (if that makes sense?), and briefly looked into ParamArray but that does not seem applicable here.
Dim BearingDim(1 To 9, 1 To 4, 1 To 8) As Range
Dim arrBearingGeneral(1 To 5, 1 To 8) As Range
Dim Test As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
'Set General Variable array to cells on the worksheet
For i = 1 To 5
For j = 1 To 8
Set arrBearingGeneral(i, j) = Cells(9 + i, 3 + j)
Next j
Next i
'Set Bearing Input Variables to Cells on the Worksheet
For p = 1 To 4
For i = 1 To 9
Select Case p
Case Is = 1
Set BearingDim(i, p, 1) = Cells(16 + i, 4)
Case Is = 2
Set BearingDim(i, p, 1) = Cells(27 + i, 4)
Case Is = 3
Set BearingDim(i, p, 1) = Cells(37 + i, 4)
Case Is = 4
Set BearingDim(i, p, 1) = Cells(49 + i, 4)
End Select
Next i
Next p
'Autopopulate standard input variables based on Bearing Type
inputMD_StdRocker BearingType:=arrBearingGeneral(1, 1), _
arrBearingDim:=BearingDim
End Sub
Sub inputMD_StdRocker(ByVal BearingType As String, ByRef _
arrBearingDim() As Variant)
Dim arrBearingDim(1 To 9, 1 To 4)
Select Case BearingType
Case Is = "MF50-I"
For j = 1 To 2
arrBearingDim(2, j) = 20
arrBearingDim(3, j) = 9
arrBearingDim(4, j) = 1.75
Next j
arrBearingDim(5, 1) = 15
'There are numerous more select case, but those were removed to keep it
'short
End Select
End Sub
The expected output is my "BearingDim" Array will have certain array index values set to a standard value from the "inputMD_StdRocker" function. Then those values will be displayed in the cell that corresponds to the array index.
Currently, I get a compile error "Type Mismatch, Array or User-Defined Type Expected". I have been able to get around the type mismatch by removing the () from "arrBearingDim()" in the function title for "inputMD_StdRocker" however, it will not pass the values back to my "BearingDim" array.
Any help would be greatly appreciated.
This is a partial answer to what (I think) is a misunderstanding you have of how to use arrays. There are a few problems in your code.
First, you're defining a two-dimensional and a three-dimensional array of Ranges when I believe you really only want to store the values captured from the worksheet. (If I'm wrong, then you are never initializing the array of Ranges, so none of the ranges in the array actually point to anything.)
Secondly, it looks as if your initial array arrBearingGeneral is always filled from the same (static) area of the worksheet. If this is so (and you really do want the values from the cells, not an array of Range objects), then you can create a memory-based array (read this website, especially section 19). So the first part of your code can be reduced to
'--- create and populate a memory-based array
Dim bearingDataArea As Range
Dim arrBearingGeneral(1 To 5, 1 To 8) As Variant
Set bearingDataArea = ThisWorkbook.Sheets("Sheet1").Range("D10:K14")
arrBearingGeneral = bearingDataArea.Value
Optionally of course you can calculate the range of your data instead of hard-coding it ("D10:K14"), but this example follows your own example.
While this isn't a complete answer, hopefully it clears up an issue to get you farther down the road.

remove an item from an integer array

I'm trying to remove an element from an integer array given its index, are there any simple ways of accomplishing just that in VB.Net?
All I can find is .RemoveAt() for removing a string in an ArrayList, but none for an integer in an integer array.
Dim PossibleValues(8) As Integer
For x As Integer = 0 To 8
PossibleValues(x) = x + 1
Next
Added the code, don't think it entails much as I am now trying to find ways to remove an element from the array PossibleValues
The problem with removing an item from an array is that it is of fixed size. So The simplest way is to convert the array to a list, ToList(), and then do the RemoveAt and then, if you need to, convert it back to a new array with ToArray().
EDIT
Dim PossibleValues(8) As Integer
For x As Integer = 0 To 8
PossibleValues(x) = x + 1
Next
Dim tempList = PossibleValues.ToList()
tempList.RemoveAt(1)
PossibleValues = tempList.ToArray()

VBA function fails when inserting values into Array

I'm totally stumped on why this isn't returning a value. This set of functions is supposed to return the SUM of all the ASCII values in a String. The String and Number arrays build properly and the SUM function works on the Array, however when it tries to assign that summed value to the return variable, it fails.
By "it fails" I mean that the code does not step to the sum line and the function returns #VALUE! to the worksheet. Everything else checks out in the immediate window and steps through properly until the last line. Any suggestions are appreciated.
Private Function StringToCharArray(ByRef sIn As String) As String()
StringToCharArray = Split(StrConv(sIn, vbUnicode), Chr(0))
'provided by Fencliff at http://www.mrexcel.com/forum/excel-questions/342725-split-string-into-array.html
End Function
Function StringToNumber(MyString As String) As Integer
Dim StringArray() As String
Dim NumberArray() As Long
StringArray() = StringToCharArray(MyString)
ReDim NumberArray(UBound(StringArray))
For i = LBound(StringArray) To UBound(StringArray)
NumberArray(i) = Asc(StringArray(i))
Next i
StringToNumber = Application.WorksheetFunction.Sum(NumberArray)
End Function
Using an example of "abc" the Split obtains an array "a", "b", "c", "". That is, with an empty string element at the end. This cannot be converted to an ascii number so causes the error.
A simplistic solution is to skip this last element:
For i = LBound(StringArray) To UBound(StringArray) - 1
I suspect the problem (the extra element) is related to the use of Unicode but I haven't investigated this.

Resources