none
Adding hyperlink to Outlook 2003 message RRS feed

  • Question

  • I have a bit of VBA code that takes what is on the clipboard and pastes it into a Outlook 2003 message as a hyperlink. The clipboard contents should be the fullname(path and filename) obtained from another macro in Word 2003 (ActiveDocument.FullName). The Outlook message format is set to HTML. I have a function(GetFilename) that takes the string(strClip) and returns only the filename at the end of the string to display only that for the hyperlink. My objective is to be able to paste multiple links if needed to an email message. It all seems to work except that it won't allow me to paste another link into the email and the curser jumps back to the beginning of the pasted link. It overwrites the initial paste. For the carriage return I've tried "& vbCrLf", "& Chr(13)" and "& <br>" to get the return, but nothing has worked. Thanks in advance for any help with this. The code is below:
     
    Sub PasteLink()
    Dim MyData As DataObject
    Dim strClip As String
    Dim msg As Outlook.MailItem
     
    Set MyData = New DataObject
    MyData.GetFromClipboard
    strClip = MyData.GetText
    strShortClip = GetFilename(strClip)
     
    Set msg = Application.ActiveInspector.CurrentItem
     
    msg.HTMLBody = "<a href=" & strClip & ">" & strShortClip & "</a>" & "<br>"
     
    End Sub
    Wednesday, March 28, 2012 11:56 PM

Answers

  • Here is the solution. Many thanks to a poster named skatonni on another forum. The suggestion that worked  for keeping it from overwriting the content was msg.HTMLBody = msg.HTMLBody + ...

    The strHLink variable I created to allow for spaces in the hyperlink.

    Also, the SendKeys was useful for positioning.

    --------------------------------------------------------------

    This is the completed Pastelink module:

    Sub PasteLink()
    Dim MyData As DataObject
    Dim strClip As String
    Dim strHLink As String
    Dim msg As Outlook.MailItem

    Set MyData = New DataObject
    MyData.GetFromClipboard
    strClip = MyData.GetText
    strHLink = Chr(34) & "file://" & strClip & Chr(34)
    strShortClip = GetFilename(strClip)

    Set msg = Application.ActiveInspector.CurrentItem

    msg.HTMLBody = msg.HTMLBody + "<a href=" & strHLink & ">" & strShortClip & "</a><br>"
    SendKeys "^{END}"

    End Sub

    --------------------------------------------------------------

    This is the GetFilename function from another module:

    Function GetFilename(ByVal strClip As String) As String

        If Right$(strClip, 1) <> "\" And Len(strClip) > 0 Then
            GetFilename = GetFilename(Left$(strClip, Len(strClip) - 1)) + Right$(strClip, 1)
        End If
    End Function

    ---------------------------------------------------------------

    This is the Word macro that puts the filename with the full path into the clipboard:

    Sub FileName()
        Dim dob As New DataObject
        dob.SetText ActiveDocument.FullName
        dob.PutInClipboard
    End Sub

    The purpose of all the above code is so that a user in Word can click one button to get the path and filename into the clipboard and then go to Outlook and paste it into a message with another button. The hyperlink only displays the filename. It works for those that use the Outlook editor for sending HTML formated emails.


    Scott B


    • Marked as answer by s_c_o_t_t_b Saturday, March 31, 2012 10:43 PM
    • Edited by s_c_o_t_t_b Saturday, March 31, 2012 10:53 PM
    Saturday, March 31, 2012 10:43 PM
  • changes:

    I added SendKeys "+{ENTER}" after the SendKeys "^{END}" and removed the <br> tag as the extra line-feed is not needed.

    The shift+enter puts the cursor at the start of the next line while the ctrl+end put it at the end of the pasted line.

    ------------------------------------------------------

    Sub PasteLink()
    Dim MyData As DataObject
    Dim strClip As String
    Dim strHLink As String
    Dim msg As Outlook.MailItem

    Set MyData = New DataObject
    MyData.GetFromClipboard
    strClip = MyData.GetText
    strHLink = Chr(34) & "file://" & strClip & Chr(34)
    strShortClip = GetFilename(strClip)

    Set msg = Application.ActiveInspector.CurrentItem


    msg.HTMLBody = msg.HTMLBody + "<a href=" & strHLink & ">" & strShortClip & "</a>"
    SendKeys "^{END}"
    SendKeys "+{ENTER}"

    End Sub

    --------------------------------------------------------


    Scott B

    • Marked as answer by s_c_o_t_t_b Monday, April 2, 2012 6:08 PM
    Monday, April 2, 2012 6:07 PM

All replies

  • Are you using Word editor or HTML?

    Have you tried Inspector.WordEditor/HTMLEditor to manipulate the text instead of directly setting the HTMLBody property?


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Thursday, March 29, 2012 12:03 AM
  • I am using the VBA editor within Outlook 2003.  I tried setting the hyperlink using the "file://" format but thought that since I need to somewhat conceal the path, I would use the HTMLBody.
    Thursday, March 29, 2012 12:12 AM
  • Dmitry,

    Thanks for the reply. To better answer your question, I am creating this for users that will mostly use the Outlook editor for emails in the HTML format. I plan on creating it again for users that will be using Word as the editor later. I am totally open to suggestions. If I am going the wrong direction, any input is appeciated. I'll start looking at the Inspector.WordEditor/HTML Editor, but I thought it would not need too much more. It works now, it just works for one email at a time. Can't paste a second link into the message without overwriting the whole message. The reason for the GetFilename function was to hide the rest of the path so only the filename is displayed. Thanks again.


    Scott B

    Thursday, March 29, 2012 1:50 AM
  • I don't think you have much of a choice - you will need to work with the Word and/or HTML editors to control the selection position and its length to make sure you do not overwrite any existing data.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Thursday, March 29, 2012 6:16 AM
  • Here is the solution. Many thanks to a poster named skatonni on another forum. The suggestion that worked  for keeping it from overwriting the content was msg.HTMLBody = msg.HTMLBody + ...

    The strHLink variable I created to allow for spaces in the hyperlink.

    Also, the SendKeys was useful for positioning.

    --------------------------------------------------------------

    This is the completed Pastelink module:

    Sub PasteLink()
    Dim MyData As DataObject
    Dim strClip As String
    Dim strHLink As String
    Dim msg As Outlook.MailItem

    Set MyData = New DataObject
    MyData.GetFromClipboard
    strClip = MyData.GetText
    strHLink = Chr(34) & "file://" & strClip & Chr(34)
    strShortClip = GetFilename(strClip)

    Set msg = Application.ActiveInspector.CurrentItem

    msg.HTMLBody = msg.HTMLBody + "<a href=" & strHLink & ">" & strShortClip & "</a><br>"
    SendKeys "^{END}"

    End Sub

    --------------------------------------------------------------

    This is the GetFilename function from another module:

    Function GetFilename(ByVal strClip As String) As String

        If Right$(strClip, 1) <> "\" And Len(strClip) > 0 Then
            GetFilename = GetFilename(Left$(strClip, Len(strClip) - 1)) + Right$(strClip, 1)
        End If
    End Function

    ---------------------------------------------------------------

    This is the Word macro that puts the filename with the full path into the clipboard:

    Sub FileName()
        Dim dob As New DataObject
        dob.SetText ActiveDocument.FullName
        dob.PutInClipboard
    End Sub

    The purpose of all the above code is so that a user in Word can click one button to get the path and filename into the clipboard and then go to Outlook and paste it into a message with another button. The hyperlink only displays the filename. It works for those that use the Outlook editor for sending HTML formated emails.


    Scott B


    • Marked as answer by s_c_o_t_t_b Saturday, March 31, 2012 10:43 PM
    • Edited by s_c_o_t_t_b Saturday, March 31, 2012 10:53 PM
    Saturday, March 31, 2012 10:43 PM
  • Do not concatenate HTML strings! Your new HTML data needs to be merged with the existing HTML body

    If you want to add something to the end of the message body, insert it just before the "</body>" tag, not at the very end of the existing HTML body.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Monday, April 2, 2012 2:16 PM
  • changes:

    I added SendKeys "+{ENTER}" after the SendKeys "^{END}" and removed the <br> tag as the extra line-feed is not needed.

    The shift+enter puts the cursor at the start of the next line while the ctrl+end put it at the end of the pasted line.

    ------------------------------------------------------

    Sub PasteLink()
    Dim MyData As DataObject
    Dim strClip As String
    Dim strHLink As String
    Dim msg As Outlook.MailItem

    Set MyData = New DataObject
    MyData.GetFromClipboard
    strClip = MyData.GetText
    strHLink = Chr(34) & "file://" & strClip & Chr(34)
    strShortClip = GetFilename(strClip)

    Set msg = Application.ActiveInspector.CurrentItem


    msg.HTMLBody = msg.HTMLBody + "<a href=" & strHLink & ">" & strShortClip & "</a>"
    SendKeys "^{END}"
    SendKeys "+{ENTER}"

    End Sub

    --------------------------------------------------------


    Scott B

    • Marked as answer by s_c_o_t_t_b Monday, April 2, 2012 6:08 PM
    Monday, April 2, 2012 6:07 PM
  • Again, Outlook might tolerate it (to a point), but the line

    msg.HTMLBody = msg.HTMLBody + "<a href=" & strHLink & ">" & strShortClip & "</a>"

    will not produce valid HTML.

    Fidn the position of the "</body" substrring and insert your data at that point.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Monday, April 2, 2012 6:18 PM
  • The following is the html source from the message after running the code. The first is the HTML source taken from the message that the first version produces. The second is the last revision. The first version overwrites the entire message. Although the revised code is not valid, it allows a second paste without overwriting the message. The first version will overwrite anything that may be previously written into the message(including signature block). Not sure what you're referring to by </body> sub string. Since a second body tag would be invalid, I assume you don't mean that. From the source, I don't see how it is producing invalid HTML. 
    First version:
    msg.HTMLBody = "<a href=" & strHLink & ">" & strShortClip & "</a>"
    produces:
    -html email source-

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML><HEAD>
    <META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
    <META name=GENERATOR content="MSHTML 8.00.6001.19046"></HEAD>
    <BODY><A
    href="file://\\SERVERNAME\SHARENAME$\DIRECTORY NAME\SUBDIRECTORY NAME\folder\384347.doc">384347.doc</A></BODY></HTML>

    second version:
    msg.HTMLBody = msg.HTMLBody + "<a href=" & strHLink & ">" & strShortClip & "</a>"
    produces:
    -html email source-

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <HTML><HEAD>
    <META content="text/html; charset=us-ascii" http-equiv=Content-Type>
    <META name=GENERATOR content="MSHTML 8.00.6001.19046"></HEAD>
    <BODY>
    <DIV><FONT size=2 face=Arial></FONT>&nbsp;</DIV><A
    href="file://\\SERVERNAME\SHARENAME$\DIRECTORY NAME\SUBDIRECTORY NAME\folder\384347.doc">384347.doc</A><FONT
    size=2 face=Arial><BR></FONT></BODY></HTML>

    The only thing that is not working as I want it, is that if there is text or a signature block already in the message, it places the paste below it, even though the cursor is placed above it. For an empty email, it of course works. Thanks again Dmitry for your input.


    Scott B

    Monday, April 2, 2012 8:31 PM
  • Again, Outlook might be smart enough to figure out that you are adding text after the "</html>"tag.

    If you look at the HTML you are seeting, you will see that it is not valid:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    < HTML><HEAD>
    < META content="text/html; charset=iso-8859-1" http-equiv=Content-Type>
    < META name=GENERATOR content="MSHTML 8.00.6001.19046"></HEAD>
    < BODY></BODY></HTML><A
    href="file://\\SERVERNAME\SHARENAME$\DIRECTORY NAME\SUBDIRECTORY NAME\folder\384347.doc">384347.doc</A>


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Tuesday, April 3, 2012 2:37 PM
  • Follow what Dmitry says and write somewhat more sophisticated code. If you want to enter your link just before signature, access mailitem's inspector, get wordeditor (case to Word's Document class) and check for bookmark of name: _MailAutoSig - this is what outlook uses to mark where default signature was added. So use Range to insert your link line above this bookmark and you will be fine.

    Tuesday, April 3, 2012 2:52 PM
  • Are you just showing that a browser can still render non valid html by how you've placed the anchor after the closing </html tag? Because when I view source of the message it clearly shows it, as in the code I've pasted above, before the closing </body or the </html tags.  Where would I see the invalid source? Even if I saved the messsage as an .htm, viewing the html source shows the <a></a> tags before the closing body tag. I will assume that you mean that the code Outlook is generating  fixes my "msg.HTMLBody = msg.HTMLBody +"(non valid html) and displays what is valid html. Thanks again for your patient advice.

    Scott B

    Wednesday, April 4, 2012 9:48 PM
  • Thanks DamienD for these hints. I'm waiting for an Outlook programming book to arrive, but for now, the somewhat less sophisticated code will have to do. Perhaps I will take this thread up later when I am better versed in the topic.


    Scott B

    Wednesday, April 4, 2012 9:52 PM
  • You would see the invalid data if you set the concatenated HTML to a variable first, and then set the HTMLBody property to that variable.

    Again, while it appears that Outlook lets you get away with setting an invalid HTML, it is better to construct valid HTML to begin with, especially if your new data is more complex or needs to be inserted in a different place.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.2 is now available!

    Wednesday, April 4, 2012 11:44 PM
  • IE and an outlook engine that i guess somewhat share engines are very forgiving in how proper your html must be for it to be rendered, they will forgive you not closing some tags and apparently also for placing html outside of its proper boundries, but as Dmitry said - it may look ok for you, but for someone using other version, etc. it might simply not show up.
    Thursday, April 5, 2012 6:05 AM
  • OK, I looked again at the source of the message in Outlook and saw the code that you showed above. I must have been looking at it from IE after it was saved as an html. Sorry about that Chief! I also found a page that explained things in more detail:

    http://msdn.microsoft.com/en-us/library/dd492012(v=office.12).aspx#Outlook2007ProgrammingCh17_AddingTextToAnItem

    From what I read there, it does not seem too easy to insert at a particular cursor position in an html formatted email. However, I did follow along with that info and cobbled together the following that works great if Word is the editor and defaults to my improved(valid html) version if Outlook is the editor.

    --------------------------------------------------------------------------------------------
    Sub PasteLink()
    Dim objOL As Outlook.Application
    Dim objNS As Outlook.NameSpace
    Dim objDoc As Word.Document
    Dim objSel As Word.Selection
    Dim MyData As DataObject
    Dim strClip As String
    Dim strHLink As String
    Dim msg As Outlook.MailItem

    Set MyData = New DataObject
    MyData.GetFromClipboard
    strClip = MyData.GetText
    strShortClip = GetFilename(strClip)

       ' On Error Resume Next
        Set objOL = Application
        If objOL.ActiveInspector.EditorType = olEditorWord Then
            Set objDoc = objOL.ActiveInspector.WordEditor
            Set objNS = objOL.Session
            Set objSel = objDoc.Windows(1).Selection
            objSel.Hyperlinks.Add Anchor:=Selection.Range, Address:=strClip, SubAddress:="", ScreenTip:="null", TextToDisplay:=strShortClip
        Else
            strHLink = Chr(34) & "file://" & strClip & Chr(34)
            Set msg = Application.ActiveInspector.CurrentItem
                  
            msg.HTMLBody = Replace(msg.HTMLBody, "<BODY>", "<BODY>" & "<a href=" & strHLink & ">" & strShortClip & "</a>", , , vbTextCompare)
                  
           ' SendKeys "^{END}"
           ' SendKeys "+{ENTER}"
           
        End If
       
    End Sub
    ---------------------------------------------------------------------------------------------

    I am now hoping to find a way of copying the body of the email from the starting <html tag to the current cursor position to a variable and then using the replace() function to concatenate that variable with the hyperlink string that I'm pasting from the clipboard because although it keeps the signature block intact, it pastes it at the start of the message. Also, I can't seem to be able to turn off the screen tip for the hyperlink. It shows the full path. Thanks again.


    Scott B


    Thursday, April 5, 2012 11:09 PM
  • if you decided to go with Word API manipulation, do as i wrote above - find bookmark with name  _MailAutoSig and insert your hypelink one line above that.
    Friday, April 6, 2012 8:35 AM
  • Thanks DamienD,
     
    Using the Word API manipulation is working fine with the signature block; no placement or displacement issues. Aren't bookmarks only part of the Word library? I have only a few users that use Word as the editor, so my objective is to get it to work as best as can be in the Outlook 2003 editor.

    Scott B

    Saturday, April 7, 2012 1:23 AM
  • You already have code that checks for word editor, so modify only that part to work better with signature. And do not worry, bookmarks work there.

    Tuesday, April 10, 2012 10:00 AM