2011-05-17 80 views
1

我正在編寫一個比較兩個excel文件的數據的Perl腳本。無法訪問Perl循環中的哈希查找表

我目前正在考慮一個excel文件的兩列並將其存儲在一個散列。我用於密鑰的數據是電子郵件地址,該值只是Excel表單中的另一個值(不重要)。我只是試圖將所有電子郵件存儲爲散列鍵,以便我可以遍歷另一個(「刪除」)excel文件,並查看該電子郵件是否存在於原始成員表中。

我的意圖是沿着這些路線的東西:

1)創建散列和查找數組:

my %members_list; 
foreach my $row (2..$MembersLastRow){ 
    $members_list{lc($Members->Cells($row,1)->{'Value'})} = lc($Members->Cells($row,2)->{'Value'}); 
} 

my @removals_list; 
foreach my $row (2..$RemovalsLastRow) 
{ 
    push(@removals_list, lc($Removals->Cells($row,1)->{'Value'})); 
} 

2)遍歷查找數組和哈希檢查是否存在:

foreach my $key (sort @removals_list) 
{ 
    print $key; 
    if($members_list{$key}){ 
     print " - MATCH!"; 
    } 
    print "\n"; 
} 

問題是,當我嘗試運行這個時,從來沒有任何匹配。刪除列表中的所有元素應存儲在members_list哈希中。我已經嘗試打印出$ members_list {$ key}到屏幕上,然後出現「未初始化的使用」等等等等等等。

我一直在爲此奮戰幾天,任何幫助都非常感謝。

這是我使用的代碼的完整頁面!

use strict; 
use 5.010; 
use Win32::OLE qw(in with); 
use Win32::OLE::Const 'Microsoft Excel'; 

$Win32::OLE::Warn = 3;        # die on errors... 

# get already active Excel application or open new 
my $Excel = Win32::OLE->GetActiveObject('Excel.Application') 
    || Win32::OLE->new('Excel.Application', 'Quit'); 
$Excel->{DisplayAlerts}=0; 
# open Excel file 

my $Book = $Excel->Workbooks->Open("**FILENAME1**"); 
my $Book2 = $Excel->Workbooks->Open("**FILENAME2**"); 

# You can dynamically obtain the number of worksheets, rows, and columns 
# through the Excel OLE interface. Excel's Visual Basic Editor has more 
# information on the Excel OLE interface. Here we just use the first 
# worksheet, rows 1 through 4 and columns 1 through 3. 


my $Members = $Book->Worksheets(1); 
$Members->{Name} = "Members - Points"; 
my $Results = $Book->Worksheets(2); 
$Results->{Name} = "Perl Results -Saved"; 

my $Removals = $Book2->Worksheets(1); 
$Removals->{Name} = "Removals"; 

my $count=0; 
my %members_list; 
my @removals_list; 

my $MembersLastRow = &findLastRow($Members); 
print "After Members Last Row\n"; 
my $RemovalsLastRow = &findLastRow($Removals); 
print "After Removals Last Row\n"; 

foreach my $row (2..$MembersLastRow) 
{ 
    next unless defined $Members->Cells($row,1)->{'Value'}; 
    $members_list{lc($Members->Cells($row,1)->{'Value'})} = lc($Members->Cells($row,2)->{'Value'}); 
} 
foreach my $row (2..$RemovalsLastRow) 
{ 
next unless defined $Removals->Cells($row,1)->{'Value'}; 
push(@removals_list, lc($Removals->Cells($row,1)->{'Value'})); 
} 

#DO THE VLOOKUP 
my $matches=1; 
print "Now doing comparisons......\n"; 
$Results->Cells($matches,1)->{'Value'} = "Removal List"; 
$Results->Cells($matches,2)->{'Value'} = "Corresponding Member List"; 


foreach my $key (sort @removals_list) 
{ 
    print $key; 
    if($members_list{$key}){ 
     print " - MATCH!"; 
    } 
    print "\n"; 
} 

print "\nComparisons Complete.\n"; 

sub findLastRow 
{ 
    $_[0]->UsedRange->Find({What=>"*", 
    SearchDirection=>xlPrevious, 
    SearchOrder=>xlByRows})->{Row}; 
} 

sub findLastCol 
{ 
    $_[0]->UsedRange->Find({What=>"*", 
    SearchDirection=>xlPrevious, 
    SearchOrder=>xlByColumns})->{Column}; 
} 

$Book->Save(); 
+0

使用[Data :: Dumper](http://perldoc.perl.org/Data/Dumper.html)這是一個標準的Perl模塊,並將其轉儲出成員列表和刪除列表中的內容。這會告訴你爲什麼你可能沒有得到任何比賽。 – 2011-05-24 16:32:02

回答

2

如果要存儲的值可能是undef,你想這樣做,而不是:

if (exists $members_list{$key}) { 

你確定你正在訪問同%members_list哈希?它還沒有超出範圍或被後來的my %members_list取代?

這說明了什麼:

use Data::Dumper; 
$Data::Dumper::Terse = $Data::Dumper::Useqq = 1; 
print Data::Dumper::Dumper({ 'removals' => [ sort @removals_list ], 'members' => [ sort keys %members_list ] }); 

+0

我剛剛嘗試過,但它做同樣的事情。我不明白它是如何超出範圍的。在inital之後我沒有「我的%members_list」。 這真的很煩人,因爲我覺得這應該工作。 我會提到我使用的模塊: 使用嚴格; 使用5.010; 使用Win32 :: OLE qw(in with); 使用Win32 :: OLE :: Const'Microsoft Excel'; – bOkeifus 2011-05-17 20:08:06

+1

您顯示的兩位之間的代碼是什麼? – ysth 2011-05-18 00:26:25

+0

我把所有的代碼放到最初的問題中。 – bOkeifus 2011-05-24 14:57:48