http://www.perlmonks.org?node_id=882809

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

Below you will find the entire code. The code does calculations on two of the columns once they are ordered based on first three columns. Instead of "printing", how do I use "Format" to write a report? I am trying to get the header to say "Totals", column names to say (Name, Letter, Number, Grade1, Grade2). There should be a solid break like after the columns names and a dashed line after each "totals line". I need to write the report to an output file. My main problem was that I was not able to get the results printed in the report. I have never used format before so I have no clue. Hopefully, you won't have to change the code. References for further learning would also help. Thanks in advance.

#!/usr/bin/perl use strict; use warnings; use DBI; my $tableName = 'hist'; unlink $tableName; open my $resFile, '>', $tableName; print $resFile <<DATA; e_id,cus,ta,gd1,gd2 Joe,A,1,85,90 Joe,A,1,80,99 Joe,A,2,50,70 Joe,A,2,60,65 Joe,A,2,87,89 Joe,B,1,82,92 Joe,B,3,30,51 Rob,A,1,64,77 Rob,B,2,20,32 DATA close $resFile; my $dbh = DBI->connect("DBI:CSV:") or die $DBI::errstr; my $sth = $dbh->prepare("SELECT * FROM $tableName"); $sth->execute(); my $query = $dbh->selectall_arrayref( "select e_id, cus, ta, gd1, gd2 from $tableName order by e_id, cus +, ta", {Slice => {}}); my $gd1Total; my $gd2Total; my $currGroup; for my $row (@$query, {map {$_, 0} qw(e_id cus ta gd1 gd2)}) { my $group = join ',', @{$row}{qw(e_id cus ta)}; $currGroup = $group if !defined $currGroup; if ($group ne $currGroup) { print " Total $gd1Total, $gd2Total\n"; $gd1Total = $gd2Total = 0; $currGroup = $group; last if $group eq '0,0,0'; } print +(join ', ', @{$row}{qw(e_id cus ta gd1 gd2)}), "\n"; $gd1Total += $row->{gd1}; $gd2Total += $row->{gd2}; } exit; [download] Prints: Joe, A, 1, 85, 90 Joe, A, 1, 80, 99 Total 165, 189 Joe, A, 2, 50, 70 Joe, A, 2, 60, 65 Joe, A, 2, 87, 89 Total 197, 224 Joe, B, 1, 82, 92 Total 82, 92 Joe, B, 3, 30, 51 Total 30, 51 Rob, A, 1, 64, 77 Total 64, 77 Rob, B, 2, 20, 32 Total 20, 32

Replies are listed 'Best First'.
Re: writing report using format
by CountZero (Bishop) on Jan 18, 2011 at 08:34 UTC
    The formating functions of Perl may have been a good idea when they were first invented and for some very simple reports they will still work OK, but nowadays I would invest some time into learning any of the templating modules.

    I am a big fan of Template Toolkit, but there are many others equally good.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: writing report using format
by eff_i_g (Curate) on Jan 18, 2011 at 04:52 UTC

      I have looked at perlform and I will look at the other two. My main problem is how do I incorporate my print results from the main code into the "format" portion of the code? In other words, how do i get my results to actually print under the indicated format? Thanks.

        Here is an example you might find useful:

        use strict; use warnings; # Formats my ($crt, $text, $num); format = @< @<<<<<<<< @###.## $crt, $text, $num . format STDOUT_TOP = @||||||||||||||||||||| "Example Format" ---------------------- Nr Text Number -- -------- -------- . my $total = 0; format RAPORT_TOTAL = ---------------------- @###.## $total ---------------------- . # End formats while (<DATA>) { s /[\n|\r]//g; # clean ($crt, $text, $num) = split(/;/, $_, 3); $total += $num; write(); } # Change format $~ = "RAPORT_TOTAL"; write(); __DATA__ 1;some data;123.34 2;other;432.54 3;testing;123.55

        Regards, Stefan