9

変数のスコープを理解し、Perl で変数を適切に宣言しようとしていますが、苦労しています。

以下のコードは基本的に、Excel ファイルを読み込んで解析し、新しい Excel ファイルに出力します。

ただし、ヘッダーの 1 つを読み取ろうとしています。ヘッダーが文字列と一致する場合は、その列番号を記録し、後でコードで使用したいと考えています。

「./parser.pl 行 38 で初期化されていない値 $site_name_col を使用しています。」というメッセージが表示されます。

38行目は「print $site_name_col;」です。

この print ステートメントは、変数が最初に初期化された {} の外にあることに気付きましたが、コードの先頭でグローバル変数として宣言されていたので、何が得られますか?

#!/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全体でアクセスおよび使用できます。この場合、グローバル変数を使用する理由はありません。

いつグローバルが必要になりますか?

  • ファイル外の別のコードから変数にアクセスできるようにしたい。たとえば、モジュールは、モジュールを呼び出すファイルからアクセスできるグローバル変数を提供する場合があります。
  • 1 つのファイル内に複数のパッケージがあります。その場合、両方のパッケージからアクセスされるものに対してグローバル変数が必要になります。ただし、これを行うのはかなり珍しいことです。

これらのことのどちらも行っていないことは明らかなので、そのままにしておく必要があります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 に答える