Running VBA from a HYPERLINK()

拈花ヽ惹草 提交于 2019-12-17 09:56:29

问题


I'm trying to let my users send email easily from their Excel spreadsheets, which they like to use as front-ends for data entry and manipulation. My intention is to write a function:

generateEmail(name, manager, cc)

and make it so the function can be invoked as-pleased by the user.

In this, Excel calls Outlook, creates a new mail, and dumps the text containing the formatted email to send, which will contain some values changing dynamically per-line from the table they are currently working on. This is the VBA function:

Function generateEmail(name, manager, cc)
    Dim OutApp As Object
    Dim OutMail As Object
    Dim strbody As String

    Set OutApp = CreateObject("Outlook.Application")
    Set OutMail = OutApp.CreateItem(0)

    strbody = "To Service Desk:" & vbNewLine & vbNewLine & _
              "Please open a ticket for CS/oe/ns/telecom/dal to request a new extension. Please find the details attached:" & vbNewLine & vbNewLine & _
              "Name: " & name & vbNewLine & _
              "Manager: " & manager & vbNewLine & _
              "CC: " & cc

    On Error Resume Next
    With OutMail
        .To = "helpdesk@test.com"
        .cc = ""
        .BCC = ""
        .Subject = "New Extension Request"
        .Body = strbody
        .Display
    End With
    On Error GoTo 0

    Set OutMail = Nothing
    Set OutApp = Nothing

End Function

Then, in the rightmost column of the table I'm adding this to, I make a column of links:

=HYPERLINK(generateEmail(H2, I2, M2), "Generate Email")

Where H2, I2 and M2 are the values that I need to inject into the email that will be generated. The users will also have data on H3, I3, M3, H4, I4, M4... and so on.

This actually works as expected, however when I make the hyperlink show up on the spreadsheet, it fires the event as soon as Excel detects a mouseover over the link. I'd wish to make it so the links are clickable and fire the function only after the user has clicked.

Is there any way to do this?

My search has come up empty, basically advising people to create links manually per cell from VBA itself. Since the dataset stored by my users will grow over time I need a way to create a new "Send Email" link every time the user adds a record.


回答1:


To run the function only on a click you can try entering as a subaddress:

=HYPERLINK("#generateEmail(H2, I2, M2)", "Generate Email")

and then add an extra line in the code to return the current address:

Function generateEmail(name, manager, cc)

Set generateEmail = Selection
'Paste Outlook Code Here 

End Function

Note this method does not get executed on the main vba thread so to test you can insert statements in the code instead of stepping through, eg:

Range("A10:C10") = Array(name, manager, cc)



回答2:


I ran into similar limitations on a project. I had to give up using hyperlink and created a workaround using the Worksheet_SelectionChange event. Assuming your formula was supposed to be on the N column, please consider using the following code inserted on your target sheet (not in a module):

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    If Target.Column = 14 Then
        Call generateEmail(Target.Offset(0, -6).Value2, Target.Offset(0, -5).Value2, Target.Offset(0, -1).Value2)
    End If

End Sub

Then you can add any text you want in that column (ie "Send Email') and when someone clicks on that cell your code will fire specifically with data from that row. Hope this helps. Regards.




回答3:


Using hyperlinks to trigger actions is a bit tricky:

  • HYPERLINK() links don't trigger Worksheet_FollowHyperlink event handlers
  • When using the "Insert Hyperlink"-type links you need a valid target address, and this can result in the selection jumping around when the user clicks on a link.

Here's one approach - place this code in the worksheet module:

Option Explicit

Dim oldAdd As String

'When a link is clicked, this gets triggered first
'   if the clicked cell has a hyperlink, remember its address
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim c As Range

    'only want single-cell selections...
    If Target.Cells.CountLarge > 1 Then
        Exit Sub
    Else
        'cell has a link? Remember the address...
        If Target.Hyperlinks.Count > 0 Then
            oldAdd = Target.Address()
        End If
    End If
End Sub

'This is called immediately after the SelectionChange event,
'  so we can use the stored address to reset the selection back
'  to the clicked cell, instead of wherever its link was pointing to
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)

    Dim c As Range

    If oldAdd <> "" Then
        Set c = Me.Range(oldAdd)
        c.Select 'undo any navigation
        'Here you could switch on the link text if you have
        '   links which need to trigger different actions
        If c.Value = "Send Mail" Then
            MsgBox "Sending mail!"
            'generateEmail [use values from cells relative to c]
        End If
    End If

End Sub

Assumes all links point to the same sheet as the one the links are on.




回答4:


The body of your email doesn't look excessively long for use with the mailto hyperlink. Consider http://www.datapigtechnologies.com/blog/index.php/emailing-from-excel-using-the-hyperlink-function/

A hyperlink in this way would only fire when clicked.



来源:https://stackoverflow.com/questions/32660492/running-vba-from-a-hyperlink

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!