Sending a selected range through Outlook - NOT A QUESTION!

dk

MrExcel MVP
Joined
Feb 15, 2002
Messages
2,942
Good afternoon all,

I've seen a few posts recently asking about sending either sending a range or a worksheet in an Outlook email as the body of the message through code. I've been looking at this and think I've come up with something that might work. I'd appreciate it if any of you XL kings and queens would take a look and see if the code works OK on your machine. I've sent a few messages to myself (sad I know :) ) and they seem to work well.

Here's the code. You need to set a reference to the Outlook object Library AND the Microsoft Scripting Runtime in order for this code to work.

Any ideas for improvement, suggestions, comments gratefully received.

Dan

Code:
Option Explicit

Sub SendRange()

'Sends a specified range in an Outlook message and retains Excel formatting

'Code written by Daniel Klann 2002

'References needed :
'Microsoft Outlook Object Library
'Microsoft Scripting Runtime


'Dimension variables
Dim olApp As Outlook.Application, olMail As Outlook.MailItem
Dim FSObj As Scripting.FileSystemObject, TStream As Scripting.TextStream
Dim rngeSend As Range, strHTMLBody As String


'Select the range to be sent
On Error Resume Next
Set rngeSend = Application.InputBox("Please select range you wish to send.", , , , , , , 8  )
If rngeSend Is Nothing Then Exit Sub    'User pressed Cancel
On Error GoTo 0

'Now create the HTML file
ActiveWorkbook.PublishObjects.Add(xlSourceRange, "C:tempsht.htm", rngeSend.Parent.Name, rngeSend.Address, xlHtmlStatic).Publish True


'Create an instance of Outlook (or use existing instance if it already exists
Set olApp = CreateObject("Outlook.Application")

'Create a mail item
Set olMail = olApp.CreateItem(olMailItem)

'Open the HTML file using the FilesystemObject into a TextStream object
Set FSObj = New Scripting.FileSystemObject
Set TStream = FSObj.OpenTextFile("C:tempsht.htm", ForReading)

'Now set the HTMLBody property of the message to the text contained in the TextStream object
strHTMLBody = TStream.ReadAll

olMail.HTMLBody = strHTMLBody

olMail.Display


End Sub
This message was edited by dk on 2002-05-14 07:21
 
Dan, I'll leave 2 & 3 for Ivan, but if you have your reference established and know the index number you can run a procedure like the following to grab the guid (where n is the order #):<pre>
Sub Grab_Reference()
Dim n As Integer, myRef
n = 4
On Error Resume Next
Set myRef = ThisWorkbook.VBProject.References.Item(n)
If Not myRef Is Nothing Then
MsgBox myRef.Name & Chr(13) & Chr(13) & myRef.Description & _
Chr(13) & Chr(13) & """" & myRef.GUID & """" & ", " & _
myRef.Major & ", " & myRef.Minor & Chr(13) & Chr(13) & _
myRef.fullpath
End If
End Sub</pre>

If you don't know the order number, you can loop through all of your references. The number at the top of the message box is the order number:<pre>
Sub Grab_References()
Dim n As Integer
On Error Resume Next
For n = 1 To ActiveWorkbook.VBProject.References.Count
MsgBox (n) & Chr(13) & Chr(13) & _
ActiveWorkbook.VBProject.References.Item(n).Name & _
Chr(13) & Chr(13) & _
ActiveWorkbook.VBProject.References.Item(n).Description & _
Chr(13) & Chr(13) & _
"""" & ActiveWorkbook.VBProject.References.Item(n).GUID _
& """" & ", " & _
ActiveWorkbook.VBProject.References.Item(n).Major & ", " & _
ActiveWorkbook.VBProject.References.Item(n).Minor & Chr(13) _
& Chr(13) & _
ActiveWorkbook.VBProject.References.Item(n).fullpath
Next n
End Sub</pre><pre></pre>
The GUIDs are all in HKEY_CLASSES_ROOT*App Name*CLSID, but not as user friendly. E.g., Word 9.0:

HKEY_CLASSES_ROOTWord.Application.9CLSID

Hope this helps with # 1.
_________________
Cheers,<font size=+2><font color="red"> Nate<font color="blue">O</font></font></font>
This message was edited by nateo on 2003-01-24 19:15
 
Upvote 0

Excel Facts

Control Word Wrap
Press Alt+Enter to move to a new row in a cell. Lets you control where the words wrap.
Hi Dan
1. The GUID (Globally Unique IDentifyer) is to be found
in the registry. The best place I have found to look
is in the TypeLib. HKEY_CLASSES_ROOTTypeLib and not
the ClassID section (CLSID), because it is the Object
library files (.olb) that contain type libraries.
Look @ NateO's code (Great NateO), I use similar to
get the GUID and all th other info needed.

2. Does the GUID take account of different versions of
software? e.g. will this code install a reference to
Outlook regardless of its version?

Yes it will, in fact if you look @ the code I gave
you will note that the Major Version number I set
for OutLook is 7 even though Excel2000 would be 9
and Xp 10.

The Full code I use takes into account some variables
Major & Minor M = Major version: m = Minor version
For compatibilty reasons I set the M version
to the lowest version number that I will be
developing for (or to be safe set @ 1).
The AddFromGuid will pickup the version # irrespective
....(as long as you have the GUID string correct!)
this is the whole point of COM (Common Object Module)
All future upgrades to an existing application interface
should fully support all previously published versions
of that interface (SOMETIMES !!). Therefore, assuming
MS follows the precepts of COM, the GUID of Excel or
any MS application will never change. If you compare
the GUID for each version of Excel you will find they
are exactly the same. Best place to look is;
the Registry @ HKEY_CLASSES_ROOTTypeLib


[3 How comes the AddFromGUID method doesn't appear when
you type it into the object browswer? If I set a reference
to the VBA extensibility library I can find it -
do you know what's going on here?]

Thats a good Q! as you would logically think that because this
command is part of the VBIDE.References (The extensibilty Lib)
that you would need to refernce this FIRST before running code
That References itself, or part of its Library!?.
I am not sure except to say that

Note: One thing to be carefull of is that when developing and
you have this code in then recompiling will error out as expected
on the code that needs the reference, so you won't know if
there are ANY other complile errors. To get around this you can set
your variables to Objects (ie. late binding) and not the
Object Librarys, or develope other code and then Import the
Module in.......
Just a few notes on Binding of which there are 2.
[]
EARLY & LATE BINDING.
Early binding is the friendly name for what C programmers
call Virtual Function Table Binding or V-Table binding
(lets not forget that it is the C programmers that provide
the Tools for VB programmers to do there job easier through
the intergration of library files with C code, they are
the tool makers, we are the Application makers), VTable is
a table of pointers to functions that the interface supports.

In order to use Early binding, the controlling application
must establish a reference to a
type library (.TLB) = A file or component within another file that
contains standard descriptions of exposed objects,
properties, and methods that are available for Automation.

Object library files (.olb) > contain type libraries,
or dynamic-link library (.DLL) > which defines the objects,
methods, and properties of the server application.

If you have a look @ your VBA Reference Table,
avail via Tools > References you will see something like
these as References;

Microsoft Excel 9.0 Object Library
C:Program FilesMicrosoft OfficeOfficeEXCEL9.OLB
Microsoft Forms 2.0 Object Library
C:WINDOWSSYSTEMFM20.DLL
Microsoft Graph 9.0 Object Library
C:Program FilesMicrosoft OfficeOfficeGRAPH9.OLB
Microsoft Office 9.0 Object Library
C:Program FilesMicrosoft OfficeOfficeMSO9.DLL
Microsoft Outlook 9.0 Object Library
C:PROGRAM FILESMICROSOFT OFFICEOFFICEmsoutl9.olb
Microsoft PowerPoint 9.0 Object Library
C:Program FilesMicrosoft OfficeOfficemsppt9.olb
Microsoft Scripting Runtime
C:WINDOWSSYSTEMSCRRUN.DLL
Microsoft VBScript Regular Expressions 5.5
C:WINDOWSSYSTEMVBSCRIPT.DLL3

Benefits of Early Binding
Performance:
Depending on what your code is doing, early
binding may significantly improve the speed of your code.
Compile-time syntax checking:
Syntax errors that you make in Automation code will fail
at compile time rather than at run time.
Code readability:
When you declare object variables as
specific types, you can simply glance at those declarations
to determine what objects a particular procedure uses.
Viewing objects:
When you've set a reference to an application's type library,
its objects and their properties and methods show up in the
Object Browser. To find out what properties and methods are
available for a particular object, just check the Object
Browser (F2 in VBA). Note right click gives you a help option.
BUT not all properties have help files avail.
For more info you need:
Microsoft Office 2000 Visual Basic for Applications Language
Reference ISBN 1-57231-955-0
Getting help:
You can get help on another application's object model from
the Object Browser, rather than having to launch the
application itself.
If you have your VBA editor setup as to list memebers then
typing the . forces excel to evaluate and display the properties
Tools > Options > Editor tab
Then click AutoList members

Late Binding
Late binding declares a variable as an Object or a Variant.
The variable is initialized by calling the GetObject or
CreateObject functions and specifying the Automation
Programmatic Identifier (ProgID).
'
To allow access to a COM object regardless of where it is located,
COM implements a mechanism to identify where the executable
implementing a given COM object is. This mechanism means COM is
not restricted to any given path for storing an object.
To do this, COM requires that every non-private object has a
unique identifier. This identifier is called a
GUID (Globally Unique Identifier). This is a 128bit number
(thus potentially allowing for a maximum of 2128 possible
COM objects) To make it easier to write a GUID, it is
normally expressed as a hexadecimal number with some
formatting applied. This form of a GUID is also referred
to as a CLSID (ClassID) where the GUID is the identification
number for a COM object.

An example CLSID looks like this;

CLSID for the Microsoft Excel 9.0 Object Library:
{00020813-0000-0000-C000-000000000046}

The formatting shown corresponds to the COM GUID type:

Type GUID
Data1 As Long '00020813
Data2 As Integer '0000
Data3 As Integer '0000
Data4(0 To 7) As Byte 'C000-000000000046
End Type

How would you like to remember something like this !!
No way, hence the ProgID. COM supports the concept of
Binary Compatibility where two objects with different
GUIDs can be used interchangeably.
Don't forget computer language is essentially BINARY !
To allow for Binary Compatible objects and to make it
easier to get at COM objects, a higher level of abstraction
from the GUID exists. This is the ProgID (Programmatic IDentifier).
The Programmatic ID is a string of the form:

Project.ClassName

Much easier to remember !?
For example, the ProgID for the Excel automation object is
Excel.Application. In a Visual Basic project, the ProgID is
determined in a logical way: from the Project Name and the
Class Name with VBA it is the Application name . So for example,

EXCEL
Application Excel.Application, Excel.Application.9
Workbook Excel.AddIn
Workbook Excel.Chart, Excel.Chart.8
Returns a workbook containing two worksheets;
one for the chart and one for its data.
The chart worksheet is the active worksheet.
Workbook Excel.Sheet, Excel.Sheet.8
Returns a workbook with one worksheet.


This information is stored in the registry like this:

HKEY_CLASSES_ROOTCLSID{00020820-0000-0000-C000-000000000046}Typelib

Note: All Excel objects have there own CLSID eg;
DataTable, worksheetFunction, Pivottable, Range, button etc
they all belong to the Excel TypeLib files eg.
HKEY_CLASSES_ROOTInterface{0002087D-0000-0000-C000-000000000046}
Default ""Button""

In fact Microsoft Office applications expose their functionality
as a set of programmable objects, so you would expect this.
Every unit of content and functionality in Office is an object
that you can programmatically examine and control. A workbook,
a document, a table, a cell, and a paragraph are all examples
of objects that are exposed by Microsoft Office applications

So Basically;
1) Office applications register all of their classes in the
Windows system registry.
2) Each class is associated with a globally unique identifier
(or GUID) called a class identifier.
3) In the registry, each class identifier (or CLSID) is
mapped to a programmatic identifier (or PROGID) and
to its application.

So you have the relationship:

PROGID<--->
CLSID ---------> SERVER

Excel.Application<--->
{00020820-0000-0000-C000-000000000046} --->
C:Program FilesMicrosoft OfficeOfficeEXCEL9.OLB

When you create an instance of the class, COM looks up the ProgID
"Excel.Application" which gives it the GUID of the object.
COM can then locate the GUID and therefore the path to the object
Note that the ProgID doesn't have to specify the version number
there is a VersionIndependent value @
ProgIDHKEY_CLASSES_ROOTCLSID{00024500-0000-0000-C000-000000000046}
VersionIndependentProgID

Value = Excel.Application

'
Late binding was the first binding method implemented in
Automation controller products (OLE). Late binding is the
friendly name for what C programmers call IDispatch-based binding.
It uses a lot of overhead and is faster than Dynamic Data
Exchange (DDE), but slower than Early binding. Late binding
is available in all products capable of being an Automation
controller. With late binding in Visual Basic, your project
does not need a reference to the Automation server's type library
and you can declare your variables as type Object.

Dim oExcelApp as Object

When you declare a variable as type Object, Visual Basic cannot
determine at compile time what sort of object reference the
variable contains, so binding occurs at run time, hence the relative
speeds between early & Late binding. When you call a property or
method of an object with late binding, the process by which
Visual Basic makes the call is twofold:
1) Gets pointer to the object, to get the name of that property or
method.
2) Execute the property or method.

late binding is most advantageous when you are writing Automation
clients that you intend to be compatible with future versions
of your Automation server. With late binding, information from
the server's type library is not ""hard wired"" into your client
so you can have greater confidence that your Automation client
can work with future versions of the Automation server without
code changes


Sorry did I say short notes....




_________________
Kind Regards,<font size=+2><font color="red"> I<font color="blue">van<font color="red"> F M</font color="blue">oala</font><font size=1> From the City of Sails
image.gif

This message was edited by Ivan F Moala on 2002-07-12 17:35
 
Upvote 0
Thanks Nate, nice code which has gone straight into my own little add-in.

Thankyou Ivan, lots of useful information. The part about being able to reference any version is very useful. There are lots of occasions where I've set a reference to a project (e.g. ADO version 2.7 on my machine) only to have it error out on a colleagues machine because they have version 2.5 installed. Excellent!

Thanks again,
Dan
 
Upvote 0
Hi Dan

I've tried this code but get undefined for
xlSourceRange amd xlHtniStatic ?? what am I missing??????

Tony
 
Upvote 0
I havent tried the code yet but it does seem to be what I am looking for. Thanks for all the great work.

I have been looking for such code for a while now...even made a post about it.

You guys are awesome.

B.
 
Upvote 0
How can we achieve to do the same thing with Lotus Notes, i e send a range as HTML?

Kind regards,
Dennis

I've never used or seen Lotus Notes before but I believe it is capable of being automated. I'd imagine that you'd need to look for the equivalent of the Outlook Mailitem object and then see if there is an HTML property (a string variable representing the HTML text in the message body). If there is then it should be easy to modify this code.
 
Upvote 0
DK,

Thanks

HTML property (a string variable representing the HTML text in the message body).

That´s the /#%¤-problem.....
Otherwise it would be an easy task but Lotus Notes was developed in the early days for OS/2 and has not yet fully adapted all the "facilities".

Funny, it´s very easy to do it manually...

Kind regards,
Dennis
 
Upvote 0

Forum statistics

Threads
1,215,316
Messages
6,124,228
Members
449,149
Latest member
mwdbActuary

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top