“解析Excel数据引发”;“文件错误”;

“解析Excel数据引发”;“文件错误”;,excel,perl,Excel,Perl,我在Perl脚本中有三个函数来解析Excel文件以获得所需的输出Excel文件。我获得了正确的输出,但出现了一个错误 文件错误:数据可能已丢失 根本原因可能是在文件中的同一Excel单元格上写入了两次 如何在维护脚本中的函数时消除此错误 输入文件 ab 苹果胡萝卜 橘子花椰菜 葡萄菠菜 期望输出文件 ab 苹果胡萝卜 橘子花椰菜 桃子芦笋 Perl代码 使用v5.10.0; 使用警告; 使用电子表格::ParseExcel; 使用电子表格::ParseExcel::SaveParser; 使

我在Perl脚本中有三个函数来解析Excel文件以获得所需的输出Excel文件。我获得了正确的输出,但出现了一个错误

文件错误:数据可能已丢失

根本原因可能是在文件中的同一Excel单元格上写入了两次

如何在维护脚本中的函数时消除此错误

输入文件
ab
苹果胡萝卜
橘子花椰菜
葡萄菠菜
期望输出文件
ab
苹果胡萝卜
橘子花椰菜
桃子芦笋
Perl代码
使用v5.10.0;
使用警告;
使用电子表格::ParseExcel;
使用电子表格::ParseExcel::SaveParser;
使用电子表格::WriteExcel;
my$parser=Spreadsheet::ParseExcel::SaveParser->new();
我的$workbook\u R=$parser->parse('C:\Perl\databases\Fruits\u and\u vegies.xls');
我的$workbook\u W=电子表格::WriteExcel->new('C:\Perl\databases\new\u Fruits\u and\u vegies.xls');
my$worksheet\u W=$workbook\u W->添加工作表();
对于我们的$worksheet\u R($workbook\u R->worksheets()){
my($row_min,$row_max)=$workeep_R->row_range();
my($col_min,$col_max)=$worksheet_R->col_range();
对于我们的$row($row\最小值..$row\最大值){
对于我们的$col($col_min..$col_max){
果摊();
蔬菜摊();
组合支架();
#------------------------------------------------------------------------------
#子水果摊-解析:用桃子代替葡萄
#------------------------------------------------------------------------------
子林分{
#如果单元格中包含葡萄,则改为写“桃子”
我的$cell\u grapes=$worksheet\u R->get\u cell($row,$col);
如果($cell\u grapes->value()=~/grapes/){
$worksheet_W->write($row,$col,“PEACHES”);
}
}
#------------------------------------------------------------------------------
#亚蔬菜站-解析:用芦笋重新包装菠菜
#------------------------------------------------------------------------------
亚蔬架{
#如果单元格中含有菠菜,则改为写“芦笋”
my$cell\u vegies=$worksheet\u R->get\u cell($row,$col);
#my$cell=$worksheet\u R->get\u cell($row,$col);
如果(/$cell\u vegies->value()=~/Spinach/){
$worksheet_W->write($row,$col,“芦笋”);
}
}
#------------------------------------------------------------------------------
#写下所有水果和蔬菜的两个变化(桃子和芦笋)
#------------------------------------------------------------------------------
副组合支架{
my$cell=$worksheet\u R->get\u cell($row,$col);
$worksheet_W->write($row,$col,$cell->value());
}
}
}
}

正如您所说,错误消息是由于一个单元格被写入了多次。通过确保每个单元格只写入一次,可以消除错误消息。由于您的三个子例程具有非常相似的功能,因此可以将它们组合成一组行来执行所有操作,并使用
if
/
else
级联来决定应采取的操作

for our $row ( $row_min .. $row_max ) {
  for our $col ( $col_min .. $col_max ) {

    my $cell = $worksheet_R->get_cell( $row, $col );
    if($cell->value() =~ /Spinach/) {
      $worksheet_W->write($row, $col,"ASPARAGUS");
    }
    elsif($cell->value() =~ /Grapes/) {
      $worksheet_W->write($row, $col,"PEACHES");
    }
    else {
      $worksheet_W->write($row, $col, $cell->value()) ;
    }
  }
}
如果您必须保留这些函数,我建议这样做,您可以使用一个函数来获取当前单元格并对其应用任何适当的转换,然后返回准备输出的文本。这将保持读取单元格和从子例程中写入单元格的重复:

for our $row ( $row_min .. $row_max ) {
  for our $col ( $col_min .. $col_max ) {
    my $cell = $worksheet_R->get_cell( $row, $col );
    $worksheet_w->write( $row, $col, produce_check($cell->value) );
  }
}
执行交换的
product\u check
sub也是一个很好的地方,可以对输入进行任何文本规范化或其他检查,例如删除额外的空白,将所有输出设置为标题大小写,等等

sub produce_check {
  my $prod = shift;
  # maybe we have to make sure there's no trailing whitespace on $prod
  $prod =~ s/\s*$//;
  my %swaps = (
    grapes => 'peaches',
    spinach => 'asparagus',
    tins => 'cans',
    zuchini => 'zucchini'
  );
  # is $prod one of pieces of produce we have to swap?
  # perhaps our input is in a mixture of cases, uppercase, lowercase, titlecase
  # to avoid having to add all those variations to the %swaps hash, we convert
  # to lowercase using `lc`
  if ( $swaps{ lc($prod) } ) {
    $prod = $swaps{ lc($prod) };
  }
  # this line uses `ucfirst($prod)` to convert all output to titlecase.
  # You could also convert everything to lowercase ( `lc($prod)` ), to
  # uppercase ( `uc($prod)` ), or just leave it as-is by using `return $prod;`
  return ucfirst( $prod );
}

相关:错误来自同一个源(一个单元格被写了好几次)——我知道您想要消除错误,并询问如何做到这一点。“可能重复”将帮助遇到相同错误的其他人查看其他相关帖子。尽我最大的努力。@user1608954:请不要这么快就拒绝你所要求的帮助。链接的问题看起来和我一样。谢谢“我警告了外星人”。但是我需要保留我的函数,这样它是模块化的,我可以在此基础上进行构建。有没有一种方法可以在保留函数的同时解决它?是的——但是对于这种脚本来说,使用单独的文本替换函数有点过分。好的编码的另一个原则是“不要重复你自己”,拥有三个功能做非常相似的事情(读取单元格内容,可能交换一个单词,写入单元格内容)将违反这一原则。我只是在考虑数据库的增长。如果我有一个巨大的excel文件呢?函数是处理if/elsif/else的更好方法吗?我正在考虑模块化。一天后,仍然在考虑这个出色的解决方案,将函数放在$worksheet_w->write中。再次感谢。