0

元の投稿が長すぎます: Spreadsheet::ParseExcel を使用して XLS ファイルでゼロ セルをフェッチする

xls のデータ構造。ファイルは次のようになります。

      col1      col2    col3   col4   col5 
row1  School    1
row2  Dean      John
row3  No.stu.   55
row4  some irrelevant stuff 
row5  School2   2
row6  Dean      Tony 
row7  No. stu.  60 
row8  some irrelevant stuff
row9  School    3
row10 Dean      James
row11 No.stu.   56
row12 No. teacher 20
row13 School    4
row14 Dean      Tom
row15 No.stu.   79
row16 No. teacher 21
row17 course    
row18           math    2
row19           eng     4      
row20 teacher   name    age   gender   race 
row21           Jane    20    female   white  
row22 student   name    Lee 
row23           SAT     1434
row24           gender  male  

imran が提案したように、Spreadsheet::ParseExcel; を使用して次の構造を使用しました。

    my %data;
    my $state = "";
    my $school = "";
    my $student = "";
    my ( $row_min, $row_max ) = $worksheet->row_range();
    my $row = $row_min;
    while ($row <= $row_max) {
        my $cell0 = $worksheet->get_cell( $row, 0 );
        my $cell1 = $worksheet->get_cell( $row, 1 );

        if (defined($cell0)) {
            my $key = $cell0->value();
            if ($key eq 'School') {
                $state = 'school';
                $school = $cell1->value();
            } elsif ($key eq 'course') {
                $state = 'course';
            } elsif ($key eq 'teacher') {
                $state = 'teacher';
            } elsif ($key eq 'student') {
                $state = 'student');
                $student = $worksheet->get_cell( $row, 2 )->value();
            } else {
                $data{$school}{$key} = $cell1->value();
            }
        } elsif ($state eq 'course') {
            # process columns for course
        } elsif ($state eq 'teacher') {
            # process columns for teacher
        } elsif ($state eq 'student') {
            # process columns for student
        }
        $row++;
    }

これはかなりうまく機能します。

しかし、各stateでは、2 行目から解析を開始しているようです。つまり、状態としてコースを主張すると、次の行に到達するまで次の行から処理を開始しますstate。ただし、たとえば、コース状態のデータ構造が学校ごとにわずかに異なる場合、つまりstateコースのキーと値の 1 つが同じ行にある場合、

     School    1 
     course    math    
               eng
     ...
     School     2
     course    phy
     ...   
     School     3 
     course    chem 
               gym 
               music 

次を使用して元のコードに固執する場合:

 } elsif ($key eq 'course') {
                $state = 'course';
                $course = $worksheet->get_cell( $row, 1 )->value();
    }

対応するハッシュテーブルは次のとおりです。

} elsif ($state eq 'course') {
            my $key = $cell1->value();
            $data{$school}{$course}{$key} =$cell1->value();
}

ただし、解析できるのは

 '1' => {
                   'math' => {
                               'eng' => 'eng'
                             },
       }
'3' => {
   'chem' => {
                               'gym' => 'gym',
                               'music' => 'music
                             },
      }

の解析はありませんschool2

問題は、このモジュールに柔軟性があり、どこからでも解析できるかどうかです。

よろしくお願いします、

4

1 に答える 1

2

上記の構造ではなく、以下のような構造が必要だと思います。

'1' => {
               'course' => {
                           'math' => 'math'
                           'eng' => 'eng'
                         },
   }
'3' => {
               'course' => {
                           'chem' => 'chem'
                           'gym' => 'gym',
                           'music' => 'music
                         },
  }

したがって、ハッシュ名は学校番号で始まり、内部にはコースのハッシュがあり、内部には提供されるすべてのコースのキーと値のペアが含まれている必要があります。

このようにして、後で非常に簡単に解析することもできます。

編集:

コードを次のように変更できます(正確な方法はわかりません):

 } elsif ($key eq 'course') {
            $state = 'course';
            $course = $state;
            $key = $worksheet->get_cell( $row, 1 )->value();
            $data{$school}{$course}{$key} = $key;
}

このようなもので動作するはずですが、要件に基づいていくつかの変更を行う必要がある場合があります。

于 2013-04-23T07:14:50.477 に答える