[英]How to get the previous paragraph's style in VSTO word 2010 using c# word addin?
[英]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.