In Excel VBA, I have a function for y with input of 3 variables (a, b, c). What I would like to do is to use VBA to apply this function automatically to a range of cells (combinations of a, b and c as listed in the worksheet).
The way I have my data set up:
b 1 1 1 1 1 2 2 2 2 3 3 3 4 4 etc.
c 2 3 4 5 6 3 4 5 6 4 5 6 5 6 etc.
a
1 . . . . . . . . . . . . . .
2 . . . . . . . . . . . . . .
3 . . . . . . . . . . . . . .
4 . . . . . . . . . . . . . .
etc.
The 'dots' are where the results of function(a,b,c) should end up (eg, top left dot should be result of "function(1,1,2)"). Of note, within a column the same paired values of b and c should be used (so within the same column, only 'a' varies while b and c remain constant).
A previous version of this function only had 2 variables as input (a and b, set up in the same way as the data above), and I used a 2D-array (values of 'a' on rows vertically, values of 'b' on columns horizontally) to apply the function on all combinations of a and b using the following code:
Sub applyfunction()
Dim ws As Worksheet
Dim arr_ab()
Dim a, b, i As Long, j As Long
For Each ws In Worksheets
If ws.Name Like "Util*" Then
With ws
a = .Range("B5:B244").Value
b = .Range("C2:CG2").Value
ReDim arr_ab(1 To UBound(a), 1 To UBound(b, 2))
For i = LBound(arr_ab) To UBound(arr_ab)
For j = LBound(arr_ab, 2) To UBound(arr_ab, 2)
arr_ab(a, b) = "=function(" & a(i, 1) & ", " & b(1, j) & ")"
Next j
Next i
.Range("C5:CG244").Value = arr_ab()
End With
End If
Next ws
End Sub
However, now that I have added a third variable (c) to the function, I want to use function(a,b,c). I have some trouble getting it to work like I did when I only had 2 variables. Is there a way to still use an array for this?
Thanks in advance for any help.
Edit: I want to use the values (not the references) of a,b,c in the function
Option Explicit
Sub ApplyFunction()
Dim Arng As Range: Set Arng = Application.Range("A4:A8")
Dim AVal As Integer
Dim ACell As Range
Dim ARow As Integer
Dim Brng As Range: Set Brng = Application.Range("C1:G1")
Dim BVal As Integer
Dim BCell As Range
Dim BCol As Integer
Dim BRow As Integer
Dim CVal As Integer
For Each ACell In Arng
AVal = ACell.Value
ARow = ACell.Row
For Each BCell In Brng
BVal = BCell.Value
BCol = BCell.Column
BRow = BCell.Row
CVal = Cells(BRow + 1, BCol)
Cells(ARow, BCol) = ABC(AVal, BVal, CVal)
Next
Next
End Sub
Function ABC(A As Integer, B As Integer, C As Integer) As Integer
ABC = A * B * C
End Function
I'm not sure if this is what you want or not. The problem you have with using three elements in the array is you lose the mapping from a 2 dimensional result set to a three dimensional array. So you would have to do something different when you want to transfer the results on to your work sheet ie not just plot the contents of the array. The short answer rot your question though is yes if can be done you could add many dimensions but it would get less and less efficient and more clumsy in mapping it to a two dimensional result set. I haven't recreated all your code with mine above but I have included enough to show you another way of doing it. I'm not checking what sheet I'm on or fully referencing cells etc but put it in a sheet and it'll do what I think you want then modify to attack the right sheets etc..
Use Application.Transpose()
to deal with 1D array, this makes things simpler:
Sub applyfunction()
Dim ws As Worksheet
Dim a As Variant, b As Variant, c As Variant
Dim i As Long, j As Long
For Each ws In Worksheets
If ws.name Like "Util*" Then
With ws
a = Application.Transpose(.Range("B5", Cells(.Rows.Count, "B").End(xlUp)).Value)
b = Application.Transpose(Application.Transpose(.Range("C2", .Cells(2, .Columns.Count).End(xlToLeft)).Value))
c = Application.Transpose(Application.Transpose(.Range("C3").Resize(, UBound(b)).Value))
ReDim abc(1 To UBound(a), 1 To UBound(b))
For i = LBound(a) To UBound(a)
For j = LBound(b) To UBound(b)
abc(i, j) = "=MyFunction(" & a(i) & ", " & b(j) & ", " & c(j) & ")"
Next j
Next i
.Range("C5").Resize(UBound(a), UBound(b)).Value = abc()
End With
End If
Next
End Sub
While you may keep b
and c
in a 2D array to shorten the code a little:
Sub applyfunction()
Dim ws As Worksheet
Dim a As Variant, bc As Variant
Dim i As Long, j As Long
For Each ws In Worksheets
If ws.name Like "Util*" Then
With ws
a = Application.Transpose(.Range("B5", Cells(.Rows.Count, "B").End(xlUp)).Value)
bc = .Range("C2", .Cells(2, .Columns.Count).End(xlToLeft)).Resize(2).Value
ReDim abc(1 To UBound(a), 1 To UBound(bc, 2))
For i = LBound(a) To UBound(a)
For j = LBound(bc, 2) To UBound(bc, 2)
abc(i, j) = "=MyFunction(" & a(i) & ", " & bc(1, j) & ", " & bc(2, j) & ")"
Next
Next
.Range("C5").Resize(UBound(a), UBound(bc, 2)).Value = abc()
End With
End If
Next
End Sub
NOTE: I used "MyFunction" instead of "function" to make my test run. Change "MyFunction" to your actual function name
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.