当前位置:  开发笔记 > 编程语言 > 正文

VSTO 2007:如何确定范围的页面和段落编号?

如何解决《VSTO2007:如何确定范围的页面和段落编号?》经验,为你挑选了2个好方法。

我正在构建一个MS Word加载项,它必须从文档中收集所有评论气球并在列表中汇总它们.我的结果将是一个ReviewItem类列表,其中包含Comment本身,段落编号和注释文本所在的页码.

我的部分代码如下所示:

    private static List FindComments()
    {
        List result = new List();
        foreach (Comment c in WorkingDoc.Comments)
        {
            ReviewItem item = new ReviewItem()
            {
                Remark = c.Reference.Text,
                Paragraph = c.Scope. ???, // How to determine the paragraph number?
                Page = c.Scope. ??? // How to determine the page number?
            };
            result.Add(item);
        }
        return result;
   }

该类的Scope属性Comment指向注释所涉及的文档中的实际文本,并且是类型Microsoft.Office.Interop.Word.Range.我无法弄清楚如何确定该范围所在的页面和段落.

对于段落编号,我实际上是指段落的"编号列表"编号,例如"2.3"或"1.3.2".

有什么建议?谢谢!



1> Michael Rega..:

试试这个页码:

Page = c.Scope.Information(wdActiveEndPageNumber);

哪个应该给你一个页码的最终值.如果您想要开头的页面值,请先尝试:

Word.Range rng = c.Scope.Collapse(wdCollapseStart);
Page = rng.Information(wdActiveEndPageNumber);

Range.Information属性

WdInformation枚举

对于段落编号,请参阅以下内容:

c.Scope.Paragraphs; //Returns a paragraphs collection

我的猜测是采取上面返回的集合中的第一个段落对象,从该段落的末尾到文档的开头获取一个新的范围并获取此整数值:

[range].Paragraphs.Count; //Returns int

这应该给出注释范围开头的准确段落编号.

Range.Paragraphs

段目标成员



2> Roy..:

在Mike Regan的帮助下给了我答案(再次感谢Mike),我设法制定了一个我想在这里分享的解决方案.也许这也澄清了我的目标.在性能方面,这可能不是最快或最有效的解决方案.随意提出改进建议.

我的代码的结果是一个ReviewItem类列表,将在别处处理.不用多说了,这是代码:

/// 
/// Worker class that collects comments from a Word document and exports them as ReviewItems
/// 
internal class ReviewItemCollector
{
    /// 
    /// Working document
    /// 
    private Word.Document WorkingDoc = new Word.DocumentClass();

    /// 
    /// Extracts the review results from a Word document
    /// 
    /// Fully qualified path of the file to be evaluated
    /// 
    public ReviewResult GetReviewResults(string fileName)
    {
        Word.Application wordApp = null;
        List reviewItems = new List();

        object missing = System.Reflection.Missing.Value;

        try
        {
            // Fire up Word
            wordApp = new Word.ApplicationClass();

            // Some object variables because the Word API requires this
            object fileNameForWord = fileName;
            object readOnly = true;

            WorkingDoc = wordApp.Documents.Open(ref fileNameForWord,
                ref missing, ref readOnly,
                ref missing, ref missing, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing);

            // Gather all paragraphs that are chapter headers, sorted by their start position
            var headers = (from Word.Paragraph p in WorkingDoc.Paragraphs
                           where IsHeading(p)
                           select new Heading()
                           {
                               Text = GetHeading(p),
                               Start = p.Range.Start
                           }).ToList().OrderBy(h => h.Start);

            reviewItems.AddRange(FindComments(headers));

            // I will be doing similar things with Revisions in the document
        }
        catch (Exception x)
        {
            MessageBox.Show(x.ToString(), 
                "Error while collecting review items", 
                MessageBoxButtons.OK, 
                MessageBoxIcon.Error);
        }
        finally
        {
            if (wordApp != null)
            {
                object doNotSave = Word.WdSaveOptions.wdDoNotSaveChanges;
                wordApp.Quit(ref doNotSave, ref missing, ref missing);
            }
        }
        ReviewResult result = new ReviewResult();
        result.Items = reviewItems.OrderBy(i => i.Position);
        return result;
    }

    /// 
    /// Finds all comments in the document and converts them to review items
    /// 
    /// List of ReviewItems generated from comments
    private List FindComments(IOrderedEnumerable headers)
    {
        List result = new List();

        // Generate ReviewItems from the comments in the documents
        var reviewItems = from Word.Comment c in WorkingDoc.Comments
                          select new ReviewItem()
                          {
                              Position = c.Scope.Start,
                              Page = GetPageNumberOfRange(c.Scope),
                              Paragraph = GetHeaderForRange(headers, c.Scope),
                              Description = c.Range.Text,
                              ItemType = DetermineCommentType(c)
                          };

        return reviewItems.ToList();
    }

    /// 
    /// Brute force translation of comment type based on the contents...
    /// 
    /// 
    /// 
    private static string DetermineCommentType(Word.Comment c)
    {
        // This code is very specific to my solution, might be made more flexible/configurable
        // For now, this works :-)

        string text = c.Range.Text.ToLower();

        if (text.EndsWith("?"))
        {
            return "Vraag";
        }
        if (text.Contains("spelling") || text.Contains("spelfout"))
        {
            return "Spelling";
        }
        if (text.Contains("typfout") || text.Contains("typefout"))
        {
            return "Typefout";
        }
        if (text.ToLower().Contains("omissie"))
        {
            return "Omissie";
        }

        return "Opmerking";
    }

    /// 
    /// Determine the last header before the given range's start position. That would be the chapter the range is part of.
    /// 
    /// List of headings as identified in the document.
    /// The current range
    /// 
    private static string GetHeaderForRange(IEnumerable headings, Word.Range range)
    {
        var found = (from h in headings
                     where h.Start <= range.Start
                     select h).LastOrDefault();

        if (found != null)
        {
            return found.Text;
        }
        return "Unknown";
    }

    /// 
    /// Identifies whether a paragraph is a heading, based on its styling.
    /// Note: the documents we're reviewing are always in a certain format, we can assume that headers
    /// have a style named "Heading..." or "Kop..."
    /// 
    /// The paragraph to be evaluated.
    /// 
    private static bool IsHeading(Word.Paragraph paragraph)
    {
        Word.Style style = paragraph.get_Style() as Word.Style;
        return (style != null && style.NameLocal.StartsWith("Heading") || style.NameLocal.StartsWith("Kop"));
    }

    /// 
    /// Translates a paragraph into the form we want to see: preferably the chapter/paragraph number, otherwise the
    /// title itself will do.
    /// 
    /// The paragraph to be translated
    /// 
    private static string GetHeading(Word.Paragraph paragraph)
    {
        string heading = "";

        // Try to get the list number, otherwise just take the entire heading text
        heading = paragraph.Range.ListFormat.ListString;
        if (string.IsNullOrEmpty(heading))
        {
            heading = paragraph.Range.Text;
            heading = Regex.Replace(heading, "\\s+$", "");
        }
        return heading;
    }

    /// 
    /// Determines the pagenumber of a range.
    /// 
    /// The range to be located.
    /// 
    private static int GetPageNumberOfRange(Word.Range range)
    {
        return (int)range.get_Information(Word.WdInformation.wdActiveEndPageNumber);
    }
}

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有