【问题标题】:Printing a range of pages in MS Word using OLE (Imprimir em ole object (word application) com delphi)使用 OLE (Imprimir em ole object (word application) com delphi) 在 MS Word 中打印一系列页面
【发布时间】:2014-06-24 18:20:04
【问题描述】:

我正在尝试从我的 Ole Object 对象打印一系列页面,但它对我不起作用 - 执行对 Doc.PrintOut 的调用时出现“类型不匹配”异常。

谁能帮我避免这个错误?以下是测试中使用的代码:

  if (OpenDialog1.Execute) then
    begin
        // Cria objeto principal de controle do Word
        WinWord := CreateOleObject('Word.Application');
        if (not (VarIsEmpty(WinWord))) then
           begin
              // Mostra o Word
              try
                  WinWord.Visible := false;
                  Docs := WinWord.Documents;
                  // Abre um documento
                  Doc := Docs.Open(OpenDialog1.FileName);
                  //Doc.PrintOut(false, Range, 1, 2);
                  //Doc.PrintOut(Copies := 2);
                  vFrom := 1;
                  vTo := 2;
                  Doc.PrintOut(Background := false, Append := false, Range :=       wdPrintFromTo, OutputFileName := EmptyParam, From := vFrom, To := vTo);
                  // erro recebido: tipo não correspondente
              finally
                  // Fecha o Word
                  WinWord.Quit;
           end;
    end;

    showmessage('Fim!');
end;

【问题讨论】:

  • 对不起,这是一个英语网站。这里说葡萄牙语的人不多。 (Sinto muito, este é um site de língua Inglês。Não há muitas pessoas aqui que falam Português。)
  • 试试葡萄牙语 SO:pt.stackoverflow.com
  • @user3772322:我认为只有英语读者可能需要知道的是“tipo não通讯员”是什么意思。谷歌翻译将其呈现为“无对应类型”。你觉得这对吗?
  • 即使修复它也值得投反对票,因为没有问题描述。只是“它不起作用”。
  • @MartynA 它被隐藏起来而不是英文。这是一个糟糕的问题。你能回答真是太好了。我赞成。但这不是一个好问题。我们不希望对糟糕的问题进行投票。它给了他们虚假的突出地位。可惜点赞不好。

标签: delphi


【解决方案1】:

我在 D7 中尝试了您的代码,使用的是 Office2007 的英文版。

我在 Doc.PrintOut 上收到异常错误,这是 Delphi 通常的“类型不匹配”。通过试验传递给 Doc.PrintOut 的参数,我认为是

Range := wdPrintFromTo

这导致了异常,因为“范围”通常是一个文本块,而 wdPrintFromTo 是一个数字常量(但是,我在下面提到的 Word 宏使用数字常量作为范围,所以 Word 可能只是不'不喜欢你用的那个)。

然后,我让 Word 录制一个宏来打印 6 页文档的前两页,并发现我可以通过进行这些更改来让您的代码正常工作:

  • 将我认为是 OleVariants 的 vFrom 和 vTo 替换为两个整数 iFrom 和 iTo(我认为这并不重要,只是更容易检查页面范围参数是否正确构造。

  • 将代码从 "vFrom := [...] 替换为 Doc.PrintOut by

    iFrom := 1;
    iTo := 2;
    
    Doc.PrintOut(
      Range := wdPrintRangeOfPages,
      Item := wdPrintDocumentContent,
      Copies := 1,
      Pages := IntToStr(iFrom) + '-' + IntToStr(iTo),
      PageType := wdPrintAllPages,
      ManualDuplexPrint := False,
      Collate := True,
      Background := True,
      PrintToFile := False,
      PrintZoomColumn := 0,
      PrintZoomRow := 0,
      PrintZoomPaperWidth := 0,
      PrintZoomPaperHeight := 0
    );
    

显然,此 PrintOut 包含的参数是 Word 宏包含的参数。通常其中一些可能是多余的。

【讨论】:

  • @TLama:感谢您的关注。我并没有试图通过我之后立即进行的编辑来回滚你的编辑,只是你的提示让我注意到了几个错别字。
  • 我完全不知道这种类型的参数传递。原来这是一个 OLE 功能stackoverflow.com/questions/885942/…
  • @Jan Doggen:是的,自从 D2 中的 Delphi 添加自动化支持以来,这种情况就一直存在。 Anders Hejlsberg 在 Compuserve 发布后的一两个星期出现在 Borland 的 Compuserve 区域,在他们最初探索自动化 OLE 对象的过程中牵着用户的手,并解释说他必须添加到编译器中的一个特性是支持这个参数传递的风格。我想 Borland 认为他们希望吸引的 VBer 会期待它并抱怨如果 Delphi 不支持它。
【解决方案2】:

谢谢大家! MartynA、Jan Doggen、David Heffernan、Mason Wheeler 和所有其他人!!

我通过以下代码得到解决方案:

<pre><code>
procedure TForm1.Button1Click(Sender: TObject);
var
  WinWord, Docs, Doc: Variant;
  vNomeImpressoraPadraoOriginal : string;
  vFrom, vTo : integer;
begin
  if (OpenDialog1.Execute) then
  begin
    try
      // Cria objeto principal de controle do Word
      WinWord := CreateOleObject('Word.Application');
      if (not (VarIsEmpty(WinWord))) then
      begin
        // Mostra o Word
        try
          WinWord.Visible := false;
          Docs := WinWord.Documents;
          // Abre um documento
          Doc := Docs.Open(OpenDialog1.FileName);
          vFrom := 1;
          vTo := 2;
          // referência do comando: http://support.microsoft.com/kb/176069/EN-US
          Doc.PrintOut(0, 0, '3', '', '1', '2');
          // previous code
          // Doc.PrintOut(Background := false, Append := false, Range :=       wdPrintFromTo, OutputFileName := EmptyParam, From := vFrom, To := vTo);
        finally
          // Fecha o Word
          WinWord.ActiveDocument.Close(SaveChanges := 0);
          WinWord.Quit;

          WinWord := Unassigned;
          Docs := Unassigned;
          Doc := Unassigned;
        end;
      end;

      showmessage('Fim!');
    finally

    end;
  end;
end;
</code></pre>

【讨论】:

  • 有趣的是,有多少种不同的方法可以让 MS Word 做同样的事情——而且您显然已经找到了另一种方法。真高兴你做到了。无论如何,如果您愿意,请随时“接受”我的回答,点击左侧的接受按钮。如果您以前没有遇到过这种情况,可以稍微提高我们在 Stack Overflow 上的“声誉”,这对我们双方都有好处 - 随着您的声誉增加,您可以做更多的事情 - 首先是能够在其他人的问题和答案上发布 cmets。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多