まず、いくつかの推奨事項:
式には括弧が多すぎるため、定義が表示されない変数や関数と相まって、コードを視覚的に解析するのが難しくなります。また、問題を示す小さな自己完結型のスクリプトを投稿していません。つまり、あなたを助けようとする人は誰でもテストスクリプトを設定する必要があります。他の人を楽にしてください。
たとえば、定義した行は$formula_range
次のように書き直すことができます。
my $formula_range = sprintf('%s!%s%d:%s%d',
$mm_arr[$mmindx - 1],
num2col(2 + $form_off),
5 + 5 * ($serv - 1),
num2col(2 + 31 + $form_off),
5 + 5 * ($serv - 1),
);
Spreadsheet :: WriteExcel :: Utilityが提供する関数を使用して、セル表記と行/列インデックスを変換できることに注意してください。
問題は、保存された数式がの形式SheetName!Range
でない場合、置換によってシート名が切り取られ、範囲内にのみ配置されることであると思われます。
この理由は、のパーサー設定に関係しているようですSpreadsheet::WriteExcel::Formula
。プレーンな範囲はrange2d
トークンとして解析されますが、シート参照のある範囲はトークンとして解析されrange3d
ます。後で、ではrepeat_formula
、トークンに対して置換が行われます。私が収集できるものから、range2d
トークンは次のようになり'_ref2dA1:A10'
ます。だから、繰り返し式'_ref2dA1:A2'
に変換されます。'_ref2dFeb!A1:10'
ただし、に渡された場合でも、コードはプレフィックスに基づいてトークンSpreadsheet::WriteExcel::Formula::parse_tokens
として分類します。range2d
最後の呼び出しを収集し、$parse_str .= $self->_convert_ref2d($token, $class);
それをに戻します'_ref2dA1:A10
。これがバグとして分類されるかどうかはわかりませんが、ユーザーのPOVからは間違いなく予想外です。
したがって、解決策は、存在が保証されているシートの名前を入力することです。
テストスクリプトは次のとおりです。
#!/usr/bin/env perl
use strict; use warnings;
use Spreadsheet::WriteExcel;
use Const::Fast;
const my @MONTHS => qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
const my $WORKBOOK => 'test.xls';
my $book = Spreadsheet::WriteExcel->new($WORKBOOK)
or die "Cannot open '$WORKBOOK': $!";
my %sheets = map {$_ => $book->add_worksheet($_)} Summary => @MONTHS;
for my $m (@MONTHS) {
for my $n (1 .. 10) {
$sheets{ $m }->write_number($n - 1, 0, $n);
}
}
my $formula = $sheets{Summary}->store_formula('=MEDIAN(Summary!A1:A2)');
for my $n (0 .. 1) {
my $replacement = sprintf(q{'%s'!A1:A10}, $MONTHS[$n]);
$sheets{Summary}->repeat_formula($n, 0, $formula, undef,
'Summary!A1:A2' => $replacement
);
}
$book->close
or die "Error closing '$WORKBOOK': $!";
そしてここにスクリーンショットがあります: