【问题标题】:VBA Passing arguments from function to subVBA将参数从函数传递给子
【发布时间】:2018-09-24 14:52:21
【问题描述】:

VBA中,我写了一个sub,为了这个问题,做了以下事情:

  1. 创建一个由用户命名的新工作表
  2. 从由两个用户输入值确定的数据库中提取数据
  3. 在新工作表中排序数据 (1)

我希望实现的功能是让用户能够直接从 Excel 工作表通过 UDF 输入 三个 变量,如下所示:

Description of how the user should interface with the code

为了实现用户界面的这种特定方法,我似乎需要使用一个函数作为一个

Function Do_Stuff_With_Theese_Imputs(x, y, z)
Call Do_Stuff(x, y, z)
End Function

Sub Do_Stuff(x, y, z)
'Code that makes the new sheet by the name "z"(argument from the function) here:
'Code for database handeling by the variables "x" & "y"(arguments from the function) here:
'Etc...
End sub

我可能会尝试以一种不必要的复杂方式解决这个问题,因此只要 UI 对于用户而言,我对其他实现的建议持开放态度。否则,我需要一些关于如何将参数 x、y 和 zfunction 传递到 sub 的帮助。

编辑: 由于我的疑问线不清楚,这已成为一个混乱点:

这是用户定义的要求,UDF(我想用作宏)可以从任何此 UDF 所在计算机上的 Exel 表访问'安装。从用户的角度来看,它应该像经典的=SUM 函数一样适用。

编辑 2: 再次明确一点,它应该可以从任何 Excel 工作表访问,而无需在打开工作表时始终显示(以buttonextra sheetform 的形式)。

我注意到这可能无法实现。

【问题讨论】:

  • Excel 的计算引擎在重新计算单元格时调用 UDF:不允许 UDF 执行影响任何其他单元格或影响全局/应用程序状态的操作。您需要的是宏,而不是 UDF。
  • 不能使用单元格公式更改公式适用的单元格以外的任何其他内容。您是否考虑过将Form 用于UI 用户输入所需信息的地方?
  • 什么会触发代码生成新工作表?每次重新计算工作表时,您尝试执行的操作都会生成一个新工作表(如果按照您尝试的方式允许)。
  • 我应该更清楚一点,这是用户定义的 requirement 以便能够在此使用 UDF(我想像宏一样工作)具体方式。现在我知道这是不可能的,我只需将该结果传递给用户并尝试实现Form。谢谢!

标签: excel vba


【解决方案1】:

选项 1:考虑使用Worksheet_Change,这样当用户更改任何单元格时,您可以使用这些单元格中的值作为参数触发Do_Stuff

您可以使用Intersect 将您的操作限制在这些单元格中。您最大的挑战是确定用户何时完成输入正确的数据 - 毕竟他们一次只能填写一个单元格(这是您最初遇到的问题)。

选项 2: 您可以在单元格旁边的工作表中添加一个按钮,而不是 Worksheet_Change。这里的一个技巧是根据单元格中的有效值启用按钮。然后,用户可以在完成后单击该按钮 - 该按钮将使用这些单元格中的值作为参数调用 Do_Stuff

以上两个选项不需要你更改Do_Stuff,它们只会影响你如何调用Do_Stuff

【讨论】:

  • 我发现ActiveX 按钮在这种情况下比表单按钮效果更好。在视觉上,有时带有格式(蓝色和下划线)等超链接的标签也可以。
  • 我想我可以将您的建议 选项 2 出售给最终用户,但这需要他们打开一个存储实现的特定 Excel 表。理想情况下,这个 UDF(实际上是一个宏)应该可以在安装了 UDF 的 任何 Excel 工作表中访问。您对此有什么建议吗?
  • 安装UDF的时候,也要安装按钮吗?甚至是定制的功能区按钮或菜单项?
  • 一个菜单项可能是可能的,虽然我真的希望它表现得像一个 UDF
  • @RA94:UDF 最大的问题是它的触发频率——通常会产生意想不到的后果。每次输入单元格之一更改时,UDF 都会触发,因此您最终会在各种奇怪的地方找到文件。如果你重新计算(满)或者你让它变得不稳定,那么它会更频繁地触发。你想要多少张新表?
【解决方案2】:

我会这样做,最好是第二种:

Sub Do_Stuff()

Dim x As Long
Dim y As Long
Dim z As String

With Worksheets(1)  'It takes the values from the first sheet, you can specify the sheet by a name
                    ' With Worksheets("NAME")

    x = .Cells(2, 2).Value
    y = .Cells(2, 3).Value
    z = .Cells(2, 4).Value

End With

'Code that makes the new sheet by the name "z"(argument from the function) here:
'Code for database handeling by the variables "x" & "y"(arguments from the function) here:
'Etc...
End Sub

或者这个:

Sub Do_Stuff()

Dim x As Long
Dim y As Long
Dim z As String

x = Application.InputBox("Write a number", "Get Number", , , , , , 1)
y = Application.InputBox("Write a number", "Get Number", , , , , , 1)
z = Application.InputBox("Write a new sheet name", "Get a new sheet name", , , , , , 2)


'Code that makes the new sheet by the name "z"(argument from the function) here:
'Code for database handeling by the variables "x" & "y"(arguments from the function) here:
'Etc...
End Sub

https://docs.microsoft.com/en-us/office/vba/api/excel.application.inputbox

【讨论】:

  • 感谢您的回复,现在我清楚地看到了我在回答这些问题时未能足够清晰的回答。这些建议绝对可行,但是它需要用户使用不同的用例,这意味着我无法应用它们。我可能正在尝试解决无法解决但始终乐于接受建议的问题。
  • 什么是必须保持不变的重要因素?在与第一个代码类似的方法中,我看不到任何可能在轻微更改或添加一些小东西后可能会出现问题的东西。如果值的那些单元格必须是动态的,那不是问题。
  • 我可能会更新我最初的问题以包含此问题,因为它似乎会引起一些混乱。由用户定义;从 any Excel 工作表(该 UDF 已在哪台计算机上安装了 Excel),应该能够调用 UDF,就像 =SUM 函数一样。因此,任何需要使用特定 Excel 工作表的建议(例如;使用buttonform 等)都不会给我希望提供的用户体验。我明白我想要达到的目标可能是不可能的,但在那种情况下,它就是无济于事。
【解决方案3】:

这是个糟糕的主意

监视单元格E5 进行更改。当检测到更改时,触发您的代码:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Address = "$E$5" Then
        Call Do_Stuff([B2], [C2], [D2])
    End If
End Sub

【讨论】:

  • 您能否让sub Worksheet_Change 监视并通过更改函数中的某些内容来触发,而不是监视单个单元格。例如; Public Function Do_Stuff_With_Theese_Imputs(x, y, z)Bolean_Var = trueEnd FunctionPrivate Sub Worksheet_Change(ByVal Target As Range)If Bolean_Var = True ThenBolean_Var = FalseCall Do_Stuff(x, y, z)End IfEnd Sub
  • @RA94 - 您的意思是使用全局变量作为标志。但是什么会触发标志?那是百万美元的问题。我认为 UDF 不能更改全局变量。
  • 是的,这就是我想要实现的基本目标,太糟糕了,它似乎不是一个有效的解决方案。读到这篇文章时,我充满了希望; link 最后一个理论要扔在那里;您能否使用 UDF 来收集信息,将其全部合并为一个字符串并将其粘贴回原始单元格,然后从某个 UDF 所做的更改中触发宏,这样宏将从 Excel 中获取它的信息单元格而不是 UDF
  • @RA94 - 我做了一些测试,UDF 可以写入全局,但这会使 Excel 进入不稳定状态(“堆栈外”错误)并最终崩溃。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-07
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
相关资源
最近更新 更多