Не удается получить доступ к таблице хэш-поиска в цикле Perl

#perl #excel #hash

#perl #excel #хэш

Вопрос:

Я пишу скрипт на Perl, который сравнивает данные двух файлов Excel.

В настоящее время я беру два столбца одного из файлов Excel и сохраняю его в хэше. Данные, которые я использую для ключа, — это адрес электронной почты, а значение — это просто другое значение на листе Excel (неважно). Я просто пытаюсь сохранить все электронные письма в виде хэш-ключей, чтобы я мог просмотреть другой файл Excel («удаления») и посмотреть, существует ли электронное письмо в исходной таблице members.

Мои намерения примерно такие:

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 = amp;findLastRow($Members);
print "After Members Last Rown";
my $RemovalsLastRow = amp;findLastRow($Removals);
print "After Removals Last Rown";

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();
  

Комментарии:

1. Используйте Data::Dumper , который является стандартным модулем Perl, и попросите его выгрузить содержимое как списка участников, так и списка удаления. Это покажет вам, почему вы, возможно, не получаете никаких совпадений.

Ответ №1:

Если сохраняемое вами значение может быть 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 ] } );
  

?

Комментарии:

1. Я только что попробовал это, но это делает то же самое. Я не вижу, как это вышло за рамки. У меня нет «my%members_list» после начального. Это действительно раздражает, потому что я чувствую, что это должно работать. Я упомяну модули, которые я использую: используйте strict; используйте 5.010; используйте Win32::OLE qw (в with); используйте Win32::OLE::Const ‘Microsoft Excel’;

2. @bOkeifus: добавлен вопрос к моему ответу

3. Неважно, я нашел проблему. Проблема была вовсе не в коде. Проблема заключалась в том, что эта программа должна была проверить исходный файл на наличие списка удалений, а затем удалить их. Я тестировал программу в списке, в котором уже отсутствовали удаления. Поэтому, когда он ничего не нашел, вот почему я подумал, что код был поврежден. На самом деле проблема заключалась в образцах, которые я использовал. Я действительно ценю, что вы изучили это вместе со мной, я подумал, что все это тоже выглядело хорошо, по-видимому, мы оба были правы!