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

It's easy enough to take a flat file (with rows as records and columns as fields) and dump it into a single Excel spreadsheet. However, I want to extend the "2-dimensional" -ness of the standard way to include another dimension. This does what I want:
$output = [ [ [0],[0],[0] ], [ [1,1,1],[1,1,1],[1,1,1] ], [ [2,2,2],[2,2,2],[2,2,2] ], [ [3,3,3],[3,3,3],[3,3,3] ], [ [4,4,4],[4,4,4],[4,4,4] ], [ [5,5,5],[5,5,5],[5,5,5] ], [ [6,6,6],[6,6,6],[6,6,6] ], [ [7,7,7],[7,7,7],[7,7,7] ], [ [8,8,8],[8,8,8],[8,8,8] ], [ [9,9,9],[9,9,9],[9,9,9] ], ]; #...other code that sets up the Excel sheet... my $Book = $Excel->Workbooks->Open("$excelfile"); for $i (1..9) { my $Sheet = $Book->Worksheets("$i"); $Sheet->Range("A1:C3")->{'Value'} = $$output[$i]; }
In this case, I have 9 sheets, named literally "1" through "9". Sheet "1" has the number 1 in cells A1:C3, Sheet "2" has the number 2 in cells A1:C3, etc. But I cannot define the "3-d" array all at once as in the example. I have a _huge_ file to deal with, one line at a time. I have a field which I want to use to define the sheet name. As I process the flat file, I want to push records into reference arrays specific to the sheet. This does the trick for dumping the flat file into one Excel sheet:
open (FILEIN,"$filein") or die "Open $filein failed: $!"; while (<FILEIN>) { @data = split; push @$output, [@data]; } close FILEIN; #...other code that sets up the Excel sheet... my $Book = $Excel->Workbooks->Open("$excelfile"); my $Sheet = $Book->Worksheets("$sheetname"); # ...other code that determines # $begcol,$begrow,$endcol,endrow $Sheet->Range("$begcol$begrow:$endcol$endrow")->{'Value'} = $output;
So how do I take this line:
push @$output, [@data];
and add the extra dimension? $data[1] has the sheet name I want to use. I tried
push $$day_output[$data[1]], [@data];
but it doesn't compile and complains thus: "Type of arg 1 to push must be array (not array element) at blah blah blah..." I'm new to references so perhaps this is easy with the right syntax... Thanks, Scott Job

Replies are listed 'Best First'.
Re: Excel, multiple sheets, and reference arrays, oh my!
by joealba (Hermit) on Jul 09, 2002 at 15:15 UTC
    Check out The Perl Data Structures Cookbook and perldoc perlreftut. Those will guide you to the answer you seek.

    BTW, you might want to try something like: push @{$day_output[$data[1]]}, [@data]; You can only push onto an array, and that will let you dereference the array reference $day_output[$data[1]].
Re: Excel, multiple sheets, and reference arrays, oh my!
by Abigail-II (Bishop) on Jul 09, 2002 at 15:20 UTC
    Urg, your questions isn't very clear. It's about references, but all the Excel details get in the way.

    I think you are asking how you make a 3-D array. But you already know that, because $output is a reference to a 3-D array, so I'm not sure what your problem with 3-D arrays is.

    As for pushing, the rules of references is very simple in Perl. Whereever you use a simple variable (sigil followed by an identifier), you may replace the identifier with a block whose value is a reference of the appropriate type. So, where you normally would do

    push @array => $element;
    you will now do:
    push @{$day_output -> [$data [1]]} => [@data];

    Abigail