【问题标题】:User defined function changing each value in an array用户定义函数更改数组中的每个值
【发布时间】:2017-02-17 19:15:29
【问题描述】:

以下是我的简单死亡率表混合代码。死亡率表始终是一个包含 106 个值的数组。运行此代码会导致 #value 错误,我不知道为什么。

Public Function MorBlend(Table1 As Variant, Blend As Double, Table2 As Variant) As Variant

Dim Table3 As Variant, int1 As Double
int1 = 0

Do While int1 <= 105

    Table3(int1) = Round(Table1(int1) * Blend / 1000000 + Table2(int1) * (1 - Blend) / 1000000, 6) * 1000000
    int1 = int1 + 1
Loop

MorBlend = Table3

End Function

【问题讨论】:

  • 了解Table1BlendTable2 是什么可能会有所帮助。
  • 您是想将数组返回给代码,还是将其用作工作表函数?
  • 为了让您的Table3(int1) = ... 行工作,您需要将Table3 声明为一个数组,当前的下限为0,上限至少为@987654327 的任何值@ 会到达。但是,如果您打算将其用作 UDF,则下限需要为 1,因此您需要将 int1 初始化为 1
  • 如果Table1Table2 是工作表上的单列范围,则table1(0) 可能指的是包含文本的标题行,而不是数字数据的第一行。另外,你需要调整Table 3的大小。
  • 感谢您的建议。表 1 和表 2 是两个死亡率表,都有 106 个值,混合是表 1 在混合中使用的百分比。

标签: arrays excel function vba


【解决方案1】:

作为一个UDF,这应该写成如下(或类似的东西):

Public Function MorBlend(Table1 As Variant, Blend As Double, Table2 As Variant) As Variant

    'Table3 needs to be a two dimensional array, with the first dimension
    'representing rows in the result, and the second dimension representing
    'columns in the result
    Dim Table3(1 To 106, 1 To 1) As Variant

    Dim Age As Integer

    For Age = 0 To 105
        Table3(Age + 1, 1) = Round(Table1(Age + 1) * Blend / 1000000 + Table2(Age + 1) * (1 - Blend) / 1000000, 6) * 1000000
    Next

    MorBlend = Table3
End Function

然后可以在单元格 C1:C106 中使用此函数(例如)并作为数组公式输入(按 Ctrl-Shift-Enter kbd> 输入公式)为

=MorBlend(A1:A106,.25,B1:B106)

注意:如果您想允许从 0 岁到 105 岁的死亡率(或其他)表,您需要修改代码以使用输入数组的UBound。上面的代码是硬编码的,期望正好是 106 速率,并且不包括对不是传入的情况的错误检查。


如果您不打算将该函数用作 UDF,则某些数组尺寸标注的限制可以较少 - 即您可以将数组尺寸标注为从 0 而不是 1 开始,并且您不需要有一个二维数组。

Public Function MorBlend(Table1 As Variant, Blend As Double, Table2 As Variant) As Variant

    Dim Table3() As Variant
    ReDim Table3(LBound(Table1) To UBound(Table1)) As Variant

    Dim Age As Integer

    For Age = LBound(Table1) To UBound(Table1)
        Table3(Age) = Round(Table1(Age) * Blend / 1000000 + Table2(Age) * (1 - Blend) / 1000000, 6) * 1000000
    Next

    MorBlend = Table3
End Function

此版本的代码可用于以下程序:

Sub Main
    Range("D2:D107") = Application.Transpose(Mor("71 GAM (50M/50F)"))
End Sub

Public Function Mor(Table As String) As Variant
    Dim Tbl_71GAM_M50F50 As Variant
    Dim Tbl_71GAM_M As Variant
    Dim Tbl_71GAM_F As Variant
    'Load tables from Excel ranges (e.g. "Tbl_716AM_M" may be the name of
    '  B2:B107, and "Tbl_716AM_F" may be the name of C2:C107)
    Tbl_71GAM_M = Application.Transpose(Range("Tbl_716AM_M"))
    Tbl_71GAM_F = Application.Transpose(Range("Tbl_716AM_F"))
    'Create a merged table
    Tbl_71GAM_M50F50 = MorBlend(Tbl_71GAM_M, 0.5, Tbl_71GAM_F)
    If Table = "71 GAM Male" Then Mor = Tbl_71GAM_M
    If Table = "71 GAM Female" Then Mor = Tbl_71GAM_F
    If Table = "71 GAM (50M/50F)" Then Mor = Tbl_71GAM_M50F50
End Function

或者,如果您想将 Mor 作为数组 UDF 调用,您可以使用以下代码

Public Function Mor(Table As String) As Variant
    Dim Tbl_71GAM_M50F50 As Variant
    Dim Tbl_71GAM_M As Variant
    Dim Tbl_71GAM_F As Variant
    'Load tables from Excel ranges (e.g. "Tbl_716AM_M" may be the name of
    '  B2:B107, and "Tbl_716AM_F" may be the name of C2:C107)
    Tbl_71GAM_M = Application.Transpose(Range("Tbl_716AM_M"))
    Tbl_71GAM_F = Application.Transpose(Range("Tbl_716AM_F"))
    'Create a merged table
    Tbl_71GAM_M50F50 = MorBlend(Tbl_71GAM_M, 0.5, Tbl_71GAM_F)
    If Table = "71 GAM Male" Then Mor = Application.Transpose(Tbl_71GAM_M)
    If Table = "71 GAM Female" Then Mor = Application.Transpose(Tbl_71GAM_F)
    If Table = "71 GAM (50M/50F)" Then Mor = Application.Transpose(Tbl_71GAM_M50F50)
End Function

然后在单元格 D2:D107 中输入一个数组公式,例如 `=Mor("71 GAM (50M/50F)")。

(可能性太多,展示它们的空间太小了。)

【讨论】:

  • 谢谢!如何调用此function 并将结果分配给另一个函数中的数组?我收到 #value 错误
  • 等等 - 当你说你“使用函数返回另一个函数”时,我以为你的意思是另一个 VBA 函数。但这不会产生#value 错误。如果您将 at 用作 UDF,即使它正在进入另一个 Excel 函数(例如 =MIN(MorBlend(A1:A106,.25,B1:B106),MorBlend(A1:A106,.5,B1:B106))),那么您将需要坚持我的第一个版本的代码。
  • 谢谢。我正在尝试使用以下内容: Public Function Mor(Table As String) As Variant Dim Tbl_Mor As Variant Dim Tbl_71GAM_M50F50 As Variant Tbl_71GAM_M50F50 = MorBlend(Tbl_71GAM_M, 0.5, Tbl_71GAM_F) If Table = "71 GAM Male" Then Tbl_Mor = Tbl_71GAM_M If Table = "71 GAM Female" Then Tbl_Mor = Tbl_71GAM_F If Table = "71 GAM (50M/50F)" Then Tbl_Mor = Tbl_71GAM_M50F50 Mor = Tbl_Mor End Function 但您的建议对我很有帮助,非常感谢。
猜你喜欢
  • 1970-01-01
  • 2020-08-11
  • 2021-12-30
  • 2022-01-03
  • 1970-01-01
  • 2013-06-26
  • 1970-01-01
  • 2017-12-02
  • 2011-04-21
相关资源
最近更新 更多