0
votes

I really hope you can help me with this one. It's taken 2 days so far. I've tried to debug by following execution into the System.variants unit but can't see the solution.

I'm trying to get Delphi XE7 to open a .doc file in Word 2010 via OLE Automation.

I set up the 16 parameters ready for the Open() function that is given in the Word2010.pas file (derived from the MSWORD.OLB type library and supplied with Delphi XE7 under ..\OCX\Servers ) then invoke it and get an EVariantBadVarTypeError Exception with message: "Invalid variant type".

I've followed the specification for the parameters carefully (I think) and can't work out what's wrong.

The Word2010.pas has a line in the preamble: // SYS_KIND: SYS_WIN32 indicating (I think) that this unit is for 32-bit case, so I'm compiling under the 32-bit Win target.

Here's the code snippet:-

`...
uses
Word2010,
Vcl.OleServer,
System.Win.ComObj,
Winapi.OLE2,
System.variants,
Winapi.ActiveX
...

procedure TDocPDF.ExOpenDocument(sDocFile :string);
var
    WordApp : _ApplicationDisp;
    DocumentTemplate  : _DocumentDisp;
    DocsCollection    : DocumentsDisp;
    vTemplate : OleVariant;
    vVisible : OleVariant;
    vOpenFormat : OleVariant;
    vConfirmConversions,
    vReadOnly ,
    vAddToRecentFiles,
    vPasswordDocument,
    vPasswordTemplate,
    vRevert,
    vWritePasswordDocument,
    vWritePasswordTemplate ,
    vEncoding : OleVariant;
    vOpenAndRepair : OleVariant;
    vDocumentDirection : OleVariant;
    vNoEncodingDialogue : OleVariant;
    vXMLTransform : OleVariant;

begin
// load a copy of Word 2010:
CoInitialize(nil);
WordApp := (CoWordApplication.Create as _ApplicationDisp);
WordApp.Visible := bVisible;
DocsCollection := WordApp.Documents as DocumentsDisp;

// set up the parameters for the .Open command:
vTemplate := sDocFile ;
vVisible := False;
vConfirmConversions:=false;
vReadOnly :=False;
vAddToRecentFiles:=False;
vPasswordDocument:=EmptyParam;
vPasswordTemplate :=EmptyParam;
vRevert:=False;
vWritePasswordDocument:=EmptyParam;
vWritePasswordTemplate:=EmptyParam;
vOpenFormat:=wdOpenFormatAuto;
vEncoding:=EmptyParam;
vOpenAndRepair:=EmptyParam;
vNoEncodingDialogue:=EmptyParam;
vDocumentDirection:=EmptyParam;
vXMLTransform:=EmptyParam;

try
   DocumentTemplate := DocsCollection.Open(vTemplate,
      vConfirmConversions,
      vReadOnly,
      vAddToRecentFiles,
      vPasswordDocument,
      vPasswordTemplate,
      vRevert,
      vWritePasswordDocument,
      vWritePasswordTemplate,
      vOpenFormat,
      vEncoding,
      vVisible,
      vOpenAndRepair,
      vDocumentDirection,
      vNoEncodingDialogue,
      vXMLTransform) as _DocumentDisp;
except on e: exception do begin
   Application.MessageBox(PChar('Problem':'+E.message),                             PChar('ExOpenDocument'), MB_OK);
end;
end;

`

Thank you very much.

Steve

1
Why do you need any casts?David Heffernan
You mean such as ' as _ApplicationDisp' inSteveF
You mean such as .... " as _ApplicationDisp" in "WordApp := (CoWordApplication.Create as _ApplicationDisp); ". ? It won't compile unless you cast the result to match. Or do you mean something else? In general I'm trying to stick to the 'dispinterface' set of objects.SteveF
I never use casts when I code like thisDavid Heffernan
Interesting. How would you do it then?SteveF

1 Answers

0
votes

This seems to me to be more complex than it needs to be. I'd write it like this:

var
  App: WordApplication;
  Docs: Documents;
  Doc: WordDocument;
....
App := CoWordApplication.Create;
App.Visible := True;
Docs := App.Documents;
Doc := Docs.Open( 'C:\desktop\temp.docx', EmptyParam, EmptyParam, EmptyParam, 
  EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, 
  EmptyParam, EmptyParam);