问题
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 triggerWorksheet_FollowHyperlinkevent 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