0

我想更改 Excel 电子表格中一堆超链接的路径。在谷歌搜索后,我发现了一个解决方案,可以解决在电子表格中添加超链接但不更改它们的问题。Microsoft在这里展示了如何使用 VBA 完成一些事情。

由于我想编辑文档中的每个超链接,我不知道如何解决的关键步骤是:

  1. 获取 Perl 中的超链接对象列表

  2. 提取他们的地址 1 by 1 和

  3. 运行正则表达式以更改路径

  4. 将更新后的路径存储在 Hyperlink->object 中并重复

我是使用 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() 不是 C:/Dwimperl/perl/vendor/lib/Win32/OLE/Lite.pm 第 167 行的 Win32::OLE::Enum 对象。无法调用方法“超链接” " 在 script.pl 第 14 行没有包或对象引用。

它正在选择正确的工作表,所以我不确定它为什么抱怨对象引用。我尝试了几种变体(在超链接周围添加 {},删除“in”,尝试将其存储为列表、散列和对散列的引用)谁能给我一些指示?谢谢!

4

1 回答 1

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

于 2012-05-25T17:44:51.800 回答