使用Word.Interop创建嵌套字段

时间:2013-05-27 13:33:34

标签: c# ms-word ms-office vsto

我正在使用VSTO,更准确地说是使用C#和“Microsoft Word”应用程序插件。我想要以编程方式创建嵌套字段。我想出了以下源代码(用于测试目的):

public partial class ThisAddIn
{
    private void ThisAddIn_Startup(object sender, EventArgs e)
    {
        // TODO This is just a test.
        this.AddDocPropertyFieldWithinInsertTextField("Author", ".\\\\FileName.docx");
    }

    private void AddDocPropertyFieldWithinInsertTextField(string propertyName, string filePath)
    {
        // TODO Horrible, since we rely on the UI state.
        this.Application.ActiveWindow.View.ShowFieldCodes = true;

        Word.Selection currentSelection = this.Application.ActiveWindow.Selection;

        // Add a new DocProperty field at the current selection.
        currentSelection.Fields.Add(
            Range: currentSelection.Range,
            Type: Word.WdFieldType.wdFieldDocProperty,
            Text: propertyName,
            PreserveFormatting: false
        );

        // TODO The following fails if a DocProperty with the specified name does not exist.

        // Select the previously inserted field.
        // TODO This is horrible!
        currentSelection.MoveLeft(
            Unit: Word.WdUnits.wdWord,
            Count: 1,
            Extend: Word.WdMovementType.wdExtend
        );

        // Create a new (empty) field AROUND the DocProperty field.
        // After that, the DocProperty field is nested INSIDE the empty field.
        // TODO Horrible again!
        currentSelection.Fields.Add(
            currentSelection.Range,
            Word.WdFieldType.wdFieldEmpty,
            PreserveFormatting: false
        );

        // Insert text BEFORE the inner field.
        // TODO Horror continues.
        currentSelection.InsertAfter("INCLUDETEXT \"");

        // Move the selection AFTER the inner field.
        // TODO See above.
        currentSelection.MoveRight(
            Unit: Word.WdUnits.wdWord,
            Count: 1,
            Extend: Word.WdMovementType.wdExtend
        );

        // Insert text AFTER the nested field.
        // TODO See above.
        currentSelection.InsertAfter("\\\\" + filePath + "\"");

        // TODO See above.
        this.Application.ActiveWindow.View.ShowFieldCodes = false;

        // Update the fields.
        currentSelection.Fields.Update();
    }

虽然提供的代码涵盖了这些要求,但它有一些主要问题(正如您可以看到的,如果阅读一些代码注释),例如:

  1. 它不健壮,因为它依赖于应用程序的UI状态。
  2. 是冗长的。任务并不复杂,imo。
  3. 这不容易理解(重构可能有所帮助,但通过解决问题1.和2.,这个缺点应该消失)。
  4. 我对WWW进行了一些研究,但还未能找到一个干净的解决方案。

    所以,我的问题是:

    • 有人可以提供(替代)C#源代码,比我更强健壮,并允许我将嵌套字段添加到“Microsoft Word”文档中吗?

1 个答案:

答案 0 :(得分:1)

我创建了一个通用实现来使用VSTO for Microsoft Word创建非嵌套和嵌套字段。您可以在this Gist中查看相关的源代码。我已经将文章Nested Fields in VBA中的VBA源代码移植到C#并应用了一些改进。

仍然不完美(需要一些额外的错误处理),但远远优于具有Selection对象的解决方案,后者依赖于用户界面的状态!