line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Data::Pivot;
|
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 NAME
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
Data::Pivot - Perl module to pivot a table
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
use Data::Pivot;
|
12
|
|
|
|
|
|
|
@newtable = pivot( table => \@table,
|
13
|
|
|
|
|
|
|
headings => \@headings,
|
14
|
|
|
|
|
|
|
pivot_column => $pivot_col_no,
|
15
|
|
|
|
|
|
|
layout => 'vertical',
|
16
|
|
|
|
|
|
|
row_sum => 'Sum',
|
17
|
|
|
|
|
|
|
row_titles => 1,
|
18
|
|
|
|
|
|
|
format => '%5.2f',
|
19
|
|
|
|
|
|
|
)
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
With Data::Pivot you can pivot a table like this:
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Some Fix Columns Pivot_Col Num_Values
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
aaa bbb ccc 01 12.20
|
28
|
|
|
|
|
|
|
aaa bbb ccc 02 134.50
|
29
|
|
|
|
|
|
|
aaa bbb ccc 03 1.25
|
30
|
|
|
|
|
|
|
xxx yyy zzz 02 22.22
|
31
|
|
|
|
|
|
|
xxx yyy zzz 03 111.11
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
Will be converted to:
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Some Fix Columns 01 02 03 Sum
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
aaa bbb ccc 12.20 134.50 1.25 147.95
|
38
|
|
|
|
|
|
|
yyy xxx zzz 0.00 22.22 111.11 133.33
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
The table can contain several columns of Num_Values, which will get into rows, if the layout is 'horizontal', like this:
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
Some Fix Columns Pivot_Col Num_Val_1 Num_Val_2 Num_Val_3
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
aaa bbb ccc 01 12.20 1.40 5.90
|
45
|
|
|
|
|
|
|
aaa bbb ccc 02 134.50 12.00 12.30
|
46
|
|
|
|
|
|
|
aaa bbb ccc 03 1.25 30.00 123.45
|
47
|
|
|
|
|
|
|
xxx yyy zzz 02 22.22 7.80 8.88
|
48
|
|
|
|
|
|
|
xxx yyy zzz 03 111.11 100.00 42.00
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
Will be converted to:
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
Some Fix Columns 01 02 03 Sum
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
aaa bbb ccc Num_Val_1 12.20 134.50 1.25 147.95
|
55
|
|
|
|
|
|
|
Num_Val_2 1.40 12.00 30.00 43.40
|
56
|
|
|
|
|
|
|
Num_Val_3 5.90 12.30 123.45 141.65
|
57
|
|
|
|
|
|
|
xxx yyy zzz Num_Val_1 0.00 22.22 111.11 133.33
|
58
|
|
|
|
|
|
|
Num_Val_2 0.00 7.80 100.00 107.80
|
59
|
|
|
|
|
|
|
Num_Val_3 0.00 8.88 42.00 50.88
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
Data::Pivot has only one function which does all the work.
|
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=head1 Functions
|
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
=head2 pivot()
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=head2 Parameters:
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
pivot receives several named parameters:
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=over
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=item table => \@table
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
A reference to an array of arrays containing all the data but no headings.
|
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
In the last example above:
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
@table = ( [ 'aaa', 'bbb', 'ccc', '01', 12.2, 1.4, 5.9 ],
|
80
|
|
|
|
|
|
|
[ 'aaa', 'bbb', 'ccc', '02', 134.5, 12, 12.3 ],
|
81
|
|
|
|
|
|
|
[ 'aaa', 'bbb', 'ccc', '03', 1.25, 30, 123.45 ],
|
82
|
|
|
|
|
|
|
[ 'xxx', 'yyy', 'zzz', '02', 22.22, 7.8, 8.88 ],
|
83
|
|
|
|
|
|
|
[ 'xxx', 'yyy', 'zzz', '03', 111.11, 100, 42 ]
|
84
|
|
|
|
|
|
|
);
|
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=item headings => \@headings
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
A reference to an array containing the column headings.
|
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
In the last example above:
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
@headings = ('Some', 'Fix', 'Columns', 'Pivot_Col', 'Num_Val_1', 'Num_Val_2', 'Num_Val_3');
|
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=item pivot_column => $no_of_col
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
The column number over which the pivoting takes place
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
In the last example above:
|
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
$no_of_col = 3;
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=item layout => 'horizontal'
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
'layout' determines whether the 'Num_Val' columns are arranged 'horizontal'ly or 'vertical'ly in the new table.
|
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=item row_sum => 'Sum'
|
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
The title of the sum column, which sums up the new pivoted columns. If this is undef the column will be omitted.
|
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=item row_title1 => 1
|
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
If this is true, a new column will be inserted after the fix columns if the layout is 'horizontal'. This column will have no heading and the contents will be the headings of the value columns.
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=item format => '%5.2f'
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
Format may be a legal sprintf format string or a reference to a subroutine.
|
117
|
|
|
|
|
|
|
The format string will be applied to each pivoted column and the sum column.
|
118
|
|
|
|
|
|
|
The subroutine will be called with each pivoted column and the sum column as parameter.
|
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=back
|
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
The full function call for the above example is:
|
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
@newtable = pivot( table => \@table,
|
125
|
|
|
|
|
|
|
headings => \@headings,
|
126
|
|
|
|
|
|
|
pivot_column => $pivot_col_no,
|
127
|
|
|
|
|
|
|
row_sum => 'Sum',
|
128
|
|
|
|
|
|
|
row_titles => 1,
|
129
|
|
|
|
|
|
|
format => '%5.2f',
|
130
|
|
|
|
|
|
|
);
|
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=cut
|
134
|
|
|
|
|
|
|
|
135
|
1
|
|
|
1
|
|
102349
|
use 5.005;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
40
|
|
136
|
1
|
|
|
1
|
|
6
|
use strict;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
40
|
|
137
|
1
|
|
|
1
|
|
5
|
use vars qw($VERSION @ISA %EXPORT_TAGS @EXPORT_OK @EXPORT);
|
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
1969
|
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
require Exporter;
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
@ISA = qw(Exporter);
|
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
%EXPORT_TAGS = ( 'all' => [ qw(
|
144
|
|
|
|
|
|
|
pivot
|
145
|
|
|
|
|
|
|
) ] );
|
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
@EXPORT = qw(
|
150
|
|
|
|
|
|
|
pivot
|
151
|
|
|
|
|
|
|
);
|
152
|
|
|
|
|
|
|
$VERSION = '0.05';
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------
|
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub pivot {
|
157
|
4
|
|
|
4
|
1
|
7457
|
my %parms = @_;
|
158
|
|
|
|
|
|
|
|
159
|
4
|
100
|
100
|
|
|
28
|
if (exists $parms{layout} and $parms{layout} eq 'vertical') {
|
160
|
1
|
|
|
|
|
7
|
return pivot_vertical(@_);
|
161
|
|
|
|
|
|
|
} else {
|
162
|
3
|
|
|
|
|
11
|
return pivot_horizontal(@_);
|
163
|
|
|
|
|
|
|
}
|
164
|
|
|
|
|
|
|
}
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub pivot_horizontal {
|
169
|
3
|
|
|
3
|
0
|
16
|
my %parms = @_;
|
170
|
|
|
|
|
|
|
|
171
|
3
|
|
|
|
|
6
|
my $table = $parms{table};
|
172
|
3
|
|
|
|
|
7
|
my $headings = $parms{headings};
|
173
|
3
|
|
|
|
|
4
|
my $pivot_column = $parms{pivot_column};
|
174
|
3
|
|
|
|
|
5
|
my $row_sum = $parms{row_sum};
|
175
|
3
|
|
|
|
|
5
|
my $row_titles = $parms{row_titles};
|
176
|
3
|
|
|
|
|
6
|
my $format = $parms{format};
|
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
|
179
|
3
|
|
|
|
|
10
|
my @sum_columns = $pivot_column + 1 .. $#$headings;
|
180
|
3
|
|
|
|
|
6
|
my $flatrow;
|
181
|
3
|
|
|
|
|
5
|
my $oldflatrow = '';
|
182
|
3
|
|
|
|
|
4
|
my %pivot_cols;
|
183
|
|
|
|
|
|
|
my $lastrow;
|
184
|
0
|
|
|
|
|
0
|
my @newtable;
|
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
#---- initialise %pivot_cols
|
187
|
|
|
|
|
|
|
#
|
188
|
3
|
|
|
|
|
7
|
foreach my $row (@$table) {
|
189
|
15
|
|
100
|
|
|
83
|
$pivot_cols{$row->[$pivot_column]} ||= [ (0) x @sum_columns ];
|
190
|
|
|
|
|
|
|
}
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
#---- read table line by line
|
193
|
|
|
|
|
|
|
#
|
194
|
3
|
|
|
|
|
9
|
foreach my $row (@$table) {
|
195
|
15
|
|
|
|
|
32
|
$flatrow = join '', @{$row}[0..$pivot_column - 1];
|
|
15
|
|
|
|
|
34
|
|
196
|
|
|
|
|
|
|
|
197
|
15
|
100
|
100
|
|
|
54
|
if ($flatrow ne $oldflatrow && $lastrow) {
|
198
|
2
|
|
|
|
|
5
|
foreach my $pivot_row (0..$#sum_columns) {
|
199
|
4
|
|
|
|
|
7
|
my @newrow;
|
200
|
4
|
100
|
|
|
|
10
|
if (!$pivot_row) {
|
201
|
2
|
|
|
|
|
7
|
splice @$lastrow, $pivot_column;
|
202
|
2
|
|
|
|
|
7
|
@newrow = @$lastrow;
|
203
|
|
|
|
|
|
|
} else {
|
204
|
2
|
|
|
|
|
6
|
@newrow = ('') x @$lastrow;
|
205
|
|
|
|
|
|
|
}
|
206
|
4
|
100
|
|
|
|
13
|
push @newrow, $headings->[$sum_columns[$pivot_row]] if $row_titles;
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
#---- sums for each row
|
209
|
|
|
|
|
|
|
#
|
210
|
4
|
|
|
|
|
6
|
my $rowsum = 0;
|
211
|
4
|
|
|
|
|
12
|
foreach (keys %pivot_cols) {
|
212
|
12
|
|
|
|
|
24
|
$rowsum += $pivot_cols{$_}->[$pivot_row];
|
213
|
|
|
|
|
|
|
}
|
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
#---- create new row
|
216
|
|
|
|
|
|
|
#
|
217
|
4
|
50
|
|
|
|
11
|
if ($format) {
|
218
|
4
|
50
|
|
|
|
10
|
if (ref $format eq 'CODE') {
|
219
|
0
|
0
|
|
|
|
0
|
push @newrow, (map({ $format->($pivot_cols{$_}->[$pivot_row]) } sort keys %pivot_cols), $row_sum ? $format->($rowsum) : ());
|
|
0
|
|
|
|
|
0
|
|
220
|
|
|
|
|
|
|
} else {
|
221
|
4
|
100
|
|
|
|
17
|
push @newrow, (map({ sprintf($format, $pivot_cols{$_}->[$pivot_row]) } sort keys %pivot_cols), $row_sum ? sprintf($format, $rowsum) : ());
|
|
12
|
|
|
|
|
110
|
|
222
|
|
|
|
|
|
|
}
|
223
|
|
|
|
|
|
|
} else {
|
224
|
0
|
0
|
|
|
|
0
|
push @newrow, (map({ $pivot_cols{$_}->[$pivot_row] } sort keys %pivot_cols), $row_sum ? $rowsum : ());
|
|
0
|
|
|
|
|
0
|
|
225
|
|
|
|
|
|
|
}
|
226
|
4
|
|
|
|
|
16
|
push @newtable, \@newrow;
|
227
|
|
|
|
|
|
|
}
|
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
#---- initialise %pivot_cols
|
230
|
|
|
|
|
|
|
#
|
231
|
2
|
|
|
|
|
39
|
$pivot_cols{$_} = [ (0) x @sum_columns ] for (keys %pivot_cols);
|
232
|
|
|
|
|
|
|
}
|
233
|
|
|
|
|
|
|
|
234
|
15
|
|
|
|
|
30
|
foreach (0..$#sum_columns) {
|
235
|
27
|
|
|
|
|
63
|
$pivot_cols{$row->[$pivot_column]}->[$_] = $row->[$sum_columns[$_]];
|
236
|
|
|
|
|
|
|
}
|
237
|
|
|
|
|
|
|
|
238
|
15
|
|
|
|
|
25
|
$lastrow = $row;
|
239
|
15
|
|
|
|
|
27
|
$oldflatrow = $flatrow;
|
240
|
|
|
|
|
|
|
}
|
241
|
3
|
50
|
|
|
|
10
|
if ($lastrow) {
|
242
|
3
|
|
|
|
|
7
|
foreach my $pivot_row (0..$#sum_columns) {
|
243
|
5
|
|
|
|
|
7
|
my @newrow;
|
244
|
5
|
100
|
|
|
|
10
|
if (!$pivot_row) {
|
245
|
3
|
|
|
|
|
9
|
splice @$lastrow, $pivot_column;
|
246
|
3
|
|
|
|
|
14
|
@newrow = @$lastrow;
|
247
|
|
|
|
|
|
|
} else {
|
248
|
2
|
|
|
|
|
7
|
@newrow = ('') x @$lastrow;
|
249
|
|
|
|
|
|
|
}
|
250
|
5
|
100
|
|
|
|
12
|
push @newrow, $headings->[$sum_columns[$pivot_row]] if $row_titles;
|
251
|
|
|
|
|
|
|
|
252
|
5
|
|
|
|
|
11
|
my $rowsum = 0;
|
253
|
5
|
|
|
|
|
13
|
foreach (keys %pivot_cols) {
|
254
|
15
|
|
|
|
|
28
|
$rowsum += $pivot_cols{$_}->[$pivot_row];
|
255
|
|
|
|
|
|
|
}
|
256
|
5
|
100
|
|
|
|
13
|
if ($format) {
|
257
|
4
|
50
|
|
|
|
10
|
if (ref $format eq 'CODE') {
|
258
|
0
|
0
|
|
|
|
0
|
push @newrow, (map({ $format->($pivot_cols{$_}->[$pivot_row]) } sort keys %pivot_cols), $row_sum ? $format->($rowsum) : ());
|
|
0
|
|
|
|
|
0
|
|
259
|
|
|
|
|
|
|
} else {
|
260
|
4
|
100
|
|
|
|
12
|
push @newrow, (map({ sprintf($format, $pivot_cols{$_}->[$pivot_row]) } sort keys %pivot_cols), $row_sum ? sprintf($format, $rowsum) : ());
|
|
12
|
|
|
|
|
84
|
|
261
|
|
|
|
|
|
|
}
|
262
|
|
|
|
|
|
|
} else {
|
263
|
1
|
50
|
|
|
|
4
|
push @newrow, (map({ $pivot_cols{$_}->[$pivot_row] } sort keys %pivot_cols), $row_sum ? $rowsum : ());
|
|
3
|
|
|
|
|
11
|
|
264
|
|
|
|
|
|
|
}
|
265
|
5
|
|
|
|
|
37
|
push @newtable, \@newrow;
|
266
|
|
|
|
|
|
|
}
|
267
|
|
|
|
|
|
|
}
|
268
|
|
|
|
|
|
|
|
269
|
3
|
100
|
|
|
|
33
|
splice @$headings, $pivot_column, @sum_columns + 1, ($row_titles ? '' : (), (sort keys %pivot_cols), $row_sum ? $row_sum : ());
|
|
|
100
|
|
|
|
|
|
270
|
3
|
|
|
|
|
33
|
return @newtable;
|
271
|
|
|
|
|
|
|
}
|
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------------------------------------------
|
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub pivot_vertical {
|
276
|
1
|
|
|
1
|
0
|
7
|
my %parms = @_;
|
277
|
|
|
|
|
|
|
|
278
|
1
|
|
|
|
|
3
|
my $table = $parms{table};
|
279
|
1
|
|
|
|
|
2
|
my $headings = $parms{headings};
|
280
|
1
|
|
|
|
|
2
|
my $pivot_column = $parms{pivot_column};
|
281
|
1
|
|
|
|
|
2
|
my $row_sum = 0;
|
282
|
1
|
|
|
|
|
3
|
my $row_titles = $parms{row_titles};
|
283
|
1
|
|
|
|
|
3
|
my $format = $parms{format};
|
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
|
286
|
1
|
|
|
|
|
3
|
my @sum_columns = $pivot_column + 1 .. $#$headings;
|
287
|
1
|
|
|
|
|
2
|
my $flatrow;
|
288
|
1
|
|
|
|
|
3
|
my $oldflatrow = '';
|
289
|
1
|
|
|
|
|
2
|
my %pivot_cols;
|
290
|
|
|
|
|
|
|
my $lastrow;
|
291
|
0
|
|
|
|
|
0
|
my @newtable;
|
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
#---- initialise %pivot_cols
|
294
|
|
|
|
|
|
|
#
|
295
|
1
|
|
|
|
|
3
|
foreach my $row (@$table) {
|
296
|
6
|
|
|
|
|
12
|
foreach (@sum_columns) {
|
297
|
18
|
|
50
|
|
|
1097
|
$pivot_cols{$row->[$pivot_column] . sprintf('<<<%03d>>>', $_) . $headings->[$_]} ||= 0;
|
298
|
|
|
|
|
|
|
}
|
299
|
|
|
|
|
|
|
}
|
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
#---- read table line by line
|
302
|
|
|
|
|
|
|
#
|
303
|
1
|
|
|
|
|
3
|
foreach my $row (@$table) {
|
304
|
6
|
|
|
|
|
12
|
$flatrow = join '', @{$row}[0..$pivot_column - 1];
|
|
6
|
|
|
|
|
15
|
|
305
|
|
|
|
|
|
|
|
306
|
6
|
100
|
100
|
|
|
21
|
if ($flatrow ne $oldflatrow && $lastrow) {
|
307
|
1
|
|
|
|
|
2
|
my @newrow;
|
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
#---- create new row
|
310
|
|
|
|
|
|
|
#
|
311
|
1
|
50
|
|
|
|
5
|
if ($format) {
|
312
|
1
|
50
|
|
|
|
6
|
if (ref $format eq 'CODE') {
|
313
|
1
|
|
|
|
|
3
|
push @newrow, (@{$lastrow}[0..$pivot_column - 1], map({ $format->($pivot_cols{$_}) } sort keys %pivot_cols));
|
|
1
|
|
|
|
|
20
|
|
|
9
|
|
|
|
|
146
|
|
314
|
|
|
|
|
|
|
} else {
|
315
|
0
|
|
|
|
|
0
|
push @newrow, (@{$lastrow}[0..$pivot_column - 1], map({ sprintf($format, $pivot_cols{$_}) } sort keys %pivot_cols));
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
316
|
|
|
|
|
|
|
}
|
317
|
|
|
|
|
|
|
} else {
|
318
|
0
|
|
|
|
|
0
|
push @newrow, (@{$lastrow}[0..$pivot_column - 1], map({ $pivot_cols{$_} } sort keys %pivot_cols));
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
319
|
|
|
|
|
|
|
}
|
320
|
1
|
|
|
|
|
21
|
push @newtable, \@newrow;
|
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
#---- initialise %pivot_cols
|
323
|
|
|
|
|
|
|
#
|
324
|
1
|
|
|
|
|
9
|
$pivot_cols{$_} = 0 for (keys %pivot_cols);
|
325
|
|
|
|
|
|
|
}
|
326
|
|
|
|
|
|
|
|
327
|
6
|
|
|
|
|
10
|
foreach (@sum_columns) {
|
328
|
18
|
|
|
|
|
53
|
$pivot_cols{$row->[$pivot_column] . sprintf('<<<%03d>>>', $_) . $headings->[$_]} = $row->[$_];
|
329
|
|
|
|
|
|
|
}
|
330
|
|
|
|
|
|
|
|
331
|
6
|
|
|
|
|
9
|
$lastrow = $row;
|
332
|
6
|
|
|
|
|
9
|
$oldflatrow = $flatrow;
|
333
|
|
|
|
|
|
|
}
|
334
|
1
|
50
|
|
|
|
5
|
if ($lastrow) {
|
335
|
1
|
|
|
|
|
2
|
my @newrow;
|
336
|
|
|
|
|
|
|
|
337
|
1
|
50
|
|
|
|
4
|
if ($format) {
|
338
|
1
|
50
|
|
|
|
6
|
if (ref $format eq 'CODE') {
|
339
|
1
|
|
|
|
|
4
|
push @newrow, (@{$lastrow}[0..$pivot_column - 1], map({ $format->($pivot_cols{$_}) } sort keys %pivot_cols));
|
|
1
|
|
|
|
|
12
|
|
|
9
|
|
|
|
|
104
|
|
340
|
|
|
|
|
|
|
} else {
|
341
|
0
|
|
|
|
|
0
|
push @newrow, (@{$lastrow}[0..$pivot_column - 1], map({ sprintf($format, $pivot_cols{$_}) } sort keys %pivot_cols));
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
342
|
|
|
|
|
|
|
}
|
343
|
|
|
|
|
|
|
} else {
|
344
|
0
|
|
|
|
|
0
|
push @newrow, (@{$lastrow}[0..$pivot_column - 1], map({ $pivot_cols{$_} } sort keys %pivot_cols));
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
345
|
|
|
|
|
|
|
}
|
346
|
1
|
|
|
|
|
590
|
push @newtable, \@newrow;
|
347
|
|
|
|
|
|
|
}
|
348
|
|
|
|
|
|
|
|
349
|
1
|
|
|
|
|
8
|
splice @$headings, $pivot_column, @sum_columns + 1, (map {s/(.*?)<<<\d+>>>(.*)/$2 $1/; $_} sort keys %pivot_cols);
|
|
9
|
|
|
|
|
53
|
|
|
9
|
|
|
|
|
24
|
|
350
|
1
|
|
|
|
|
22
|
return @newtable;
|
351
|
|
|
|
|
|
|
}
|
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
1;
|
355
|
|
|
|
|
|
|
__END__
|