otism has asked for the wisdom of the Perl Monks concerning the following question:

Esteemed brethren of the code,

I have a some code I've thrown together to read through an Excel 2007 spreadsheet - which is working just fine to a point. I can open the file - read the values - print some out - and close the file. Everything seems absolutely peachy on the surface.

The problem is that in the background EXCEL.EXE in the task manager just will not go away! If I have other worksheets open in the background, THEY will close and the app window go away, but the process called from the script remains.

Does anyone have any ideas what I can do to cause this process to go away?

PC - Windows XP Pro SP 2 ( VDI )

MS Office Excel 2007

Perl details:

C:\>perl -V Summary of my perl5 (5.0 patchlevel 5 subversion 03) configuration: Platform: osname=MSWin32, osvers=4.0, archname=MSWin32-x86-object uname='' hint=recommended, useposix=true, d_sigaction=undef usethreads=undef useperlio=undef d_sfio=undef Compiler: cc='cl.exe', optimize='-Od -MD -DNDEBUG -TP -GX', gccversion= cppflags='-DWIN32' ccflags ='-Od -MD -DNDEBUG -TP -GX -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_OBJECT' stdchar='char', d_stdstdio=define, usevfork=false intsize=4, longsize=4, ptrsize=4, doublesize=8 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10 alignbytes=8, usemymalloc=n, prototype=define Linker and Libraries: ld='link', ldflags ='-nologo -nodefaultlib -release -libpath:"C:\Perl\lib\C ORE" -machine:x86' libpth="C:\Perl\lib\CORE" libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32. lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock 32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib PerlCRT.lib libc=C:\Perl\lib\CORE\PerlCRT.lib, so=dll, useshrplib=yes, libperl=perlcore. lib Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release -libpath:"C: \Perl\lib\CORE" -machine:x86' Characteristics of this binary (from libperl): Locally applied patches: ActivePerl Build 522 Built under MSWin32 Compiled at Nov 2 1999 09:52:28 @INC: C:/Perl/lib C:/Perl/site/lib

use strict; use Win32::OLE qw(in with); use Win32::OLE::Const 'Microsoft Excel'; use Win32::OLE::Variant; use Win32::OLE::NLS qw(:LOCALE :DATE); use FindBin qw($Bin); $Win32::OLE::Warn = 3; my $Excel = Win32::OLE->new('Excel.Application','Quit'); my $curpath = "$Bin/"; undef my $j; for $j (0 .. length($curpath)){ if(substr($curpath,$j,1)eq '/'){substr($curpath,$j,1) = '\\';} } undef my $listfile; $listfile = "filelist.txt"; my $syscmd = "dir \/b *.xlsx > ".$listfile; system($syscmd); sleep 2; close(STDERR); open(STDERR, ">load_error_log.txt"); open(RDR0, $listfile); undef my $listread; while ($listread = <RDR0>){ chomp($listread); my $ExcelFile = $curpath.$listread; print "*Loading $ExcelFile*\n"; my $Book = $Excel->Workbooks->Open($ExcelFile) || die("Unable to o +pen $ExcelFile ", Win32::OLE->LastError()); sleep 5; my $Sheet = $Book->Worksheets(1); my $LastRow = $Sheet->UsedRange->Find({What=>"*", SearchDirection=>xlPrevious, SearchOrder=>xlByRows})->{Row}; my $LastColumn = $Sheet->UsedRange->Find({What=>"*", SearchDirection=>xlPrevious, SearchOrder=>xlByColumns})->{Column}; my $RangeVal; for $j(65 .. (65 + $LastColumn)){ $RangeVal = chr($j)."1"; print $Sheet->Range($RangeVal)->{Value}."\t"; } print "\n"; $Book->Close(0); $Excel->Quit(); undef $Book; undef $Excel; } close(RDR0); close(WRT0); close(STDERR);

Replies are listed 'Best First'.
Re: MS Excel 2007 never dies - or at least the process wont
by davies (Monsignor) on Aug 25, 2011 at 07:35 UTC

    No solution, I'm afraid, but possibly some pointers. I'm running XP pro but I run Excel 2002 as it has various features I like or need. When I run your code, I don't get any Excel files opened because the code runs only in the directory in which it exists itself (not how I would write it) and I don't have Excel files there. I get a "File not found" message and the instance of Excel ends.

    I hope you understand why I don't want to mix up your problem code with my valuable Excel files. If you are looking in the right place for your problem, it may be down to the Excel version. I don't have 2007, but look in the configuration options for anything that might cause it to persist. It will be an option that doesn't exist in earlier versions, if you have something like 2002 or 2003 for comparison.

    However, there are some very strange things in your code. I'm reluctant to do a full critique while you're trying to solve a different problem, but do you realise, for example, that you are creating your Excel instance before your while loop but then trying to destroy it within the while loop? This means that you will try to destroy the instance once for each file. One of two things will happen. Either it will be impossible to process more than one file (because Excel has been destroyed) or Perl will do some of its famous DWIMmery and create a new Excel instance inside the loop, meaning that the one created outside the loop will not be destroyed. This is pretty wild speculation by me, but it might explain your problem.

    It's also possible that you have an XY problem. If you tell us what you are really trying to do, we might be able to help you more.

    Regards,

    John Davies

Re: MS Excel 2007 never dies - or at least the process wont
by kcott (Archbishop) on Aug 25, 2011 at 09:38 UTC

    The following is not a solution; rather thoughts and suggestions as I'm unable to replicate your environment.

    I was originally going to suggest that an alternative might be Spreadsheet::XLSX which the documentation describes as: "Perl extension for reading MS Excel 2007 files".

    However, I noticed your perl -V output has "... perl5 (5.0 patchlevel 5 subversion 03) ... Compiled at Nov 2 1999 ...". As Spreadsheet::XLSX source code has use 5.006000;, you won't be able to use this with your current (12-year old) version of Perl.

    This led me to thinking that there might be some some incompatibility between your 1999 Perl and 2007 Excel. If you add use warnings; (after use strict;), you may get some output indicating such a problem.

    While I appreciate that upgrading Perl will not be a trivial task, I would recommend you look at doing so.

    P.S. For future reference, the perl -V output would have been much easier to read if wrapped in <code>...</code> tags.

    -- Ken

      Thanks Ken - and would love to update the environment but it's a far more extensive environment than just my virtual station on the server that will be required to run the code. The script this is derived from is part of a package deliverable for repeated use and unfortunately the deadline for the initial completion of the script for the procedure at hand is rather more pressing than a broadcast environment update would support.
Re: MS Excel 2007 never dies - or at least the process wont
by Jim (Curate) on Aug 25, 2011 at 05:08 UTC

    Whittle that busy Perl script down to the bare minimum code that exhibits the problem you're having, and that someone can easily run without having to emulate your private world, and I'll bet you you'll get plenty of helpful responses to your inquiry.

      If it were my private world it would be up to date and not have this problem. Thanks though - for the valuable insight into what you seem to view as the norm - apathy.
Re: MS Excel 2007 never dies - or at least the process wont
by locked_user sundialsvc4 (Abbot) on Aug 25, 2011 at 13:07 UTC

    First of all, it puzzles me greatly why you are ordering Excel to Quit(), and then waiting 5 seconds (I suppose) for it to have time to do so.   Once Excel has been started, knowing this to be an expensive process, you want it to stay active for the duration.

    But, “OLE knows how to do that already.”   The OLE subsystem, not your requesting process, is the party that should be made solely responsible for starting the service process (Excel, in this case), and for ending it.   This is done in part, I think, because of clients that otherwise would, as your program does, constantly ask the hosting program to quit.

    I don’t see any evidence that you actually defined a Quit() destructor ... and this, technically, is probably the reason why it isn’t quitting ... but my point is that you don’t want it to quit every time, as you are now praying for it to do.

    By far the easiest way to approach OLE is at the document level, not the application level.   (It is my crystalline opinion that this is what the architects had in mind.)   Unless you specifically need to control the visibility of the app to the user, you want to be talking to Excel.Spreadsheet, or what-have-you, not the Excel.Application that, you happen to know, is what drives “spreadsheets.”   Ask for what you want to manipulate, and address your supplications to those things, not the application itself.   OLE can, and will, determine and launch and manage those application instances on your behalf, and it will do so much more efficiently than you are, in the present case, attempting to do.

      The wait was just a futile troubleshooting attempt. Thanks to all who provided input regarding structure of the code - rather than the placement of files. The structure as it stands is designed to read more than one file if applicable - so the loop you may be referring to is a loop that should indeed close each worksheet prior to beginning anew. I don't experience this problem on my pc - leading me to believe that the recommendations regarding updating perl surely would help. Unfortunately don't have the option of a blanket update of the various user VDI environments where the code will need to function - or rather the time to accomplish that task. I'll try revising the sequencing of application and workbook calls to see if that helps. I really dont want to manipulate any values within the spreadsheet, only read them and then use ODBC to write to and update DB records.

        Closing the file within the loop makes sense. Closing the application within the loop doesn't make sense to me. If there's a reason, I'd be very interested in it.

        Regards,

        John Davies