我刚开始用Perl编写代码,我只是想知道下面的代码是否可以提高效率,或者可以用更少的代码完成.
我已经对Win32::OLE模块和Text::CSV模块进行了一些研究,但这似乎是从我到目前为止阅读的方式.
这个问题基本上是一个问老人的新手:"嘿,我怎样才能成为一个更好的Perl程序员?"
代码的目的是从Excel工作簿的指定工作表中的指定范围获取数据,并将这些范围的内容写入CSV文件.
此外,我知道我需要实现一般检查,比如$cellValue在将它添加到数组之前确保我的定义等等,但我正在寻找更多的整体结构.就像有没有办法通过将所有整行放入一个数组,或者数组或引用中的整个范围,或者那种性质的东西来展平循环?
谢谢
use strict;
use warnings;
use Spreadsheet::XLSX;
my $excel = Spreadsheet::XLSX -> new ('C:\scott.xlsm',);
my @sheets = qw(Fund_Data GL_Data);
foreach my $sheet (@sheets) {
my $worksheet = $excel->Worksheet($sheet);
my $cell = $worksheet->get_cell(25,0);
if ($cell) { # make sure cell value isn't blank
my $myFile = "C:/$sheet.csv";
open NEWFILE, ">$myFile" or die $!;
# write all cells from Range("A25:[MaxColumn][MaxRow]") to a csv file
my $maxCol = $worksheet->{MaxCol};
my $maxRow = $worksheet->{MaxRow};
my @arrRows;
my $rowString;
# loop through each row and column in defined range and string together each row and write to file
foreach my $row (24 .. $maxRow) {
foreach my $col (0 .. $maxCol) {
my $cellValue = $worksheet->{Cells} [$row] [$col]->Value();
if ($rowString) {
$rowString = $rowString . "," . $cellValue;
} else {
$rowString = $cellValue;
}
}
print NEWFILE "$rowString\n";
undef $rowString;
}
}
}
Run Code Online (Sandbox Code Playgroud)
没有理由拥有内循环:
print NEWFILE join(",", map { $worksheet->{Cells}[$row][$_] } 0 .. $maxCol), "\n";
Run Code Online (Sandbox Code Playgroud)
另外,请确保您的索引正确无误.我不熟悉Spreadsheet :: XLSX,因此请确保max col&row与其他代码一样为零.如果他们不是那么你会想要迭代0 .. $maxCol-1.
马克的建议非常好.另一个小的改进是替换"做一堆嵌套逻辑if $cell,"不做任何事情unless $cell- 这样你有更多可读的代码(删除1个额外的缩进/嵌套块;并且不必担心如果发生什么,如果$ cell是空的.
# OLD
foreach my $sheet (@sheets) {
my $worksheet = $excel->Worksheet($sheet);
my $cell = $worksheet->get_cell(25,0);
if ($cell) { # make sure cell value isn't blank
# All your logic in the if
}
}
# NEW
foreach my $sheet (@sheets) {
my $worksheet = $excel->Worksheet($sheet);
next unless $worksheet->get_cell(25,0); # You don't use $cell, so dropped
# All your logic that used to be in the if
}
Run Code Online (Sandbox Code Playgroud)
正如您所指出的,Text::CSV根据您的数据是否需要根据CSV标准引用(例如,包含空格,逗号,引号等等),这将是一件好事.如果可能需要引用,请不要重新发明轮子,Text::CSV而是用于打印.未经测试的例子是这样的:
# At the start of the script:
use Text::CSV;
my $csv = Text::CSV->new ( { } ); # Add error handler!
# In the loop, when the file handle $fh is opened
foreach my $row (24 .. $maxRow) {
my $cols = [ map { $worksheet->{Cells}[$row][$_] } 0 .. $maxCol) ];
my $status = $csv->print ($fh, $cols);
# Error handling
}
Run Code Online (Sandbox Code Playgroud)