Interop word find range

title description ms.date ms.topic dev_langs helpviewer_keywords author ms.author manager ms.technology ms.workload

Find and replace text in documents programmatically

Learn how you can use Visual Studio to programmatically search for and replace text in a Microsoft Word document.

02/02/2017

how-to

VB

CSharp

documents [Office development in Visual Studio], searching

text searches, replacing text

text searches, documents

text [Office development in Visual Studio], searching in documents

text [Office development in Visual Studio], text searches

John-Hart

johnhart

jmartens

office-development

office

How to: Programmatically search for and replace text in documents

[!INCLUDE Visual Studio]
The xref:Microsoft.Office.Interop.Word.Find object is a member of both the xref:Microsoft.Office.Interop.Word.Selection and the xref:Microsoft.Office.Interop.Word.Range objects, and you can use either one to search for text in Microsoft Office Word documents. The replace command is an extension of the find command.

Use a xref:Microsoft.Office.Interop.Word.Find object to loop through a Microsoft Office Word document and search for specific text, formatting, or style, and use the xref:Microsoft.Office.Interop.Word.Find.Replacement%2A property to replace any of the items found.

[!INCLUDEappliesto_wdalldocapp]

Use a Selection object

When you use a xref:Microsoft.Office.Interop.Word.Selection object to find text, any search criteria you specify are applied only against currently selected text. If the xref:Microsoft.Office.Interop.Word.Selection is an insertion point, then the document is searched. When the item is found that matches the search criteria, it is automatically selected.

It is important to note that the xref:Microsoft.Office.Interop.Word.Find criteria are cumulative, which means that criteria are added to previous search criteria. Clear formatting from previous searches by using the xref:Microsoft.Office.Interop.Word.Find.ClearFormatting%2A method prior to the search.

To find text using a Selection object

  1. Assign a search string to a variable.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet68″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet68″:::

  2. Clear formatting from previous searches.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet69″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet69″:::

  3. Execute the search and display a message box with the results.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet70″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet70″:::

    The following example shows the complete method.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet67″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet67″:::

Use a Range object

Using a xref:Microsoft.Office.Interop.Word.Range object enables you to search for text without displaying anything in the user interface. The xref:Microsoft.Office.Interop.Word.Find object returns True if text is found that matches the search criteria, and False if it does not. It also redefines the xref:Microsoft.Office.Interop.Word.Range object to match the search criteria if the text is found.

To find text using a Range object

  1. Define a xref:Microsoft.Office.Interop.Word.Range object that consists of the second paragraph in the document.

    The following code example can be used in a document-level customization.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet72″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet72″:::

    The following code example can be used in a VSTO Add-in. This example uses the active document.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationAddIn/ThisAddIn.cs» id=»Snippet72″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationAddIn/ThisAddIn.vb» id=»Snippet72″:::

  2. Using the xref:Microsoft.Office.Interop.Word.Range.Find%2A property of the xref:Microsoft.Office.Interop.Word.Range object, first clear any existing formatting options, and then search for the string find me.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet73″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet73″:::

  3. Display the results of the search in a message box, and select the xref:Microsoft.Office.Interop.Word.Range to make it visible.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet74″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet74″:::

    If the search fails, the second paragraph is selected; if it succeeds, the search criteria are displayed.

    The following example shows the complete code for a document-level customization. To use this example, run the code from the ThisDocument class in your project.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet71″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet71″:::

    The following example shows the complete code for a VSTO Add-in. To use this example, run the code from the ThisAddIn class in your project.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationAddIn/ThisAddIn.cs» id=»Snippet71″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationAddIn/ThisAddIn.vb» id=»Snippet71″:::

Search for and replace text in documents

The following code searches the current selection and replaces all of the occurrences of the string find me with the string Found.

To search for and replace text in documents

  1. Add the following example code to the ThisDocument or ThisAddIn class in your project.

    C#

    :::code language=»csharp» source=»../vsto/codesnippet/CSharp/Trin_VstcoreWordAutomationCS/ThisDocument.cs» id=»Snippet75″:::

    VB

    :::code language=»vb» source=»../vsto/codesnippet/VisualBasic/Trin_VstcoreWordAutomationVB/ThisDocument.vb» id=»Snippet75″:::

    The xref:Microsoft.Office.Interop.Word.Find class has a xref:Microsoft.Office.Interop.Word.Find.ClearFormatting%2A method, and the xref:Microsoft.Office.Interop.Word.Replacement class also has its own xref:Microsoft.Office.Interop.Word.Replacement.ClearFormatting%2A method. When you are performing find-and-replace operations, you must use the ClearFormatting method of both objects. If you use it only on the xref:Microsoft.Office.Interop.Word.Find object, you might get unanticipated results in the replacement text.

  2. Use the xref:Microsoft.Office.Interop.Word.Find.Execute%2A method of the xref:Microsoft.Office.Interop.Word.Find object to replace each found item. To specify which items to replace, use the Replace parameter. This parameter can be one of the following xref:Microsoft.Office.Interop.Word.WdReplace values:

    • xref:Microsoft.Office.Interop.Word.WdReplace.wdReplaceAll replaces all found items.

    • xref:Microsoft.Office.Interop.Word.WdReplace.wdReplaceNone replaces none of the found items.

    • xref:Microsoft.Office.Interop.Word.WdReplace.wdReplaceOne replaces the first found item.

See also

  • How to: Programmatically set search options in Word
  • How to: Programmatically loop through found items in documents
  • How to: Programmatically define and select ranges in documents
  • How to: Programmatically restore selections after searches
  • Optional parameters in Office solutions
  • Remove From My Forums
  • Question

  • I would like to clean up this word document.  the below code works.  but I would like to better understand Word Interop.  instead of finding each line and replace with «» to remove the bottom signature.   is there
    a way to delete lines starting with «Your Name» and ending with «youremail@server.com»  and everything in between?  I guess setting a range and delete?  and or
    deleting everything after a specific find.    any help is greatly appreciated. 

     Dim objWord As Word.Application = New Word.Application
            Dim objDoc As Document = objWord.Documents.Open(LoadDir & tbEMailIfContains.Text & eMailHitCount & ".rtf")
            objWord.Visible = False
    
            'This does Header!!!
            Do While objDoc.Content.Find.Execute(FindText:="Subject:", Wrap:=Word.WdFindWrap.wdFindContinue) = True
                objWord.Selection.Range.Bookmarks("line").Range.Delete()
            Loop
    
            'This Does Footer
            objDoc.Content.Find.Execute(FindText:="Your Name", ReplaceWith:="", Replace:=Word.WdReplace.wdReplaceAll)
            objDoc.Content.Find.Execute(FindText:="Your Title", ReplaceWith:="", Replace:=Word.WdReplace.wdReplaceAll)
            objDoc.Content.Find.Execute(FindText:="Your Company", ReplaceWith:="", Replace:=Word.WdReplace.wdReplaceAll)
            objDoc.Content.Find.Execute(FindText:="Your Address", ReplaceWith:="", Replace:=Word.WdReplace.wdReplaceAll)
            objDoc.Content.Find.Execute(FindText:="Your Work Number", ReplaceWith:="", Replace:=Word.WdReplace.wdReplaceAll)
            objDoc.Content.Find.Execute(FindText:="Your Cell Number", ReplaceWith:="", Replace:=Word.WdReplace.wdReplaceAll)
            objDoc.Content.Find.Execute(FindText:="youremail@server.com", ReplaceWith:="", Replace:=Word.WdReplace.wdReplaceAll)
    
    
            objWord.Documents.Close(Word.WdSaveOptions.wdSaveChanges)
            objWord.Quit()


    Work Smarter Not Harder

    • Edited by

      Tuesday, June 28, 2016 1:45 PM

Answers

  • Hi
    jimbrown.ws

    as you asked to find the text and then try to search in document. so I modify the code that I had mentioned above and make little changes in that now it can able to search the text and from that we can get line number and then we will try to delete the range.

    Sub Main()
    
            Dim objWord As Word.Application = New Word.Application
            Dim objDoc As Word.Document
            objDoc = objWord.Documents.Open("C:Usersv-padeeDesktopdem16.docx")
            objWord.Visible = True
    
            Dim rng, myRange, myRange1 As Word.Range
            Dim start, finish As Integer
            myRange = objDoc.Content
            myRange.Find.Execute("Your name:")
            myRange.Select()
    
            start = myRange.Information(Word.WdInformation.wdFirstCharacterLineNumber)
    
            myRange1 = objDoc.Content
            myRange1.Find.Execute("youremail@server.com")
            myRange1.Select()
    
            finish = myRange1.Information(Word.WdInformation.wdFirstCharacterLineNumber)
    
    
            Dim startLocation As Object = objDoc.Sentences(start).Start
            Dim endLocation As Object = objDoc.Sentences(finish).End
    
            ' Supply a Start and End value for the Range.
            rng = objDoc.Range(Start:=startLocation, End:=endLocation)
    
            ' Select the Range
            rng.Select()
            rng.Delete()
            objWord.Documents.Close(Word.WdSaveOptions.wdSaveChanges)
            objWord.Quit()
        End Sub

    Regards

    Deepak


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.

    Click
    HERE to participate the survey.

    • Marked as answer by
      jimbrown.net
      Thursday, June 30, 2016 7:00 PM

Задача: вывести данные в документ Word. На самом деле это очень большая и необъятная тема, примерно как сам Word, 90% возможностей которого не используются обычными пользователями. Сузим до более простой и чаще встречающейся на практике задачи, с которой в своей время пришлось столкнуться мне самому: надо вывести красивую справку, договор, отчет или иной документ Word с добавлением данных из кода C#. Само собой должны поддерживаться версии Word до 2007, так что о новых форматах файлов придется забыть.

Для начала вспомним, что в Word есть такая замечательная вещь как шаблоны. Соответственно большую часть сложного оформления можно вынести в них и из кода открывать шаблон и вставлять данные в нужные места. Для начала ограничимся простыми строками (типовая задача в крупных предприятиях — вставка дат, цифр, фио и тому подобных вещей, договор на сумму такую-то, от такой-то даты с фио таким-то с параметрами объекта такими-то).

Задача на текущую статью: открыть из кода C# шаблон Word и что-то в него вставить. Шаблон в формате .dot приготовим заранее, в том же самом ворде. Для связи с ним будем использовать механизм COM Interoperability (сокращенно Interop), то есть запускать отдельный exe-процесс самого Word и через специальный интерфейс управлять им. Интерфейсы слава богу есть и находятся они в специальных библиотеках, поставляемых вместе с Office, но документация по ним крайне невнятная, поведение местами очень странное и не логичное. В версиях Visual Studio 2010 и выше возможности программирования Office расширены, но текущее руководство действительно и для 2008 студии.

Нам надо

1. Подключить нужные библиотеки
2. Открыть шаблон Word
3. Найти в нем нужное место
4. Вставить в него строку с информацией

1. Проект в студии у нас уже должен быть. В разделе Ссылки/References кликаем правой кнопкой, идем в «Добавить ссылку» и ищем Microsoft.Office.Interop.Word. В параметрах добавленной библиотеки ставим true в Копировать локально/Copy local, так как библиотеку надо копировать вместе с исполняемыми файлами проекта.

В код добавляем соответствующие using

using Word = Microsoft.Office.Interop.Word;
using System.Reflection;

2. Теперь вам предстоит провести много времени с замечательным интерфейсом Word, который представляет сам текстовый редактор и его потроха в виде разнообразных обьектов. Сейчас важны два — Application и Document. Переменные для них по ряду не очевидных причин лучше объявлять через интерфейсы.

Word._Application application;
Word._Document document;

Так же почти все функции Word требуют объектных параметров, даже если внутри них сидят простые строки и логические значения, так что лучше заранее сделать несколько оберток

Object missingObj = System.Reflection.Missing.Value;
Object trueObj = true;
Object falseObj = false;

Чтобы запустить Word и открыть в нем шаблон с диска (путь известен), потребуется примерно такой код

//создаем обьект приложения word
application = new Word.Application();
// создаем путь к файлу 
Object templatePathObj = "путь к файлу шаблона";;

// если вылетим не этом этапе, приложение останется открытым
try
{
    document = application.Documents.Add(ref  templatePathObj, ref missingObj, ref missingObj, ref missingObj);
}
catch (Exception error)
{
    document.Close(ref falseObj, ref  missingObj, ref missingObj);
    application.Quit(ref missingObj, ref  missingObj, ref missingObj);
    document = null;
    application = null;
    throw error;
}
_application.Visible = true;

Принципиально важны два момента

1. Мы создаем неуправляемый ресурс, который не соберет сборщик мусора — отдельный процесс в памяти с приложением Word, если мы его не закроем и не выведем на экран, он так и останется там висеть до выключения компьютера. Более того такие ворды могут накапливаться незаметно для пользователя, программист-то еще прибьет их вручную. Заботиться о высвобождения неуправляемого ресурса должен программист.

2. По умолчанию Word запускается невидимым, на экран его выводим мы.

Для начала рассмотрим самый простой и примитивный вариант — поиск и замена строки в документе Word. Некоторые программисты так и работают — ставят в шаблон текстовую метку вроде @@nowDate и заменяют ее на нужное значение.

Пришло время познакомится с фундаментом работы с Word — великим и ужасным объектом Range. Его суть сложно описать словами -это некоторый произвольный кусок документа, диапазон (range), который может включать в себя все что угодно — от пары символов, до таблиц, закладок и прочих интересных вещей. Не стоит путать его с Selection — куском документа, выделенным мышкой, который само собой можно конвертировать в Range. Соотвественно нам надо получить Range для всего документа, найти нужную строку внутри него, получить Range для этой строки и уже внутри этого последнего диапазона заменить текст на требуемый. И не стоит забывать, что документ может иметь сложную структуру с колонтитулами и прочей ересью, возможный универсальный метод для замены всех вхождений данной строки:

// обьектные строки для Word
object strToFindObj = strToFind;
object replaceStrObj = replaceStr;
// диапазон документа Word
Word.Range wordRange;
//тип поиска и замены
object replaceTypeObj;
replaceTypeObj = Word.WdReplace.wdReplaceAll; 
// обходим все разделы документа
for (int i = 1; i <= _document.Sections.Count; i++)
{
    // берем всю секцию диапазоном
    wordRange = _document.Sections[i].Range;

    /*
    Обходим редкий глюк в Find, ПРИЗНАННЫЙ MICROSOFT, метод Execute на некоторых машинах вылетает с ошибкой "Заглушке переданы неправильные данные / Stub received bad data"  Подробности: http://support.microsoft.com/default.aspx?scid=kb;en-us;313104
    // выполняем метод поиска и  замены обьекта диапазона ворд
    wordRange.Find.Execute(ref strToFindObj, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref replaceStrObj, ref replaceTypeObj, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing);
    */

    Word.Find wordFindObj = wordRange.Find;
    object[] wordFindParameters = new object[15] { strToFindObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, replaceStrObj, replaceTypeObj, _missingObj, _missingObj, _missingObj, _missingObj };

    wordFindObj.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, null, wordFindObj, wordFindParameters);
}

Редкий глюк подробно описан здесь.

На самом деле это не самый лучший метод для вставки информации в документ, так как могут возникнуть сложности с уникальными именами для текстовых меток (если текст одной входит в начало другой, данный метод найдет ее и заменит), их совпадением с произвольным текстом и так далее.

Даже если нам надо найти (и например отформатировать) именно строку с текстом внутри документа, лучше всего выдать наружу найденный Range и уже с ним производить разные злодеяния. Получим примерно такой метод:

object stringToFindObj = stringToFind;
Word.Range wordRange;
bool rangeFound;

//в цикле обходим все разделы документа, получаем Range, запускаем поиск
// если поиск вернул true, он долже ужать Range до найденное строки, выходим и возвращаем Range
// обходим все разделы документа
for (int i = 1; i <= _document.Sections.Count; i++)
{
    // берем всю секцию диапазоном
    wordRange = _document.Sections[i].Range;

    /*
    // Обходим редкий глюк в Find, ПРИЗНАННЫЙ MICROSOFT, метод Execute на некоторых машинах вылетает с ошибкой "Заглушке переданы неправильные данные / Stub received bad data"  Подробности: http://support.microsoft.com/default.aspx?scid=kb;en-us;313104
    // выполняем метод поиска и  замены обьекта диапазона ворд
    rangeFound = wordRange.Find.Execute(ref stringToFindObj, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing);
    */

    Word.Find wordFindObj = wordRange.Find;

    object[] wordFindParameters = new object[15] { stringToFindObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj };

    rangeFound = (bool)wordFindObj.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, null, wordFindObj, wordFindParameters);

    if (rangeFound) { return wordRange; }
}

// если ничего не нашли, возвращаем null
return null;

Простейшее решение проблемы уникальности текста (нужно нам найти Range слова Word, но внутри всего документа оно встречается десятки раз) — искать строку внутри строки, сначала найти уникальную строку, потом не уникальную внутри нее, неэстетично, но дешево, надежно и практично.

// оформляем обьектные параметры
object stringToFindObj = stringToFind;
bool rangeFound;

/*
Обходим редкий глюк в Find, ПРИЗНАННЫЙ MICROSOFT, метод Execute на некоторых машинах вылетает с ошибкой "Заглушке переданы неправильные данные / Stub received bad data" 
http://support.microsoft.com/default.aspx?scid=kb;en-us;313104
rangeFound = containerRange.Find.Execute(ref stringToFindObj, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing);
*/

Word.Find wordFindObj = containerRange.Find;

object[]  wordFindParameters = new object[15] { stringToFindObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj, _missingObj };

rangeFound = (bool)wordFindObj.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, null, wordFindObj, wordFindParameters);

if (rangeFound) { return containerRange; }
else { return null; }

Если строку надо просто заменить, то сойдет простейшее

_range.Text = "Это текст заменит содержимое Range";

Но так как Range является универсальный контейнером для любого куска документа Word, то его возможности неизмеримо шире, часть их будет рассмотрена в дальнейших заметках.

Если нам надо просто встать в начало документа (и что-то вставить уже туда):

object start = 0;
object end = 0;
_currentRange = _document.Range(ref start, ref end);

Сохранить документ на диск можно следующим образом

Object pathToSaveObj = pathToSaveString;
_document.SaveAs(ref pathToSaveObj, Word.WdSaveFormat.wdFormatDocument, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj, ref _missingObj);
  1. Работаем с MS Word из C#, часть 0, класс и тестовый проект-пример WinForms
  2. Работаем с MS Word из C#, часть 1. Открываем шаблон, ищем текст внутри документа
  3. Работаем с MS Word из C#, часть 2. Вставляем текст на закладку и форматируем
  4. Работаем с MS Word из C#, часть 3. Работа с таблицами
  5. Работаем с MS Word из C#, часть 4. Обьединяем несколько файлов в один, считаем количество страниц
  6. Microsoft.Office.Interop.Word Namespace
  7. Range Interface

What I’m trying to do is take Indentifiers that I type into a word doc and set bookmarks on them.

Say I have a Word Doc with the following text

«The Raven» is a narrative poem by the American <Goody> Edgar Allan Poe, first published in January 1845. It is noted for its musicality, <HereIAm> language, and supernatural atmosphere. It tells of a talking raven’s mysterious visit to a distraught lover, <AnotherWord> the man’s slow descent into madness. The lover, often identified as being a student,[1][2] is lamenting the loss of his love, Lenore. The raven, sitting on a bust of Pallas, seems to further instigate his distress with its constant repetition of the word, «Nevermore». Throughout the poem, Poe makes allusions to folklore and various classical works.

I Would like to use something like a Regex to find strings formated like <[SomeText]> and then create a bookmark over <[SomeText]>. IE, in the above paragraph I would create bookmarks fro <AnotherWord>, <Goody>, And <HereIAm>

To do this using Word, I would highlight the <[SomeText]> then goto Insert->Bookmark.

I believe I can figure out how to add the bookmark as long as I get can a Range object that covers the text range of the <[SomeText]> identifier. I’ve tried running a regex on the Word.Content.Text using Text.RegularExpression.Regex and I get find the matches but when I try to create a range from the starting index of the match and the index of the last character its not selecting the right text.

Another problem that I noticed, is if Word.Content.Text is used, it does not return text that is inside a head or footer. I will also need code that can find these identifiers within header and footer fields.

Thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
 
namespace sourse
{
    class word
    {
        Object wordMissing = System.Reflection.Missing.Value;
          Object wordTrue = true;
        Object wordFalse = false;
        public Word.Table tables;
 
        //рабочие параметры
        // если использовать Word.Application и Word.Document получим предупреждение от компиллятора
        public Word._Application wordApplication;
        public Word._Document wordDocument;
        Object templatePathObj;
        
        // определяет поведение в случае ошибки при поиске и замене строки, по умолчанию открытый документ и приложенеи Word закрываются
        public bool CloseIFReplaceFailed = true;
 
        /// <summary>
        /// возвращает количество таблиц в документе
        /// </summary>
        /// <returns></returns>
        public int tableCount()
        {
            return wordDocument.Tables.Count;
        }
        
     
        public bool runMacros(string macros)
        {
            try
            {
                wordApplication.Run(macros);
                return true;
            }
            catch
            {
                MessageBox.Show(@"Ошибка  макроса");
                return false;
            }
        }
       
        // фиксированные параметры для передачи приложению Word
 
        public void copyToWord(ref word MainDoc, word secondDoc)
        {
            Word.Range wordrange = secondDoc.wordApplication.ActiveDocument.Range(
           secondDoc.wordApplication.ActiveDocument.Content.Start,
           secondDoc.wordApplication.ActiveDocument.Content.End);
            wordrange.Copy();
            Word.Range w = MainDoc.wordApplication.ActiveDocument.Range(
            MainDoc.wordApplication.ActiveDocument.Content.End - 1,
            MainDoc.wordApplication.ActiveDocument.Content.End);
            w.Paste();
        }
 
        public void GetFont(Font _font)
        {
            Word.Range w = wordApplication.ActiveDocument.Range(
        wordApplication.ActiveDocument.Content.Start,
        wordApplication.ActiveDocument.Content.End);
            w.Font.Name = _font.Name;
            w.Font.Size = _font.Size;
        }
       
        public bool Visible
        {
            get
            {
                if (documentClosed()) { throw new Exception("Ошибка при попытке изменить видимость Microsoft Word. Программа или документ уже закрыты."); }
                return wordApplication.Visible;
 
            }
            set
            {
                if (documentClosed()) { throw new Exception("Ошибка при попытке изменить видимость Microsoft Word. Программа или документ уже закрыты."); }
                wordApplication.Visible = value;
            }
            // завершение public bool Visible
        }
 
        // конструктор, создаем по шаблону, потом возможно расширение другими вариантами
        public word()
        {
            wordApplication = new Word.Application();
 
 
            //создаем ноый документ методом приложения Word по поути к шаблону документа
            try
            {
                wordDocument = wordApplication.Documents.Add(ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing);
            }
            // если произошла ошибка, то приложение Word надо закрыть
            catch (Exception error)
            {
                wordApplication.Quit(ref wordMissing, ref  wordMissing, ref wordMissing);
                wordApplication = null;
                throw new Exception("Ошибка. Не удалось открыть шаблон документа MS Word. " + error.Message);
            }
            // завершение createFromTemplate(string templatePath)
        }
        public word(string templatePath)
        {
            CreateFromTemplate(templatePath);
        }
 
        // создаем приложение Word и открывает новый документ по заданному файлу шаблона
        public void CreateFromTemplate(string templatePath)
        {
            //создаем обьект приложения word
            wordApplication = new Word.Application();
 
            // создаем путь к файлу используя имя файла
            templatePathObj = templatePath;
 
            //создаем ноый документ методом приложения Word по поути к шаблону документа
            try
            {
                wordDocument = wordApplication.Documents.Add(ref  templatePathObj, ref wordMissing, ref wordMissing, ref wordMissing);
            }
            // если произошла ошибка, то приложение Word надо закрыть
            catch (Exception error)
            {
                wordApplication.Quit(ref wordMissing, ref  wordMissing, ref wordMissing);
                wordApplication = null;
                throw new Exception("Ошибка. Не удалось открыть шаблон документа MS Word. " + error.Message);
            }
            // завершение createFromTemplate(string templatePath)
        }
       
        public bool GetTable(int count)
        {
            try
            {
                var table = wordDocument.Tables[count];
                tables = table;
                return true;
            }
            catch
            {
                MessageBox.Show(@"Не получилось выявить таблицу");
                return false;
            }
 
        }
        public string Seath(string findStr)
        {
            string res = " ";
            object missing;
            missing = Type.Missing;
            object findText = findStr;
 
 
            wordApplication.Selection.Find.ClearFormatting();
 
            if (wordApplication.Selection.Find.Execute(ref findText,
                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, ref missing))
            {
                //  MessageBox.Show("Text found.");
                wordApplication.Selection.Expand(Word.WdUnits.wdLine);
 
 
                res = wordApplication.Selection.Text.Remove(wordApplication.Selection.Text.Length - 1, 1);
            }
 
            return res;
        }
       
       
       
 
 
        // ПОИСК И ЗАМЕНА ЗАДАННОЙ СТРОКИ
        public void ReplaceString(string strToFind, string replaceStr, string replaceTypeStr)
        {
            if (documentClosed()) { throw new Exception("Ошибка при выполнении поиска и замены в Microsoft Word. Программа или документ уже закрыты."); }
 
            // обьектные строки для Word
            object strToFindObj = strToFind;
            object replaceStrObj = replaceStr;
            // диапазон документа Word
            Word.Range wordRange;
            //тип поиска и замены
            object replaceTypeObj;
 
            if (replaceTypeStr == "all")
            {
                // заменять все найденные вхождения
                replaceTypeObj = Word.WdReplace.wdReplaceAll;
            }
            else if (replaceTypeStr == "one")
            {
                // заменять только первое найденное вхождение
                replaceTypeObj = Word.WdReplace.wdReplaceOne;
            }
            else
            {
                Close();
                throw new Exception("Неизвестный тип поиска и замены в документе Word.");
            }
 
            try
            {
                // обходим все разделы документа
                for (int i = 1; i <= wordDocument.Sections.Count; i++)
                {
                    // берем всю секцию диапазоном
                    wordRange = wordDocument.Sections[i].Range;
 
                    // выполняем метод поискаи  замены обьекта диапазона ворд
                    wordRange.Find.Execute(ref strToFindObj, ref wordMissing, ref wordMissing, ref wordMissing,
                    ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing, ref replaceStrObj,
                    ref replaceTypeObj, ref wordMissing, ref wordMissing, ref wordMissing, ref wordMissing);
                }
 
            }
            catch (Exception error)
            {
                if (CloseIFReplaceFailed)
                {
                    this.Close();
                }
                throw new Exception("Ошибка при выполнении поиска и замены в документе Word.  " + error.Message);
            }
            // завершение функции поиска и замены SearchAndReplace
        }
        // тоже поиск и замена
        private void WordReplace(string old_str, string new_str)
        {
            foreach (Microsoft.Office.Interop.Word.Range tmpRange in wordDocument.StoryRanges)
            {
                // Set the text to find and replace
                tmpRange.Find.Text = old_str;
                tmpRange.Find.Replacement.Text = new_str;
 
                // Set the Find.Wrap property to continue (so it doesn't
                // prompt the user or stop when it hits the end of
                // the section)
                tmpRange.Find.Wrap = Microsoft.Office.Interop.Word.WdFindWrap.wdFindContinue;
 
                // Declare an object to pass as a parameter that sets
                // the Replace parameter to the "wdReplaceAll" enum
                object replaceAll = Microsoft.Office.Interop.Word.WdReplace.wdReplaceAll;
                object missing = System.Type.Missing;
                // Execute the Find and Replace -- notice that the
                // 11th parameter is the "replaceAll" enum object
                tmpRange.Find.Execute(ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref replaceAll,
                    ref missing, ref missing, ref missing, ref missing);
            }
        }
 
 
        // закрытие открытого документа и приложения
        public void Close()
        {
            if (documentClosed()) { throw new Exception("Ошибка при попытке закрыть Microsoft Word. Программа или документ уже закрыты."); }
 
            wordDocument.Close(ref wordFalse, ref  wordMissing, ref wordMissing);
            wordApplication.Quit(ref wordMissing, ref  wordMissing, ref wordMissing);
            wordDocument = null;
            wordApplication = null;
        }
 
        // если документ уже закрыт, true
        private bool documentClosed()
        {
            if (this.wordApplication == null || this.wordDocument == null) { return true; }
            else { return false; }
        }
 
        // завершение class WordDocument
 
 
    }
 
 
}

Вопрос был бы простым, но добавленное к нему дополнительное предложение оказалось для меня большой головной болью. Подвох в том, что мне нужны не все выделенные слова, а фразы из файла 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);
    }
}

Теперь рассмотрим следующий текст:

Верит о борьбе с холестерином, сгоранием, профилактикой и лечением, и фокусником.

Теперь предположим, что кто-то выделил «du cholestérol«, мой код явно выбирает два слова «du» и «cholestérol«. Как сделать так, чтобы постоянно выделенная область отображалась как одно слово? Я имею в виду «du cholestérol» должен быть возвращен как один объект в List, Любая логика, что мы сканируем символ char по символу, отмечаем начальную точку выделения как начальную точку выделения, а конечную точку выделения как конечную точку выделения?

PS: Если есть библиотека с необходимыми возможностями на любом другом языке, пожалуйста, дайте мне знать, поскольку сценарий не зависит от языка. Мне нужно только получить желаемые результаты как-то.

РЕДАКТИРОВАТЬ: изменил код с Start а также End как предположил Оливер Ханаппи. Но проблема по-прежнему заключается в том, что если есть две такие выделенные фразы, разделенные только пробелом, программа считает обе фразы одной. Просто потому, что он читает Words а не пробелы. Может потребоваться некоторые правки if (thisStart == prevEnd)?

2013-03-20 12:56

4

ответа

Решение

Вы можете сделать это гораздо эффективнее с помощью 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-20 14:12

Вы можете посмотреть свойства Start и End диапазонов и проверить, равен ли конец первого диапазона началу второго.

В качестве альтернативы вы можете переместить диапазон на одно слово (см. WdUnits.wdWord), а затем проверить, соответствуют ли перемещенные начало и конец началу и концу второго слова.

2013-03-20 13:29

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-04 14:06

Я начал с логики Оливера, все было хорошо, но тестирование показало, что этот метод не учитывает пробелы. Таким образом, выделенные фразы, разделенные пробелом, не разделяются. Я использовал подход кода VB, предоставленный grahamj42, и добавил его в качестве библиотеки классов и включил ссылку в мой проект форм окон C#.

Мой 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.Find код в библиотеке классов VB, который просто принимает Range И его Range.Last и возвращает List(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-22 10:44

        public ResultType_enum Create(Document document, Word.Application application, out Word._Document doc, out string message)
        {
            try
            {
                isWork = true;
                message = "";

                Object trueObj = true;
                Object falseObj = false;
                Object begin = Type.Missing;
                Object end = Type.Missing;
                doc = null;

                // если вылетим не этом этапе, приложение останется открытым
                try
                {
                    doc = application.Documents.Add(ref missingObj, ref missingObj, ref missingObj, ref missingObj);
                    // Общий Стиль
                    object patternstyle = Word.WdStyleType.wdStyleTypeParagraph;
                    Word.Style wordstyle = doc.Styles.Add("myStyle", ref patternstyle);
                    wordstyle.Font.Size = 9;
                    wordstyle.Font.Name = "Times New Roman";
                    Word.Range wordrange = doc.Range(ref begin, ref end);
                    object oWordStyle = wordstyle;
                    wordrange.set_Style(ref oWordStyle);

                    // Вставляем параграфы
                    doc.Paragraphs.Add(ref missingObj);
                    doc.Paragraphs.Add(ref missingObj);
                    doc.Paragraphs.Add(ref missingObj);
                    doc.Paragraphs.Add(ref missingObj);
                    doc.Paragraphs.Add(ref missingObj);

                    doc.Paragraphs.Add(ref missingObj);
                    doc.Paragraphs.Add(ref missingObj);
                    doc.Paragraphs.Add(ref missingObj);
                    doc.Paragraphs.Add(ref missingObj);
                    doc.Paragraphs.Add(ref missingObj);

                    doc.Paragraphs[1].Range.Text = "«Утверждаю»";
                    doc.Paragraphs[1].Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
                    doc.Paragraphs[1].Range.ParagraphFormat.LeftIndent = 300;
                    doc.Paragraphs[1].Range.ParagraphFormat.LineSpacing = 11;
                    doc.Paragraphs[1].SpaceAfter = 0;
                    doc.Paragraphs[1].SpaceBefore = 0;
                    doc.Paragraphs[2].LineUnitAfter = 0;
                    doc.Paragraphs[2].LineUnitBefore = 0;
                    doc.Paragraphs[3].LineUnitAfter = 0;
                    doc.Paragraphs[3].LineUnitBefore = 0;
                    doc.Paragraphs[4].LineUnitAfter = 0;
                    doc.Paragraphs[4].LineUnitBefore = 0;

                    doc.Paragraphs[2].Range.Text = "Руководитель";
                    doc.Paragraphs[2].Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
                    doc.Paragraphs[2].Range.ParagraphFormat.LeftIndent = 300;

                    doc.Paragraphs[4].Range.Text = "Форма 2. Сведения о качестве, технических характеристиках товара, его безопасности, функциональных характеристиках (потребительских свойствах) товара, размере и иные сведения о товаре, представление которых предусмотрено документацией об аукционе в электронной форме";
                    doc.Paragraphs[4].Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                    // Подсчитываем количество строк у продуктов (потому что одно свойство продукта занимает одну строку)
                    int propertiesCount = 0;
                    foreach (Product product in document.Products)
                    {
                        var myTemplate = product.Templates.FirstOrDefault(m => m.Name.Trim().ToLower() == "форма 2");
                        IEnumerable<Property> productProperties = product.Properties.SelectMany(m => m.ParamValues.Where(p => myTemplate.Param.Contains(p.Param))).Select(f => f.Property).Distinct();

                        propertiesCount += productProperties.Count();
                    }

                    Object defaultTableBehavior =
                     Word.WdDefaultTableBehavior.wdWord9TableBehavior;
                    Object autoFitBehavior =
                     Word.WdAutoFitBehavior.wdAutoFitWindow;
                    Word.Table wordtable = doc.Tables.Add(doc.Paragraphs[5].Range, 3 + propertiesCount, 8,
                      ref defaultTableBehavior, ref autoFitBehavior);

                    // Объединение ячеек
                    object begCell = wordtable.Cell(1, 1).Range.Start;
                    object endCell = wordtable.Cell(2, 1).Range.End;
                    Word.Range wordcellrange = doc.Range(ref begCell, ref endCell);
                    wordcellrange.Select();
                    application.Selection.Cells.Merge();

                    begCell = wordtable.Cell(1, 2).Range.Start;
                    endCell = wordtable.Cell(2, 2).Range.End;
                    wordcellrange = doc.Range(ref begCell, ref endCell);
                    wordcellrange.Select();
                    application.Selection.Cells.Merge();

                    begCell = wordtable.Cell(1, 3).Range.Start;
                    endCell = wordtable.Cell(2, 3).Range.End;
                    wordcellrange = doc.Range(ref begCell, ref endCell);
                    wordcellrange.Select();
                    application.Selection.Cells.Merge();

                    begCell = wordtable.Cell(1, 4).Range.Start;
                    endCell = wordtable.Cell(1, 6).Range.End;
                    wordcellrange = doc.Range(ref begCell, ref endCell);
                    wordcellrange.Select();
                    application.Selection.Cells.Merge();

                    begCell = wordtable.Cell(1, 5).Range.Start;
                    endCell = wordtable.Cell(2, 7).Range.End;
                    wordcellrange = doc.Range(ref begCell, ref endCell);
                    wordcellrange.Select();
                    application.Selection.Cells.Merge();

                    begCell = wordtable.Cell(1, 6).Range.Start;
                    endCell = wordtable.Cell(2, 8).Range.End;
                    wordcellrange = doc.Range(ref begCell, ref endCell);
                    wordcellrange.Select();
                    application.Selection.Cells.Merge();

                    /*begCell = wordtable.Cell(4, 6).Range.Start;
                    endCell = wordtable.Cell(propertiesCount + 4, 6).Range.End;
                    wordcellrange = doc.Range(ref begCell, ref endCell);
                    wordcellrange.Select();
                    application.Selection.Cells.Merge();*/

                    // Окраска строки с номерами
                    begCell = wordtable.Cell(3, 1).Range.Start;
                    endCell = wordtable.Cell(3, 8).Range.End;
                    wordcellrange = doc.Range(ref begCell, ref endCell);
                    wordcellrange.Select();
                    application.Selection.Shading.BackgroundPatternColor = Word.WdColor.wdColorGray10;

                    // Заполнение заголовка
                    doc.Tables[1].Cell(1, 1).Range.Text = "№ п/п";
                    doc.Tables[1].Cell(1, 1).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(1, 2).Range.Text = "Наименование материала";
                    doc.Tables[1].Cell(1, 2).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(1, 3).Range.Text = "Указание на товарный знак (его словесное обозначение) (при наличии), знак обслуживания (при наличии), фирменное наименование (при наличии), патенты (при наличии), полезные модели (при наличии), промышленные образцы (при наличии), наименование страны происхождения товара";
                    doc.Tables[1].Cell(1, 3).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(1, 4).Range.Text = "Технические характеристики";
                    doc.Tables[1].Cell(1, 4).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                    doc.Tables[1].Cell(2, 4).Range.Text = "Требуемый параметр";
                    doc.Tables[1].Cell(2, 4).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(2, 5).Range.Text = "Требуемое значение";
                    doc.Tables[1].Cell(2, 5).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(2, 6).Range.Text = "Значение, предлагаемое участником";
                    doc.Tables[1].Cell(2, 6).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                    doc.Tables[1].Cell(1, 5).Range.Text = "Единица измерения";
                    doc.Tables[1].Cell(1, 5).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(1, 6).Range.Text = "Сведения о сертификации";
                    doc.Tables[1].Cell(1, 6).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                    doc.Tables[1].Cell(3, 1).Range.Text = "1";
                    doc.Tables[1].Cell(3, 1).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(3, 2).Range.Text = "2";
                    doc.Tables[1].Cell(3, 2).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(3, 3).Range.Text = "3";
                    doc.Tables[1].Cell(3, 3).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(3, 4).Range.Text = "4";
                    doc.Tables[1].Cell(3, 4).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(3, 5).Range.Text = "5";
                    doc.Tables[1].Cell(3, 5).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(3, 6).Range.Text = "6";
                    doc.Tables[1].Cell(3, 6).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(3, 7).Range.Text = "7";
                    doc.Tables[1].Cell(3, 7).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                    doc.Tables[1].Cell(3, 8).Range.Text = "8";
                    doc.Tables[1].Cell(3, 8).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                    // Заполняем продукты
                    ParamValue paramValue = null;
                    int productIndexCompilator = 0;
                    int propertyIndexCompilator = 0;
                    for (int i = 0; i < propertiesCount; i++)
                    {
                        if (!isWork) break;
                        // Получаем свойства продукта на шаблон
                        var myTemplate = document.Products.ElementAt(productIndexCompilator).Templates.FirstOrDefault(m => m.Name.Trim().ToLower() == "форма 2");
                        IEnumerable<Property> productProperties = document.Products.ElementAt(productIndexCompilator).Properties.SelectMany(m => m.ParamValues.Where(p => myTemplate.Param.Contains(p.Param))).Select(f => f.Property).Distinct();

                        if (propertyIndexCompilator == 0)
                        {
                            // Объединяем ячейки по продукту (т.к. свойство занимает строку)
                            begCell = wordtable.Cell(i + 4, 1).Range.Start;
                            endCell = wordtable.Cell(i + 4 + productProperties.Count() - 1, 1).Range.End;
                            wordcellrange = doc.Range(ref begCell, ref endCell);
                            wordcellrange.Select();
                            try
                            {
                                application.Selection.Cells.Merge();
                            }
                            catch
                            {

                            }

                            begCell = wordtable.Cell(i + 4, 2).Range.Start;
                            endCell = wordtable.Cell(i + 4 + productProperties.Count() - 1, 2).Range.End;
                            wordcellrange = doc.Range(ref begCell, ref endCell);
                            wordcellrange.Select();
                            try
                            {
                                application.Selection.Cells.Merge();
                            }
                            catch
                            {

                            }

                            begCell = wordtable.Cell(i + 4, 3).Range.Start;
                            endCell = wordtable.Cell(i + 4 + productProperties.Count() - 1, 3).Range.End;
                            wordcellrange = doc.Range(ref begCell, ref endCell);
                            wordcellrange.Select();
                            try
                            {
                                application.Selection.Cells.Merge();
                            }
                            catch
                            {

                            }

                            begCell = wordtable.Cell(i + 4, 8).Range.Start;
                            endCell = wordtable.Cell(i + 4 + productProperties.Count() - 1, 8).Range.End;
                            wordcellrange = doc.Range(ref begCell, ref endCell);
                            wordcellrange.Select();
                            try
                            {
                                application.Selection.Cells.Merge();
                            }
                            catch
                            {

                            }

                            doc.Tables[1].Cell(i + 4, 1).Range.Text = Convert.ToString(productIndexCompilator + 1) + '.';
                            doc.Tables[1].Cell(i + 4, 1).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                            doc.Tables[1].Cell(i + 4, 2).Range.Text = document.Products.ElementAt(productIndexCompilator).Name;
                            doc.Tables[1].Cell(i + 4, 2).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphJustify;

                            doc.Tables[1].Cell(i + 4, 3).Range.Text = document.Products.ElementAt(productIndexCompilator).TradeMark;
                            doc.Tables[1].Cell(i + 4, 3).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphJustify;

                            // Сертификация
                            paramValue = productProperties.ElementAt(propertyIndexCompilator).ParamValues.FirstOrDefault(m => m.Param.Name == "Сертификация");
                            if (paramValue != null)
                            {
                                doc.Tables[1].Cell(i + 4, 8).Range.Text = paramValue.Value;
                            }
                            else
                            {
                                doc.Tables[1].Cell(i + 4, 8).Range.Text = "";
                            }

                            doc.Tables[1].Cell(i + 4, 8).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
                        }

                        // Требуемый параметр
                        paramValue = productProperties.ElementAt(propertyIndexCompilator).ParamValues.FirstOrDefault(m => m.Param.Name == "Требуемый параметр");
                        if (paramValue != null)
                        {
                            doc.Tables[1].Cell(i + 4, 4).Range.Text = paramValue.Value;
                        }
                        else
                        {
                            doc.Tables[1].Cell(i + 4, 4).Range.Text = "";
                        }
                        doc.Tables[1].Cell(i + 4, 4).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                        // Требуемое значение
                        paramValue = productProperties.ElementAt(propertyIndexCompilator).ParamValues.FirstOrDefault(m => m.Param.Name == "Требуемое значение");
                        if (paramValue != null)
                        {
                            doc.Tables[1].Cell(i + 4, 5).Range.Text = paramValue.Value;
                        }
                        else
                        {
                            doc.Tables[1].Cell(i + 4, 5).Range.Text = "";
                        }
                        doc.Tables[1].Cell(i + 4, 5).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                        // Значение, предлагаемое участником
                        paramValue = productProperties.ElementAt(propertyIndexCompilator).ParamValues.FirstOrDefault(m => m.Param.Name == "Значение, предлагаемое участником");
                        if (paramValue != null)
                        {
                            doc.Tables[1].Cell(i + 4, 6).Range.Text = paramValue.Value;
                        }
                        else
                        {
                            doc.Tables[1].Cell(i + 4, 6).Range.Text = "";
                        }
                        doc.Tables[1].Cell(i + 4, 6).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                        // Единица измерения
                        paramValue = productProperties.ElementAt(propertyIndexCompilator).ParamValues.FirstOrDefault(m => m.Param.Name == "Единица измерения");
                        if (paramValue != null)
                        {
                            doc.Tables[1].Cell(i + 4, 7).Range.Text = paramValue.Value;
                        }
                        else
                        {
                            doc.Tables[1].Cell(i + 4, 7).Range.Text = "";
                        }
                        doc.Tables[1].Cell(i + 4, 7).Range.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;

                        propertyIndexCompilator++;
                        if (productProperties.Count() == propertyIndexCompilator)
                        {
                            propertyIndexCompilator = 0;
                            productIndexCompilator++;
                        }

                    }
                }

                catch (Exception er)
                {
                    if (doc != null)
                        doc.Close(ref falseObj, ref missingObj, ref missingObj);
                    doc = null;
                }

                application.Visible = true;
                return ResultType_enum.Done;
            }
            catch (Exception ex)
            {
                doc = null;
                message = ex.Message + 'n' + ex.StackTrace;
                return ResultType_enum.Error;
            }
            finally {
                isWork = false;
            }
        }

Понравилась статья? Поделить с друзьями:
  • Interop excel save file
  • Internet word of mouth
  • Internet word derived from
  • Internet fill in the gaps with the correct word the
  • Internet explorer редактировать с помощью word