1

Word 文書内の複数のテーブルからデータを抽出しようとしています。テーブル内のデータをテキストに変換しようとすると、エラーが発生します。ConvertToTextメソッドには、2 つのオプションのパラメーター (データを分離する方法とブール値) があります。現在のコードは次のとおりです。

#usr/bin/perl
#OLEWord.pl

#Use string and print warnings
use strict;use warnings;
#Using OLE + OLE constants for Variants and OLE enumeration for Enumerations
use Win32::OLE qw(in);
use Win32::OLE::Const 'Microsoft Word';
use Win32::OLE::Variant;

my $var1 = Win32::OLE::Variant->new(VT_BOOL, 'true');

$Win32::OLE::Warn = 3;

#set the file to be opened
my $file = 'C:\work\SCL_International Financial New Fund Setup Questionnaire V1.6.docx';

#Create a new instance of Win32::OLE for the Word application, die if could not open the application
my $MSWord = Win32::OLE->GetActiveObject('Excel.Application') or Win32::OLE->new('Word.Application','Quit');

#Set the screen to Visible, so that you can see what is going on
$MSWord->{'Visible'} = 1;
 $MSWord->{'DisplayAlerts'} = 0; #Supress Alerts, such as 'Save As....'

#open the request file or die and print warning message
my $Doc = $MSWord->{'Documents'}->Open($file) or die "Could not open ", $file, " Error:", Win32::OLE->LastError();

#$MSWord->ActiveDocument->SaveAs({Filename => 'AlteredTest.docx', 
                            #FileFormat => wdFormatDocument});

my $tables = $MSWord->ActiveDocument->{'Tables'};

for my $table (in $tables){
   my $tableText = $table->ConverToText(wdSeparateByParagraphs,$var1);
   print "Table: ", $tableText, "\n";
}


$MSWord->ActiveDocument->Close;
$MSWord->Quit;

そして、私はこのエラーが発生しています:

OLEWord.pl 行 31 で「strict subs」が使用されている間はベアワード「VT_BOOL」は許可されません OLEWord.pl 行 31 で「strict subs」が使用されている間は ベアワード
「true」は許可されません

4

4 に答える 4

3

のようなものVT_BOOLが定数として定義されていない場合、perlはそれらをベアワードと見なします。他の人はすでにそれらに関する情報を提供しました。

問題の根本的な原因は、 Win32 :: OLE::Variantモジュールによってエクスポートされる定数が欠落していることです。追加:

use Win32::OLE::Variant;

スクリプトに追加して、最初のエラーを削除します。2番目の問題も同様の問題でtrueあり、同様に定義されていません。それを次のように置き換える1か、定数を自分で定義します。

use constant true => 1;

編集:テーブルテキストを抽出する例を次に示します。

my $tables = $MSWord->ActiveDocument->{'Tables'};
for my $table (in $tables){
   my $tableText = $table->ConvertToText({ Separator => wdSeparateByTabs });
   print "Table: ", $tableText->Text(), "\n";
}

あなたのコードでは、メソッド名にタイプミスがありましたConverToText。また、メソッドはRangeオブジェクトを返すため、Text実際のテキストを取得するにはメソッドを使用する必要があります。

于 2011-07-19T15:53:00.007 に答える
2

「ベアワード」エラーは、コードの構文エラーが原因で発生します。「暴走した複数行」は、通常、エラーの開始点を特定し、通常、括弧や引用符の不一致が原因で、行が完了していないことを意味します。

何人かの SO-ers が指摘しているように、それは Perl のようには見えません! Perl インタープリターは、その特定の言語を話さないため、構文エラーをためらっています! ソース

strict を使用しない場合、警告は表示されません。(ただし、適切なコードには使用する必要があります)

ベアワードについて読んで、それらが何であるかを知り、このエラーをどのように修正できるかを自分で知ることができます。

Bareword について学習するためのリンクを次に示します。 1. perl.com 2. alumnus

于 2011-07-19T15:15:16.080 に答える
1

「use strict」を削除すると、「Bareword」エラーが削除されます

于 2011-07-19T14:46:48.230 に答える
0

すべてのドキュメント テーブルを 1 つの xls ファイルに抽出する

     sub doParseDoc {

           my $msg     = '' ; 
           my $ret     = 1 ; # assume failure at the beginning ...

           $msg        = 'START --- doParseDoc' ; 
           $objLogger->LogDebugMsg( $msg );
           $msg        = 'using the following DocFile: "' . $DocFile . '"' ; 
           $objLogger->LogInfoMsg( $msg );
           #-----------------------------------------------------------------------
           #Using OLE + OLE constants for Variants and OLE enumeration for Enumerations


           # Create a new Excel workbook
           my $objWorkBook = Spreadsheet::WriteExcel->new("$DocFile" . '.xls');

           # Add a worksheet
           my $objWorkSheet = $objWorkBook->add_worksheet();


           my $var1 = Win32::OLE::Variant->new(VT_BOOL, 'true');

           Win32::OLE->Option(Warn => \&Carp::croak);
           use constant true => 0;

           # at this point you should have the Word application opened in UI with t
           # the DocFile
           # build the MS Word object during run-time 
           my $objMSWord = Win32::OLE->GetActiveObject('Word.Application')
                             or Win32::OLE->new('Word.Application', 'Quit');  

           # build the doc object during run-time 
           my $objDoc   = $objMSWord->Documents->Open($DocFile)
                 or die "Could not open ", $DocFile, " Error:", Win32::OLE->LastError();

           #Set the screen to Visible, so that you can see what is going on
           $objMSWord->{'Visible'} = 1;
           # try NOT printing directly to the file


            #$objMSWord->ActiveDocument->SaveAs({Filename => 'AlteredTest.docx', 
                                        #FileFormat => wdFormatDocument});

           my $tables        = $objMSWord->ActiveDocument->Tables();
           my $tableText     = '' ;   
           my $xlsRow        = 1 ; 

           for my $table (in $tables){
              # extract the table text as a single string
              #$tableText = $table->ConvertToText({ Separator => 'wdSeparateByTabs' });
              # cheated those properties from here: 
              # https://msdn.microsoft.com/en-us/library/aa537149(v=office.11).aspx#officewordautomatingtablesdata_populateatablewithdata
              my $RowsCount = $table->{'Rows'}->{'Count'} ; 
              my $ColsCount = $table->{'Columns'}->{'Count'} ; 

              # disgard the tables having different than 5 columns count
              next unless ( $ColsCount == 5 ) ;

              $msg           = "Rows Count: $RowsCount " ; 
              $msg           .= "Cols Count: $ColsCount " ; 
              $objLogger->LogDebugMsg ( $msg ) ; 

              #my $tableRange = $table->ConvertToText({ Separator => '##' });
              # OBS !!! simple print WILL print to your doc file use Select ?!
              #$objLogger->LogDebugMsg ( $tableRange . "\n" );
              # skip the header row
              foreach my $row ( 0..$RowsCount ) {
                 foreach my $col (0..$ColsCount) {

                    # nope ... $table->cell($row,$col)->->{'WrapText'} = 1 ; 
                    # nope $table->cell($row,$col)->{'WordWrap'} = 1  ;
                    # so so $table->cell($row,$col)->WordWrap() ; 

                    my $txt = ''; 
                    # well some 1% of the values are so nasty that we really give up on them ... 
                    eval {
                       $txt = $table->cell($row,$col)->range->{'Text'}; 
                       #replace all the ctrl chars by space
                       $txt =~ s/\r/ /g   ; 
                       $txt =~ s/[^\040-\176]/ /g  ; 
                       # perform some cleansing - ColName<primary key>=> ColName
                       #$txt =~ s#^(.[a-zA-Z_0-9]*)(\<.*)#$1#g ; 

                       # this will most probably brake your cmd ... 
                       # $objLogger->LogDebugMsg ( "row: $row , col: $col with txt: $txt \n" ) ; 
                    } or $txt = 'N/A' ; 

                    # Write a formatted and unformatted string, row and column notation.
                    $objWorkSheet->write($xlsRow, $col, $txt);

                 } #eof foreach col

                 # we just want to dump all the tables into the one sheet
                 $xlsRow++ ; 
               } #eof foreach row
               sleep 1 ; 
           }  #eof foreach table

           # close the opened in the UI document
           $objMSWord->ActiveDocument->Close;

           # OBS !!! now we are able to print 
           $objLogger->LogDebugMsg ( $tableText . "\n" );

           # exit the whole Word application
           $objMSWord->Quit;

           return ( $ret , $msg ) ; 
     }
     #eof sub doParseDoc
于 2015-02-11T14:05:59.813 に答える