Но вот совсем другой подход, когда количество строк или колонок неизвестно.
В этом примере продемонстрировано, как можно создать табличную часть в документе Word.
Выбор, какой из перечисленных далее методов использовать, за Вами.
Одно дело, когда заранее известно количество строк в таблице. И решение, соответственно, тоже простое: создать в шаблоне таблицу и заполнить переменные программно. Ссылка на данный пример //infostart.ru/public/18940/
Но вот совсем другой подход, когда количество строк или колонок неизвестно.
История «Как я к этому пришел»
Появилась необходимость распечатывать договора по каждому контрагенту, а как известно договор может быть 1 или несколько.
Тогда, еще в 2006 году вопрос решился 5 шаблонами, в табличных частях которых было от 1 до 5 строк (ограничились 5 договорами). Вопрос решился и забылся. Но вот вопрос стал актуален по причине печати нового договора, в котором задействована номенклатура, а количество строк ведь может переваливать добрую сотню наименований. И следовательно — выход в создании динамической таблицы в шаблоне Word, который и описан двумя самыми простыми способами.
Есть 2 подхода к созданию таблицы.
1) Вам нужна таблица с равной шириной колонок, так сказать созданная автоматически.
2) У вас есть шаблон таблицы (только шапка и 1 строка).
Код создания таблицы с автоформатом.
Процедура СоздатьПример1(Кнопка)
НовоеНапоминание = ПолучитьМакет("Пример1");
Массив = Новый Массив(5);//сделаем таблицу из 5 строк + шапка
MsWord = НовоеНапоминание.Получить();
//макет является ActiveDocwment с загруженым в него Word-файлом
Попытка
//Вставление таблицы с 10 строки
MsWord.Application.Visible = 0;
Word = MsWord.Application;
Док=Word.Documents(1);
Док.Activate();
//подготовка таблицы:
//Вариант №1 Самый простой
Word.Selection.MoveDown(,10); //10 строка - первая строка таблицы
//Конец Варианта №1
//Вариант №2
Word.Bookmarks("ff").Select(); //Где ff - это набор любых символов, вплоть до непечатаемых;)
//Конец Варианта №2
Табл= Word.Selection.Range;
//Формируем заголовок:
Табл.InsertAfter("Сумма*Валюта*Назначение*Дата долга*Вид документа*Номер документа* *Дата оплаты");
Табл.InsertParagraphAfter();
//сама таблица
Для й = 1 по Массив.Количество() Цикл
Табл.InsertAfter(массЗнчСтрокиТЧ[0]+"*"+массЗнчСтрокиТЧ[1]+"*"+массЗнчСтрокиТЧ[2]+"*"+массЗнчСтрокиТЧ[3]+"*"+ массЗнчСтрокиТЧ[4]+ "*"+массЗнчСтрокиТЧ[5]+ "*"+массЗнчСтрокиТЧ[6]+ "*"+массЗнчСтрокиТЧ[7]);
Табл.InsertParagraphAfter();
КонецЦикла;
Табл.ConvertToTable("*");
//Происходит конвертация строки в таблицу
//не нравятся звездочки - используйте другой символ
Док.Tables(1).AutoFormat(1);
ПечатныйНомер = "-"+Формат(ТекущаяДата(),"ДФ=yyyy.MM.dd")+"-"+Формат(ДатаОтчета,"ДФ=yyyy.MM.dd");
Файл = КаталогВременныхФайлов() + "" + ПечатныйНомер + ".doc";
Док.SaveAs(Файл);
Док.Close(0);
//МассивДокументов.Добавить(Файл); //добавлял в массив путь к файлу и после всех манипуляций открывал каждый файл
ЗапуститьПриложение("""" + Файл + """");
Исключение
Сообщить(ОписаниеОшибки());
Word.Quit();
КонецПопытки;
КонецПроцедуры
Код создания таблицы с наследуемым форматом.
Процедура СоздатьПример2(Кнопка)
НовоеНапоминание = ПолучитьМакет("Пример2");
Массив = Новый Массив(5);//добавим 4 строки
MsWord = НовоеНапоминание.Получить();
//макет является ActiveDocwment с загруженым в него Word-файлом
Попытка
MsWord.Application.Visible = 0;
Word = MsWord.Application;
Док=Word.Documents(1);
Док.Activate();
Если Массив.Количество()>1 Тогда
//Переместиться вниз на 10 строк от начала документа
Word.Selection.MoveDown(,10); //10 строка - первая строка таблицы
//назад на 1 символ (окончание строки таблицы)
Word.Selection.MoveLeft(,1);
//кво документов которые необходимо забить в табличную часть
Word.Selection.InsertRows(Массив.Количество()-1);
Word.Selection.MoveLeft(,1);
Для й = 11 по Массив.Количество()+9 Цикл
ЗаполнитьСтрокуТЧ(0,Word);
Word.Selection.MoveRight(,1);
КонецЦикла;
КонецЕсли;
ПечатныйНомер = "-"+Формат(ТекущаяДата(),"ДФ=yyyy.MM.dd")+"-"+Формат(ДатаОтчета,"ДФ=yyyy.MM.dd");
//Таблицу заполнять не буду, только шапку
Замена = Док.Content.Find;
Замена.Execute("", Ложь, Истина, Ложь, , , Истина, , Ложь, "ООО 'Пупкин inc.'");
Замена = Док.Content.Find;
Замена.Execute("", Ложь, Истина, Ложь, , , Истина, , Ложь, Формат(ТекущаяДата(),"Л=uk; ДЛФ=D"));
Замена = Док.Content.Find;
Замена.Execute("", Ложь, Истина, Ложь, , , Истина, , Ложь, ПечатныйНомер );
Файл = КаталогВременныхФайлов() + "" + ПечатныйНомер + ".doc";
Док.SaveAs(Файл);
Док.Close(0);
//МассивДокументов.Добавить(Файл); //добавлял в массив путь к файлу и после всех манипуляций открывал каждый файл
ЗапуститьПриложение("""" + Файл + """");
Исключение
Сообщить(ОписаниеОшибки());
Word.Quit();
КонецПопытки;
КонецПроцедуры
Процедура ЗаполнитьСтрокуТЧ(знчЭл,Word)
Если знчЭл массЗнчСтрокиТЧ.Количество()-1 Тогда
текЭлем = массЗнчСтрокиТЧ[знчЭл];
Rng = Word.Selection.Range;
Rng.InsertAfter(текЭлем);
ДлинаЗнч = СтрДлина(текЭлем)+1;
Word.Selection.MoveRight(,ДлинаЗнч);
Если знчЭл < массЗнчСтрокиТЧ.Количество()-1 Тогда
знчЭл = знчЭл + 1;
ЗаполнитьСтрокуТЧ(знчЭл,Word);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
По возможности — пример…
Заранее благодарен
Мне не сложно;) будет вечерком.
Добавил простенький примерчик. Жду комментов))))
Покрасьте кодhttp://infostart.ru/public/19856/
еще скриншоты бы не помешали
Код подкрашу, а вот скриншоты к чему? это статья.
(5) На статью не тянет.
Это пример, часть работающего кода. Решил поделиться с теми, кому это может пригодиться. Зачем выпендриваться и придираться к словам? (6)
(7) Материал нормальный только пожалуйста оформите нормально
http://infostart.ru/public/19856/
Раскрасте с помощью обработки
А скриншоты нужны обязательно т.к. многие и смотреть не будут код и обработку, а плюс поставят за полезный пример (я бы например так и сделал т.к. для меня сейчас материал не актуален, но может потом понадобится). Еще желательно ссылочки на подобные обработки например те, которые работают с вордом.
(8) я то и раскрасил вот той обработкой.
а что показывать в скриншотах? листочек word? 😉 это же пример.. так сказать заготовка.
Если уж так надо — могу сделать 4 скрина: 2 (по 1 на каждый вариант) «до» и «после».
Причина почему я выложил — нигде толком не было объяснения как же быть в ситуации когда нужна таблица в договоре, а количество строк/столбцов варьируется.
З.Ы. подобные ссылки видны справа.
использовал материал команд VBA для Word.
(7) На момент написания комментария кода не было.
А было 5 строк текста и приложенная обработка — это больше к «программе» относилось, чем статье. И последите за словами, перед Вами никто не «выпендривался»
(10) Изначально выложил только код.
После попросили (1) пример, для чего прикрепил обработку.
Автор, глянь на это
http://infostart.ru/public/18940/
В своё время здорово выручила.
(12) видел, и что? это готовый шаблон, который надо заполнять ручками. а если не знать сколько реквизитов, т.е. выбирать через * все поля? как тогда?
в данном примере(если можно так назвать) , повторюсь, описывается возможность создания строк в ЛЮБОМ МЕСТЕ даже не зная сколько строк выйдет всего.
Если есть пожелания — выслушаю. ссылку добавлю в шапку.
Полезный пример. Спасибо
Спасибо! Пример очень пригодится и в качестве ученого материала. и в качестве его практической реализации в отчётах, которых последнее время треуется всё больше и сложнее.
{ВнешняяОбработка.ПечатьАктаНаСписание.МодульОбъекта(225)}: Ошибка при вызове метода контекста (InsertRows): Произошла исключительная ситуация (Microsoft Word): Метод или свойство недоступны, поскольку некоторые или все объекты не ссылаются на таблицу. Как раз нужно сделать ВПФ Требования накладной в макете Ворд. Вставил твой код и вот такая ошибка.
(16) Очень интересно. хотелось бы узнать как появилась такая ошибка. Можно по-подробнее?
Сорри…Вопрос снят таблицу в макете разместил не там где надо вот он и поругался.
Материал очень полезный, но пожалста можно привести пример кода который будет в создаваемую таблицу в макете запихивать данные из моей ТабЗнач.В общем задача такая сделать ВПФ списания материалов из документа Требование накладная. Запросом все данные получил нарисовал стандартный табличный макетик, но заказчик хочет чтоб в Ворде это все выводилось..Если не трудно пособите.
(19)
не трудно, надо только ваши исходники;))
куда обработку положить?или прям в сообщение код вставить?
(21)весь в работе.
Сегодня посмотрел обработку по печати Акта.
А где Ваш макет word’овский? Ведь ресурс чтобы помогать а не делать за кого-то работу)
Спасибо за материал! но у меня возникла проблема:
В документе 5 листов, таблица на последнем(150 строка), но дальше чем на 44 строке(последняя строка первого листа) программа не видит таблицу:
{ВнешняяОбработка.Договор_поставки.МодульОбъекта(363)}: Ошибка при вызове метода контекста (InsertRows): Произошла исключительная ситуация (Microsoft Word): Метод или свойство недоступны, поскольку некоторые или все объекты не ссылаются на таблицу.
Как добавить таблицу на последний лист?
(23)Как добавить таблицу на последний лист?
Можно воспользоваться «шаблоном таблицы» или если используете таблицу с автоформатом — тогда перейти на последнюю страницу командой контрл+ енд
(24) я как раз и делаю через шаблон. если таблица находится не на первой странице, программа ее не находит
(25) Значит word не находит текст для замены, хоть на 99 странице будет текст в таблице.
данный механизм успешно работает при заполнении договоров купли-продажи в 15 и более листов)
Добрый день!
Спасибо за полезный пример, мне он помог.
По второй части хочу уточнить вот какой момент.
Если документ ворд состоит из некоего текста и шаблона таблицы, и текст динамически генерирует одинэсом, то заранее неизвестно, в каком месте документа будет таблица. Поэтому использовать
Word.Selection.MoveDown(,10); //10 строка — первая строка таблицы
не получится. Предлагаю поставить в первой пустой ячейке таблицы закладку, назвать ее, к примеру, ff и использовать так:
Word.Bookmarks(«ff»).Select();
ЗЫ и строку в таблице можно добавлять по мере необходимости 🙂 Но это вкусовщина уже, работает и так, и эдак.
(27)Полностью согласен, но! в моем примере таблица на десятой строке;)
можно даже вставить непечатаемый символ и отслеживать его. Мой пример не является аксиомой, а лишь механизмом для дальнейшего развития темы;)
UPD: (27) добавил в шапке в первом примере 😉
(28) и этот пример очень полезен! Пожалуй, один из самых наглядных среди n страниц поиска яндекса. Мне ранее не требовалось делать экспорт в вород, благодаря примеру разобрался быстро.
Можно еще в конце статьи добавить ссылок на объектную модель ворда.
А не подскажете, есть ли где пример «пряморукого» импорта из ворда (надо импортировать не тупо текст, текст получается в одном свойстве. Надо анализировать формат текста и в соотв. с ним разносить строки по реквизитам)? Перерыл пол-гугла, не нашел ничего толкового. В результате сделал перебор текста построчно через paragraphs. В каждом параграфе у первого слова проверяется формат, и дальше уже дело техники. Работает прямо скажем небыстро 🙁 А хочется сделать максимально хорошо.
Показать
Полезный пример. Спасибо
Автору жирный плюс. Опередил ты меня — недавно только закончил обработку, с печатью произвольного числа целой кучи разных таблиц, намучался изрядно.
спасибо.
видно, автор копнул глубоко, кое что пригодится
(29) я уже где-то встречал парсер ворда, думаю что он не сложнее парсера mt940 и подобных форматов;)
у Word’a есть команды на VBA, которыми можно позиционироваться на каждом элементе, будь то слово, таблица, рисунок…
(33) у меня определенные трудности были не с тем, как обработать данные, а с тем, как их получить 🙂 Объектная модель ворда для меня непривычна и незнакома, вот и сложности возникли 🙂
То что надо, именно это и искал, примерчик очень хороший… Благодарю плюсом!!!
спасибо!
просто,удобно. для начала обучения работы с вордом — отличный вариант.
Предлагаю так же посмотреть и мой вариантhttp://infostart.ru/public/95012/
(37) apalon_pss, мне кажется или это лишь часть описанного в моей статье?;))
спасибо! простой пример и очень понятно. отличный вариант. Автору спасибо, поможет для обучения работы с вордом —
А как в макете настроить чтобы применить вариант: Word.Bookmarks(«ff»).Select(); //Где ff — это набор любых символов
Нужно просто ввести понравившиеся вам символы в любом месте макета.
Word.Bookmarks(«ff»).Select() — это команда ищет в макете символы ff
Дорога ложка к обеду, спасибо за информацию.
(41) нет, она не ищет символы ff. она ищет метку с именем ff :)) вставлять метки в документе <> написать имя в текте документа
http://prosto1s.ru/index.php/24-pechat-v-word-chast-2-metod-zameny-tegov-klonirovanie-abzatsev-stok-tablitsy
смотрите
там написано как добавлять метки
(43) monkbest, именно ищет текст и заменяет его на все что захочет пользователь.
З.Ы. метки это совсем другое;) матчасть рулит
(44) Word.Bookmarks(«ff»).Select();
Bookmarks — коллекция меток документа
через скобочки с именем метки, можно получить саму метку
у неё есть метод select, который возвращает выделение области от начала метки до конца метки
это выделение можно скопировать в буфер, вырезать, вставить на его место то что уже лежит в буфере (cut() copy() paste())
Вот интересно как сделать две таблицы программно ?
По метке мы заменили одну таблицу, а если нужно вставить еще одну ниже.
Или таблицы нужно создавать в цикле, одна под одной как быть?
Метка уже не сработает, потому что ее перезаписали и на ее месте находится первая таблица.
Получается что метка служит всего навсего начальной областью куда нужно вставить первую таблицу но что дальше?
Если Вы заранее знаете что там будет еще одна таблица — тогда добавить еще метку и обработать по уже известному алгоритму)
Метки обрабатываются последовательно.
Друзья, кто-нибудь подскажет, можно ли в текст документа вставить специальный символ? Например символ бесконечности, евро или фунта стерлингов.
(48) kuza_87,
Можно. Используй комбинацию Аль+
Долго формируется таблица.
А как заполнить данные в таблице из табличной части нужного объекта?
(27) не получается определить закладку. У меня пишет, что метод объекта не обнаружен Bookmarks. Попробовал заменить в вашей обработке, тоже самое. Может можно как-то еще определить с какой строки начинается таблица? Или может я просто не правильно пишу?
Word.Bookmarks(«ff»).Select();
(52) «ff» это любой текст.
Можете вставить хоть «Тут должна быть таблица»
и в макете эта фраза должна присутствовать.
А какой офис установлен?
(53) я уж не совсем дурачок :). Я создал закладку на первой строке таблицы с названием ff. Офис 16 года. Не работает. Если честно, то метод слишком запутан. Я реализовал по-другому. Все чудесно работает. Но у меня четкое количество колонок. Хотя, думаю, если поковыряться то можно и произвольное сделать 🙂
Показать
(54) Все оказалось куда проще. Достаточно прописать это для создания колонки
Я как 1С-ник не могу добавлять строку или колонку как процедуру. Машинально переменную пишу 🙂 Хотя можно и без нее.
(55) Возможно за 8 лет офис и обрел новые функции VBA, хотя не исключено что я мог это пропустить;)