繁体   English   中英

如何检测 Paragraph.Range 在 C# Word AddIn 中的 TOC 内

[英]How to detect that a Paragraph.Range is inside a TOC in a C# Word AddIn

我正在制作具有一些功能的MS-Word 插件 其中之一是删除过多的空行(当前规则规定文档不能有超过两个连续的空行,并且在最后一行文本之后不能有空行)。

我编写了一个代码来尝试实现这一目标:

private void formatText() {
    Microsoft.Office.Interop.Word.Paragraphs paragraphs = Globals.ThisAddIn.Application.ActiveDocument.Paragraphs;
    Boolean isPreviousLineEmpty = false;
    Boolean isLastLine = true;

    for (int i = paragraphs.Count - 1; i > 0; i--) {
        Microsoft.Office.Interop.Word.Paragraph paragraph = paragraphs[i];

        if (paragraph.Range.Text.Trim().Equals("")) {
            if (isLastLine) {
                paragraph.Range.Delete();
                continue;
            }

            if (isPreviousLineEmpty) {
                paragraph.Range.Delete(); //This is the line where the error happens
            }   

            isPreviousLineEmpty = true;
            continue;
        }

        if (isLastLine) {
            paragraph.Range.Text = paragraph.Range.Text.TrimEnd();
            isLastLine = false;
        }

        isPreviousLineEmpty = false;
    }
}

它一直有效,直到我在文档中添加了“目录”(TOC)。 现在我得到一个错误:

System.Runtime.InteropServices.COMException:“无法编辑范围。”

原因是:我的代码试图删除 TOC 上有一条白线,但它不能。 我已经搜索了文档/互联网,并尝试了所有我能想到的能够阻止我的代码在 TOC 行上运行的方法,但没有任何效果。

我需要一种方法来知道我可以跳过该行,因为我不需要删除 TOC 中的空白行。

目前,我能做的是用 Try/Catch 块包装执行删除的特定行,但我认为这不是最好的解决方案(因为我可能会忽略其他错误 go,这只是一个消音器)。

有谁知道这种情况的正确方法?


更新:

Freeflow评论之后,我用这个替换了我所有的方法代码:

private void formatText() {
    Microsoft.Office.Interop.Word.Find find = Globals.ThisAddIn.Application.ActiveDocument.Range().Find;
    Microsoft.Office.Interop.Word.Paragraphs paragraphs = Globals.ThisAddIn.Application.ActiveDocument.Paragraphs;
    Boolean operationResult = true;

    //Remove blank lines at the end of the document
    for (int i = paragraphs.Count - 1; i > 0; i--) {
        Microsoft.Office.Interop.Word.Paragraph paragraph = paragraphs[i];

        if (paragraph.Range.Text.Trim().Equals("")) {
            paragraph.Range.Delete();
            continue;
        }

        paragraph.Range.Text = paragraph.Range.Text.TrimEnd();

        break;
    }

    //Remove blank lines between paragraphs
    while (operationResult) {
        operationResult = find.Execute("^p^p^p", false, false, false, false, false, false, null, null, "^p^p",
            Microsoft.Office.Interop.Word.WdReplace.wdReplaceAll);
    }
}

到目前为止,它一直运行良好。 如果出现任何问题,我会在这里发布。

谢谢你的评论。 如果您将其转换为答案,我会将其标记为已接受的答案。

Word object model 有一个有用的方法: InRange ,它允许检查一个文本范围是否属于另一个文本范围。 因此,从逻辑上讲,可以比较段落的位置是否在 TOC 内。

下面是一个测试示例,最初写在 VBA 中。 我正在将其即时转换为 C#,因此可能存在一些小的语法错误...

public void TestRangeInToc()
{
    Word.Document doc =Globals.ThisAddIn.Application.ActiveDocument;
    bool HasToc = false;

    if(doc.TablesOfContents.Count > 0)
    {
        HasToc = true;
    }

    foreach(Word.Paragraph para In doc.Paragraphs)
    {
        if(HasToc)
        {
            if(IsRangeInTOC(para.Range, doc))
            {
               Debug.Print("in range");
               //skip this one
            }
        }
    }
}

public bool IsRangeInTOC(Word.Range rng, Word.Document doc)
{
    Word.TableOfContents toc         
    foreach(toc in doc.TablesOfContents)
    {
        if(rng.InRange(toc.Range))
        {
            return true;
            break;
        }
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM