返回0的函数,当与子函数执行相同的函数时返回正确的值

时间:2018-04-03 16:37:40

标签: excel vba excel-vba

以下函数在工作簿中使用时,返回0值或#VALUE,尽管作为sub执行时返回正确的值。我已经尝试创建一个函数,将下面的代码作为子函数返回,但我得到了相同的结果。我的函数搜索工作簿中的每个工作表,找到以" Budget *"开头的表,并将单元格添加到用户指定的列中。页数是未知的,因此不可能尝试将此函数写为单元格的实际值。我很难过!

Example1 Example2

Function IncomeSum(Month)

ColumnNumber = Month.Column
IncomeMonthSum = 0
Dim WS As Worksheet

For Each WS In Worksheets
    If WS.Tab.Color = 255 Then Exit For
    If WS.Index >= 4 Then

        For Each Tbl In WS.ListObjects
            If Tbl.Name Like "Budget*" Then
            TableName = Tbl.Name
            Exit For
            End If
        Next Tbl

    ColumnSum = Application.WorksheetFunction.Sum(Range(TableName & "[[#All],[Column" & ColumnNumber & "]]"))
    IncomeMonthSum = IncomeMonthSum + ColumnSum
    End If
Next WS

IncomeSum = IncomeMonthSum

End Function

1 个答案:

答案 0 :(得分:0)

您的功能存在多个问题,主要问题是WS.Activate,然后针对ActiveSheet进行操作。您有一个WS工作表对象 - 使用它;不允许UDF Activate工作表。

然后,您没有声明您正在使用的变量。这意味着你在破坏所有内容时只有1个错字,并且你没有获得正确类型的对象变量所能获得的所有 IntelliSense 。在模块顶部指定Option Explicit,并为每个局部变量设置Dim语句。无论你把Dim语句放在哪里,它们都不可执行 - 我的建议是尽可能地将它们放在第一个任务中。

TableName将在WS次迭代之间保留其先前的值,这意味着即使WS没有表,您的代码也会尝试使用上一次迭代的{{1} }}。在迭代之间重置它(或者更好的是,提取一个私有函数,在给定TableName的情况下为ListObject提供。)

Worksheet

您有Option Explicit Public Function IncomeSum(ByVal Month As Range) As Double Dim ColumnNumber As Long ColumnNumber = Month.Column Dim WS As Worksheet For Each WS In ThisWorkbook.Worksheets If WS.Tab.Color = 255 Then Exit For If WS.Index >= 4 Then Dim Tbl As ListObject Dim TableName As String For Each Tbl In WS.ListObjects If Tbl.Name Like "Budget*" Then TableName = Tbl.Name Exit For End If Next Tbl If TableName <> vbNullString Then Dim ColumnSum As Double ColumnSum = Application.WorksheetFunction.Sum(WS.Range(TableName & "[[#All],[Column" & ColumnNumber & "]]")) Dim IncomeMonthSum As Double IncomeMonthSum = IncomeMonthSum + ColumnSum TableName = vbNullString End If End If Next WS IncomeSum = IncomeMonthSum End Function - 假设对提供的ListObject范围进行了正确验证,您可以使用Month代替对表公式进行硬编码。