in reply to Help with Spreadsheet::ParseExcel

The code needs some basic checks on whether the worksheet contains 'Account Names' and 'Account Numbers' columns before trying to access data in those columns. In addition there should be checks on whether the accessed rows contain data.

If the cells don't contain information then Spreadsheet::ParseExcel will return undef values.

The following is a working example. Substitute the prints for database inserts and the warns for error reporting and you should be most of the way there.

#!/usr/bin/perl use strict; use warnings; use Spreadsheet::ParseExcel; my $parser = Spreadsheet::ParseExcel->new(); my $workbook = $parser->parse( 'accounts.xls' ); if ( !defined $workbook ) { die $parser->error(), ".\n"; } WORKSHEET: for my $worksheet ( $workbook->worksheets() ) { my $sheetname = $worksheet->get_name(); my ( $row_min, $row_max ) = $worksheet->row_range(); my ( $col_min, $col_max ) = $worksheet->col_range(); my $account_name_col; my $account_number_col; # Skip worksheet if it doesn't contain data. if ( $row_min > $row_max ) { warn "\tWorksheet $sheetname doesn't contain data.\n"; next WORKSHEET; } # Check for certain column headers in the first data row. COLUMN: for my $col ( $col_min .. $col_max ) { my $cell = $worksheet->get_cell( $row_min, $col ); next COLUMN unless $cell; $account_name_col = $col if $cell->value() eq 'Account N +ames'; $account_number_col = $col if $cell->value() eq 'Account N +umbers'; } # Check that we found the required columns headers. if ( defined $account_name_col && defined $account_number_col +) { ROW: for my $row ( $row_min + 1 .. $row_max ) { my $name_cell = $worksheet->get_cell( $row, $account +_name_col ); my $number_cell = $worksheet->get_cell( $row, $account +_number_col ); if ( defined $name_cell && defined $number_cell ) { my $name = $name_cell->value(); my $number = $number_cell->value(); # We have the data we are looking for. Do somethin +g with it. print "Worksheet = $sheetname\n"; print "Row = $row\n"; print "Account name = $name\n"; print "Account number = $number\n\n"; } else { # Handle the error condition in some way. warn "\tWorksheet $sheetname, Row = $row doesn't c +ontain " . "'Account Names' and 'Account Numbers' data.\n +"; next ROW; } } } else { # Handle the error condition in some way. warn "\tWorksheet $sheetname: Didn't find 'Account Names' +and " . "'Account Numbers' headings.\n"; next WORKSHEET; } } __END__

--
John.

Replies are listed 'Best First'.
Re^2: Help with Spreadsheet::ParseExcel
by Anonymous Monk on Jan 12, 2011 at 17:26 UTC
    Thanks for the help this made sense now! Where do I find some explanation about how you used words like "WORKSHEET", "COLUMN" in your code.
      They are just labels for use with next. It is a way of differentiating which loop level you are existing from.

      I sometimes use them for clarity if there is more than one level of nested next. I thought it might help see the call flow in this case.

      See perlfunc for an explanation of next with labels.

      --
      John.

        Thanks again for your great help!