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

Hi All

I was create a program which produce some data.Now i use the Spreadsheet::WriteExcel to store the data.But i need some more fexible way to store the data.
use Spreadsheet::WriteExcel; my $workbook =Spreadsheet::WriteExcel->new("final_status.xls"); $worksheet = $workbook->add_worksheet(); $format = $workbook->add_format(); $format->set_bold(); $format->set_color('Blue'); $format->set_align('center'); $col = $row = 0; $worksheet->set_column( 0, 0, 20 ); #Serial No $worksheet->set_column( 1, 1, 15 ); #Test ID $worksheet->set_column( 2, 2, 15 ); # Status $worksheet->set_column( 3, 3, 15 ); # Total $worksheet->set_column( 4, 4, 15 ); # Pass $worksheet->write(A1,"Serial No:", $format); $worksheet->write(B1,"Testcase ID:", $format); $worksheet->write(C1,"Status:", $format); $worksheet->write(D1,"Total:", $format); $worksheet->write(D3,"Total Pass:", $format); $worksheet->write(D4,"Total Fail:", $format); $worksheet->write(E1,"Result:", $format); # Manual Entry $worksheet->write(C2, "pass"); $worksheet->write(C3, "fail"); $worksheet->write(C4, "pass"); $worksheet->write(C5, "fail"); $worksheet->write(C6, "fail"); $worksheet->write(C7, "fail"); $worksheet->write(C8, "fail"); $worksheet->write(C9, "fail"); ##########code to store the data in row wise my $row=3; my $col=0; my $slno=1; my $testid='00A'; my $status='pass'; $worksheet->write($row,$col,$status); my $array_ref; my @array = ($slno, $testid, $status); $array_ref = \@array; $worksheet->write_row($row, $col, $array_ref); ###Formula To claculat the total $worksheet->write('E3', '=COUNTIF(C2:C9,"pass")'); $worksheet->write('E4', '=COUNTIF(C2:C9,"FAIL")');

Here i manually enter the data.So i think about the other way to implement the same.

1.How can i create a subroutine so that from my main program i pass the 3 value and catch it and write the value in excel sheet.As i not sure about the usges of write_row in subroutine.

In case of formula the row and column not taking the variable.As i need to write the result in last row and last column.

Any hint ,suggestion will help a lot

Replies are listed 'Best First'.
Re: Create a excel sheet with formula ???
by jmcnamara (Monsignor) on Nov 08, 2006 at 09:34 UTC

    I think that there are 2 things that might help you here. The first is the write_col() worksheet method which will write a column or an array of data in one go.

    The second is that since a formula is initially only a string you can generate it programmatically based on the number of cells that you have. Both of these points are shown in this short example:

    #/usr/bin/perl -wl use strict; use Spreadsheet::WriteExcel; my $workbook = Spreadsheet::WriteExcel->new("z.xls"); my $worksheet = $workbook->add_worksheet(); my @column = ( 'pass', 'fail', 'pass', 'pass', ); my @array = ( [ '1', '00A', 'pass' ], [ '2', '01A', 'fail' ], [ '3', '01B', 'fail' ], [ '4', '02A', 'pass' ], ); $worksheet->write_col('B2', \@column); $worksheet->write_col('D2', \@array); # Generate the formula. my $first_row = 2; # B2 in this example my $last_row = $first_row + @array -1; $worksheet->write('H2', '=COUNTIF(F2:F' . $last_row . ', "FAIL")' +); __END__


      Thnax .By using ur suggestion i shot out my problem.But if i pass the data by argument then it will only write the last data ,Bcz each call it will create the new file.So i need a formula to append the data .Plz give suggestion

        I've recently begun using Spreadsheet::WriteExcel. If you're getting a new worksheet each time a sub is called, you may have

        $ws = $workbook -> add_worksheet();

        In the sub; this will create a new worksheet on each call, numbering them sequentially (1, 2, .... n). You could pass $ws to the sub, and manage worksheet creation in the calling routine (my preference) or surround the add_worksheet call with some logic so it's not invoked after the first invocation.


        At that time [1909] the chief engineer was almost always the chief test pilot as well. That had the fortunate result of eliminating poor engineering early in aviation.

        —Igor Sikorsky, reported in AOPA Pilot magazine February 2003.
Re: Create a excel sheet with formula ???
by prasadbabu (Prior) on Nov 08, 2006 at 06:38 UTC

    If I understood your question correctly, I am answering your second question.

    In case of formula the row and column not taking the variable

    Change your formula code as shown below. Here the variables working perfectly in the formula.
    my $first = 'C2'; my $second = 'C9'; for my $r (3..4) { $worksheet->write("E$r", "=COUNTIF($first:$second, \"pass\")"); $r++; $worksheet->write("E$r", "=COUNTIF($first:$second, \"FAIL\")"); + }
    Also try to use strict and warnings.


      Thnax i always write the $r instade of "E$r";

      So for my next point that is, is there any way to put this in to a subroutine and use this value in excel.
      my @array= ($slno, $testid, $status); $array_ref = \@array; $worksheet->write_row($row, $col, $array_ref);

      here the @array takes the constant value,but if i pass it from other module then itis like
      sub Entry(@) { my @data= @_; $slno=$ddd[0]; $testid=$ddd[1]; $status=$ddd[2]; my @array= ($slno, $testid, $status); $array_ref = \@array; $worksheet->write_row($row, $col, $array_ref); }

      Then it is not working properly.I think i was missing something.Plz give some instuction
        I tried out your code, and it creates a nice spreadsheet. Thank you for providing your working code!

        I'm not sure I understand your question. However.. If I was to write a function that takes your three values it would be thus:

        sub Entry( $ $ $ $ ) { my ( $row, $slno, $testid, $status ) = @_; $worksheet->write( "A$row", $slno ); $worksheet->write( "B$row", $testid ); $worksheet->write( "C$row", $status ); }
        and call it thus
        # skip header row on Excel Spreadsheet my @entries = ( [ "1", "00A", "pass" ], [ "2", "01A", "fail" ], [ "3", "01B", "fail" ], [ "4", "02A", "pass" ], ); for (my $i = 0; $i < @entries; $i++) { my ( $slno, $testid, $status ) = @{$entries[$i]}; Entries( $i+2, $slno, $testid, $status ); }