【问题标题】:Word 2010 automation: 'goto bookmark'Word 2010 自动化:“转到书签”
【发布时间】:2011-05-06 15:34:18
【问题描述】:

我有一个用 Delphi-7 编写的程序,它可以打开一个基于模板的新 Word 文档。
打开文档后,自动跳转到书签(在模板中预定义)并在其中添加一些文本。
以下代码在 Word 2003 中运行良好,但在 Word 2010 中会导致 invalid variant operation 错误消息(为了清楚起见,我省略了 try/except 块)

wrdapp:= CreateOleObject ('Word.Application');
wrdDoc:= wrdapp.documents.add (wrdApp.Options.DefaultFilePath[wdUserTemplatesPath] + '1.dot'
wrdApp.selection.goto (wdGotoBookmark, unassigned, unassigned, 'B1')

如果我将第三行替换为

wrdDoc.bookmarks.item ('B1').select

该程序在 Word 2003 中运行良好,但在 Word 2010 中仍然崩溃。

Word 2010“转到”书签的正确代码是什么?

【问题讨论】:

  • 只是好奇,如果你在第一行和第二行之间等待 10 秒 (Sleep(10000);),你还会得到错误吗?
  • 难以置信但真实!让您的评论成为答案,因为睡眠是代码工作的原因。我将时间缩短到 5 秒,但这也奏效了。
  • 等一下...必须有比固定睡眠间隔更好的方法。当然,这种方法可能适用于几乎所有实例,但可能有一种方法可以保证在每个实例中都有效。人们会期望像wrdApp.WaitUntilReady...

标签: delphi automation ms-word delphi-7


【解决方案1】:

Word 2010 有一个与加载 Normal.dotm 相关的错误(也许还有插件,谁知道呢?)。当您像往常一样启动 Word 2010 时,您会看到一个初始屏幕,并且 Word 会执行一些初始化,包括加载 Normal.dotm。当您通过自动化启动 Word - CreateOleObject('Word.Application') - 它不会等到 Normal.dotm 加载并立即返回。但是在 Normal.dotm 仍在加载时执行操作似乎会使 Word 崩溃。我为解决这个问题所做的就是创建一个等待模板加载的循环。您也可以选择延迟以给 Word 初始化时间,但到目前为止,循环正常工作。

类似这样的:

wrdapp := CreateOleObject('Word.Application');

//loop that waits for the normal template to load
while wrdapp.Templates.Count = 0 do
  Sleep(200);

//continue operations

PS:我这里没有 Delphi,所以代码可能包含错误,但你明白了

【讨论】:

  • 嗯,“错误”是understatement...
  • 未循环的“睡眠”效果很好,尽管我认为我会使用循环,因为它可能会节省时间。我注意到在运行更正的程序时,在睡眠期间屏幕上弹出并关闭了一个小窗口,但它发生得如此之快,以至于我看不到窗口中写入的内容。可能与模板有关....
  • @No'am Newman:确实,窗口标题说的是“正在下载”
【解决方案2】:

我认为您应该将“GoTo_”调用中的常量替换为变量。像这样:

...
var 
  vWhat, vBookmark:OleVariant;
begin
  ...
  vWhat:=wdGoToBookmark;
  vBookmark:='B1';
  wrdApp.Selection.GoTo_(vWhat,emptyParam,emptyParam,vBookmark);
  ...
end;

【讨论】:

  • 使用变量给出了以下错误消息:“在书签 B1 上出错 - 模块 'Testword.exe' 中地址 00458BCB 的访问冲突。读取地址 00000000”。顺便说一句,我写的是“wrdApp.Selection.goto”而不是“wrdApp.selection.goto_”,因为后者会导致 Office 2003 出现错误“自动化对象不支持方法 goto_”。
【解决方案3】:

您好,希望对您有所帮助。我正在使用 D2010 和 Office 2010

我在做什么:如果我找到一个书签名称,我会在此处插入一个单词 Document

我的部分代码:


try
  Template    := EmptyParam;
  NewTemplate := true;
  ItemIndex   := 1;
  try
     Wdapplication.Connect;
  except
     Screen.Cursor := crDefault;
     MessageDlg('No se detecta Word Puede no estar instalado(1) o versi?n incorrecta de Word', mtError, [mbOK], 0);
     Abort;
     result := False;
  end;
  Wdapplication.Visible := true; // False;
  WdApplication.Caption := 'Kalemat automation';
  {Turn Spell checking of because it takes a long time if enabled and slows down Winword}
  WdApplication.Options.CheckSpellingAsYouType := false;
  WdApplication.Options.CheckGrammarAsYouType := false;
  lbInfo.Lines.Add('Word connected');
except
  on E: Exception do begin
     ShowMessage(E.Message);
     WdApplication.Disconnect;
     result := False;
     Exit;
  end;
end;

//-
if wdapplication.Documents.Count > 0 then begin
  Screen.Cursor         := crDefault;
  MessageDlg(
     'Por Favor cierre todos sus Word-documentos antes de proseguir...', mtWarning,
     [mbRetry], 0);
  wdApplication.Visible := true;
  WdApplication.Disconnect;
     result := False;
  exit;
end
else begin
  with WdApplication do begin
     //      OnQuit             := WordAppQuit;
     //      OnChangeDocument   := WordDocChange;
     //      OnOpenDocument     := WordDocOpen;
     //      OnPreCloseDocument := WordPreClose;
     //      OnCloseDocument    := WordDocClose;
     //      DisableSystemCloseBox;
  end
end;
{Create new document}
Template     := EmptyParam;
NewTemplate  := false;
oNewDocument := ModEsc;

// abre documento 
lbInfo.Lines.Add('Abriendo escritura '+ModEsc);

WdApplication.Documents.AddOld(oNewDocument, NewTemplate);
// Conecta con al instancia de Word
WdDocument.ConnectTo(WdApplication.Documents.Item(ItemIndex));
sBookMarkName := 'FPROEMIO';
lbInfo.Lines.Add('Busca marcador Proemio');
if WdDocument.Bookmarks.Exists(sBookMarkName) then begin
  //     ShowMessage(' -Existe: '+sBookMarkName);
  owhat := wdGotoBookMark;
  owhich := unAssigned;
  ocount := unAssigned;
  //-->>>      //     ShowMessage(' -Ve a..: '+sBookMarkName);
  //-->>>      //   Ve a ese marcados addendum

  wdDocument.GoTo_(oWhat, oWhich, OCount, sBookMarkName);

  //     ShowMessage(' GoTo_.. ya estoy en: '+sBookMarkName);
  //   Lo encontre
  oRange       := '';
  oConformConv := false;
  oLink        := false;
  oattachment  := false;
  fl_Name      := proemi;
  lbInfo.Lines.Add('Insertando Proemio '+Proemi);
  if not FileExists(fl_name) then begin
     Screen.Cursor := crDefault;
     lbInfo.Lines.Add('No Existe Documento PROEMIO ');
     MessageDlg('Documento FPROEMIO NO EXISTE, Revise el modelo de escritura', mtError, [mbRetry], 0);
  end
  else
    wdDocument.Bookmarks.Item(sBookMarkName).Range.InsertFile(Fl_Name, oRange, oConformConv, oLink, oattachment);
  //     ShowMessage(' -.. inserte el addendum');
end
else begin
  lbInfo.Lines.Add('No Existe Marcador PROEMIO ');
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多