VBA For每个sum循环函数返回0

时间:2018-04-03 13:53:29

标签: vba function

我对VBA比较陌生,并且一直在努力使复杂的功能发挥作用。我特别难以接受我创建的这个函数,它作为Sub而不是函数。我的函数搜索工作簿中的每个工作表,找到一个以“Budget *”开头的表,并在用户指定的列中添加单元格(现在它是activecell,但我希望这是一个输入功能)。页数是未知的,因此不可能尝试将此函数写为单元格的实际值。我甚至尝试创建一个调用sub的单独函数,但这也不起作用。当我在工作表中使用该函数时,我得到的值是0.请帮忙!

Private Sub IncomeSum()

Application.ScreenUpdating = False

ColumnNumber = ActiveCell.Column
IncomeMonthSum = 0

For Each WS In Sheets
    WS.Activate
    If ActiveSheet.Tab.Color = 255 Then Exit For
    If ActiveSheet.Index >= 4 Then

        For Each Tbl In ActiveSheet.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

Answer = MsgBox(IncomeMonthSum)

Application.ScreenUpdating = True

End Sub

这是我试图调用sub的函数:

Function IncomeSum2()

IncomeSum
IncomeSum2 = IncomeMonthSum

End Function

我甚至逐步完成了上面的功能,并为子中的值添加了监视功能。我开始在函数中运行代码,并观察它通过sub,然后返回到函数。手表显示子工作正常,并且值是正确的,但是一旦代码从Sub返回到函数,突然值恢复为零。

编辑:

谢谢@DisplayName!这是我真正想要的,它只返回值0:

Function IncomeSum(Month)

ColumnNumber = Month.Column
IncomeMonthSum = 0

For Each WS In Sheets
    WS.Activate
    If ActiveSheet.Tab.Color = 255 Then Exit For
    If ActiveSheet.Index >= 4 Then

        For Each Tbl In ActiveSheet.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

3 个答案:

答案 0 :(得分:0)

这是最快的&最脏的解决方案:

Dim IncomeMonthSum As Long

Function IncomeSum2()

    IncomeSum
    IncomeSum2 = IncomeMonthSum

End Function

有很多人反对声明模块变量并使用它们,这确实是一种不好的做法。但在您的情况下,很明显您曾调用IncomeSum,然后尝试获取在IncomeMonthSum中生成的IncomeSum中的值。只有在将IncomeMonthSum声明为模块变量时才可以执行此操作。见这个简短的例子:

Public Sub TestMe()
    TestMe2
    Debug.Print A
End Sub

Public Sub TestMe2()
    A = 5
End Sub

在其中,您可以注意到,ATestMeTestMe2中的单独变量。这被称为"变量范围"。只要变量的范围不同,那么两个A - s就彼此无关。

最好的方法是重写代码,从而从函数返回IncomeMonthSum

答案 1 :(得分:0)

函数IncomeSum2正在调用IncomeSum来修改局部变量IncomeMonthSum。由于IncomeMonthSum是本地的,尝试从另一个子/函数访问它会返回0,因为该子/函数无法访问该变量。

要访问该变量,您可以尝试在模块开头声明IncomeMonthSumPublic变量,例如:

Public IncomeMonthSum as Double
Sub IncomeSum ()
    '...

如另一个答案中所述,这是一个“肮脏的”#34;做法。您应该尝试更改代码,以便可以返回变量并将其作为参数传递给另一个函数。

答案 2 :(得分:0)

Function IncomeSum2()了解IncomeMonthSum Private Sub IncomeSum()内部Private Sub IncomeSum() 变量集的价值,你必须将这个变量传递给他们

变化:

Private Sub IncomeSum(IncomeMonthSum) ' have 'IncomeSum() sub accept a parameter named 'IncomeMonthSum'

为:

Function IncomeSum2()

    IncomeSum
    IncomeSum2 = IncomeMonthSum

End Function

并改变:

Function IncomeSum2()
    IncomeSum IncomeMonthSum ' call 'IncomeSum()' sub passing variable 'IncomeMonthSum' as its parameter
    IncomeSum2 = IncomeMonthSum ' return the value of 'IncomeMonthSum' as processed by 'IncomeSum' call above
End Function

为:

@(Html.Kendo().Grid<WorkTimesViewModel>(Model.WorkTimes)
      .Name("grid")
      .Columns(columns =>
      {
          columns.Bound(p => p.Project).Title(Html.LabelFor(m => m.Projekt).ToString()).Width(140).ClientTemplate("#: Project.Name #");
          columns.Bound(p => p.Activity).Title(Html.LabelFor(m => m.Aktivität).ToString()).Width(140).ClientTemplate("#: Activity.Name #");
          columns.Bound(p => p.Duration).Title(Html.LabelFor(m => m.Dauer).ToString()).Format("{0:t}").Width(80);
          columns.Bound(p => p.Description).Title(Html.LabelFor(m => m.Bemerkung).ToString()).Width(180);
          columns.Command(command =>
          {
              command.Edit().Text(" ").CancelText(" ").UpdateText(" ");
              command.Destroy().Text(" ");
          }
              ).Width(140);
      })
      .Editable(editable => editable.Mode(GridEditMode.InLine).DisplayDeleteConfirmation(Html.LabelFor(m => m.LöschAktivi).ToString()))
      .HtmlAttributes(new { style = "width: 830px; height: 302px;" })
      .ToolBar(toolbar => toolbar.Create().Text(Html.LabelFor(m => m.NeuerArbeitszeiteintrag).ToString()))
      .Scrollable()
      .Selectable(conf => conf.Enabled(true).Mode(GridSelectionMode.Single).Type(GridSelectionType.Row))
      .Events(a => a.Edit("onGridEdit"))
      .DataSource(dataSource => dataSource
                                    .Ajax()
                                    .Events(e => e.Error("error_handler").RequestEnd("onRequestEnd"))
                                    .Model(model =>
                                    {
                                        model.Id(p => p.Id);
                                        model.Field(p => p.Project).DefaultValue(ViewData["defaultProject"] as ProjectViewModel);
                                        model.Field(p => p.Activity).DefaultValue(ViewData["defaultActivity"] as ActivityViewModel);
                                        model.Field(p => p.Description).DefaultValue("");
                                        model.Field(p => p.Duration).DefaultValue(new DateTime(1, 1, 1, 1, 0, 0, DateTimeKind.Utc));

                                    })