【问题标题】:Assign Macro with Multiple Arguments to Button VBA将具有多个参数的宏分配给按钮 VBA
【发布时间】:2018-01-18 20:18:58
【问题描述】:

我正在开发一个 VBA 宏,我想为每一行添加按钮。我想为每个按钮分配相同的宏,每行具有不同的参数。按钮运行的宏是一个简单的宏,它根据按钮所在行的信息生成一封电子邮件,并将其保存到用户的 Outlook 草稿文件夹中。

我遇到的问题是,当我将电子邮件代码归类为函数时,它会立即运行,而不是将其分配给按钮。当我将它归类为子时,我收到一个编译错误,指出“编译错误:预期的函数或变量”

主宏代码如下:

Sub addButtons()
    Dim lastCol As Integer
    Dim lastRow As Integer
    Dim r As Range
    Dim btn As Button
    Dim uid As String
    Dim rDate As String
    Dim i As Integer

    lastCol = Cells(1, Columns.Count).End(xlToLeft).Column + 1
    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    rDate = Str(Date)
    rDate = Replace(rDate, "/", "D")

    For i = 2 To lastRow
        Set r = ActiveSheet.Range(Cells(i, lastCol), Cells(i, lastCol))
        Set btn = ActiveSheet.Buttons.Add(r.Left, r.Top, r.Width, r.Height)
        uid = ActiveSheet.Cells(i, 1).Text
        With btn
            .OnAction = newhireEmail(i, rDate)
            .Caption = "Email " & uid & "?"
            .name = "btn" & (i - 1)
        End With
    Next i

    r.EntireColumn.ColumnWidth = 15
End Sub

我也可以发布电子邮件的代码,但我不认为它应该是相关的,因为我希望除非单击按钮,否则根本不运行该代码。

感谢您的宝贵时间!

【问题讨论】:

  • 我过去曾推荐过此方法,但有时我更喜欢使用格式化为看起来像按钮的单元格并捕获工作表的Selection_Change 事件,而不是使用表单按钮。然后,您可以拥有一个使用 Target 的宏来获取您所在的特定行。
  • 查看上一个答案:stackoverflow.com/a/41026906/1274820
  • 你的函数newhireEmail在哪里?
  • 我在上一个答案中没有说,但是您也可以使用Application.Caller 来获取按钮的名称并让您的每个按钮都指向同一个宏 - 它比创建更干净每个按钮都有一个新的子按钮。
  • 只是为了重新考虑您的项目,如前所述,我将有一个电子邮件按钮并使用行中的一个单元格进行选择。第一条评论是正确的,因为行中的太多按钮将成为文件大小和屏幕刷新的怪物。不是你不能做,而是你不应该做。做出选择,然后使用可重复使用的代码对该目标采取行动。

标签: vba excel


【解决方案1】:

这可能不是您提出的问题的答案,但我确实想介绍几种不同的方法来解决此任务。

其中一种更轻量级的方法是订阅工作表扩展的事件(并且您不需要)。例如,当我有一个惊人的相似过程时,我订阅了工作表双击事件。当我双击一个单元格时,它会从该行编译信息,并将其传递给电子邮件子程序。

如果您想要更直观的线索,但又不想要按钮的顶部,请考虑使用超链接。这是一个两步过程,但是当我完成此操作时,它比大量按钮工作得更快、更有效。 (注意:每个工作表的超链接限制为 65,530 个。如果您需要更多,这将不起作用)。

首先,生成超链接:

Sub AddHyperlinks()
    Dim lastCol As Long
    Dim lastRow As Long
    Dim s As Worksheet

    Set s = ActiveSheet


    lastCol = s.Cells(1, Columns.Count).End(xlToLeft).Column + 1
    lastRow = s.Cells(s.Rows.Count, 1).End(xlUp).Row

    For i = 2 To lastRow
        s.Hyperlinks.Add Anchor:=s.Cells(i, lastCol), _
        Address:="", _
        SubAddress:=s.Cells(i, lastCol).Address, _
        TextToDisplay:="Send Email"
    Next i
End Sub

接下来,订阅相应工作表中的FollowHyperlinks 事件,并在那里生成您的代码。超链接目标将引用超链接的单元格地址,您可以从中获取任何需要的数据:

Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
    'Submit whatever code you want here
    MsgBox Target.SubAddress
End Sub

【讨论】:

  • 如果我使用这个,它会影响工作表上的其他超链接吗?我需要一个清晰可见的标记来开始电子邮件处理,所以我不能只使用双击,但有问题的工作表的每一行都有一个超链接。
  • @Cameron 这是一种权衡,但可以根据需要进行管理。例如,您可以检查超链接的子地址属性,如果它在某个列中,则只执行电子邮件。如果你不想使用超链接,你可以创建一个“浮动按钮”,这样工作表上只有一个按钮,但它会随着 activecell 移动。当然,这需要在按下按钮之前选择所需的行。
猜你喜欢
  • 1970-01-01
  • 2012-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多