среда, 26 октября 2016 г.

Вывод из 1С 7.7 в Word (OLE, с разбиением страницы на колонки)


Задача: Снова встала задача вывести из 1С в Word немного текста. В этот раз отличительной особенностью стала необходимость вывода шапки на всю ширину страницы, а таблицу - разместить ниже в 2 колонки.

Для небольших таблиц в пару сотен строк кода работает прекрасно. Для больших - лучше формировать не через OLE, иначе можно смело оставлять на пару часов.

Решение: Задача старая, много полезных ссылок:
https://helpf.pro/faq8/view/635.html
http://superadm.net/index.php?name=pages&op=view&id=98
http://infostart.ru/public/67727/ - с готовым примером, много комментариев
http://www.delphimaster.ru/articles/dbtoword/index.html - отличные примеры на Дельфи
Самый лучший и полный  - http://scriptcoding.ru !


Под катом моя версия и копия с инфостарта.


Сделал у себя примерно такое:

Процедура Сформировать()

 word = CreateObject("Word.Application"); // создаем новый объект
 word.Documents.Add();    // добавляем в него документ
 w = word.Documents(1);    // а можно ActiveDocument

 page1 = w.Sections(1).PageSetup;  // отступы в пунктах, примерно 1.4 см
 page1.BottomMargin = 40;
 page1.TopMargin = 40;
 page1.LeftMargin = 41;
 page1.RightMargin = 40;
 
 p1 = w.Paragraphs.Item(1);   // первый абзац уже есть в документе, не надо добавлять
 p1.LineSpacingRule = 0;    // wdLineSpaceSingle = 0, одинарный, по-умолчанию
 p1.SpaceAfter = 0;    // отступы до и после
 p1.SpaceBefore = 0;
 
 r1 = p1.Range;     // область 1-го параграфа
 r1.Font.Bold = 1;
 r1.Font.Size = 10;
 r1.Text = СокрЛП(выбФирма.Наименование);
 
 //
 w.Paragraphs.Add();                         // добавляем параграф, параметры оформления наследуются от предыдущего, снова задавать не надо
 p2 = w.Paragraphs.Item(2);
 r2 = p2.Range;        // область 1-го параграфа
 r2.Text = "Прайс-лист на "+РабочаяДата();
 
 w.Content.InsertParagraphAfter();   // вставим новый параграф
 p = w.paragraphs.last.range;    // получим текущую позицию курсора
 p.InsertBreak(3);     // вставим разрыв страницы в текущую позицию (wdSectionBreakContinuous=3 - новый раздел без разрыва страницы)
    
 w.Sections(2).PageSetup.TextColumns.Add();
 
 p = w.paragraphs.last.range;    // получим текущую позицию курсора

 t = w.Tables.Add(p, 1, 3, 1, 2);   // параметры: позиция, число строк, число колонок, автоподбор высоты и отображение границ таблицы

 t.Columns(1).PreferredWidth=10;    // устанавливаем ширину колонок
 t.Columns(2).PreferredWidth=50;
 t.Columns(3).PreferredWidth=20;

 Row1 = t.Rows(1);     // задаем заголовки колонок
 Row1.Cells(1).Range.Text="№ п/п";
 Row1.Cells(2).Range.Text="Наименование";
 Row1.Cells(3).Range.Text="Цена";
   
 Для поз = 1 По 100 Цикл

  Если поз%10=0 Тогда
   Состояние("Обработано "+поз+" строк.");
  КонецЕсли;
  
  r = t.Rows.Add();

  r.Cells(1).Range.Text = поз;
  r.Cells(1).Range.Font.Bold = 0;
         r.Cells(1).Range.ParagraphFormat.Alignment = 1; // Выравнивание по левому краю

  r.Cells(2).Range.Text = "Товар "+Поз;
  r.Cells(2).Range.Font.Bold = 0;

  r.Cells(3).Range.Text = поз * 100;
  r.Cells(3).Range.ParagraphFormat.Alignment = 1;
  r.Cells(3).Range.Font.Bold = 0;

 КонецЦикла; 
 
 Word.Visible = 1; // показываем
 Word = 0;  // 
 
КонецПроцедуры


А вот пример с Инфостарта:

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

    Попытка
       
Объект = Получить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();
       
Объект = Неопределено;
    КонецПопытки;

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


Комментариев нет: