2012-05-25 90 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

相关问题