![](/img/trans.png)
[英]Perl Excel::Writer::XLSX formula not calculating when workbook is opened
[英]perl Excel::Writer::XLSX copy formula to several subsequent cells of a row
在 EXCEL 你可以寫一個公式,標記單元格並使用標記右下角的“+”將公式復制到同一行或列的后續單元格。 相對參考會自動調整。
有沒有辦法用 Excel::Writer::XLSX 來完成這個?
我已經編寫了一個基本實現,它可以在下方和右側處理單個單元格。 您可以使用它作為示例來了解如何做更復雜的事情。 它用$
過濾掉固定單元格,因為它們不能遞增。 它不適用於拉起或離開。
我添加了一個測試來解釋 output 的樣子。 解釋如下。
use strict;
use warnings;
use feature 'say';
# caveat: does not check if the cells are inside of quotes!
sub pull_formula {
my ($formula, $from, $to) = @_;
my ($col_from, $row_from) = $from =~ m/([A-Z]+)([0-9]+)/;
my ($col_to, $row_to) = $to =~ m/([A-Z]+)([0-9]+)/;
my @formulas;
# determine direction, do we go down or right
if ($col_from eq $col_to) {
# pulling down, increment numbers
foreach my $n (++$row_from .. $row_to) {
$formula =~ s{
([A-Z]+)
([0-9]+)
}{$1 . ($2+1)}gex;
push @formulas, $formula;
}
}
else {
# pulling right, increment letters
foreach my $n (++$col_from .. $col_to) {
$formula =~ s{
(?<! \$) # not preceded by a dollar
(?<col> [A-Z]+) # column
(?<dollar> \$?) # optional dollar sign for row
(?<row> [0-9]+) # row
}{
do { my $c = $+{col}; ++$c }
. $+{dollar}
. $+{row}
}gex;
push @formulas, $formula;
}
}
return \@formulas;
}
use Test::More;
is_deeply pull_formula('=B5 + C5', 'A5', 'A8'), [
'=B6 + C6',
'=B7 + C7',
'=B8 + C8',
];
is_deeply pull_formula('=MIN(B5:B$999)', 'A5', 'A8'), [
'=MIN(B6:B$999)',
'=MIN(B7:B$999)',
'=MIN(B8:B$999)',
];
is_deeply pull_formula('=VLOOKUP(B3,B$2:E$7,2,FALSE)', 'B3', 'B5'), [
'=VLOOKUP(B4,B$2:E$7,2,FALSE)',
'=VLOOKUP(B5,B$2:E$7,2,FALSE)',
];
is_deeply pull_formula('=SUM(Y1:Y10)', 'Y11', 'AB11'), [
'=SUM(Z1:Z10)',
'=SUM(AA1:AA10)',
'=SUM(AB1:AB10)',
];
done_testing;
這個想法是用公式調用 function,你想要填充的范圍是兩個 arguments。如果你可以訪問工作表,你當然可以只用一個單元格參數來完成這一切,你還想添加多少填寫。但這更容易。
我們首先將單元格分成 cols 和 rows,然后決定是否要增加數字(行)或字母(cols)。
數字更簡單,因為我們可以對它們進行數學運算。 一般的想法是迭代公式,找到每個出現的單元格,並將其替換為下一個更高的單元格。 我們使用的正則表達式替換具有用於在模式中添加格式的/x
標志、用於將替換視為 Perl 代碼的/e
標志以及用於全局執行此操作的/g
標志,這意味着盡可能多地重復。
對於字母,模式更棘手。 我們不需要獲取前面帶有美元符號$
的字母,因此在開始時有一個否定的回顧。 我使用命名捕獲組 ( (?<name>pattern)
) 使捕獲更易於閱讀。 注意所有空格都被忽略,它來自/x
修飾符。 對於字母,數字前面是否有美元並不重要,但我們必須捕獲它。 如果沒有美元, $+{dollar}
將是一個空字符串。
Perl 以與 Excel 列相同的方式遞增字母。 AA
在Z
之后,這很方便。 但是 Perl 只對范圍和增量運算符++
執行此操作,我們不能將其應用於捕獲變量,因此我們必須首先將其分配給一個新變量。 為了在替換內部執行此操作,我們使用了一個do
塊。
我已將所有模式放入一個數組中並返回一個引用,但是您當然可以直接寫入工作表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.