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

I've got an Excel spreadsheet where I'm not having success editing directly. This is a long shot but one of the alternatives I thought of is if I could edit it programmatically. The sheet has many charts. What I want to do is change the data source of the SERIES function of each chart (basically, the problem is some charts use data from the wrong sheet, so I want to update the sheet name in the SERIES. There are many charts so it would be faster to update them programmatically). Is this possible with any of the Perl modules? I've searched the web and all I found was modules that let you create a new chart, but thought I'd ask. (I also have a question posted on StackOverflow about performing the desired edit directly in Excel)

Replies are listed 'Best First'.
Re: Excel chart enumeration and editing
by davies (Monsignor) on Jun 26, 2014 at 22:23 UTC

    You haven't shown us what you have tried, which means it's harder to guide you. A general rule is that ANYTHING that can be done on the face of the spreadsheet (i.e. excluding VBA) can be done from Perl via Win32::OLE. You might want to have a look at Re: pie chart color -- Win32::OLE for some code where I set up & then play around with a chart. Each workbook has a charts collection. If you know the index of the chart you want, you can point to it with something like $wb->charts($index) and then add or change the settings at your whim.

    Regards,

    John Davies

Re: Excel chart enumeration and editing
by Ratazong (Monsignor) on Jun 27, 2014 at 09:38 UTC
Re: Excel chart enumeration and editing
by poj (Abbot) on Jun 27, 2014 at 15:34 UTC
    Try this, it should list the SERIES data for all the charts in the workbook.
    If it does then the code I have commented out may be all you need to make the changes.
    #!perl use strict; use Win32::OLE::Const 'Microsoft Excel'; Win32::OLE->Option(Warn => 3); my $ex = Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application', 'Quit'); # change filename to suit my $wb = $ex->Workbooks->Open('c:/temp/testchart.xls') ; for my $ws ( $wb->Sheets->in){ print "\nSheet = ".$ws->Name."\n"; for my $obj ( $ws->ChartObjects->in ){ my $cht = $obj->Chart; print "Name = ".$cht->Name."\n"; print "Title = ".$cht->ChartTitle->text."\n" if $cht->hasTitle; for my $ser ($cht->SeriesCollection->in){ my $SERIES = $ser->{'FormulaR1C1'}; print $ser->Name.' ['.$SERIES."]\n"; # make changes as appropriate #my $NEWSERIES = $SERIES; #if ($NEWSERIES =~ s/Sheet1/Sheet2/g){; # $ser->{'FormulaR1C1'} = $NEWSERIES; # print "--> Changed to [$NEWSERIES]\n"; #}; } } } # save and exit $wb->SaveAs( 'c:\\temp\\changed.xls' ); undef $wb; undef $ex;
    poj
      The code worked perfectly. Thanks for setting me on the right path!