Пример работы с 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 не будет опубликован. Обязательные поля помечены *