Mike Rosenblum
01-15-2004, 10:37 AM
Automating Excel from VB 6.0
This is a primer on using OLE Automation to create an Excel instance in Visual Basic 6.0 and control Excel from a VB6 Application. The following would also apply for Automating Excel from another Office Application such as Word, Access or Outlook.
The first step in Automating Excel is to add a Reference to the Microsoft Excel Object Library:
(1) Within VB 6.0, choose Alt|Project|References...
(2) Scroll down until you find "Microsoft Excel 10.0 Object Library", which could also be 8.0, 9.0, 11.0, or 12.0, depending on which version of Excel you are using. Click within the check box and then click <OK>. Now your Library reference is loaded.
Next you write your code!
A basic shell for creating a new Excel Object Reference and disposing of it cleanly could look like the following: Sub Main()
Dim oExcel As Excel.Application
Dim oWB As Excel.Workbook
Dim oWS As Excel.Worksheet
Set oExcel = New Excel.Application
oExcel.Visible = True ' <-- *** Optional ***
' Your Code Goes Here
' Your Code Goes Here
' Your Code Goes Here
' Your Code Goes Here
Cleanup:
Set oWS = Nothing
If Not oWB Is Nothing Then oWB.Close
Set oWB = Nothing
oExcel.Quit
Set oExcel = Nothing
End Sub
oExcel vs. 'Application'
In the above, your Excel.Application instance is created with the following two lines: Dim oExcel As Excel.Application
Set oExcel = New Excel.Application From then on you will control your Excel instance by making use of oExcel at all times. Do not use the word "Application" as you would in VBA.
It may seem like a cruel joke, but any usage of the global 'Application' reference will appear to run correctly within VB 6.0, but in fact this is true only the first time you run your code. Unfortunately, your VB6 App would be unable to release the 'Application' global reference and your Excel instance would "hang", unable to close. The second time running, your code could exhibit all kinds of bizarre behavior.
To be clear: code like the following, which is perfectly legal in VBA, would be disastrous in VB6:
Range("A1").Value = 25 ' <-- 'Application' is IMPLIED here.
Application.DisplayAlerts = False ' <-- Uses 'Application'! No good!
Workbooks("Book1").Close ' <-- 'Application' is again implied.
Instead, use the following equivalent:
Set oWS = oExcel.ActiveSheet ' <-- oWS now holds a reference to oExcel.
oWS.Range("A1").Value = 25 ' <-- oWS holds a reference to oExcel.
oExcel.DisplayAlerts = False ' <-- 'oExcel' instead of 'Application'.
oExcel.Workbooks("Book1").Close ' <-- Again, use 'oExcel', not 'Application'.
In the corrected code, above, 'oExcel' is used to refer to the currently running instance of Excel.
For more on this, see post #6 on Finding & Repairing Unqualified References (http://www.xtremevbtalk.com/showthread.php?p=900556#post900556) below.
For further reading on avoiding the use of the 'Application' _Global:
(1) Excel Automation Fails Second Time Code Runs (MSKB 178510) (http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q178/5/10.asp)
(2) Error or Unexpected Behavior with Office Automation When You Use Early Binding in Visual Basic (MSKB 319832) (http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q319832&)
Cleanup
Within the first example at the top of this lesson, note that the cleanup section is careful to (1) close the Workbook with 'oWB.Close', (2) exit the Excel.Application by calling 'oExcel.Quit', and then (3) set both those variables to 'Nothing'.
To help that happen smoothly, the code is making use of 'oExcel.DisplayAlerts = False' and 'On Error Resume Next' to prevent the code from either reporting errors or asking the User for input during the 'Cleanup' phase.
"Your Code Goes Here"
In the main code section, above, within the block reading "Your Code Goes Here" is where you can have fun! Some suggestions for manipulating the Excel environment could look like the following: Dim oRng1 As Excel.Range
Dim oRng2 As Excel.Range
Set oWB = oExcel.Workbooks.Add
Set oWS = oWB.Worksheets("Sheet1")
Set oRng1 = oWS.Range("A1")
Set oRng2 = oWS.Range("B2:E5")
oRng1.Value = "Hello World"
Call oRng1.Copy(Destination:=oRng2)
oWB.SaveAs("Hello World.xls") ' <-- Results saved here. Note that the above carefully avoids any reference to 'Application', either implied or otherwise. All references trace back to 'oExcel', not to 'Application'.
Putting It All Together
Replacing the "Your Code Goes Here" section with the "Hello World" code above, should now give us a combined routine that looks as follows: Sub Main()
Dim oExcel As Excel.Application
Dim oWB As Excel.Workbook
Dim oWS As Excel.Worksheet
Set oExcel = New Excel.Application
oExcel.Visible = True ' <-- *** Optional ***
Dim oRng1 As Excel.Range
Dim oRng2 As Excel.Range
Set oWB = oExcel.Workbooks.Add
Set oWS = oWB.Worksheets("Sheet1")
Set oRng1 = oWS.Range("A1")
Set oRng2 = oWS.Range("B2:E5")
oRng1.Value = "Hello World"
Call oRng1.Copy(Destination:=oRng2)
oWB.SaveAs("Hello World.xls") ' <-- Results saved here.
Cleanup:
Set oWS = Nothing
If Not oWB Is Nothing Then oWB.Close
Set oWB = Nothing
oExcel.Quit
Set oExcel = Nothing
End Sub
Hopefully, this will help you incorporate Excel into your VB6 App with ease.
Best of luck out there...
:),
Mike
Further Info:
For an advanced example of using Automation to turn Excel and Word into a reporting tool, see Garrett Sever's superb coding sample in the Code Library: Using Excel and Word for Reports (http://www.xtremevbtalk.com/showthread.php?t=16520).
Special Thanks
To the Excel Experts: herilane, mark007, tinyjack, Kluz, Italkid and Insomniac, and the rest of the ExVBF team for their questions, comments and guidance... Thanks guys. :)
This is a primer on using OLE Automation to create an Excel instance in Visual Basic 6.0 and control Excel from a VB6 Application. The following would also apply for Automating Excel from another Office Application such as Word, Access or Outlook.
The first step in Automating Excel is to add a Reference to the Microsoft Excel Object Library:
(1) Within VB 6.0, choose Alt|Project|References...
(2) Scroll down until you find "Microsoft Excel 10.0 Object Library", which could also be 8.0, 9.0, 11.0, or 12.0, depending on which version of Excel you are using. Click within the check box and then click <OK>. Now your Library reference is loaded.
Next you write your code!
A basic shell for creating a new Excel Object Reference and disposing of it cleanly could look like the following: Sub Main()
Dim oExcel As Excel.Application
Dim oWB As Excel.Workbook
Dim oWS As Excel.Worksheet
Set oExcel = New Excel.Application
oExcel.Visible = True ' <-- *** Optional ***
' Your Code Goes Here
' Your Code Goes Here
' Your Code Goes Here
' Your Code Goes Here
Cleanup:
Set oWS = Nothing
If Not oWB Is Nothing Then oWB.Close
Set oWB = Nothing
oExcel.Quit
Set oExcel = Nothing
End Sub
oExcel vs. 'Application'
In the above, your Excel.Application instance is created with the following two lines: Dim oExcel As Excel.Application
Set oExcel = New Excel.Application From then on you will control your Excel instance by making use of oExcel at all times. Do not use the word "Application" as you would in VBA.
It may seem like a cruel joke, but any usage of the global 'Application' reference will appear to run correctly within VB 6.0, but in fact this is true only the first time you run your code. Unfortunately, your VB6 App would be unable to release the 'Application' global reference and your Excel instance would "hang", unable to close. The second time running, your code could exhibit all kinds of bizarre behavior.
To be clear: code like the following, which is perfectly legal in VBA, would be disastrous in VB6:
Range("A1").Value = 25 ' <-- 'Application' is IMPLIED here.
Application.DisplayAlerts = False ' <-- Uses 'Application'! No good!
Workbooks("Book1").Close ' <-- 'Application' is again implied.
Instead, use the following equivalent:
Set oWS = oExcel.ActiveSheet ' <-- oWS now holds a reference to oExcel.
oWS.Range("A1").Value = 25 ' <-- oWS holds a reference to oExcel.
oExcel.DisplayAlerts = False ' <-- 'oExcel' instead of 'Application'.
oExcel.Workbooks("Book1").Close ' <-- Again, use 'oExcel', not 'Application'.
In the corrected code, above, 'oExcel' is used to refer to the currently running instance of Excel.
For more on this, see post #6 on Finding & Repairing Unqualified References (http://www.xtremevbtalk.com/showthread.php?p=900556#post900556) below.
For further reading on avoiding the use of the 'Application' _Global:
(1) Excel Automation Fails Second Time Code Runs (MSKB 178510) (http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q178/5/10.asp)
(2) Error or Unexpected Behavior with Office Automation When You Use Early Binding in Visual Basic (MSKB 319832) (http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q319832&)
Cleanup
Within the first example at the top of this lesson, note that the cleanup section is careful to (1) close the Workbook with 'oWB.Close', (2) exit the Excel.Application by calling 'oExcel.Quit', and then (3) set both those variables to 'Nothing'.
To help that happen smoothly, the code is making use of 'oExcel.DisplayAlerts = False' and 'On Error Resume Next' to prevent the code from either reporting errors or asking the User for input during the 'Cleanup' phase.
"Your Code Goes Here"
In the main code section, above, within the block reading "Your Code Goes Here" is where you can have fun! Some suggestions for manipulating the Excel environment could look like the following: Dim oRng1 As Excel.Range
Dim oRng2 As Excel.Range
Set oWB = oExcel.Workbooks.Add
Set oWS = oWB.Worksheets("Sheet1")
Set oRng1 = oWS.Range("A1")
Set oRng2 = oWS.Range("B2:E5")
oRng1.Value = "Hello World"
Call oRng1.Copy(Destination:=oRng2)
oWB.SaveAs("Hello World.xls") ' <-- Results saved here. Note that the above carefully avoids any reference to 'Application', either implied or otherwise. All references trace back to 'oExcel', not to 'Application'.
Putting It All Together
Replacing the "Your Code Goes Here" section with the "Hello World" code above, should now give us a combined routine that looks as follows: Sub Main()
Dim oExcel As Excel.Application
Dim oWB As Excel.Workbook
Dim oWS As Excel.Worksheet
Set oExcel = New Excel.Application
oExcel.Visible = True ' <-- *** Optional ***
Dim oRng1 As Excel.Range
Dim oRng2 As Excel.Range
Set oWB = oExcel.Workbooks.Add
Set oWS = oWB.Worksheets("Sheet1")
Set oRng1 = oWS.Range("A1")
Set oRng2 = oWS.Range("B2:E5")
oRng1.Value = "Hello World"
Call oRng1.Copy(Destination:=oRng2)
oWB.SaveAs("Hello World.xls") ' <-- Results saved here.
Cleanup:
Set oWS = Nothing
If Not oWB Is Nothing Then oWB.Close
Set oWB = Nothing
oExcel.Quit
Set oExcel = Nothing
End Sub
Hopefully, this will help you incorporate Excel into your VB6 App with ease.
Best of luck out there...
:),
Mike
Further Info:
For an advanced example of using Automation to turn Excel and Word into a reporting tool, see Garrett Sever's superb coding sample in the Code Library: Using Excel and Word for Reports (http://www.xtremevbtalk.com/showthread.php?t=16520).
Special Thanks
To the Excel Experts: herilane, mark007, tinyjack, Kluz, Italkid and Insomniac, and the rest of the ExVBF team for their questions, comments and guidance... Thanks guys. :)