Дано:

Word тип COMОбъект - это макет печатной формы типа Active document, содержащий печатную форму типа MS Word, заполненную в соответствии с заданием.

простыми методами Item("ИНН").Value я заполняют в коде переменные печатной формы, например так:
Word.Variables.Item("ИНН").Value = Выборка.ИНН;

Есть строки, которые при определенных условиях надо удалить из макета Word, удалить совсем так, чтобы текст ниже переместился на 1 строку вверх (на ту, которую удалим).

Вопрос:
подскажите, люди добрые, какой метод лучше всего мне использовать для этой цели?
---
Делов-то :)
---
RailMen,
Вот именно просто строку - боюсь что никак. Поймите, что там просто НЕТ такого понятия как "строка" на объектном уровне (они переносятся :)).
Так что определитесь сначала, что именно нужно удалить. Варианты: Абзац, СтрокаТАБЛИЦЫ, Раздел, ... Но не строка.
---
Вознаграждение 30 попугаев за ответ до конца дня.
---
Уточнение:
1) Если текст расползается на 2 строки, то удалить надо 2 строки, если на 3 строки, то 3 строки удалить и т.д.
2) Заменить найденный текст на пустой символ "" - не предлагать, т.к. это не приведет к удалению строки.
---
RailMen,
Уточните:
- Удалить предложение содержащее искомый шаблон (От абзаца до точки или от точки до точки)?
- Удалить абзац содержащее искомый шаблон (От абзаца до абзаца)?
---
AnryMc, От абзаца до абзаца - это подходит.
---
Упростим задачу. Есть три строки в Word, каждая с нового абзаца:

Заявление.
Удалить
На основании СЗ № от

Нужно удалить 2 строку, содержащую текст "Удалить", полученный результат должен содержать 2 строки:

Заявление.
На основании СЗ № от

После какого упрощения можно говорить об удалении абзаца №2.
---
Вот нашел скрипт на VBA

```1c
    ' Скрипт ищет строки с определенным словом и удаляет ее.
    Sub DeleteLine()
    Dim DeleteLine As String
    DeleteLine = InputBox("Введите слово для удаления строки", "Удаляем строки")
    If DeleteLine = Empty Then Exit Sub
    Application.ScreenUpdating = False
    With ActiveDocument.Range.Find
    .ClearFormatting
    .Text = DeleteLine
    .Format = False
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
    While .Execute
    .Parent.Select
    Selection.HomeKey Unit:=wdLine
    Selection.EndKey Unit:=wdLine, Extend:=wdExtend
    Selection.Delete
    Wend
    End With
    Application.ScreenUpdating = True
    End Sub
```

Здесь про команды:
http://www.askit.ru/custom/vba_office/m10/10_05_02_word_selection_members.htm
---
Сейчас посмотрю, попробую. Что получится - тут напишу. Если все будет "ок" - попугаи твои )

Что-то типа конструкции:
Word.Selection.Start = бла;
Word.Selection.End = блабла;
Word.Selection.Delete();
---
Предварительное решение задачи:

//Word тип COMОбъект - это макет печатной формы типа Active document, содержащий печатную форму типа MS Word, заполненную в соответствии с заданием.
//Пример определения Word в коде 1С:
//СсылкаМакет = ПолучитьМакет(ИмяМакета);
//Word = СсылкаМакет.Получить();

    Selection = Word.Application.Selection; //объект для программной работы с выделенным участком текста в VBA
    Find = Selection.Find; //объект для программного поиска и замены текста в документе Word средствами VBA, БЕРЕМ ИЗ Selection
    Find.Text = СимволыКоторыеНадоУдалить+Символы.ВК;
    Если Find.Execute() Тогда //метод для запуска поиска, если Истина, то вхождения найдены
     Selection.Delete();
    КонецЕсли;

Чтобы символы не просто очистились, но и строка сдвинулась вверх надо в конец искомых символов добавить символ возврата корректки.

Эта конструкция не работает, если текст, который надо удалить, был заполнен программно через конструкцию {DOCVARIABLE "СимволыКоторыеНадоУдалить"\*MERGEFORMAT}

Строго говоря, тут нет удаления строки/абзаца. Это некий финт ушами. Хотелось бы изучить другие варианты решения.
---
Если верить записи макроса, то такое:

    Selection.MoveUp Unit:=wdParagraph, Count:=1 //перемещаемся в начало абзаца
    Selection.MoveDown Unit:=wdParagraph, Count:=1, Extend:=wdExtend//выделяем, как понимаю абзац
    Selection.Delete Unit:=wdCharacter, Count:=1//удаляем нафик абзац

:)
---
antz, как узнать в какой абзац переместиться и какой удалить? в смысле как узнать какой абзац(ы) содержит искомые символы?
---
2) Заменить найденный текст на пустой символ "" - не предлагать, т.к. это не приведет к удалению строки.
 как раз то что надо, только потом потребуется:

РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(1, "Sub Макрос2()");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(2, "With Selection.Find");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(3, ".Text = ""^p^p""");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(4, " .Replacement.Text = ""^p""");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(5, ".Forward = True");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(6, ".Wrap = wdFindContinue");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(7, ".Format = False");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(8, ".MatchCase = False");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(9, ".MatchWholeWord = False");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(10, ".MatchWildcards = False");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(11, ".MatchSoundsLike = False");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(12, ".MatchAllWordForms = False");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(13, "End With");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(14, "Selection.Find.Execute Replace:=wdReplaceAll");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(15, "Selection.Find.Execute Replace:=wdReplaceAll");
РабочийДок.VBProject.VBComponents("NemMacros").CodeModule.InsertLines(16, "End Sub");
Док.Run("Макрос2");

//где Док - объект ворд, РабочийДок - сам документ
---
гыук320, прокомментируйте пожалуйста, что происходит в строках макроса и почему его надо выполнить после замены искомой строки на пустой символ ""
---
гыук320,
А зачем вам VB (я так понимаю, это VisualBacic.Net)?
И при чём тут ёксель? В Ворде совершенно другая объектная модель...
---
Ivanovag123, мой рабочий пример в 1с правда 7.7, нет не VisualBacic.Net, а VBA (VisualBacic for application или как-то так за 15 лет забыл :)

```1c
    Процедура ек()

    Попытка
    //В данном примере запускается программа Excel,

    // затем в нее передаются некоторые данные, и затем

    // на их основе строится диаграмма.

    // Создаем объект Excel и присвоим его переменной языка

    ОкноЕхсеl = СоздатьОбъект("Excel.Application");

    // устанавливаем имя окна Excel

    ОкноЕхсеl.Caption = "Отчет";

    // создадим новую рабочую книгу

    РабочаяКнига = ОкноЕхсеl.Workbooks.Add(); // Добавить рабочую книгу
    РабочаяКнига.Activate();

    ЧислоРядов = 10;

    ЧислоСтолбцов = 5;

    // проставим названия строк

    Для Ряд = 1 По ЧислоРядов Цикл

    Ячейка = ОкноЕхсеl.Cells(Ряд + 1, 1);

    Ячейка.Value = "Строка " + Строка(Ряд);

    КонецЦикла;

    // проставим названия столбцов

    Для Столбец = 1 По ЧислоСтолбцов Цикл

    Ячейка = ОкноЕхсеl.Cells(1, Столбец + 1);

    Ячейка.Value = "Столбец " + Строка(Столбец);

    КонецЦикла;

    // заполним ячейки таблицы значениями

    Для Ряд = 1 По ЧислоРядов Цикл

    Для Столбец = 1 По ЧислоСтолбцов Цикл

    Ячейка = ОкноЕхсеl.Cells(Ряд + 1, Столбец + 1);

    Ячейка.Value = Ряд + Столбец;

    КонецЦикла;

    КонецЦикла;

    // выделим область в таблице и присвоим ее переменной языка

    Область = ОкноЕхсеl.Range(ОкноЕхсеl.Cells(1, 1),

    ОкноЕхсеl.Cells(ЧислоРядов + 1, ЧислоСтолбцов + 1));

    // зададим имя выделенной области

    Область.Name = "ОбластьДанных";

    // определим рамку выделенной области и присвоим ее переменной языка

    Рамка = Область.Borders;

    // установим стили для рамки выделенной области

    Рамка.LineStyle = 1;

    //Рамка.Colorlndex = 3;

    // построим диаграмму Лист=РабочаяКнига.Worksheets(1);

    //Диаграмма = Лист.ChartObjects();
    //
    //Диаграмма = Диаграмма.Add(5, 5 + Область.Тор + Область.Height,
    //
    // Область.Width, Область.Height);
    //
    //МояДиаграмма = Диаграмма.Chart;
    //
    //МояДиаграмма.ChartWizard("ОбластьДанных ", -4102, 6, 1, 1, 1, 1, "Отчет");

    // сделаем окно Excel видимым и активным

    ОкноЕхсеl.Visible = 1;

    Исключение
    Сообщить(ОписаниеОшибки());
    Возврат;
    КонецПопытки;

    // Эксел= СоздатьОбъект("Excel.Application");
    ////РабочаяКнига = Эксел.Workbooks.Open(ИмяНужногоФайла); //Открываем файл
    // РабочаяКнига = Эксел.Workbooks.Add(); // Добавить рабочую книгу
    // РабочаяКнига.Activate();

    НашЛист = РабочаяКнига.Sheets(1); //Устанавливаем нужный лист

    РабочаяКнига.VBProject.VBComponents.Add(1); // добавляем модуль номер 1

    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(1, "Sub Раскраска()");
    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(2, "Range("A2:F5").Select");
    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(3, " Selection.Font.ColorIndex = 3");
    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(4, "Range("A8:F10").Select");
    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(5, " Range("F8").Activate");
    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(6, " With Selection.Interior");
    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(7, ".ColorIndex = 6");
    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(8, ".Pattern = xlSolid");
    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(9, " End With");
    РабочаяКнига.VBProject.VBComponents("Module1").CodeModule.InsertLines(10, "End Sub");
    ОкноЕхсеl.Run("Раскраска");
    ОкноЕхсеl.ActiveWorkBook.save();
    ОкноЕхсеl.WorkBooks.close();
    ОкноЕхсеl.Quit();

    КонецПроцедуры
```
---
гыук320, поставил вам СПАМ за второй километровый пост про ёксель (вы тему видели?)
---
Ivanovag123,
тему видел
в 11 посте макрос ОТЛИЧНО ВЫПОЛНЯЕТ СВОЮ РАБОТУ В ВОРДЕ, если не лень проверти!!!
 With Selection.Find
        .Text = "^p^p"
        .Replacement.Text = "^p"
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
    Selection.Find.Execute Replace:=wdReplaceAll

плюс пример реализации в 1с, не вижу где ушел от темы
---
гыук320, чисто визуально должно в целом работать. Только код избыточен. Можно покороче написать. Нет?
---
RailMen,

 With Selection.Find
 .Text = "^p^p"
 .Replacement.Text = "^p"
 End With
 Selection.Find.Execute Replace:=wdReplaceAll
тоже рабочий вариант
---
гыук320, это похоже на правду. По-тестирую.
---
гыук320, твое решение уступает решению antz тк как у тебя сначала меняется текст на пустой символ, а затем удаляются пустые строки. Тут явно 1 лишняя операция: замена строки поиска на пустой символ. Сама идея потом удалять пустые строки не очень "практичная" : вдруг нам нужно по заданию иметь пустую строку?

А в варианте antz удаляются непосредственно строки, удовлетворяющие условию поиска.

Если я не прав, поправьте меня.
---
RailMen, если решение то сделал бы так(:

```1c
    With Selection.Find
    .Text = "Нужная строка"+"^p"
    .Replacement.Text = "
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
```

До этого было просто одно из направлений куда можно двигаться!!! :_
---
гыук320, я не сколько не хотел усомниться в Вас. Просто решение antz было более законченным и подходящим (он обработку выложил).

Почему то метод Find.Execute() не ищет внутри параметров типа {DOCVARIABLE "Параметр1"\*MERGEFORMAT}, которые заполняются программно так:
Word.Variables.Item("Параметр1").Value = "УдалитьСтроку";

Так что ни один вариант не работает внутри конструкций {DOCVARIABLE "Параметр1"\*MERGEFORMAT}, где Параметр1 - программно заполняемый параметр
---
в двух словах макрос находит два в подряд идущих знака обзаца и заменяет на один, тем самым удаляется пустуя строка
---
Как-то так.
---
Не, в (19) неправильно, сорри. Щас еще подумаю)
---
antz, Ок
---
Да? Я на плохом примере тестил, показалось - накосячил. Вот рабочий вариант сто пудов.
---
antz, результаты тестирования: если в тексте "строка поиска" встречается несколько раз, то удаляет только первую попавшуюся. А надо все )
В конце еще обнули переменные связанные с "Word.Application", чтобы они в памяти не висли лишний раз.
---
Делов-то :)
---
antz, ТАКИ ДА! РАБОТАЕТ!!!
---
antz, в результате более тщательного тестирования нашел еще косяк или "фичу":

эта конструкция не работает, если текст, который надо найти и удалить, был заполнен программно через конструкцию вставленную в Word {DOCVARIABLE "Параметр1"\*MERGEFORMAT}.

Например, если в коде я пишу:
Word.Variables.Item("Параметр1").Value = "УдалитьСтроку";

то код antz строку "УдалитьСтроку" не найдет, ну и не удалит соответственно

На основе кода antz сделал процедуру:

Процедура Word_УдалитьСтрокуПоиска(WordApplication,СтрокаПоиска)

 Find = WordApplication.Selection.Find;
 Find.Text = СтрокаПоиска;
 Find.Execute();
 Пока Find.Found Цикл
  Selection = Find.Application.Selection;
  Selection.MoveUp(4);
  Selection.MoveDown(4, 1, 1);
  Selection.Delete(1);
  Find.Execute()
 КонецЦикла;

КонецПроцедуры
---
Я, кстати, у себя с docvariable попробовал - удаляет.
---
antz, да ну... завтра буду еще раз пробовать.
---
Млин, да всё же элементарно.
Берёте нужный вам документ в Ворде, запускаете запись макроса, делаете что нужно, спопите запись, и смотрите что он вам там нарисовал.
Подправить конешно придётся, но в общем поймёте. Чуток полазить по объектной модели Ворда,- и вуаля.
---
Ivanovag123, да, спсб, я уже понял, что смотреть запись макроса это самое удобное.

(34) antz, я протестировал, все работает. Вот обработка, для тестирования, она же содержит процедуру "Word_УдалитьАбзацСодержащийСтрокуПоиска":
---
Есть путь проще.
Делаешь закладку в ворде: "Вставка" - "Закладка"

Закладка должна ссылкаться на весь текст, который предполагается удалять.

Программно удаляешь, если надо:
MSWord.Bookmarks("Имя закладки").Select();
MSWord.Application.Selection.Delete();
---
MSWord.Bookmarks("Имя закладки").Select();
MSWord.Application.Selection.Delete();

У меня так не получилось, но получилось через ActiveDocument:

MSWord.ActiveDocument.Bookmarks("Имя закладки").Select();
MSWord.Application.Selection.Delete();

Спасибо за наводку, удалять закладки это очень удобно!