uvs has asked for the wisdom of the Perl Monks concerning the following question:

Hello,
I am trying to parse excel sheet in active state perl using Win32::OLE. I am having difficulty even to read the worksheet names if the worksheet position is passed through a hash.
Trying to do: Get position & Worksheet Name (after identifying what each one means <- not important in this issue)

Problem:
I tried 3 methods to loop and get the worksheet name and position but 2 worked and 3rd did not work (Looping though hash). I am more interested in the 3rd one since my code is based on that logic.
Can anyone please help.
Thank you in advance
UVS
Code: my $oBook = $Excel->Workbooks->Open("C:\\Inetpub\\wwwroot\\YAI\\WIN_TE +ST\\INPUT\\abc.xls"); $Excel->{DisplayAlerts}=0; my $sheetcnt = $oBook->Worksheets->Count(); print "---Total wks=$sheetcnt---\n"; # Block 1 works fine foreach my $iSheet(1..$sheetcnt){ my $name=$oBook->Worksheets($iSheet)->{Name}; my $Sheet = $oBook->Worksheets($iSheet); print "At Pos=$iSheet Wks name=$name\n"; if($name=~/Header/){$H_TEST{"HEADER"}{$iSheet}=1;} if(($name=~/ALO/)){$H_TEST{"DATA"}{$iSheet}=1;} } print "\n-------------------------\n"; # Block 2 works fine foreach my $Sheet(in $oBook->{Worksheets}){ print "\t" .$Sheet->{Name} ."\n"; } print "\n-------------------------\n"; # Prints the content of the hash - works fine foreach my $tag(sort keys %H_TEST) { foreach my $iSheet(sort keys %{$H_TEST{$tag}}){ print "Tag=$tag at $iSheet\n"; } } print "\n-------------------------\n"; # ---> This block does not work. Particularly # my $sheet = $oBook->Worksheets->{$iSheet}; # If $iSheet is replaced with numeric value it works foreach my $tag(sort keys %H_TEST) { foreach my $iSheet(sort keys %{$H_TEST{$tag}}){ my $sheet = $oBook->Worksheets->{$iSheet}; my $name=$oBook->Worksheets($iSheet)->{Name}; print "Tag=$tag Position2=$iSheet and name=$name\n"; } } ---------------Output with errors-------- Content-type: text/plain ---Total wks=3--- At Pos=1 Wks name=Header At Pos=2 Wks name=SCM_NAME_RULES At Pos=3 Wks name=ALO ------------------------- Header SCM_NAME_RULES ALO ------------------------- Tag=DATA at 3 Tag=HEADER at 1 ------------------------- <h1>Software error:</h1> <pre>Win32::OLE(0.1707) error 0x80020009: &quot;Exception occurred&quo +t; in METHOD/PROPERTYGET &quot;3&quot; at C:\Inetpub\wwwroot\YAI\TEST +ING\DB\read_excel_cells.pl line 99 </pre> <p> For help, please send mail to this site's webmaster, giving this error + message and the time and date of the error. </p> [Fri Oct 19 11:07:43 2007] read_excel_cells.pl: Win32::OLE(0.1707) err +or 0x80020009: "Exception occurred" [Fri Oct 19 11:07:43 2007] read_excel_cells.pl: in METHOD/PROPERTY +GET "3" at C:\Inetpub\wwwroot\YAI\TESTING\DB\read_excel_cells.pl line + 99

Replies are listed 'Best First'.
Re: Looping Hash keys to get excel wks using Win32::OLE does not work
by ikegami (Patriarch) on Oct 19, 2007 at 16:45 UTC

    The keys of (non-magical) hashes are always strings. Therefore, $iSheet contains a string, the stringification of the sheet number. Because $iSheet contains a string, you're telling Excel to return the Worksheet *named* "3" instead of the Worksheet *at index* 3. Convert $iSheet to a number.

    my $sheet = $oBook->Worksheets->{0+$iSheet};

    Better yet, use a HoA instead of a HoH. You never use the hash value, and I don't think you're using it to get rid of dups.

    HoH (current):

    if ($name =~ /Header/) { $H_TEST{"HEADER"}{$iSheet} = 1; } if ($name =~ /ALO/) { $H_TEST{"DATA"}{$iSheet} = 1; } ... foreach (sort keys %{$H_TEST{$tag}}) { my $iSheet = 0 + $_;

    HoA (proposed):

    if ($name =~ /Header/) { push @{$H_TEST{"HEADER"}}, $iSheet; } if ($name =~ /ALO/) { push @{$H_TEST{"DATA"}}, $iSheet; } ... foreach my $iSheet (sort @{$H_TEST{$tag}}) {
      Thank you!!!!!!! It worked like a charm. Before posting i was planning to convert $iSheet to numeric and then test it out but thought that might not be the problem. Turns out that was the problem.

      Thank you very much for prompt reply. It made my day.