3

質問は簡単だったのですが、余分な条項が追加されたことは、私にとって大きな頭痛の種であることが判明しました。ここでの問題は、強調表示されたすべての「単語」ではなく、Word ファイルの「フレーズ」が必要なことです。私は次のコードを書きました:

using Word = Microsoft.Office.Interop.Word;

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        Word.ApplicationClass wordObject = new Word.ApplicationClass();
        wordObject.Visible = false;
        object file = "D:\\mywordfile.docx";
        object nullobject = System.Reflection.Missing.Value;
        Word.Document thisDoc = wordObject.Documents.Open(ref file, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject);
        List<string> wordHighlights = new List<string>();

        //Let myRange be some Range which has my text under consideration

        int prevStart = 0;
        int prevEnd = 0;
        int thisStart = 0;
        int thisEnd = 0;
        string tempStr = "";
        foreach (Word.Range cellWordRange in myRange.Words)
        {
            if (cellWordRange.HighlightColorIndex.ToString() == "wdNoHighlight")
            {
                continue;
            }
            else
            {
                thisStart = cellWordRange.Start;
                thisEnd = cellWordRange.End;
                string cellWordText = cellWordRange.Text.Trim();
                if (cellWordText.Length >= 1)   // valid word length, non-whitespace
                {
                    if (thisStart == prevEnd)    // If this word is contiguously highlighted with previous highlighted word
                    {
                        tempStr = String.Concat(tempStr, " "+cellWordText);  // Concatenate with previous contiguously highlighted word
                    }
                    else
                    {
                        if (tempStr.Length > 0)    // If some string has been concatenated in previous iterations
                        {
                            wordHighlights.Add(tempStr);
                        }
                        tempStr = "";
                        tempStr = cellWordText;
                    }
                }
                prevStart = thisStart;
                prevEnd = thisEnd;
            }
        }

        foreach (string highlightedString in wordHighlights)
        {
            MessageBox.Show(highlightedString);
        }
    }
    catch (Exception j)
    {
        MessageBox.Show(j.Message);
    }
}

ここで、次のテキストを検討してください。

Le thé vert a un rôle dans la diminution du cholestérol, la 燃焼 des graisses, la prévention du diabète et les AVC, et conjurer la démence.

ここで、誰かが " du cholestérol " を強調表示したとします。私のコードは明らかに " du " と " cholestérol " という 2 つの単語を選択します。連続的に強調表示された領域を 1 つの単語として表示するにはどうすればよいですか? つまり、" du cholestérol " は の 1 つのエンティティとして返される必要がありListます。ドキュメントを文字ごとにスキャンし、強調表示の開始点を選択の開始点としてマークし、強調表示の終点を選択の終点としてマークするロジックはありますか?

PS: 他の言語で必要な機能を備えたライブラリがある場合は、シナリオが言語固有ではないため、お知らせください。どういうわけか望ましい結果を得るだけです。

編集: Oliver Hanappi の提案に従ってコードを修正しましたStartEndしかし、空白だけで区切られた 2 つのハイライトされたフレーズがある場合、プログラムは両方のフレーズを 1 つと見なすという問題が依然としてあります。単にWordsスペースではなくを読み取るためです。周りに編集が必要かもしれif (thisStart == prevEnd)ませんか?

4

4 に答える 4

2

Find を使用すると、これをはるかに効率的に行うことができます。Find を使用すると、より迅速に検索され、一致する連続したテキストがすべて選択されます。ここのリファレンスを参照してください http://msdn.microsoft.com/en-us/library/office/bb258967%28v=office.12%29.aspx

強調表示されたテキストのすべての出現箇所を出力する VBA の例を次に示します。

Sub TestFind()

  Dim myRange As Range

  Set myRange = ActiveDocument.Content    '    search entire document

  With myRange.Find

    .Highlight = True

    Do While .Execute = True     '   loop while highlighted text is found

      Debug.Print myRange.Text   '   myRange is changed to contain the found text

    Loop

  End With

End Sub

これが理解を深めるのに役立つことを願っています。

于 2013-03-20T14:12:20.070 に答える
1

You can look at the Start and End properties of the ranges and check whether the end of the first range equals the start of the second.

As an alternative, you may move the range by one word (see WdUnits.wdWord) and then check if the moved start and end equals the start and end of the second word.

于 2013-03-20T13:29:31.633 に答える
0

grahamj42 の回答は問題ありません。C# に翻訳しました。ドキュメント全体で一致を見つけたい場合は、次を使用します。

Word.Range content = thisDoc.Content

ただし、使用する必要がある脚注などの単語を一致させたい場合は、これは mainStoryRange のみであることに注意してください。

Word.StoryRanges stories = null;
stories = thisDoc.StoryRanges;
Word.Range footnoteRange = stories[Word.WdStoryType.wdFootnotesStory]

私のコード:

Word.Find find = null;
Word.Range duplicate = null;
try
{
    duplicate = range.Duplicate;
    find = duplicate.Find;
    find.Highlight = 1;

    object str = "";
    object missing = System.Type.Missing;
    object objTrue = true;
    object replace = Word.WdReplace.wdReplaceNone;

    bool result = find.Execute(ref str, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref objTrue, ref str, ref replace, ref missing, ref missing, ref missing, ref missing);
    while (result)
    {
        // code to store range text
        // use duplicate.Text property
        result = find.Execute(ref str, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref objTrue, ref str, ref replace, ref missing, ref missing, ref missing, ref missing);
    }
}
finally
{
    if (find != null) Marshal.ReleaseComObject(find);
    if (duplicate != null) Marshal.ReleaseComObject(duplicate);
}
于 2013-04-04T14:06:20.100 に答える
-1

Oliver のロジックから始めましたが、問題ないように見えましたが、テストの結果、この方法では空白が考慮されていないことがわかりました。そのため、スペースだけで区切られた強調表示されたフレーズが区切られていませんでした。私は grahamj42 が提供する VB コード アプローチを使用し、それをクラス ライブラリとして追加し、C# Windows フォーム プロジェクトに参照を含めました。

私の C# Windows フォーム プロジェクト:

using Word = Microsoft.Office.Interop.Word;

次に、tryブロックを次のように変更しました。

Word.ApplicationClass wordObject = new Word.ApplicationClass();
wordObject.Visible = false;
object file = "D:\\mywordfile.docx";
object nullobject = System.Reflection.Missing.Value;
Word.Document thisDoc = wordObject.Documents.Open(ref file, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject, ref nullobject);

List<string> wordHighlights = new List<string>();


// Let myRange be some Range, which has been already selected programatically here


WordMacroClasses.Highlighting macroObj = new WordMacroClasses.Highlighting();
List<string> hiWords = macroObj.HighlightRange(myRange, myRange.End);
foreach (string hitext in hiWords)
{
    wordHighlights.Add(hitext);
}

そして、これは単純にとそのを受け入れてを返すRange.FindVB クラス ライブラリのコードです。RangeRange.LastList(Of String)

Public Class Highlighting
    Public Function HighlightRange(ByVal myRange As Microsoft.Office.Interop.Word.Range, ByVal rangeLimit As Integer) As List(Of String)

        Dim Highlights As New List(Of String)
        Dim i As Integer
        i = 0

        With myRange.Find
            .Highlight = True
            Do While .Execute = True     ' loop while highlighted text is found

                If (myRange.Start < rangeLimit) Then Highlights.Add(myRange.Text)

            Loop
        End With
        Return Highlights
    End Function
End Class
于 2013-03-22T10:44:26.483 に答える