0

Excel スプレッドシートで多数のハイパーリンクのパスを変更したいと考えています。Google で検索したところ、スプレッドシートにハイパーリンクを追加しても変更しないという問題の解決策を見つけました。Microsoft は、VBA に近いものを作成する方法を示しました

ドキュメント内のすべてのハイパーリンクを編集したいので、解決方法がわからない主な手順は次のとおりです。

  1. Perl でハイパーリンク オブジェクトのリストを取得する

  2. アドレスを 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 オブジェクトではありません。メソッド "Hyperlinks" を呼び出せません" 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 に答える