Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Re^4: Creating a table from raw data!

by blackadder (Hermit)
on Nov 19, 2009 at 19:09 UTC ( [id://808232] : note . print w/replies, xml ) Need Help??

in reply to Re^3: Creating a table from raw data!
in thread Creating a table from raw data!

Spent ages debugging the above to no avail,..still didn't work!

I started again

Now; I have this data in colum A in excel
RDUB010 34:34:36:7U 87:23:89:6C RDUB090 90:39:12:6U 34:34:36:7Z 87:23:89:6N 34:38:36:7U
And i want to create a data structure like this
San : SAN_01 Lun: RDUB010 WWn1: 34:34:36:7U WWn2: 34:34:36:7U Lun: RDUB090 WWn1:90:39:12:6U WWn2:34:34:36:7Z WWn3:87:23:89:6N WWn4:34:38:36:7U San: SAN_02 . . . and so forth
So I put this PERL script together to do the job;
#! c:/perl/bin/perl.exe # # use strict; use Win32::OLE qw(in with); use Win32::OLE::Const 'Microsoft Excel'; use Data::Dumper qw/Dumper/; use vars qw/$Storage/; my $data; $Win32::OLE::Warn =2; my $excel = Win32::OLE->GetActiveObject('Excel.Application') || Win32: +:OLE->new('Excel.Application'); my $xls_path = "c:\\test.xlsx"; my $xls = $excel->Workbooks->Open("$xls_path"); foreach my $sheet ( in $xls->Worksheets ) { $Storage ={}; $Storage->{SAN} = $sheet->Name, $/; print $Storage->{SAN}."\n"; my $San_data = $xls->Worksheets("$Storage->{SAN}"); my @Colum_A = $San_data->UsedRange->{'Value'}; foreach my $array (@Colum_A) { foreach my $element (@$array) { foreach my $info (@$element) { if ($info !~ /:/) { next if not defined $info; push (@{$Storage->{LUNs}}, "$info"); } if ($info =~ /:/) { push (@{$Storage->{LUNs}}->{WWN}}, "$info"); } } } print "\n_______________\n"; } print Dumper $Storage; }
When I ran the script I get this output, which is wrong
SAN_01 ______________ $VAR1 = { 'ARRAY(0x1b68610)' => { 'WWN' => [ '34:34:36:7U', '87:23:89:6C', '90:39:12:6U', '34:34:36:7Z', '87:23:89:6N', '34:38:36:7U', ] }, 'LUNs' => [ 'RDUB010', 'RDUB090' ], 'SAN' => 'SAN_01' };
Could someone for the love of God or Perl tell me where am I going wrong and what can I do to get it right? THANKS A BUNCH

Replies are listed 'Best First'.
Re^5: Creating a table from raw data!
by graff (Chancellor) on Nov 19, 2009 at 22:24 UTC
    I'm sorry, but the code you just posted could not have produced the output that you posted with it. The script has a syntax error on this line (inside the last "if" block, line 42 when I downloaded it):
    push (@{$Storage->{LUNs}}->{WWN}}, "$info");
    Note the extra close-curly-brace. I think if you change it to read as follows:
    push (@{$$Storage{LUNs}{WWN}}, $info);
    there won't be a syntax error, and it might behave better. Apart from that, there's a warning from this line:
    $Storage->{SAN} = $sheet->Name, $/;
    The ", $/" part does no good at all -- the warning is "useless use of a variable in void context". Just remove those four characters.

    There's nothing more I can say, because I don't use windows or Win32::OLE. To read from an Excel file, I use Spreadsheet::ParseExcel, which works fine.

Re^5: Creating a table from raw data!
by johngg (Canon) on Nov 19, 2009 at 23:32 UTC

    I'm not sure if this the sort of data structure you are after. It isn't the same as your structure but I think it reflects the hierarchy implied by your data. I have hopefully managed to replicate the sort of data you have in the spreadsheet in my @sanData array.

    use strict; use warnings; use Data::Dumper; # @sanData is equivalent to $sheet->Name() and @Column_A data # in your 'foreach my $sheet' loop. my @sanData = ( { name => q{SAN_01}, data => [ qw{ RDUB010 34:34:36:7U 87:23:89:6C RDUB090 90:39:12:6U 34:34:36:7Z 87:23:89:6N 34:38:36:7U } ], }, { name => q{SAN_02}, data => [ qw{ RDUB030 34:7U:34:36 87:89:23:6C RDUB070 90:12:39:7Z 36:34:34:6U 89:23:87:6N 34:36:38:7U } ], }, ); my $storage = {}; foreach my $rhSheet ( @sanData ) { my $name = $rhSheet->{ name }; $storage->{ $name } = {}; my $currentLUN = q{}; foreach my $dataItem ( @{ $rhSheet->{ data } } ) { if ( $dataItem =~ m{:} ) { push @{ $storage->{ $name }->{ $currentLUN } }, $dataItem; } else { $currentLUN = $dataItem; $storage->{ $name }->{ $currentLUN } = []; } } } print Data::Dumper->Dumpxs( [ $storage ], [ qw{ storage } ] );

    The Data::Dumper output.

    $storage = { 'SAN_01' => { 'RDUB090' => [ '90:39:12:6U', '34:34:36:7Z', '87:23:89:6N', '34:38:36:7U' ], 'RDUB010' => [ '34:34:36:7U', '87:23:89:6C' ] }, 'SAN_02' => { 'RDUB070' => [ '90:12:39:7Z', '36:34:34:6U', '89:23:87:6N', '34:36:38:7U' ], 'RDUB030' => [ '34:7U:34:36', '87:89:23:6C' ] } };

    I hope this is helpful.



Re^5: Creating a table from raw data!
by BioLion (Curate) on Nov 20, 2009 at 10:18 UTC

    I bugfixed my code... I shouldn't post untested stuff! It seems to give what you are after. graff and johngg have also given you good approaches, so hopefully you are all set now.

    It seems like getting the data wasn't the problem, but creating and navigating complex datastructures - whenever I am having problems like this, i find perldsc and perlref very helpful for avoiding frustrations! And as far as deciding on the most appropriate datastructure, that is really down to experimenting and seeing what works for you!

    Just a something something...