HowTo write a formula in cell using perl WIN32::OLE - excel

I try to insert a formula =IF(D2="";"";COUNTIF(D:D;D2)) in an Excel worksheet.
Here is the code I'm trying:
$WorkSheet->Cells($Row2Use,'L')->{Formula} = "=IF(D".$Row2Use."=\"\",\"\",COUNTIF(D:D,D".$Row2Use.")"; # =IF(D2="";"";COUNTIF(D:D;D2))
I also tried using {Value} instead of {Formula} without success!
What did I wrong

This following works for me. Code taken and modified from the link given by xxfelixxx.
use Cwd 'abs_path';
use Win32::OLE;
use Win32::OLE qw(in with);
use Win32::OLE::Const "Microsoft Excel";
$Win32::OLE::Warn = 3;
my $Excel = Win32::OLE->GetActiveObject('Excel.Application') || Win32::OLE->new('Excel.Application', 'Quit');
$Excel->{Visible} = 1;
my $Book = $Excel->Workbooks->Add;
my $Sheet = $Book->Activesheet;
$Sheet->Range("A1")->{Value} = 1;
$Sheet->Range("A2")->{Value} = 1;
$Sheet->Range("A3")->{Formula} = "=SUMA(R[-2]C:R[-1]C)";

Related

How to read Excel file in Perl by sheet name

I am looking for some examples/advice on how to write a Perl script
to read data from an Excel file by sheet name and not sheet number.
This is an example with Spreadsheet, but it doesn't work with sheet name:
#Code Perl :
use Spreadsheet::Read qw(ReadData);
{
my $book = ReadData ("test.xls");
my $sheet = $book->sheet ("name_3");
my #rows = rows ($sheet);
...
}
Can you help me please?
It works for me when I use the OO API:
use warnings;
use strict;
use Spreadsheet::Read;
my $book = Spreadsheet::Read->new('test.xls');
my $sheet = $book->sheet('Sheet1');
my #rows = $sheet->rows();

Umlauts in Excel data

I am reading Data From Excel and if the text in the cell contains umlauts (äöü) they not be correctly seen by my Perl script. The char is replaced by substitution character.
What do I need to do to correctly read special characters from Excel?
# get reference to Excel, Active Window, Active Sheet
my $excel = Win32::OLE->GetActiveObject('Excel.Application');
my $book = $excel -> ActiveWindow;
my $sheet = $book -> ActiveSheet();
my $text = $sheet->Cells(1, 2)->{Value};
It works for me (Windows 10, Strawberry Perl 5.30) when printing the content to the Windows command prompt window and using STDOUT encoding cp437:
use feature qw(say);
use strict;
use warnings;
use Win32::OLE;
use open ':std', ':encoding(cp437)';
# get reference to Excel, Active Window, Active Sheet
my $excel = Win32::OLE->GetActiveObject('Excel.Application');
my $book = $excel -> ActiveWindow;
my $sheet = $book -> ActiveSheet();
my $text = $sheet->Cells(1, 1)->{Value};
say $text;
Output:
äöü
Edit:
As noted by #ikegami you should determine the console output-code-page programmatically (instead of hardcoding the value cp437 as I did) like this:
use Win32;
my $coe = "cp" . Win32::GetConsoleOutputCP();
binmode STDOUT, "encoding($coe)";
See also this post for more information.

Save Excel spreadsheet file without the password

I am trying to open password protected excel and save it with no password.
I know the password. When I am trying to run the code below, the file is being saved with the password.
#!/usr/bin/perl
use strict;
use warnings,
use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel *';
my $file = "in.xls";
my $outFile = "out.xls";
my $Excel = Win32::OLE->new ('Excel.Application', 'Quit');
$Excel->{'Visible'} = 0; #0 is hidden, 1 is visible
$Excel->{'DisplayAlerts'} = 0; #0 is hide alerts
my $Book = $Excel->Workbooks->Open({FileName => "$file", Password => 'test'});
my $Sheet = $Book->Worksheets('test');
$Sheet->Activate();
$Book->SaveAs({Filename=>"$outFile",FileFormat=>xlWorkbookNormal});
$Excel->Quit();
Please advise.
Thank you,
-Andrey
Try:
$Book->Unprotect('test'); # Where 'test' is your password
Reference: Workbook.Unprotect Method (Excel)
I figured out the answer:
$Book->SaveAs({Filename=>"$outFile",FileFormat=>xlWorkbookNormal, Password => undef});
Thanks guys.

How to save Excel file in working directory in Win32::OLE

I am trying to parse an Excel file in perl. After I extract the required info from it, I close the Excel file. At the end I am trying to save a new Excel file with a different name in the same directory. But this Excel is getting stored in 'My Documents' folder.
use Storable ;
use Cwd;
use Win32::OLE ;
use Win32::OLE qw(in with) ;
use Win32::OLE in ;
use Win32::OLE::Const 'Microsoft Excel';
use Excel::Writer::XLSX;
my $Excel = Win32::OLE->new("Excel.Application");
my $excel = $Excel->Workbooks->Add();
my $sheet = $excel->Worksheets(1);
$sheet->Activate();
my $new_file = "Temp_file.xlsm";
my $new_excel = cwd.'\\'.$new_file;
$new_excel =~ s/\//\\/g;
$excel->SaveAs($new_excel);
$Excel->{DisplayAlerts} = 0;
$excel->{Saved} = 1;
$excel->Close;
Here is an update based on your code. First, you are letting Win32::OLE errors to be silently ignored. Instead, set: $Win32::OLE::Warn = 3 so it croaks whenever something goes wrong. Second, the way you try to obtain an Excel.Application instance is not correct. For one thing, if something goes wrong, you will have instances of Excel will remain floating around.
You are also confusing an Excel instance, a workbook, and the sheets it contains. If you did have $Win32::OLE::Warn = 3, you would have received a notification of where things are going wrong.
You should also always have use strict and use warnings in your script. Others will be more inclined to try to help if they know your problem is not caused by some trivial typo.
You also don't need three separate use Win32::OLE statements.
The code below "works". Compare it to yours.
Finally, if you are manipulating your sheet via Win32::OLE, there is no reason to have Excel::Writer::XLSX in your code.
use feature 'say';
use strict;
use warnings;
use File::Spec::Functions qw( rel2abs );
use Win32::OLE qw(in with) ;
use Win32::OLE::Const 'Microsoft Excel';
$Win32::OLE::Warn = 3;
my $excel = eval {
Win32::OLE->GetActiveObject('Excel.Application');
} || Win32::OLE->new('Excel.Application', sub { $_[0]->Quit });
my $wb = $excel->Workbooks->Add;
my $sheet = $wb->Worksheets->Add;
$wb->SaveAs( rel2abs('temp_file.xlsm') );
$excel->{DisplayAlerts} = 0;
$wb->{Saved} = 1;
$wb->Close;

Deleting rows in already existing excel file by using perl

guys,
Iam trying to delete used rows in already existing excel file
i tried with below code
use strict;
use warnings;
use Win32::OLE;
my $xl = Win32::OLE->new('Excel.Application');
$xl->{Visible} = 0;
my $nShtsOld = $xl->{SheetsInOldWorkbook};
$xl->{SheetsInOldWorkbook} = 1;
my $wb = $xl->Workbooks->Open('C:\Users\u304079\Desktop\Test_S1_Legacy_US.xlsx');
$xl->{SheetsInOldWorkbook} = $nShtsOld;
my $sht = $wb->Sheets(o);
my $end = $sht->Usedrange->Row->Count;
print $end;
for (my $count = $end; 0 < $count; $count--)
{
my $cell = $sht->{Cells};
if (!defined $cell->{Value})
{
$cell->entireRow->delete;
}
}
# save and exit
$xl->SaveAs('C:\Users\u304079\Desktop\Test_S1_Legacy_US.xlsx');
$xl->close();
but iam unable to do with following code getting error message as
Can't call method "Usedrange" on an undefined value"
It looks like my $sht = $wb->Sheets(o); may be a typo. Should that be a zero 0 instead?

Resources