Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get Perl's Spreadsheet::WriteExcel to create formulas with VLOOKUP?

Tags:

excel

perl

I'm having difficulty with Spreadsheet::WriteExcel and formulas that use VLOOKUP. The following test script populates a worksheet with some data and tries to create a VLOOKUP formula. When I open the resulting Excel file, the formula results are displayed as #VALUE!. If I manually edit any of the cells containing formulas (press F2 and then just ENTER without changing anything), I can get Excel to evaluate the formula properly. Any idea what going wrong?

For what it's worth, if I open the same file in OpenOffice, the formulas work fine.

use strict;
use warnings;
use Spreadsheet::WriteExcel;

my $wb = Spreadsheet::WriteExcel->new('foo.xls');
my $ws = $wb->add_worksheet;

for my $r (0 .. 9){
    for my $c (0 .. 4){
        $ws->write($r, $c, $r * 10 + $c);
    }
    $ws->write($r, 10, $r * 10);
    my $formula = sprintf('=VLOOKUP(K%s, A1:B10, 2, FALSE)', $r + 1);
    $ws->write( $r, 11, $formula );
    # $ws->write_formula( $r, 11, $formula ); # Does not help either.
}

Version info:

  • Excel 2007 SP2.
  • Spreadsheet::WriteExcel: tried both 2.25 and 2.37.
like image 853
FMc Avatar asked Dec 23 '22 05:12

FMc


2 Answers

I am the author of Spreadsheet::WriteExcel.

This is a known error with the formula parser and certain formula types in WriteExcel. You can work around it using store_formula() and repeat_formula() as shown below:

use strict;
use warnings;
use Spreadsheet::WriteExcel;

my $wb = Spreadsheet::WriteExcel->new('foo.xls');
my $ws = $wb->add_worksheet;

my $formula = $ws->store_formula('=VLOOKUP(K1, A1:B10, 2, FALSE)');

# Workaround for VLOOKUP bug in WriteExcel.
@$formula = map {s/_ref2d/_ref2dV/;$_} @$formula;

for my $r (0 .. 9){
    for my $c (0 .. 4){
        $ws->write($r, $c, $r * 10 + $c);
    }
    $ws->write($r, 10, $r * 10);

    $ws->repeat_formula( $r, 11, $formula, undef, qr/^K1$/, 'K' . ($r +1) );
}
like image 89
jmcnamara Avatar answered Mar 08 '23 23:03

jmcnamara


I'm maintainer of writeexcel rubygem. for example, ruby code is below.

require 'rubygems'
require 'writeexcel'

wb = WriteExcel.new('fooruby.xls')
ws = wb.add_worksheet

formula = ws.store_formula('=VLOOKUP(K1, A1:B10, 2, FALSE)')

# Workaround for VLOOKUP bug in WriteExcel.
formula.map! {|f| f.sub(/_ref2d/, '_ref2dV') }

(0..9).each do |row|
  (0..4).each { |col| ws.write(row, col, row * 10 + col) }
  ws.write(row, 10, row * 10)
  ws.repeat_formula(row, 11, formula, nil, /^K1$/, "K#{row+1}" )
end

wb.close
like image 35
cxn03651 Avatar answered Mar 09 '23 00:03

cxn03651