因此,我正在名为CreateWorkbook的子例程中创建工作簿,使用SQL查询动态添加工作表,并将工作表分配给%ws对象。导出时,工作簿包含所有选项卡。
但是,我在另一个子例程中访问这些工作表时遇到了问题。
use Excel::Writer::XLSX;
use strict;
use warnings;
use Data::Dumper;
my @lang_ids;
my @lang_types_ids;
sub run {
my ($self, $app_id, $filepath, $args) = @_;
my $workbook = CreateWorkbook($filepath, $app_id, $report_type, $lang_ids);
return {};
}
这一个创建工作簿和工作表使用所有可用的语言,如:英语、西班牙语、德语等。单个工作表由正在传递的对象**%ws引用。如果我硬编码$ws{test},则可以正常工作。动态$ws{$final_name}添加具有正确名称的工作表,例如,$ws{spanish}**,并且在导出excel时,我可以看到所有单个选项卡。
sub CreateWorkbook {
my ($filepath, $app_id, $report_type, $lang_ids) = @_;
#print "Print filepath: $filepath \n";
my $sth;
my $workbook_writer = Excel::Writer::XLSX->new($filepath);
die "Problems creating new Excel file: $!" unless defined $workbook_writer;
my %fmt;
$fmt{fmt_normal} = $workbook_writer->add_format(num_format => '@');
$fmt{fmt_normal}->set_size(11);
my %ws;
#this line works great and I'm able to access it in subroutine
$ws{test} = $workbook_writer->add_worksheet('test');
foreach my $lang_id (@lang_ids) {
$sth = $app_id->_dbh->prepare(
"SELECT name FROM languages where id = ?")
|| die("Problem preparing query");
$sth->execute($lang_id) || die("Problem executing query");
while ( my $name = $sth->fetchrow_array ) {
$name=~s/ /_/g;
my $final_name = lc $name;
#line below adds worksheet to workbook but cannot be accessed in subroutine
$ws{\$final_name} = $workbook_writer->add_worksheet($name);
}
}
$workbook_writer->close() or die "Error closing file: $!";
return {
fmt => \%fmt,
ws => \%ws,
workbook_writer => $workbook_writer,
};
这里有个问题,访问**$ws{test}可以正常工作,但是我无法访问$ws{$final_name},即使我硬编码了$ws{spanish}**这样的值
sub add_data {
my ($app_id, $workbook, $report_type, $lang_ids, $lang_types_ids) = @_;
my %fmt = %{ $workbook->{fmt} };
my %ws = %{ $workbook->{ws} };
my %workbook_writer = %{ $workbook->{workbook_writer} };
my $sth;
my $sth2;
foreach my $lang_id (@lang_ids) {
$sth = $app_id->_dbh->prepare(
"SELECT name FROM languages where id = ?")
|| die("Problem preparing query");
$sth->execute($lang_id) || die("Problem executing query");
while ( my $name = $sth->fetchrow_array ) {
$name=~s/ /_/g;
my $final_name = lc $name;
#THIS WORKS FINE
$ws{test}->write( 0, $languages, $name . " - " . $lang_id, $fmt{fmt_normal} );
#ERROR: cannot call write method on undefined
$ws{\$final_name}->write( 0, $languages, $name . " - " . $lang_id, $fmt{fmt_normal} );
}
}
}
我花了太多的时间在上面。我检查了这些工作表是否被分配给了CreateWorkbook子例程中的对象变量,它们是,但是不能在子例程之外访问它们。
我真的很感激你的帮助。我想我传递错误或者没有解引用它。
1条答案
按热度按时间mspsb9vt1#
这只是对Perl引用的误解;与练习册或工作表无关。
如果
%ws
是一个散列,$final_name
是一个字符串,那么$ws{\$final_name} = ...
创建一个如下所示的散列条目:$ws{'SCALAR(0x25f79c0)'} = ...
换句话说,散列键不是字符串,而是存储该键的内存位置。删除反斜杠,您将得到一个由
$final_name
的实际内容正确索引的散列条目