in reply to Re^2: Win32::Ole excel external data range
in thread Win32::Ole excel external data range
I feared that the "with" clause was doing what you described. I don't know about other languages, but while it will compile in VB6, it won't execute twice - the second call causes a weird crash. This is documented, but I didn't find the documentation before suffering the wounds. I'm therefore very reluctant to use With except in VBA, where it works.use strict; use warnings; use Win32::OLE; my $xl = Win32::OLE->new('Excel.Application'); $xl->{EnableEvents} = 0; $xl->{ReferenceStyle} = 1; #xlA1. xlR1C1 = -4150?!?! $xl->{ScreenUpdating} = 0; #ScreenUpdating is false because the use +r would not normally need to see the Excel instance churning $xl->{Visible} = 1; my $wb = $xl->Workbooks->Add; my $nSheets = $wb->Sheets->Count; #I want 2 sheets - no more, no less. + No matter what $luser's default is. if ($nSheets == 1) { $wb->Sheets->Add({After=>$wb->Sheets(1)}); } if ($nSheets > 2) { for (3 .. $nSheets) { $wb->Sheets(3)->Delete; } } my $shtData = $wb->Sheets(1); my $shtCri = $wb->Sheets(2); $shtData->{Name} = "Data"; $shtCri->{Name} = "Criteria"; for my $sht (1..2) { $wb->Sheets($sht)->Cells(1, 1)->{Value} = "A"; $wb->Sheets($sht)->Cells(1, 2)->{Value} = "B"; $wb->Sheets($sht)->Cells(2, 1)->{Value} = "-"; $wb->Sheets($sht)->Cells(2, 2)->{Value} = "-"; $wb->Sheets($sht)->Range("A2:B2")->{HorizontalAlignment} = 5 #xlFi +ll } $wb->Names->Add({Name=>'zTopData', RefersTo=>'=Data!$A$1'}); $wb->Names->Add({Name=>'zEndData', RefersTo=>'=Data!$B$2'}); $wb->Names->Add({Name=>'zData', RefersTo=>'=OFFSET(zTopData,0,0,ROW(zE +ndData)-ROW(zTopData),COLUMN(zEndData)-COLUMN(zTopData)+1)'}); $wb->Names->Add({Name=>'zTopCriterion', RefersTo=>'=Criteria!$A$1'}); $wb->Names->Add({Name=>'zEndCriterion', RefersTo=>'=Criteria!$B$2'}); $wb->Names->Add({Name=>'zCriterion', RefersTo=>'=OFFSET(zTopCriterion, +0,0,ROW(zEndCriterion)-ROW(zTopCriterion),COLUMN(zEndCriterion)-COLUM +N(zTopCriterion)+1)'}); my $nRows = 98; #Your example has 99 rows in the rnge. This smells lik +e a deliberate overrun to me, but just in case... for (1 .. $nRows) { #Insert some random data $shtData->Range('zEndData')->EntireRow->Insert; $shtData->Cells($_ + 1, 1)->{Value} = int(rand(10)+1); $shtData->Cells($_ + 1, 2)->{Value} = int(rand(10)+1); } $shtCri->Range('zEndCriterion')->EntireRow->Insert; $shtCri->Cells(2, 1)->{Value} = int(rand(10)+1); $shtData->Range('zData')->AdvancedFilter({Action=>1, CriteriaRange=>$s +htCri->Range('zCriterion')}); #xlFilterInPlace = 1 $shtData->Activate; #To get to the filtered list $xl->{EnableEvents} = 1; $xl->{ScreenUpdating} = 1;
|
|---|