473,408 Members | 1,852 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

Automation Problem

I have a problem with the following code, which leaves an instance of
Excel visible in Task Manager.

By a process of elimination I have got it down to the fact that
something in the DoCmd.Transfer Spreadsheet line is holding on to an
Excel reference somewhere - can anybody assist (if I comment this line
out, the instance is released, and not visible in Task Manager).

Private Sub btnLoadData_Click()
Dim xlApp2 As Object
Dim xlBook As Workbook
Dim xlSheet As Worksheet
Dim strFilename as string
Set strfilename = "c:\test.xls"
Set xlApp2 = CreateObject("Excel.Application")
xlApp2.Visible = True
Select Case Me.Data_File_From
Case "West Herts"
xlApp2.Workbooks.Open FileName:=strFileName,
Password:="barbados"
Case "Luton"
xlApp2.Workbooks.Open FileName:=strFileName
Case "Stoke Mand"
xlApp2.Workbooks.Open FileName:=strFileName,
Password:="amersham"
Case "South Bucks"
xlApp2.Workbooks.Open FileName:=strFileName,
Password:="amersham"
Case "South Bucks Susp"
xlApp2.Workbooks.Open FileName:=strFileName,
Password:="amersham"
End Select

DoCmd.TransferSpreadsheet , , strImportTableName, strFileName, True

xlApp2.Workbooks.Close
fCloseApp ("XLMain")

Set xlBook = Nothing

xlApp2.Quit
Set xlApp2 = Nothing

End Sub
Function fCloseApp(lpClassName As String) As Boolean

Dim lngRet As Long, hWnd As Long, pID As Long

hWnd = apiFindWindow(lpClassName, vbNullString)
If (hWnd) Then
lngRet = apiPostMessage(hWnd, WM_CLOSE, 0, ByVal 0&)
Call apiGetWindowThreadProcessId(hWnd, pID)
Call apiWaitForSingleObject(pID, INFINITE)
fCloseApp = Not (apiIsWindow(hWnd) = 0)
End If
End Function

Thanks

Gary
Nov 13 '05 #1
5 4114
I have been down this EXACT same road many a time and had the EXACT same
problem as you and used the EXACT same api code to try to close that
instance of Excel :). I finally found a solution that seems to work
between 99-100% of the time.

First, I would make the TransferSpreadsheet call and then I would do the
CreateObject thing after TransferSpreadsheet.

Second, instead of using an Object variable for xlApp2, I would make a
reference to your Excel Library (incase you haven't already) and
dimension your vars like this:

Dim xlApp2 As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.WorkSheet

Then you can use CreateObject(...). Note that I did not use the New
keywork in the Dim statements. I have tried New without CreateObject
but had issues. If you just reference the vars as I did and use
CreateObject, then xlApp2.Quit will really quit and no more Excel in
Task Manager. Plus, you get intellisense dropdowns this way.
Rich

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 13 '05 #2

"Gary Cobden" <ga*********@nhs.net> wrote in message
news:4a**************************@posting.google.c om...
I have a problem with the following code, which leaves an instance of
Excel visible in Task Manager.

By a process of elimination I have got it down to the fact that
something in the DoCmd.Transfer Spreadsheet line is holding on to an
Excel reference somewhere - can anybody assist (if I comment this line
out, the instance is released, and not visible in Task Manager).

Private Sub btnLoadData_Click()
Dim xlApp2 As Object
Dim xlBook As Workbook
Dim xlSheet As Worksheet
Dim strFilename as string
Set strfilename = "c:\test.xls"
Set xlApp2 = CreateObject("Excel.Application")
xlApp2.Visible = True
Select Case Me.Data_File_From
Case "West Herts"
xlApp2.Workbooks.Open FileName:=strFileName,
Password:="barbados"
Case "Luton"
xlApp2.Workbooks.Open FileName:=strFileName
Case "Stoke Mand"
xlApp2.Workbooks.Open FileName:=strFileName,
Password:="amersham"
Case "South Bucks"
xlApp2.Workbooks.Open FileName:=strFileName,
Password:="amersham"
Case "South Bucks Susp"
xlApp2.Workbooks.Open FileName:=strFileName,
Password:="amersham"
End Select

DoCmd.TransferSpreadsheet , , strImportTableName, strFileName, True

xlApp2.Workbooks.Close
fCloseApp ("XLMain")

Set xlBook = Nothing

xlApp2.Quit
Set xlApp2 = Nothing

End Sub
Function fCloseApp(lpClassName As String) As Boolean

Dim lngRet As Long, hWnd As Long, pID As Long

hWnd = apiFindWindow(lpClassName, vbNullString)
If (hWnd) Then
lngRet = apiPostMessage(hWnd, WM_CLOSE, 0, ByVal 0&)
Call apiGetWindowThreadProcessId(hWnd, pID)
Call apiWaitForSingleObject(pID, INFINITE)
fCloseApp = Not (apiIsWindow(hWnd) = 0)
End If
End Function

Thanks

Gary


Wthout commenting on the DoCmd.TransferSpreadsheet, your procedures need to
implement error handling. This is pasted from a reply a recently posted on
the same issue:
Here is an example of some error handling which calls xlApp.Quit if an error
occurs (e.g. trying to open a non-existant workbook) but only if the
instance of Excel was one that the code created - ie Excel was not already
running:

Sub OpenWorkbook()

On Error GoTo Err_Handler

Dim xlApp As Object
Dim xlBook As Object
Dim blnError As Boolean
Dim blnNewApp As Boolean

' Switch off normal error handling as we
' attempt to use ruuning instance of Excel
' If Excel is not running, we try to start an instance
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
If Err.Number <> 0 Then
Err.Clear
Set xlApp = CreateObject("Excel.Application")
If Err.Number <> 0 Then
blnError = True
MsgBox "Error starting Excel", vbCritical, "Error"
GoTo Exit_Handler
Exit Sub
Else
blnNewApp = True
End If
End If

' Switch normal error handling back on
On Error GoTo Err_Handler

Set xlBook = xlApp.Workbooks.Open("C:\Test.xls")

xlApp.Visible = True
Exit_Handler:

On Error Resume Next

If Not xlBook Is Nothing Then
Set xlBook = Nothing
End If

If Not xlApp Is Nothing Then

If blnError And blnNewApp Then
xlApp.Quit
End If

Set xlApp = Nothing

End If

Exit Sub

Err_Handler:
blnError = True
MsgBox Err.Description, vbExclamation, "Error No: " & Err.Number
Resume Exit_Handler

End Sub
Nov 13 '05 #3
Hi Rich

Thanks for your suggestion – which I hoped was going to work

Unfortunately, if I use the CreateObject statement after the Transfer
Spreadsheet as suggested, I get error 3161 – Could not decrypt file

Any further suggestions?

Thanks

Gary


*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 13 '05 #4
Hi Gary,

Yes, I do have another suggestion. I steer away from
TransferSpreadsheet because of the very issue you describe. I use ADO
when I pass data to Excel. This technique is a little more
sophisticated than TransferSpreadSheet but offers a lot more control and
reliability. I will give you a sample code below. First, you need to
make sure you have Mdac2.5 and Mdac2.6 loaded on the computer you will
run this code. Mdac2.5 is the last version of Mdac that contains Jet
for interfacing with Access. Mdac2.6 is an upgrade for 2.5 which really
makes a difference in the ADO code useability. I think if you load 2.6
without having 2.5, the ADO may not work. You should be able to find
Mdac at MSDN or Google. Anyway, you make a reference in Tools/References
to Microsoft ActiveX Data Objects 2.6. Then here is the sample code:

-----------------------------------------------------------
Sub DataToExcelADO()
Dim DB As Database, RS1 As Recordset, strSql As String
Dim j As Integer, t As Integer, RetVal as Variant
Dim cn As New ADODB.Connection, RS As New ADODB.Recordset

Set DB = CurrentDb

strSourcePath = Left(DB.Name, Len(DB.Name) - Len(Dir(DB.Name)))
strSourcePath = strSourcePath & "testExcel.xls;"
RS.CursorLocation = adUseClient
cn.Mode = adModeReadWrite
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & strSourcePath & _
"Extended Properties=""Excel 8.0;HDR=NO;"""

'---clear old data first
DoEvents
For j = 2 To 50 'clear old data from Excel Sheet
strSql = "SELECT * FROM [Sheet1$A" & j & ":U" & j & "]"
RS.Open strSql, cn, adOpenDynamic, adLockPessimistic
For k = 0 To RS.Fields.Count - 1: RS(k) = Null: Next
RS.Update
RS.Close
Next

'---populate Sheet1
Set RS1 = DB.OpenRecordset("tblTestData")
f = RS1.Fields.Count
j = 2
DoEvents
Do While Not RS1.EOF
strSql = "SELECT * FROM [Sheet1$A" & j & ":U" & j & "]"
RS.Open strSql, cn, adOpenDynamic, adLockPessimistic
For k = 0 To RS1.Fields.Count - 1
RS(k) = RS1(k)
Next
RS.Update
RS.Close
j = j + 1
RS1.MoveNext
t = t + 1
RetVal = SysCmd(acSysCmdSetStatus, t)
Loop
RS1.Close
cn.Close
End Sub
---------------------------------------------------------

Note that this technique does not use automation. You are referencing a
specific Excel workbook to write to. You can't do that with
TransferSpreadsheet. There are a few Gotcha's though. First, you have
to pre-populate the Excel sheet you are going to write to, save, then
delete the fake data. This preps the sheet for ADO. Then usually, you
can leave the cells in General format, but sometimes ADO complains if
you write data from a Date/Time field in an Access Table. So format
those columns in Excel as Date or Time.

The next Gotcha is that ADO will only write one row at a time to Excel.
If you try Select * from your table of 500 rows, it will write the first
row 500 times to Excel. So you have to close the ADO recordset var RS
for each row. But it is lightening fast. You can write 500 rows in
about 5 seconds, if that. Also note, that for the Excel file that I
reference, you have to end it with a semi colon ";"

strSourcePath = strSourcePath & "testExcel.xls;"

Then, the sql statement

strSql = "SELECT * FROM [Sheet1$A" & j & ":U" & j & "]"

references the sheet you will write to. You can name the sheet anything
you want in Excel, but you have to use the same name in this sql
statement. I am writing here to columns A through U. j is the row
counter. Note in the example code, I start j at Row 2 then I increment
j. I also use

RetVal = SysCmd(acSysCmdSetStatus, t)

to monitor the progress of the Do Loop. SysCmd write to the status bar
at the bottom of Access. But back to the sql statement, you can write
your data to any column, row you want by referencing it in the sql
statement

strSql = "SELECT * FROM [Sheet1$H" & j & ":AD" & j & "]"

This write to columns H through AD. Just make sure you have the same
number of columns in your table. Just a word of FYI, ADO is very
touchy. It does a lot of complaining about data types. So start out
with just text fields, like say a table with 5 columns of text. So your
sql statement would be

strSql = "SELECT * FROM [Sheet1$A" & j & ":E" & j & "]"

The Excel workbook can be open or close. Works much faster if the
workbook is closed. Once you are done passing your data, you can then
use automation to do other stuff. I do this all the time.

HTH
Rich


*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 13 '05 #5
>>
You are referencing a specific Excel workbook to write to. You can't do
that with TransferSpreadsheet.
<<

Correction: You can reference a specific workbook with
TransferSpreadsheet, but you can't re-use that workbook unless you
delete the TransferSheet first because TransferSpreadsheet doesn't
overwrite. You don't have this problem with the ADO method. ADO will
write to any sheet you reference, and/or overwrite. Word of Caution, if
you pass 500 rows of data with ADO and then pass 300 rows another day,
you still have 200 old rows left over. So you need to clear out the old
data first. I usually, prep a worksheet for 10,000 rows with fake data
-- ";lkj;lkj;" --, save the workbook, then delete the fake data and save
again. The workbook will server as a template workbook (but not really
a template, not .xlt, just xls - once you pass your data use automation
to save the workbook as something else). Note: Prep Date/Time columns
with date/time data 1/1/1900, 00:05 and drag that down for 10,000 rows,
then delete.

Rich

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 13 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: qwweeeit | last post by:
Hi all, Elliot Temple on the 1 June wrote: > How do I make Python press a button on a webpage? I looked at > urllib, but I only see how to open a URL with that. I searched > google but no...
25
by: Neil Ginsberg | last post by:
I have a strange situation with my Access 2000 database. I have code in the database which has worked fine for years, and now all of a sudden doesn't work fine on one or two of my client's...
12
by: Cheval | last post by:
Has anyone had any problems with inter-office automation between MS Word and MS Access in Office 2003? I have recently installed office 2003 in a new folder and have left the older office 2000...
1
by: Jimmer | last post by:
I've got what should be an easy automation problem, but the solution simply isn't coming to me. I've got several public variables set up for automation as follows: Public gappExcel As...
4
by: Daniel | last post by:
Hello, i have a problem with the word automation from c#. First, i want to mention, that i don't have any dependencies from word in my c#-project, i want to use the system.reflection model to...
2
by: Alfredo Magallón Arbizu | last post by:
Hello, I have an ASP.NET application that reads an Excel file through automation. The app has a loop until first cell of a row is blank. While the app works perfectly under Windows 2003, it...
16
by: RichardP | last post by:
Hi there everyone - I'm new to this forum. I am having an issue when running an application from an instance of Access which has been started through automation (early or late bound, makes no...
12
by: Tomas | last post by:
Hi, I have worked with VB.NET for half a year (semi-newbie). Currently I am looking around for some books for those that crossed the starting hurdle. There are too many books out there-make...
0
by: Sharath | last post by:
Quality Globe is Glad to Offer you the Fast Track course on Automation, QTP Basics and Advanced, and Quality Center Starting Date: June 4th, 2007 Timings: 10 AM to 3:30 PM Duration: 50 Hours ...
0
by: Sharath | last post by:
"Inspired" by the huge success of our first two automation fast track batches We are forced to start third fast track automation batch ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.