我对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
答案 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
在其中,您可以注意到,A
是TestMe
和TestMe2
中的单独变量。这被称为"变量范围"。只要变量的范围不同,那么两个A
- s就彼此无关。
最好的方法是重写代码,从而从函数返回IncomeMonthSum
。
答案 1 :(得分:0)
函数IncomeSum2
正在调用IncomeSum
来修改局部变量IncomeMonthSum
。由于IncomeMonthSum
是本地的,尝试从另一个子/函数访问它会返回0,因为该子/函数无法访问该变量。
要访问该变量,您可以尝试在模块开头声明IncomeMonthSum
为Public
变量,例如:
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));
})