自动化 Word - 另存为(SaveAs)

3
我尝试编写一个简单的MFC-Word自动化程序,每1分钟保存一次。我参考了这篇文章:http://www.codeproject.com/KB/office/MSOfficeAuto.aspx 以下是我正在尝试实现的内容。由于我对COM不熟悉,所以可能存在问题:我的VBA是由Word 2010生成的。
ActiveDocument.SaveAs2 FileName:="1.docx", FileFormat:=wdFormatXMLDocument _
    , LockComments:=False, Password:="", AddToRecentFiles:=True, _
    WritePassword:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, _
     SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:= _
    False, CompatibilityMode:=14

以下是我编写的实现 VBA 代码:

{
    COleVariant varName(L"b.docx");
    COleVariant varFormat(L"wdFormatXMLDocument");
    COleVariant varLockCmt((BYTE)0);
    COleVariant varPass(L"");
    COleVariant varReadOnly((BYTE)0);
    COleVariant varEmbedFont((BYTE)0);
    COleVariant varSaveNativePicFormat((BYTE)0);
    COleVariant varForms((BYTE)0);
    COleVariant varAOCE((BYTE)0);
    VARIANT x;
    x.vt = VT_I4;
    x.lVal = 14;
    COleVariant varCompability(&x);;

    VARIANT result;
    VariantInit(&result);
    _hr=OLEMethod(  DISPATCH_METHOD, &result, pDocApp, L"SaveAs2",10,
                    varName.Detach(),varFormat.Detach(),varLockCmt.Detach(),varPass.Detach(),varReadOnly.Detach(),
                    varEmbedFont.Detach(),varSaveNativePicFormat.Detach(),varForms.Detach(),varAOCE.Detach(),varCompability.Detach()
                 );
}

我没有从这个代码中得到任何错误信息,但它并没有起作用。
3个回答

2

VBA语法使用命名参数,参数的顺序和数量不重要。但是,在从C++调用时,您需要按正确顺序传递所需数量的参数。

SaveAs2被定义为:

void SaveAs2(
    ref Object FileName,
    ref Object FileFormat,
    ref Object LockComments,
    ref Object Password,
    ref Object AddToRecentFiles,
    ref Object WritePassword,
    ref Object ReadOnlyRecommended,
    ref Object EmbedTrueTypeFonts,
    ref Object SaveNativePictureFormat,
    ref Object SaveFormsData,
    ref Object SaveAsAOCELetter,
    ref Object Encoding,
    ref Object InsertLineBreaks,
    ref Object AllowSubstitutions,
    ref Object LineEnding,
    ref Object AddBiDiMarks,
    ref Object CompatibilityMode
)

因此,它有17个参数,这意味着如果您要传递CompatibilityMode,则应指定它们全部,如您的示例中指定的第10个参数(对应于SaveFormsData)。

如果您不需要所有参数或仅用于测试,则可以尝试更简单的代码:

_hr = OLEMethod(DISPATCH_METHOD, &result, pDocApp, L"SaveAs2", 2, varName.Detach(), varFormat.Detach());

如果您需要其余的参数,您需要传递所有参数,直到您需要设置的参数。在这种情况下,您可以传递。
COleVariant vtOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

对于您不想设置的参数。

编辑 - 测试代码

这对我有效:

    CoInitialize(NULL);

    CLSID clsid;
    IDispatch *pWApp;
    HRESULT hr = CLSIDFromProgID(L"Word.Application", &clsid);
    hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)&pWApp);

    hr = OLEMethod(DISPATCH_PROPERTYPUT, NULL, pWApp, L"Visible", 1, COleVariant((long)1));

    VARIANT result;
    VariantInit(&result);
    hr = OLEMethod(DISPATCH_PROPERTYGET, &result, pWApp, L"Documents", 0);
    IDispatch *pDocs = result.pdispVal;

    VARIANT result2;
    VariantInit(&result2);
    hr = OLEMethod(DISPATCH_METHOD, &result2, pDocs, L"Open", 1, COleVariant(L"D:\\Archive\\t1.docx"));
    IDispatch *pDoc = result2.pdispVal;

    VARIANT result3;
    VariantInit(&result3);
    hr = OLEMethod(DISPATCH_METHOD, &result3, pDoc, L"SaveAs2", 1, COleVariant(L"D:\\Archive\\t2.docx"));

    CoUninitialize();

它不起作用,最重要的是“SaveAs2”或“SaveAs”返回未知名称。 - Dzung Nguyen
这意味着您正在发送错误的接口。您确定pDocApp是一个文档吗?我将使用测试代码更新我的答案。 - Recep
我发现如果有多个参数,我必须反转发送到OLEMethod的参数顺序。例如:我将我的Word docx保存为pdf并使用以下OleMethod调用:hr = OleMethod(DISPATCH_METHOD,&result3,pDocs,L“SaveAs2”,2,varFormat,varName);其中varFormat被定义为VT_I4,lVal = 17,varName被定义为VT_BSTR,表示我的完整路径pdf文件名。varName.bstrVal = :: SysAllocString(L“c:\ filename.docx”); - Ken_sf

0

将您的变量varFormatwdFormatXMLDocument更改为整数12(可能与您对varCompability变量所做的操作类似)。另外,在"SaveAs2"之后的10是什么意思?


不是这样的 :) 。这很奇怪,他们没有提供任何关于我应该发送哪个L"name"的文档。 - Dzung Nguyen
你不需要发送任何L"name" - 只需发送整数即可。 - Todd Main

0

既然您开了悬赏,我就重新开始吧。

将变量varFormat从wdFormatXMLDocument更改为整数12(可能与您已经完成的varCompability变量类似)。wdFormatXMLDocumentWdSaveFormat的枚举,在Word 2003中引入。无需发送L"name" - 只需发送整数12

如果这些是先前保存的文档(即不是新文档),请先执行转换以使其达到正确的格式(例如ActiveDocument.Convert)。


你在引用哪个版本的Word?我知道你正在使用SaveAs2,但是它是被自动化的那个版本吗? - Todd Main

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接