【问题标题】:Excel VBA - use array for function (3 variables)Excel VBA - 将数组用于函数(3个变量)
【发布时间】:2018-09-17 15:08:39
【问题描述】:

在 Excel VBA 中,我有一个 y 函数,输入 3 个变量(a、b、c)。我想做的是使用 VBA 将此功能自动应用于一系列单元格(工作表中列出的 a、b 和 c 的组合)。

我设置数据的方式:

  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.

“点”是 function(a,b,c) 的结果应该结束的地方(例如,左上角的点应该是“function(1,1,2)”的结果)。值得注意的是,在一列内应该使用相同的 b 和 c 配对值(因此在同一列内,只有 'a' 变化,而 b 和 c 保持不变)。

此函数的先前版本只有 2 个变量作为输入(a 和 b,设置方式与上面的数据相同),我使用了一个二维数组(垂直行上的 '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

但是,既然我已经向函数添加了第三个变量 (c),我想使用函数 (a,b,c)。当我只有 2 个变量时,我很难让它像我一样工作。有没有办法仍然为此使用数组?

提前感谢您的帮助。

编辑:我想在函数中使用 a、b、c 的值(不是引用)

【问题讨论】:

  • 您希望生成的公式使用 a、b、c 的值还是对包含值的单元格的引用?
  • @chrisneilsen 我希望得到的公式使用 a、b、c 的值(而不是引用)。我编辑了问题以明确这一点。
  • 更改为`b = .Range("C2:CG3").Value` 和= "=function(" & a(i, 1) & ", " & b(1, j) & "," &b(2,j) & ")"
  • @chrisneilsen 这似乎可行,谢谢!有没有办法将您的评论标记为有帮助?

标签: arrays vba excel function


【解决方案1】:

使用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

虽然您可以将bc 保留在二维数组中以稍微缩短代码:

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

注意:我使用“MyFunction”而不是“function”来运行我的测试。将“MyFunction”更改为您的实际函数名称

【讨论】:

    【解决方案2】:
    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
    

    我不确定这是否是您想要的。在数组中使用三个元素时遇到的问题是您丢失了从二维结果集到三维数组的映射。因此,当您想将结果转移到工作表上时,您必须做一些不同的事情,即不仅仅是绘制数组的内容。简短的回答会破坏您的问题,但是如果可以做到,您可以添加许多维度,但是在将其映射到二维结果集时,效率会越来越低,而且越来越笨拙。我没有用上面的代码重新创建你的所有代码,但我已经包含了足够多的代码来向你展示另一种方法。我不是在检查我在哪个工作表上或完全引用单元格等,而是把它放在一个工作表中,它会做我认为你想要的然后修改以攻击正确的工作表等。

    【讨论】:

      猜你喜欢
      • 2020-01-02
      • 2017-11-04
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多