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

At the risk of appearing even MORE embarrased that I already do, can anyone tell me what the following message means. I am trying to build 9 spreadsheets into a single xls book using Win32::OLE. I have gone so far as cloning the sample in the ActiveState doc & it works fine. The only difference I can see is that my broken code tries to loop through several files building one sheet per file. It appears that I can create the book, add 9 sheets, and set the column headings, but I can't change the sheet name, or populate the range of data cells.

Win32::OLE(0.1707) error 0x80020009: "Exception occurred" in PROPERTYPUT "Name" at CSV2xls.pl line 148
at C:/Perl/AS_Perl/lib/Win32/OLE/Lite.pm line 221
Win32::OLE::Tie::STORE('Win32::OLE::Tie=HASH(0x1f287e0)', 'Name', '') called at CSV2xls.pl line 148
Debugged program terminated. Use q to quit or R to restart

Here's the code piece
# ************************************************* # Start Excel and create new workbook with 9 sheets use Win32::OLE qw(in valof with); use Win32::OLE::Const 'Microsoft Excel'; use Win32::OLE::NLS qw(:DEFAULT :LANG :SUBLANG); my $lgid = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); $Win32::OLE::LCID = MAKELCID($lgid); $Win32::OLE::Warn = 3; my $Excel = Win32::OLE->new('Excel.Application', 'Quit'); $Excel->{SheetsInNewWorkbook} = 9; my $Book = $Excel->Workbooks->Add; my $Sheet = $Book->Worksheets(1); my $sheet_count = 0; # ************************************************* # Read each 'selected' file and load them into an array my @rows; my @fields; foreach $file (@csvFiles) { open (csvFILE, $file) || die "Cannot open $csvFile $!\n"; $csvFile = $file; # Skip the first record (too long) of each file, we'll deal with it +later my $inBuf = <csvFILE>; $sheet_count++; while ($inBuf = <csvFILE>) { chomp($inBuf); if (scalar @fields > $line_limit) {last;} # Runaway safety net $inBuf =~ s/^\"//; # Take out any LEADING or $inBuf =~ s/\"$//; # TRAILING double quotes # OK, Process this record @fields = split(/\,/,$inBuf); push @rows, [@fields]; } # End of while inBuf, or we exceeded Safety Net close csvFILE; # **************************************** # Build the Spreadsheet from the CSV Array # print "\nLoading Sheet \($sheet_count\) of $xlsFile from $csvFile \n +"; $Sheet = $Book->Worksheets($sheet_count); $Sheet->{Name} = substr($cvsFile,0,6); #This fails # Insert column titles - hmmm wonder why THESE work? my $Range = $Sheet->Range("A1:J1"); $Range->{Value} = [qw(Dept ItemCnt GrSales VoidCnt VoidAmt RefundCnt + RefundAmt CouponCnt CouponAmt CustCnt)]; $Range->Font->{Bold} = 1; # This works too # Add csv data to spreadsheet print "\n\nAdding data from $csvFile to Sheet $xlsFile\n"; $Range = $Sheet->Range(sprintf "A2:J%d", 2+$#rows); $Range->{Value} = \@rows; # This fails similar to Name } # End of Foreach csvFile # ********************************************* # Save workbook to file $xlsFile unlink $xlsFile if -f $xlsFile; #This works fine $Book->SaveAs("$directory\\$xlsFile"); $Book->Close;

Also, if I set a breakpoint & key the Name line by hand, then continue, it works fine. I'm at a loss. Thanks for any insight you can offer, this is the first time I've tried to use any :: module.

Replies are listed 'Best First'.
Re: OLE module working 'part-time'
by Corion (Patriarch) on Sep 24, 2007 at 19:57 UTC

    I can only guess that @csvFiles doesn't contain what you think it should. Excel doesn't like two worksbooks open that have the same (base) filename. Maybe that's part of the problem, or maybe Excel doesn't like that particular name. Output the sheet names before your script tries to set them, or hardcode the names and try that.

    As an aside, you have an error in your error message that use strict; would have caught:

    open (csvFILE, $file) || die "Cannot open $csvFile $!\n";

    That code will never produce a meaningful error message because $csvFile will either be empty or the previous filename at that place in the code.

      I think I only have one book open , it's the sheets that are multiple. I'll try the hard code way & see what happens. Also, I do use strict, but I have BOTH names defined. I had to change the file name field & forgot to also change the die part. Thanks.

      I tried hard coding the name, and it now doesn't die, but it doesnt set the sheet name either.
Re: OLE module working 'part-time'
by roboticus (Chancellor) on Sep 25, 2007 at 01:19 UTC
    Aim9b:

    You might consider using Spreadsheet::WriteExcel, unless you're using Excel features that it doesn't handle yet. It's quite simple to use, and you avoid having hung Excel processes running in the background. (Been there, done that.)

    ...roboticus

      Thanks, I think that's how I started out, then I ran across the OLE sample. I have no idea which approach is better. At one time, I thought that I read where one included the other. I'm still learning & the curve seems to be getting steeper as I go.

      This is a typical user, so I have no idea how the spreadsheet will evolve. Right now, we're at the "all I need is" stage. But we know how long THAT will last. Currently I just need to generate a sheet per day, one for the week, & a summary page. But as for other features, only time will tell. I'll go back & see what I have from my early version. Thanks again.
        I had to use the Spreadsheet module because we don't have office products on our servers, yet the users still wanted their spreadsheets. For a while, we used .CSV files which made our merchant IDs hideous (they're 16 digit numbers, which Excel helpfully reformatted into reals...). Then I stumbled across this package and never looked back.

        ...roboticus