Как скопировать и вставить диапазон таблиц в Word?

РЕДАКТИРОВАТЬ: Если у вас есть пример в VBA, я возьму его. Я просто пытаюсь понять, как использовать объект Range с коллекцией Tables для копирования и вставки нескольких таблиц без зацикливания. Иными словами, как я могу указать диапазон 1..lastTable, используя коллекцию Tables? Если я смогу увидеть работающий пример VBA, я буду работать над преобразованием VBA -> Perl.

Я пытаюсь использовать Perl-модуль Win32::OLE (через превосходный обзор Дэйва Рота). book) для автоматизации нескольких задач, которые мне нужно постоянно выполнять с некоторыми документами Word. Тем не менее, книга (и большинство веб-примеров), как правило, использует Excel для примеров, поэтому я не уверен, как эффективно копировать и вставлять объект коллекции Tables.

Вот фрагмент моего кода:

my $originalDoc = $MSWord->Documents->Open('C:\Perl\testDocument.doc');
my $newDoc = $MSWord->Documents->Add;
my $selection = $MSWord->Selection(); # this may be spurious

my $Count = int( $originalDoc->Tables()->{Count} );
my $range = $originalDoc->Tables()->Range( { Start => $originalDoc->Tables(1)->{Range}->{Start},
                                             End   => $originalDoc->Tables($Count)->{Range}->{End}
                                           } );
$range->Copy();
$newDoc->Range()->Paste();

В исходном коде использовались абзацы, а не таблицы, поэтому я предполагаю, что некоторые из ошибок являются артефактами этого кода (или, что более вероятно, моим непониманием этого кода).


person romandas    schedule 15.09.2009    source источник
comment
Я предлагаю попробовать выполнить задачу вручную во время записи макроса, а затем посмотреть на созданную подпрограмму VBA. Вы должны быть в состоянии обобщить это и перенести на Perlish без особых проблем.   -  person j_random_hacker    schedule 16.09.2009
comment
Использование этого метода просто показывает мне, как использовать Selection для получения одной таблицы, тогда как, если я попытаюсь выбрать несколько таблиц, макрос будет написан для захвата текста между ними, а это не то, что мне нужно.   -  person romandas    schedule 17.09.2009


Ответы (1)


Копирование и вставка таблиц по одной может предпочтительнее:

#!/usr/bin/perl

use strict;
use warnings;

use File::Spec::Functions qw( catfile );

use Win32::OLE;
use Win32::OLE::Const 'Microsoft Word';
$Win32::OLE::Warn = 3;

my $word = get_word();
$word->{Visible} = 1;

my $doc = $word->{Documents}->Open(catfile $ENV{TEMP}, 'test.doc');
my $newdoc = $word->Documents->Add;

my $n_tables = $doc->Tables->Count;

for my $table_i ( 1 .. $n_tables ) {

    my $table = $doc->Tables->Item($table_i);
    $table->Select;
    $word->Selection->Copy;

    my $end = $newdoc->GoTo(wdGoToLine, wdGoToLast);
    $end->InsertBefore("\n");
    $end = $newdoc->GoTo(wdGoToLine, wdGoToLast);
    $end->Select;

    $word->Selection->Paste;
}

$doc->Close(0);
$newdoc->SaveAs('test-output.doc');

sub get_word {
    my $word;
    eval {
        $word = Win32::OLE->GetActiveObject('Word.Application');
    };

    die "$@\n" if $@;

    unless(defined $word) {
        $word = Win32::OLE->new('Word.Application', sub { $_[0]->Quit })
            or die "Oops, cannot start Word: ",
                   Win32::OLE->LastError, "\n";
    }
    return $word;
}
person Sinan Ünür    schedule 20.09.2009
comment
Здорово! Однако один вопрос... нет ли способа выбрать диапазон объектов из объекта коллекции? Скажем, все табличные объекты без какого-либо другого текста за одну операцию? Я просто спрашиваю, возможно ли это — у меня создается впечатление, что это не так, или, по крайней мере, это не работает так, как я думаю. - person romandas; 20.09.2009
comment
@romandas Я так не думаю. В коллекции Tables нет метода Range. - person Sinan Ünür; 20.09.2009