2012-05-25 120 views
0

我想更改Excel電子表格中一堆超鏈接的路徑。搜索谷歌後,我碰到一個solutions的問題加入超鏈接到電子表格,但不是改變他們。微軟展示瞭如何與VBA here接近。使用Perl Win32獲取Excel工作表中的超鏈接列表:Win32 :: OLE

因爲我想在我的文檔編輯每一個超鏈接,我不知道如何解決的關鍵步驟是:

  1. 在Perl

  2. 獲取超鏈接對象的列表提取其地址1 1和

  3. 運行正則表達式來進行路徑變更

  4. 店裏的T他更新超鏈接 - >對象的路徑並重復

我是使用OLE的新手,並且在(1)上被絆倒。以下是我迄今爲止嘗試:

#!perl 
use strict; 
use warnings; 
use 5.014; 
use OLE; 
use Win32::OLE::Const "Microsoft Excel"; 

my $file_name = 'C:\path\to\spreadsheet.xlsx'; 
my $excel = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;}); 
$excel->{Visible} = 1; 
my $workbook = $excel->Workbooks->Open($file_name); 
my $sheet = $workbook->Worksheets('Sheet 1'); 
foreach my $link (in $sheet->Hyperlinks) { 
say $link->Address; 
} 

但是這給代碼中的錯誤:

Win32::OLE(0.1709): GetOleEnumObject() Not a Win32::OLE::Enum object at C:/Dwimperl/perl/vendor/lib/Win32/OLE/Lite.pm line 167. Can't call method "Hyperlinks" without a package or object reference at at script.pl line 14.

它選擇合適的工作,所以我不知道爲什麼它抱怨的對象引用。我嘗試了幾種變化(在超鏈接周圍添加{},刪除'in',嘗試將它作爲列表存儲,作爲散列,並作爲散列的引用)任何人都可以給我一些指示嗎?謝謝!

+0

'Sheet'和'1'之間應該有空格嗎? Excel默認將其工作表'Sheet1'命名爲無空格。 – Joel

+0

你的代碼真的說'foreach我的$鏈接(在$ sheet-> Hyperlinks)''?我認爲不會,因爲這會編譯爲'$ sheet-> - >> Hyperlinks',而工作表沒有'in'的方法。 – Borodin

+1

@BORODIN **(COLLECTION)** **:*如果COLLECTION是一個OLE集合對象,那麼'$ COLLECTION'返回集合中所有成員的列表,這是'Win32 :: OLE的一個快捷方式: :Enum-All($ COLLECTION)',它最常用於'foreach'循環*「中。我認爲OP不得不使用'in($ sheet-> Hyperlinks)',但我發現''in''是片狀的。或者換一種說法,當我使用'in'時遇到了問題,我一直可以通過使用明確構建的'Win32 :: OLE :: Enum'迭代器來避免這種情況。 –

回答

2

首先,你應該設置$Win32::OLE::Warn=3,這樣你的腳本就會在出現問題的時候發聲。其次,我知道你不能在舊版本的Excel中按名稱選擇工作表,但我不知道最新版本中的情況。最後,我認爲你會發現使用Win32::OLE::Enum更容易。

下面是一個例子:

#!/usr/bin/env perl 

use 5.014; 
use warnings; use strict; 

use Carp qw(croak); 
use Path::Class; 
use Try::Tiny; 
use Win32::OLE; 
use Win32::OLE::Const 'Microsoft Excel'; 
use Win32::OLE::Enum; 
$Win32::OLE::Warn = 3; 

my $book_file = file($ENV{TEMP}, 'test.xls'); 
say $book_file; 

my $excel = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;}); 
$excel->{Visible} = 1; 

my $book = $excel->Workbooks->Open("$book_file"); 
my $sheet = get_sheet($book, 'Sheet with Hyperlinks'); 
my $links = $sheet->Hyperlinks; 
my $it = Win32::OLE::Enum->new($links); 

while (defined(my $link = $it->Next)) { 
    my $address = $link->{Address}; 
    say $address; 
    if ($address =~ s/example/not.example/) { 
     $link->{Address} = $address; 
     $link->{TextToDisplay} = "Changed to $address"; 
    } 
} 

$book->Save; 
$book->Close; 
$excel->Quit; 

sub get_sheet { 
    my ($book, $wanted_sheet) = @_; 

    my $sheets = $book->Worksheets; 
    my $it = Win32::OLE::Enum->new($sheets); 

    while (defined(my $sheet = $it->Next)) { 
     my $name = $sheet->{Name}; 
     say $name; 
     if ($name eq $wanted_sheet) { 
      return $sheet; 
     } 
    } 

    croak "Could not find '$wanted_sheet'"; 
} 

工作簿確實含有與名稱"Sheet with Hyperlinks"的片材。該表中的單元A1包含http://example.comA2包含http://stackoverflow.com

相關問題