Пример работы с Word через OLE. Часть 1. Создание документа без использования макетов.

Кроме прочего в статье присутствует пример создания таблицы с любым количеством колонок и столбцов. Несколько строк с форматированием текста и таблицы. Создание "объединенных" ячеек.

В качестве примера использования можно указать вот такую ситуацию: в зависимости от типа клиента (договора, документа и т.п) формируются разные тексты договоров с разным количеством таблиц. В реальности, конечно должен использоваться и макет и описанные здесь динамические механизмы.

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

Тестировалось на Office 2007.

Исп. переменные: «ПутьКФайлу» — строка. Полное имя файла в формате MSWord.

«Ссылка» — ДокументСсылка (в моем случае — счет).

Вот текст модуля:

 

Процедура ВыполнитьОбработку() Экспорт

    Попытка
        Объект = ПолучитьCOMОбъект(ПутьКФайлу);
       
// Покажем документ. Для красоты.
       
Объект.Application.Visible = 1;
       
Word = Объект.Application;

        Doc = Объект.Application.Documents(1);
       
Doc.Activate();

        // Готовим переменную в которой будет содержимое нашего документа
        // (текст, таблицы и проч).
       
Text = Word.Selection;

        // Очистим документ
        // Ctrl-A
       
Text.WholeStory();
       
// Del
       
Text.Delete(1, 1);
       
// Двигаемся на 3 строки ниже. Документ пустой, поэтому добавляем
        // строки «Переводами коретки»

        Text.TypeText(Символы.ВК);
       
Text.TypeText(Символы.ВК);
       
Text.TypeParagraph(); // другой вариант того же действия
        // Выводим текст.
       
Text.TypeText(«Обычный текст, набранный первую очередь»);

        // Курсор в конце строки
        // Эмулируем нажатие Shift+Home — выделяем строку
       
Text.HomeKey(, 1);
       
// Форматирование выделенной строки
       
Text.Font.Bold = 9999998;
       
Text.Font.Size = 14;
       
Text.Font.Name = «Verdana»;

        // Сдвигаем курсор. Сдвинуть курсор по строкам возможно, только,
        // если эти строки уже содержат текст, иначе ничего не произойдет.
       
Text.MoveUp(,2);   // вверх на 2 строки
        //Word.Selection.MoveDown(,числострок); // вниз
        //Word.Selection.MoveLeft(,числострок); // влево
        //Word.Selection.MoveRight(,числострок);// вправо

        // Добавление текста. Текст выводится начиная с текщей позиции
        // курсора.
        Text.HomeKey(, 1);
       
Text.TypeText(«Обычный текст, набранный во вторую очередь»);

        Text.MoveDown(,1); // вниз на 2 строки
       
Text.EndKey(); // в конец строки
       
Text.TypeParagraph(); // и в начало следующей строки

        // Очищаем форматирование
        Text.ClearFormatting();
       
// Добавляем таблицу.
        // Получаем текущую позицию курсора
       
Position = Text.Range();

        // Параметры: Позиция, число строк, число колонок,
        // последние 2 параметра отвечают за автоподбор высоты и отображение
        // границ таблицы
       
Table = Doc.Tables.Add(Position, 1, 6, 1, 2);

        // Устанавливаем ширину колонок
       
Table.Columns(1).PreferredWidth=10;
       
Table.Columns(2).PreferredWidth=50;
       
Table.Columns(3).PreferredWidth=10;
       
Table.Columns(4).PreferredWidth=10;
       
Table.Columns(5).PreferredWidth=10;
       
Table.Columns(6).PreferredWidth=10;

        // Задаем заголовки колонок
       
Row1=Table.Rows(1);
       
Row1.Cells(1).Range.Text=«№ п/п»;
       
Row1.Cells(2).Range.Text=«Наименование»;
       
Row1.Cells(4).Range.Text=«Кол-во»;
       
Row1.Cells(3).Range.Text=«Ед. изм.»;
       
Row1.Cells(5).Range.Text=«Цена,руб.»;
       
Row1.Cells(6).Range.Text=«Сумма,руб.»;

        // Построчно выводим содержимое таблицы Товары
       
НомерСтроки = 1;
        Для каждого
СтрокаТовары Из Ссылка.Товары Цикл
           
Row=Table.Rows.Add();
           
Row.Cells(1).Range.Text=НомерСтроки;
           
// Выравнивание по левому краю
           
Row.Cells(1).Range.ParagraphFormat.Alignment = 1;
           
// В качестве текста можно передать только значение «простого» формата
            // все агрегатные объекты, переданные как текст, что нормально для платформы 1с
            // вызовут исключение.
           
Row.Cells(2).Range.Text=СтрокаТовары.Номенклатура.Наименование
                   +?(ЗначениеЗаполнено(СтрокаТовары.ХарактеристикаНоменклатуры),
                  
» («+СтрокаТовары.ХарактеристикаНоменклатуры+«)»,«»);
           
Row.Cells(4).Range.Text=Строка(СтрокаТовары.Количество);
           
Row.Cells(4).Range.ParagraphFormat.Alignment = 1;
           
Row.Cells(3).Range.Text=?(ЗначениеЗаполнено(СтрокаТовары.Номенклатура.БазоваяЕдиницаИзмерения)
                                  ,
СтрокаТовары.Номенклатура.БазоваяЕдиницаИзмерения.Наименование,«-«);
           
Row.Cells(3).Range.ParagraphFormat.Alignment = 1;
           
Row.Cells(5).Range.Text=Формат(СтрокаТовары.Цена,«ЧДЦ=2»);
           
Row.Cells(5).Range.ParagraphFormat.Alignment = 1;
           
Row.Cells(6).Range.Text=Формат(СтрокаТовары.Сумма,«ЧДЦ=2»);
           
Row.Cells(6).Range.ParagraphFormat.Alignment = 1;
           
НомерСтроки=НомерСтроки+1;
        КонецЦикла;

        // Задаем форматирование первой строки
        // Если сделать это сразу, то все новые строки таблицы будут
        // формироваться с тем же форматом
       
Row1.Range.Font.Bold = 9999998;
       
Row1.Range.Font.Size = 14;
       
Row1.Range.Font.Name = «Verdana»;
       
Row1.Range.ParagraphFormat.Alignment = 1;

        // Последняя строка…
       
Row = Table.Rows.Add();
       
Row.Range.Font.Bold = 9999998;
       
Row.Cells(1).Range.Text=«Итого:»;
    Исключение
       
Doc.Save();
       
Сообщить(ОписаниеОшибки());
       
Объект.Application.Quit();
       
Объект = Неопределено;
    КонецПопытки;

    Попытка // эта конструкция выдает исключительную ситуацию, но при этом
        // результат все-равно работает))
        // объединяем ячейки в конце таблицы
       
Table.cell(НомерСтроки+1, 1).Merge(Table.cell(НомерСтроки+1, 5));
    Исключение
    КонецПопытки;

    Попытка
        Row.Cells(1).Range.ParagraphFormat.Alignment = 3;
       
Row.Cells(2).Range.Text=Формат(Ссылка.Товары.Итог(«Сумма»), «ЧДЦ=2»);
       
Row.Cells(2).Range.ParagraphFormat.Alignment = 1;

        Doc.Save();
       
Объект.Application.Quit();
       
Объект = Неопределено;
    Исключение
       
Doc.Save();
       
Сообщить(ОписаниеОшибки());
       
Объект.Application.Quit();
       
Объект = Неопределено;
    КонецПопытки;

КонецПроцедуры

16 Comments

  1. codewriter

    А визуальнно что в итоге получится?

    Reply
  2. Nikola23

    Добавил картинку. Хотя суть примера не в конкретном результате.

    Reply
  3. triera2000

    ЗдОрово, буду пользовать, спасибо!

    Reply
  4. ZiZu

    Word.Selection.MoveDown(,числострок); // вниз

    Word.Selection.MoveLeft(,числострок); // влево

    Word.Selection.MoveRight(,числострок);// вправо

    У меня с параметрами не ругаются.

    Опустил курсор тупо в цикле Word.Selection.MoveDown()

    Reply
  5. ZiZu

    Правда Офис тот что с виндой)) 💡

    Reply
  6. Nikola23
    У меня с параметрами не ругаются.

    В каком смысле? Я вроде не писал, что с параметрами ругаются…

    Reply
  7. mike2005

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

    Reply
  8. evg61

    Здравствуйте, Nikola23!

    Спасибо за представленный материал! Очень много полезных ньюансов! Когда начал пробовать чтото добавить возникли вопросы, например:

    То что можно в файле Word записать макрос и разобрать код понятно. Вопрос в том, как его правильно перенести в среду 1с8.1 Можете подсказать источник, где бы этот вопрос был подробно расписан?

    А еще столкнулся с такой проблемой. Может быть поможете… Вставляю картинку в Файл Word. При выполнении Объект.Application.Visible = 1 он отображается в масштабе 75%. Я вставляю в него картинку. Сохраняюю Все получается. При открытии этого файла в масштабе 100% картинка увеличивается в размерах. Как корректно выполнять вставку картинки?

    Спасибо!

    Reply
  9. Мария_19

    (0) Формула для объединения ячеек в таблице Table.cell(i+1,3).merge(Table.cell(i+1,4));

    Не подскажите, а какая для разбиения?

    Или где искать? 😳

    Reply
  10. Vlad_M

    Вот в таком варианте объединение ячеек не вызывает исключения:

    Row.Cells(1).Merge(Row.Cells(5));

    Reply
  11. kapafla
            // объединяем ячейки в конце таблицы
    Table.cell(НомерСтроки+1, 1).Merge(Table.cell(НомерСтроки+1, 5));
    

    Скажите, а как в документе наоборот найти объединенные ячейки, или просто установить факт того, что например Документ.Tables(1) содержит объединенные ячейки…. Мне просто нужно прервать цикл загрузки документа, если в таблице есть объединенные ячейки

    Спасибо заранее…

    Reply
  12. Nikola23

    (11) kapafla, предлагаю копать код. Гарантирую, что у объединенной ячейки есть свойство типа Merged или что-то подобное.

    Reply
  13. advanter

    // Выравнивание по левому краю

    Row.Cells(1).Range.ParagraphFormat.Alignment = 1;

    По верхнему краю (wdCellAlignVerticalTop) — 0

    По центру (wdCellAlignVerticalCenter) — 1

    По нижнему краю (wdCellAlignVerticalBottom) — 3

    Reply
  14. Nikola23

    (13) Вероятно, с годами константы изменились. Разработка велась лет много назад. Офис был по-моему 2010.

    Reply
  15. sulitckaja

    Может сможет подсказать кто, как в документе Word скопировать и вставить ниже уже существующую таблицу.

    Делаю так:

    Шаблон = Новый COMОбъект(«Word.Application»);

    Шаблон.Documents.Open(ИмяФайлаПолное);

    Шаблон.Application.Documents(1).Content.Tables(1).Range.Copy();

    Шаблон.Application.Documents(1).Content.InsertParagraphAfter();

    Шаблон.Application.Documents(1).Content.Paste();

    В результате таблица копируется но весь текст и предыдущая таблица исчезает.

    Заранее благодарна.

    Reply
  16. Nikola23

    (15)

    Запустите запись макроса, выполните все необходимые действия по копированию таблицы.

    Код который подучится — адаптируйте для 1с.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *