2011-05-17 40 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