VBA Trend returned value - arrays

I have two array defined inside of VBA, and I want to find by linear interpolation points in between based on known values.
Sub example()
Dim boundpoint(1 To 2) As Integer
Dim boundeleva(1 To 2) As Double
Dim totELEV as Integer
ReDim plvl(201) as Double
Dim out As Variant
totELEV = 12
boundeleva(1) = -61.90
boundeleva(2) = -260.25
boundpoint(1) = 1
boundpoint(2) = 201
For i = 1 to totELEV
out = Application.WorksheetFunction.Trend(boundPoint,boundEleva,ELEV(i),True)
plvl(i) = Application.WorksheetFunction.RoundUp(out,0)
Next i
End Sub
But of course it is not working due to mismatch. If I understand it right, "trend" is returning an array for each ELEV(i).
Now I just want the returned value to be a Double that can be rounded up to the closest Integer.
Any suggestion?
Thank you!

Related

Problem working with variant data type w/vba

I am trying to learn to use variant data type but facing issues.
Public Function z_score(sections As Range, marks As Range) As Variant
Dim n As Integer
Dim score() As Variant 'marks range has a few empty cells and error cells as well
'hence using variant data type
n = UBound(sections.Value)
ReDim score(1 To n, 1 To 2)
score = marks.Value 'assigning marks range values to first column of score
For i = 1 To n 'adding second column with integer index for calling later
score(i, 2) = i
Next i
z_score = score
End Function
I am getting value error instead of nx2 matrix as output.
Can you please help how to resolve the error.
Any help is much appreciated, thanks..
There are a few areas that could cause this code to fail, I'm afraid:
If the passed in range is only 1 cell, the assignment to an array will throw an error.
VBA doesn't have a method for copying or cloning arrays, so your code score = marks.Value isn't doing what your comments are saying,
The sections parameter doesn't appear to be doing anything. You are sizing the array against it, but then iterating the marks array to assign values.
I'm not sure what you want to do with the function, but if it is a UDF called from a worksheet, it would need to be a formula array.
You could adjust your code as follows to have something a little more robust:
Public Function z_score(marks As Range) As Variant
Dim scoreArray() As Variant, marksArray() As Variant
Dim i As Long
marksArray = RangeValueToArray(marks)
ReDim scoreArray(1 To UBound(marksArray, 1), 1 To 2)
For i = 1 To UBound(marksArray, 1)
scoreArray(i, 1) = i
scoreArray(i, 2) = marksArray(i, 1)
Next
z_score = scoreArray
End Function
Private Function RangeValueToArray(rng As Range) As Variant
Dim v() As Variant
If rng.Cells.Count = 1 Then
ReDim v(1 To 1, 1 To 1)
v(1, 1) = rng.Value2
RangeValueToArray = v
Exit Function
End If
v = rng.Value2
RangeValueToArray = v
End Function
I think I figured out the problem. Assigning values of range to array works but makes the assigned array two dimensional array but with only 1 column if given range has only one column or row! So moving the redim with preserve to after assignment line worked for my purpose.
But if one wants to assign values to a column other than first in a 2D array (albeit with 1 column), only solution I am aware of at this point is to do iteration the way Ambie suggested.
Public Function z_score(sections As Range, marks As Range) As Variant
Dim score() As Variant 'marks range has a few empty cells and error cells as well
'hence using variant data type
Dim n As Integer
n = UBound(sections.Value)
score = marks.Value 'assigning marks range values to first column of score
ReDim Preserve score(1 To n, 1 To 2)
For i = 1 To n 'adding second column with integer index for calling later
score(i, 2) = i
Next i
z_score = score
End Function

Element wise array operations in VBA Function

I have created a custom Function in VBA, the inputs to which are a cell value and three different ranges of the same length. The code is as below more or less:
Public Function MYTEST(CELLVALUE As Double, ByRef INPRNG As Range, ByRef RNG1 As Range, ByRef RNG2 As Range)
Dim i As Double
DIM A As Double
DIM B As Double
Dim MODRNG As Range
For i = LBound(INPRNG) To UBound(INPRNG)
MODRNG(i) = INPRNG(i) * RNG1(i) + CELLVALUE * RNG2(i)
Next i
A= MODRNG.Cells(1,1)
B= MODRNG.Cells(2,1)
mytest =A+B
End Function
I get a #VALUE! error when I run this code.
My question is three fold:
Are my variables/ranges declared incorrectly or is the For loop causing issues?
Is there a way to use For Each loop instead of For Next?
Can I do the array operation (of the for loop) in my excel worksheet and send the modified array to the function?
Please see the snap shot for clarity.
Thanks!
I'm not sure if I understood your goal, but this will throw a number taking from first and second (cell/array position) for the MODRNG.
Option Explicit
Public Function MYTEST(CELLVALUE As Double, ByRef INPRNG As Range, ByRef RNG1 As Range, ByRef RNG2 As Range) As Long
Dim i As Double
Dim A As Double
Dim B As Double
ReDim MODRNG(1 To INPRNG.Cells.Count)
For i = 1 To INPRNG.Cells.Count
MODRNG(i) = INPRNG(i) * RNG1(i) + CELLVALUE * RNG2(i)
Next i
A = MODRNG(1)
B = MODRNG(2)
MYTEST = A + B
End Function
thought If you only want the first and second values, I don't see why would you take a range bigger than 2 cells.

Using VBA to assign range of cell values to array of variables

I'm very new to VBA, to bear with me here.
I want to assign a set of variables the value of a set of ranges ie. run a brief code to simplify the following
Dim Sample 1 as string
Sample1 = activeworksheet.range("C17").value
Dim Sample 2 as string
Sample2 = activeworksheet.range("C18").value}
and so on
Following an excelfunctions.net tutorial, I know that I can shorten the declaration to
Dim Sample(1 to 20) as a string
But the tutorial drops it there(because it's a tutorial about names), suggesting I populate it as follows
sample(1)=activesheet.range("C7").value
sample(2)=activesheet.range("C7").value
and so on
I found the discussion below to be on the right track to answer my quest, but I am having trouble applying it to my situation. (Excel VBA Array Ranges for a loop)
As a follow up note, I am ultimately trying to assign values to these variables for use in the following procedures, rather than declaring and assigning them each time.
Thanks!
Try something like this:
Sub test()
Dim sampleArr(1 To 20) As String
Dim i As Integer
Dim rng As Range, cel As Range
i = 1
Set rng = Range("C1:C20")
For Each cel In rng
sampleArr(i) = cel.Value
i = i + 1
Next cel
For i = LBound(sampleArr) To UBound(sampleArr)
Debug.Print sampleArr(i)
Next i
Also, if you know the range you want to put into an array, you can simply set an array to that range:
Sub test()
Dim sampleArr() As Variant
Dim i As Integer
Dim rng As Range, cel As Range
i = 1
Set rng = Range("C1:C20") ' Note, this creates a 2 Dimensional array
sampleArr = rng ' Right here, this sets the values in the range to this array.
For i = LBound(sampleArr) To UBound(sampleArr)
Debug.Print sampleArr(i, 1) ' you need the ",1" since this is 2D.
Next i
End Sub
You should :
Define the range you want to retrieve data
For each cell of the range, retrieve your datas
dim tab() As string, cell as range, i as integer
i = 0
redim tab(0)
for each cell in ActiveWorksheet.Range("C1:C20")
tab(i) = cell
i = i + 1
redim preserve tab(i)
next
edit : I indent the code to display it correctly
Additional way to the above you can only use:
Arr = ActiveWorksheet.Range("C1:C20").Value
Then you can directly use:
Arr(i,1) where i is C1 to C20 range!

Assigning Range array from a returning function

I want to have an array of ranges to create charts from them.
Here's how I had it:
Dim infoR As Range
Dim aRng() As Range
Dim numLvls As Integer
Set infoR = Range("H1:H100");
numLvls = getLevels()
Set aRng() = getOnlyNumericCellToArrayRanges(infoR, numLvls)
The function is this:
Function getOnlyNumericCellsRangesArrays(ByVal actRange As Range, ByVal numLvls As Integer) As Range()
Dim aRng() As Range
Redim aRng(0 To numLvls - 1)
'Some code
Set getOnlyNumericCellToArrayRanges = aRng()
End Function
I've seen several arrays examples over the internet and they use variant as a data type for that means but it doesn't compile like that too.
I've found that works with some changes:
Dim aRng
'Some code
aRng = getOnlyNumericCellToArrayRanges(infoR)
I think passing the array by reference could work, however I want to know if there is a way to make the array declaration and assignment to Range data type explicitly from the beginning.
Or how can I cast the result array back into a Range array?
An array is not an object (even when it's an array of objects), so you don't need Set here...
Sub Tester()
Dim arrRng() As Range, x As Long
arrRng = GetRangeArray()
For x = LBound(arrRng) To UBound(arrRng)
Debug.Print arrRng(x).Address()
Next x
End Sub
Function GetRangeArray() As Range()
Dim arrRng() As Range
ReDim arrRng(1 To 3)
Set arrRng(1) = ActiveSheet.Range("A1")
Set arrRng(2) = ActiveSheet.Range("A3")
Set arrRng(3) = ActiveSheet.Range("A5")
GetRangeArray = arrRng
End Function

Assigning an array value to a variable in VBA causes my UDF to exit

I can't seem to figure out why this UDF is exiting on the currentInput = inputArray(i). Here is the relevant code:
Function OrderRange(inputRange As Range) As Variant
Dim length As Integer
inputHeight = inputRange.Count
Dim inputArray As Variant
inputArray = inputRange
Dim strippedArray() As Variant
ReDim strippedArray(0 To (inputHeight - 1))
Dim currentInput As String
Dim i As Integer
For i = 0 To (inputHeight - 1)
currentInput = inputArray(i)
'...computations on currentInput...'
strippedArray(i) = currentInput
Next i
OrderRange = strippedArray
End Function
The debugger reaches currentInput = inputArray(i) but once I move to the next line, the function terminates and a #VALUE! error is entered into the cell I call the function from. I know this is a specific question, but I'm sure it's a general issue and I'll edit this original post to reflect what the general problem is.
Edit: This is an issue regarding assignment of a range to a variant array.
Variant arrays created by setting them equal to ranges have two dimensions even if they are only one column, or row, wide. So if you call the function with A1:A10 you'll get a 10 * 1 array. Also the lower bound of the dimensions will be one, not zero. So you'd have to do something like:
For i = 1 To (inputHeight)
currentInput = inputArray(i, 1)
Also you should use Option Explicit so that you're reminded to declare all variables. InputHeight is never declared.

Resources