Below is the output I got when I use print Dumper(\%Data) in my code
{
"" => undef,
"123456789012:SRIRAMA" => [123456789012, "SRIRAMA", 856.06, 0, 0, 0],
"389252737122:RAMA" => [389252737122, "RAMA", 345.76, 0, 0, 0],
}
This data I have to write to an Excel file like below
Number Name number name amt amt2 amt3 amt4
123456789012 SRIRAMA 123456789012 SRIRAMA 856.06 0 0 0
389252737122 RAMA 389252737122 RAMA 345.76 0 0 0
The first two columns are one SQL result and rest of the columns are another SQL query result.
The first query result I have put in a map and searched based on the key in second query result and finally I got the output above.
Here, Number and Name—the first two columns—are keys for searching the data.
The code below is after getting the SQL result:
foreach ( @Sqlresult ) {
$rec_cntr = $rec_cntr + 1;
my @fields = undef;
chop;
next if /^$/;
next if /ERROR:/;
next if /ORA-/;
@fields = split( /::/, $_ );
my $fldref = @fields;
$ent_id = undef;
$ent_id = $fields[0];
$key = undef;
$key = $fields[0] . ":" . $name;
push( @{ $Data{$key} }, $fields[1] );
}
$rec_cntr = 0;
The below code snippet I use when the records are not there pushing as zero.
my $kkey = undef;
for $kkey ( sort keys %Data ) {
next if $kkey eq '';
my $Lent = @{ $Data{$kkey} };
if ( $Lent < 5 ) {
push( @{ $Data{$kkey} }, 0 );
}
print scalar @{ $Data{$kkey} };
}
print Dumper( \%Data );
The above print Dumper produces the information shown at the start of the question
Here is where the data is written into an Excel sheet
my $dt = `date +%m-%d-%Y_%\I%\M`;
chop $dt;
my $FileName = "/data_reports/AdjestedFile" . $dt . ".xls";
#my $workbook = Spreadsheet::WriteExcel->new( $FileName );
my $workbook = Excel::Writer::XLSX->new( $FileName );
# Define the format and add it to the worksheet
my $format = $workbook->add_format(
center_across => 1,
bold => 1,
size => 10,
color => "black",
bg_color => "grey",
border_color => "black",
align => "vcenter",
);
my $formatnum = $workbook->add_format();
$formatnum->set_num_format( '00000000000' );
my $formatamt = $workbook->add_format();
$formatamt->set_num_format( '0.00' );
$formatamt->set_align( 'right' );
my $formattext = $workbook->add_format( num_format => '@' );
my $prev_feetype = "";
my $current_ws;
$current_ws = $workbook->add_worksheet();
$current_ws->keep_leading_zeros( 1 );
$current_ws->set_column( 0, 16, 17, $formattext );
$current_ws->set_column( 1, 1, 13, $formattext );
$current_ws->set_column( 2, 2, 10, $formatnum );
$current_ws->set_column( 3, 3, 10, $formattext );
$current_ws->set_column( 4, 4, 10, $formattext );
$current_ws->set_column( 5, 5, 10, $formattext );
$current_ws->set_column( 6, 6, 10, $formattext );
$current_ws->set_column( 7, 7, 10, $formattext );
my $cl = 0;
$current_ws->write_string( 0, $cl++, "Number", $format );
$current_ws->write_string( 0, $cl++, "Name", $format );
$current_ws->write_string( 0, $cl++, "amt", $format );
$current_ws->write_string( 0, $cl++, "NA", $format );
$current_ws->write_string( 0, $cl++, "NA", $format );
$current_ws->write_string( 0, $cl++, "NA", $format );
$current_ws->write_string( 0, $cl++, "NA", $format );
$current_ws->write_string( 0, $cl++, "NA", $format );
my $rownum = 1;
foreach ( %Data ) {
my @fields = undef;
chop;
next if /^$/;
@fields = split( /,/, $_ );
my $fldref = \@fields;
my $clcntr = 0;
my $ent_id = "";
foreach ( @fields ) {
if ( $clcntr == 1 ) {
$ent_id = $_;
}
if ( isfloat( $_ ) ) { #and $clcntr != 9 ) {
$current_ws->write_number( $rownum, $clcntr++, $_ );
}
else {
$current_ws->write_string( $rownum, $clcntr++, $_ );
}
}
}
There's a lot to read there, but these ideas may help
Always
use strictanduse warningsat the top of every Perl program you write. It is invaluable for locating the more obvious bugsDon't initialise arrays with
@data = undef. If you want to empty an existing array then write@data = (). If you are declaring a new array thenmy @datawill create a new empty arrayThe exact same advice applies to hashes, and that will be the reason for the
"" => undefat the start of your%DatahashDon't use
my $dt = `date +%m-%d-%Y_%\I%\M`. You are starting a whole new shell process just to ask it the time. You shouldand
The result from this won't need
chompingBut are you sure you want
%I? That gives you the 12-hour time, so the value will reset to zero at midday.%Hgives you 24-hour time, and is much more likely to be usefulchompis preferable tochopunless you're doing something unusual.chopwill just remove the last character from a string, whatever it is, whilechompwill remove the last character if it is a newlinefor ( %Data ) { ... }will loop over the hash setting$_to key1, val1, key2, val2 etc. That isn't what you wantIn this case, since the information in the key is duplicated in the value, you probably want
for ( values %Data ) { ... }. But that value is an array reference so no splitting is requiredThis is probably closer to what you need