简体   繁体   English

Excel VBA-对函数使用数组(3个变量)

[英]Excel VBA - use array for function (3 variables)

In Excel VBA, I have a function for y with input of 3 variables (a, b, c). 在Excel VBA中,我有一个y函数,输入了3个变量(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). 我想做的是使用VBA自动将此功能应用于一系列单元格(工作表中列出的a,b和c的组合)。

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)"). “点”是函数(a,b,c)的结果应终止的位置(例如,左上角的点应为“ 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). 值得注意的是,在一列中应使用相同的b和c配对值(因此,在同一列中,只有“ a”变化而b和c保持不变)。

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: 该函数的先前版本只有2个变量作为输入(a和b,设置方式与上面的数据相同),我使用了2D数组(垂直行上“ a”的值,“ b”的值'(在水平列上)),使用以下代码将函数应用于a和b的所有组合:

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). 但是,既然我已经向函数添加了第三个变量(c),我想使用function(a,b,c)。 I have some trouble getting it to work like I did when I only had 2 variables. 我很难像我只有2个变量时那样工作。 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 编辑:我想在函数中使用a,b,c的值(不是引用)

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: 使用Application.Transpose()处理一维数组,这使事情变得更简单:

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: 虽然可以将bc保留在2D数组中以缩短代码一些:

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. 注意:我使用“ MyFunction”而不是“ function”来进行测试。 Change "MyFunction" to your actual function name 将“ MyFunction”更改为您的实际函数名称

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM