【问题标题】:How can I copy and paste a range of tables in Word?如何在 Word 中复制和粘贴一系列表格?
【发布时间】:2010-11-28 14:34:33
【问题描述】:

编辑:如果您有 VBA 中的示例,我会接受。我只是想了解如何将 Range 对象与 Tables 集合一起使用来复制和粘贴多个表而不循环。换句话说,如何使用 Tables 集合指定 1..lastTable 的范围?如果我能看到一个有效的 VBA 示例,我将处理 VBA --> Perl 转换。

我正在尝试使用 Perl 的 Win32::OLE 模块(通过 Dave Roth 的优秀书籍)来自动化我需要在一些 Word 文档上重复执行的几个任务。但是,本书(以及大多数 Web 示例)倾向于使用 Excel 作为示例,因此我不确定如何使用 Tables 集合对象有效地复制和粘贴。

这是我的代码的 sn-p:

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();

原始代码使用的是段落,而不是表格,所以我假设一些错误是该代码的伪影(或者更可能是我不理解该代码)。

【问题讨论】:

  • 我的建议是尝试在录制宏的同时手动执行任务,然后查看生成的 VBA 子程序。您应该能够轻松地将其概括并转换为 Perlish。
  • 使用这个方法只是向我展示了如何使用 Selection 来获取一个表,而如果我尝试选择多个表,则编写宏来获取它们之间的文本,这不是我的追赶。

标签: perl ms-word range copy-paste win32ole


【解决方案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;
}

【讨论】:

  • 太棒了!不过有一个问题.. 有没有办法从集合对象中选择一系列对象?比如说,所有表格对象,一次操作中没有任何其他文本?我只是在问这是否可能——我的印象是不可能,或者至少它不像我认为的那样工作。
  • @romandas 我不这么认为。 Tables 集合没有 Range 方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
相关资源
最近更新 更多