9

我正在尝试理解变量范围并在 Perl 中正确声明变量,但我遇到了困难。

下面的代码基本上是读入一个 excel 文件,对其进行解析,然后将其输出到一个新的 excel 文件中。

但是,我正在尝试读取其中一个标题,如果标题与我的字符串匹配,我想记录该列号,并稍后在代码中使用它。

我在 ./parser.pl 第 38 行收到“使用未初始化值 $site_name_col in print”。

第 38 行是“打印 $site_name_col;”

我意识到这个打印语句在最初初始化变量的 {} 之外,但它在代码开头被声明为全局变量,那么给出了什么?

#!/usr/bin/perl -w

use strict;
use warnings;
use vars qw($site_name_col);
use Spreadsheet::WriteExcel;
use Spreadsheet::ParseExcel;

my ($fname1) = @ARGV;

my $parser   = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse($fname1);

my $new_workbook = Spreadsheet::WriteExcel->new('formated_list.xls', $fname1);

if (!defined $workbook) {

    die $parser->error(), ".\n";
}

for my $worksheet ( $workbook->worksheets() ) {

    my ($wsheet_name) = $worksheet->get_name();
    my $new_worksheet = $new_workbook->add_worksheet($wsheet_name);  

    my ($row_min, $row_max) = $worksheet->row_range();
    my ($col_min, $col_max) = $worksheet->col_range();

    for my $row ($row_min .. $row_max) {

        for my $col ($col_min .. $col_max) {

            my $cell = $worksheet->get_cell($row, $col);
            next unless $cell;

            print "Row, Col = ($row, $col)\n";

            if ( $cell->value() =~ /Site Name/ ) {

                $site_name_col = $col;
            }
            print $site_name_col;

            $new_worksheet->write($row, $col, $cell->value());
        }
    }
}

$new_workbook->close();
4

4 回答 4

5

use vars qw()不再推荐。声明一个全局变量使用our $my_var 你的问题可能来自于条件$cell->value() =~ /Site Name/。它可能永远不会满足,所以你的变量永远不会得到一个值。

于 2012-10-24T05:23:18.933 回答
3

我承认这篇文章有点老了,但是......对于那些多年后仍然来到这个页面的人(比如我自己):

我想您正在阅读的这些 Excel 工作表可能不是您创建的。因此,您可能会遇到大小写问题,当然,正则表达式是区分大小写的。检查期间数据大写或小写:if (lc($cell->value()) =~ /site name/) ...

使用our 拥有一个全球性的原因有很多。site_name 似乎是所有文件都可能需要的东西......

杰瑞特

编辑:

这会更好:

if ($cell->value()) =~ /site name/i) { print $col; }

根本不需要在 if 语句之外打印...节省打印很多...很多次...

于 2015-02-27T02:06:42.643 回答
1

只是为了澄清其他人已经说过的话,在文件顶部声明的变量my可以被整个文件访问和使用。在这种情况下,没有理由使用全局变量。

你什么时候想要一个全球性的?

  • 您希望文件外部的另一段代码可以访问变量。例如,一个模块可能提供一个全局变量,调用该模块的文件可以访问该变量。
  • 您在一个文件中有多个包。在这种情况下,您需要一个全局变量来存储两个包都访问的内容。然而,这样做是相当不寻常的。

很明显,你没有做任何这些事情,所以你应该坚持使用my. 如果您确实想声明一个全局变量,那么正确的方法是使用our. 该命令有一些重要的细微之处,在链接文档中进行了解释。

于 2012-10-24T07:58:00.603 回答
0

在这种情况下你不需要声明全局变量,局部变量就足够了。请参见下面的示例。

if ( $cell->value() =~ /Site Name/ ) {

    my $site_name_col = $col;
    print $site_name_col;
}

或者

my $site_name_col = ''; # default value
if ( $cell->value() =~ /Site Name/ ) {

    $site_name_col = $col;
}
print $site_name_col;
于 2012-10-24T05:30:16.403 回答