VSTO C# Word 插件,我不知道如何获得通配符查找和替换以不替换表格之外的文本

问题描述 投票:0回答:1

我试图忽略表格外部的文本,不对其进行注释或替换,并且仅在表格内部查找和替换。正确的行为应该是将单词 [Pp]ounds 替换为 lbs。如果它在表中并对其进行注释,如果 [Pp]ounds 在表之外,则不应对其进行注释或替换。

这是在我单击将运行我的函数的按钮之前文档的状态。

这是之后的状态。它正确地更改了 Pounds 的第一个实例并对其进行了注释,然后第二个单词 Pounds 被更改(错误地),但它正确地省略了注释。然后错误地,它甚至没有到达单词 Pounds 的第三个实例,它应该将其替换为 lbs。并评论了它。

wordRangeFindReplace.Find.Execute(MatchWildcards: true, Replace: WdReplace.wdReplaceOne);//Just set the argument MatchWildcards here!! like you wrote in this line : wordRange.Find.Execute(FindText: wildCardText, MatchCase: false, MatchWildcards: true);
            while (wordRangeFindReplace.Find.Found && (bool)wordRangeFindReplace.get_Information(Word.WdInformation.wdWithInTable))

我认为 Word.WdInformation.wdWithInTable 可以做到。 我认为 Find.Execute 方法在 wdWithInTable 可以检查它是否在表中之前对其进行更改,现在我也不知道为什么它没有移动到第二个表以及单词 Pounds 的第三个或第四个实例。

我无法在调试器中判断磅更改为磅的确切时刻。 我也试过了

for (int i = 1; i <= numberOfTables; i++)
            {
                if (wordRangeFindReplace.Start >= document.Tables[i].Range.Start)
                {*/ 

我得到了类似的结果。

这是完整的代码。 这是在单击事件处理程序中调用 get 的代码。

Rule pounds = new Rule("Pounds", "Pounds shouldn't be spelled out", RuleType.WildCardFindAndReplaceInTable);

pounds.WildCardFindAndReplaceInTable("[Pp]ounds", "lbs.", "Abbreviate units of weight in tables (for example, lbs. and oz.). (Rule 49)");

这是方法 WildCardFindAndReplaceInTable

public void WildCardFindAndReplaceInTable(string textToFind, string replacementText, string commentMessage)
    {
        Microsoft.Office.Interop.Word.UndoRecord ur = Globals.ThisAddIn.Application.UndoRecord;
        ur.StartCustomRecord("FindReplaceAndCommentWithWildCards");

        Microsoft.Office.Interop.Word.Range wordRangeFindReplace = null;
        Word.Document document = Globals.ThisAddIn.Application.ActiveDocument;
        wordRangeFindReplace = document.Content;
        wordRangeFindReplace.Find.ClearFormatting();
        wordRangeFindReplace.Find.ClearAllFuzzyOptions();
        wordRangeFindReplace.Find.Replacement.ClearFormatting();
        wordRangeFindReplace.Find.IgnoreSpace = true;
        wordRangeFindReplace.Find.MatchCase = false;
        wordRangeFindReplace.Find.MatchWildcards = true;
        wordRangeFindReplace.Find.Text = textToFind;

        wordRangeFindReplace.Find.Replacement.Text = replacementText;
        wordRangeFindReplace.Find.Forward = true;
        wordRangeFindReplace.Find.Wrap = WdFindWrap.wdFindStop;

        //don't forget the Replace argument
        wordRangeFindReplace.Find.Execute(MatchWildcards: true, Replace: WdReplace.wdReplaceOne);//Just set the argument MatchWildcards here!! like you wrote in this line : wordRange.Find.Execute(FindText: wildCardText, MatchCase: false, MatchWildcards: true);
        while (wordRangeFindReplace.Find.Found && (bool)wordRangeFindReplace.get_Information(Word.WdInformation.wdWithInTable))
        {
            object commentText = "[REPLACED] " + commentMessage + " -CME";
            Word.Range rng = Globals.ThisAddIn.Application.ActiveDocument.Range(wordRangeFindReplace.Start, wordRangeFindReplace.End);
            //rng.Text = replacementText;//This is wrong!! refer to above
            document.Comments.Add(rng, ref commentText);
            wordRangeFindReplace.Find.ClearFormatting();

            // Next Find
            //don't forget to reset the range wordRange
            wordRangeFindReplace.SetRange(wordRangeFindReplace.End, wordRangeFindReplace.Document.Content.End);

            //wordRange.Find.Execute(FindText: wildCardText, MatchCase: false, MatchWildcards: true);
            wordRangeFindReplace.Find.Execute(MatchWildcards: true, Replace: WdReplace.wdReplaceOne);
        }

        ur.EndCustomRecord();

    }

我只是不知道这里发生了什么,以及我做错了什么。 感谢任何帮助,谢谢!

c# ms-word vsto add-in
1个回答
0
投票

您的一条评论 (

//rng.Text = replacementText;//This is wrong!! refer to above
) 表明您可能之前就做了正确的事情。主要问题是当您这样做时

wordRangeFindReplace.Find.Execute(MatchWildcards: true, Replace: WdReplace.wdReplaceOne);

Word 将立即进行替换,即在您实际检查找到的文本是否在表格中之前。

因此您需要更改两个 .Execute 语句,这样它就可以执行以下操作:

wordRangeFindReplace.Find.Execute(MatchWildcards: true, Replace: WdReplace.wdReplaceNone);

(或者我认为你可以完全省略第二个参数)

那么当你在表格中找到文本时,你需要进行替换。但是,就目前情况而言,如果找不到文本或文本不在表中,循环就会终止。因此,如果您在任何表格之前都有一个“查找”文本实例,您的代码将不会再查找。

所以在我看来,你需要更多类似这样的东西。 [我现在实际上正在使用 VBA 翻译,因此可能 C# 语法错误。另外,这意味着我还没有实际测试过.信息测试。]

    while (wordRangeFindReplace.Find.Found)
    { 
        if ((bool)wordRangeFindReplace.get_Information(Word.WdInformation.wdWithInTable))
        {
            // actually do the replacement
            wordRangeFindReplace.Text = replacementText;
            object commentText = "[REPLACED] " + commentMessage + " -CME";
            you don't need to work so hard to create the comment!
            wordRangeFindReplace.Comments.Add(wordRangeFindReplace, ref commentText);            
        }
        // then set up the next Find regarless of whether you were in a table or not.
        wordRangeFindReplace.Find.ClearFormatting();

        // Next Find
        //don't forget to reset the range wordRange
        wordRangeFindReplace.SetRange(wordRangeFindReplace.End, wordRangeFindReplace.Document.Content.End);

        wordRangeFindReplace.Find.Execute(MatchWildcards: true, Replace: WdReplace.wdReplaceNone);
    }

从那里开始,我建议您从头开始重新考虑循环逻辑,因为它可能会简化它,并且如果您不执行“查找与替换”,则不需要其他几行

© www.soinside.com 2019 - 2024. All rights reserved.