Получение списка гиперссылок из листа Excel с Perl Win32::OLE

Я хочу изменить путь для набора гиперссылок в электронной таблице Excel. После поиска в Google я натолкнулся на решение проблемы добавления гиперссылок в электронные таблицы, но не их изменения. Microsoft показала, как что-то сблизить с VBA здесь.

Поскольку я хочу редактировать каждую гиперссылку в своем документе, ключевые шаги, которые я не знаю, как решить:

  1. Получить список объектов гиперссылок в Perl

  2. Извлеките их адреса 1 на 1 и

  3. Запустите регулярное выражение, чтобы изменить путь

  4. Сохраните обновленный путь в объекте Hyperlink-> и повторите

Я новичок в использовании 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 () Не объект Win32::OLE::Enum в строке C:/Dwimperl/perl/vendor/lib/Win32/OLE/Lite.pm 167. Невозможно вызвать метод "Гиперссылки msgstr "без ссылки на пакет или объект в строке script.pl 14.

Он выбирает правильный лист, поэтому я не уверен, почему он жалуется на ссылку на объект. Я пробовал несколько вариантов (добавление {} вокруг гиперссылок, удаление "в", попытка сохранить его как список, как хеш и как ссылку на хеш) Может кто-нибудь дать мне несколько указателей? Спасибо!

1 ответ

Решение

Во-первых, вы должны установить $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.com а также A2 содержащиеся http://stackru.com,

Другие вопросы по тегам