VBA UDF 返回#VALUE!

Posted

技术标签:

【中文标题】VBA UDF 返回#VALUE!【英文标题】:VBA UDF returning #VALUE! 【发布时间】:2011-05-09 10:20:21 【问题描述】:

所以我有一个用 Visual Basic 编写的非常简单的 UDF,可以在 excel 中使用。它计算你的大约。税收。假设我这样使用它:

=Taxes(I23-I18,I24-I20,"Married")

如果我输入这个,效果很好。现在,如果我保存工作表并重新启动 excel,单元格现在会显示 #VALUE!如果我选择公式并再次按回车键,它会重新计算它。我究竟做错了什么? Application.Volatile 不应该是必需的,但我正在尝试想法......

Private Type TaxBracket
    Perc As Double
    Floor As Currency
    Limit As Currency
End Type

Public Function Taxes(gross1 As Currency, gross2 As Currency, filingStatus As String) As Currency
    Application.Volatile True
    Dim brackets(6) As TaxBracket
    Dim stdDeduction As Currency
    Dim ssTaxRate As Double
    Dim medicareTaxRate As Double
    Dim Tax As Double

    stdDeduction = 5700
    ssTaxRoof = 106800
    ssTaxRate = 0.062
    medicareTaxRate = 0.0145

    Tax = medicareTaxRate * (gross1 + gross2)
    Tax = Tax + IIf(gross1 < ssTaxRoof, ssTaxRate * gross1, ssTaxRate * ssTaxRoof)
    Tax = Tax + IIf(gross2 < ssTaxRoof, ssTaxRate * gross2, ssTaxRate * ssTaxRoof)

    brackets(0).Perc = 0.1
    brackets(1).Perc = 0.15
    brackets(2).Perc = 0.25
    brackets(3).Perc = 0.28
    brackets(4).Perc = 0.33
    brackets(5).Perc = 0.35

    If filingStatus = "Single" Then
        brackets(0).Floor = 0
        brackets(1).Floor = 8375
        brackets(2).Floor = 34000
        brackets(3).Floor = 82400
        brackets(4).Floor = 171850
        brackets(5).Floor = 373650
        brackets(0).Limit = 8375
        brackets(1).Limit = 34000
        brackets(2).Limit = 82400
        brackets(3).Limit = 171850
        brackets(4).Limit = 373650
        brackets(5).Limit = 1000000000

        Tax = Tax + incomeTaxes(gross1, brackets, stdDeduction) + incomeTaxes(gross2, brackets, stdDeduction)
    ElseIf filingStatus = "Married" Then
        brackets(0).Floor = 0
        brackets(1).Floor = 16750
        brackets(2).Floor = 68000
        brackets(3).Floor = 137300
        brackets(4).Floor = 209250
        brackets(5).Floor = 373650
        brackets(0).Limit = 16750
        brackets(1).Limit = 68000
        brackets(2).Limit = 137300
        brackets(3).Limit = 209250
        brackets(4).Limit = 373650
        brackets(5).Limit = 1000000000

        Tax = Tax + incomeTaxes(gross1 + gross2, brackets, stdDeduction * 2)
    Else
        Taxes = "N/A"
        Return
    End If
    Taxes = Tax
End Function

Private Function incomeTaxes(gross As Currency, brackets() As TaxBracket, deduction As Currency) As Currency
    Dim Tax As Double
    Dim taxable As Double

    Tax = 0
    taxable = gross - deduction


    For i = 0 To 5
      If taxable > brackets(i).Limit Then
        Tax = Tax + (WorksheetFunction.Min(taxable, brackets(i).Limit) - brackets(i).Floor) * brackets(i).Perc
      Else
        If taxable > brackets(i).Floor Then
            Tax = Tax + (taxable - brackets(i).Floor) * brackets(i).Perc
        Else
            'tax = tax
        End If
      End If
    Next i

    incomeTaxes = Tax
End Function

【问题讨论】:

【参考方案1】:

您的 UDF 看起来不错,除了使用货币数据类型(可能应该使用双精度或变体,因为 Excel 使用的是这种类型)。 使用 UDF 获取 #Value 的通常原因是输入参数之一无法转换为正确的类型。如果您的输入单元格在工作簿打开时不包含数值,您将获得 #Value。这可能是由计算顺序问题引起的,导致第一次调用该函数时未计算上游先例单元格之一。 尝试将输入参数声明为变量而不是货币,并添加一些临时 debug.print 语句以在即时窗口中显示输入参数。

【讨论】:

感谢您的意见。我将所有参数更改为变体,但没有运气。我也试过这个公式:=Taxes(100000,200000,"Single")。这个公式不依赖于另一个单元格,但仍然不是运气。现在测试调试输出。还有什么想法吗? 经过进一步调查,似乎有效。我只需要刷新一次所有内容。谢谢! 大卫,我没有跟踪 - 你的解决方案是什么?

以上是关于VBA UDF 返回#VALUE!的主要内容,如果未能解决你的问题,请参考以下文章

Excel VBA:不满足条件时如何让UDF返回0

编辑 VBA UDF 以求和括号中的数字,同时忽略括号中的单词

如何将 Excel 数组公式传递给 VBA UDF?

从 Excel 与 VBA 调用时,VBA UDF 给出不同的答案

VBA 用户定义函数返回奇怪或没有结果

当用户输入超过预期的参数时,强制 VBA 中的 UDF 显示 MsgBox?