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

I am having trouble saving a spreadsheet.
This spreadsheet has already been copied
I am using the line
    $excel->Workbooks(1)->SaveAs($sp_full)  or ($excel_res = 0, $ew_message = "Could not save spreadsheet <$sp_full>");
To try and find out why I used the following two lines to get the error number and corresponding message
$en_num = Win32::GetLastError(); $en_f = Win32::FormatMessage($en_num);
I get the error number of 317 but $en_f does not contain anything
I then get a dialog box asking if I want to save the changes to the spreadsheet.
If I add the line, before trying to save, of $excel->{DisplayAlerts}=1;
I get a message indicating that the file is there and asking if I want to overwrite it.
Can anyone suggest why this is happening and how I can cure the problem?

Replies are listed 'Best First'.
Re: Error 317 saving spreadsheet
by Corion (Patriarch) on Mar 08, 2007 at 15:57 UTC

    Win32::GetLastError will only return a meaningfull value if called immediately after the system call. It most likely doesn't return Excel-specific information, so likely you're out of luck with your strategy of trying to find out something more specific about the error condition.

    There seems to be no way to convince Excel to save the file unconditionally with the ->SaveAs method, overwriting what is potentially there, so I think you'll have to use

    $excel->{DisplayAlerts} = 0; $excel->Workbooks(1)->SaveAs( $sp_full );

    The documentation doesn't say much on using the return value of ->SaveAs, so you might have to guess whether it worked or not.

      There seems to be no way to convince Excel to save the file unconditionally with the ->SaveAs method, overwriting what is potentially there

      You could copy the spreadsheet to the new name before opening and modifying it.

Re: Error 317 saving spreadsheet
by Sagacity (Monk) on Mar 08, 2007 at 17:18 UTC

    merrymonk ,

    From MSDN:

    ERROR_MR_MID_NOT_FOUND 317 The system cannot find message text for message number 0x%1 in the message file for %2.

    The $en_f = Win32::FormatMessage($en_num); can't provide a string because the text that would be used for that string doesn't exist.

    ikegami's suggestion may point to this:

    From CPAN:

    Win32::CopyFile(FROM, TO, OVERWRITE)

    CORE The Win32::CopyFile() function copies an existing file to a new file. All file information like creation time and file attributes will be copied to the new file. However it will not copy the security information. If the destination file already exists it will only be overwritten when the OVERWRITE parameter is true. But even this will not overwrite a read-only file; you have to unlink() it first yourself.

    $excel->{DisplayAlerts}=1; I get a message indicating that the file is there and asking if I want to overwrite it.

    Looking at the above, I believe the error has to do with an attempt to overwrite an existing file(The very file you have open).

    Using the Win32::CopyFile(FROM, TO, OVERWRITE) to allow the overwrite may solve the problem.

      Thank you for the comments and help which stopped m looking in crypts that would have nothing in them!
      I have done more work and to help I used the sub below.
      I believe that I have found that the problem was caused by having a directory
      that contained ‘[]’ characters since when I removed these all was well.
      It would interesting to know if these characters are not ‘preferred’ in some sense.
      To confuse matters, I have a suspicion that this will not be found on all PCs under windows but I cannot be sure
      sub copy_edit_savesp_test($$$) { my ($file_name, $dir_in, $dir_out) = @_; my ($file_name_in_full, $file_name_out_full, $excel, $excel_res, $work +book, $copy_res); my ($add_data_sp, $row, $workbook_res, $ew_message, $wksht, $wksht_str +, $worksheet); $file_name_in_full = $dir_in . '\\' . $file_name; $file_name_out_full = $dir_out . '\\' . $file_name; $copy_res = copy($file_name_in_full, $file_name_out_full); print "\ndir file <$file_name>\nin <$dir_in>\n$dir_out\n"; print "\n[copy_edit_savesp_test] copy res <$copy_res> for <$file_name_ +out_full>\n"; $excel_res = 1; $excel = Win32::OLE->new('Excel.Application', 'Quit') or ($excel_res = + 0, $ew_message = "Could not create excel object"); print "[copy_edit_savesp_test] open res <$excel_res> excel <$excel> wo +rkbook <$workbook>\n"; if($excel_res == 1) { $workbook_res = 1; $ew_message = "work book ok"; $workbook = $excel->Workbooks->Open($file_name_out_full) or ($wor +kbook_res = 0, $ew_message = "Could not open excel workbook"); print "[copy_edit_savesp_test] after workbook result <$workbook_re +s> message <$ew_message>\n"; $add_data_sp = 'yes'; if($add_data_sp eq 'yes') { $wksht +=1; $wksht_str = "sheet" . $wksht; $worksheet = $excel->ActiveWorkbook->Worksheets($wksht_str); $row = 2; $worksheet->Cells($row,9)->{Value} = "row $row 9"; $row = 3; $worksheet->Cells($row,6)->{Value} = "row $row 6"; $worksheet->Cells($row,8)->{Value} = "row $row 8"; } else { print "\n[copy_edit_savesp_test]no data added to spredsheet\n" +; } } $excel->{DisplayAlerts}=0; $ew_message = "just before saving spreadsheet"; print "before message <$ew_message>\n"; $excel_res = 1; $excel->Workbooks(1)->SaveAs($file_name_out_full) or ($excel_res = 0, + $ew_message = "Could not save spreadsheet>"); print "[copy_edit_savesp_test] after saving spredsheet result <$excel_ +res> message <$ew_message>\n\n"; $excel->{DisplayAlerts}=1; }
Re: Error 317 saving spreadsheet
by merrymonk (Hermit) on Mar 08, 2007 at 15:49 UTC
    I apologise for 'replying' to my own question but this contains more details
    that may help to understand what is happening.
    I now realise that I have asked a similar question before but no Monk could help
    However one Monk did want some more details. Here they are
    I am using the following modules
    use Win32; use Win32::OLE; use Win32::OLE::Const 'Microsoft Excel';
    and the following to open the workbook etc
    $excel = Win32::OLE->new('Excel.Application', 'Quit') or ($excel_ +res = 0, $ew_message = "Could not create excel object"); $workbook = $excel->Workbooks->Open($new_finnpower_full) or ($workboo +k_res = 0, $ew_message = "Could not open excel workbook");

    I believe that both of these worked since I could manually save the altered spreadsheet
    and I did not get any errors from these statements.
Re: Error 317 saving spreadsheet
by ikegami (Patriarch) on Mar 08, 2007 at 16:13 UTC

    GetLastError is only meaningful after a system call returns an error. It's wrong to use it there.