我试图忽略表格外部的文本,不对其进行注释或替换,并且仅在表格内部查找和替换。正确的行为应该是将单词 [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();
}
我只是不知道这里发生了什么,以及我做错了什么。 感谢任何帮助,谢谢!
您的一条评论 (
//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);
}
从那里开始,我建议您从头开始重新考虑循环逻辑,因为它可能会简化它,并且如果您不执行“查找与替换”,则不需要其他几行