Рейтинг: 5/5
У попередній статті ми створювали шаблон друкованої форми для керованого застосування. Він у нас виводив просту фразу "Привіт світ" в табличний документ. На базі того зразка можна створювати друковані форми формують табличні документи. Однак як відомо вони володію рядом обмежень і незручностей. Перерахую ті, які мені відомі:
1. Не можна ставити різний шрифт всередині одного осередку. Тобто щоб виділити в абзаці тексту одне слово, треба замучили з розбиттям і підгонкою абзацу на окремі клітини таблиці.
2. Погано переносяться великі осередки. якщо осередок
не влазить на поточну сторінку цілком, вона почнеться на наступній сторінці, навпіл вона не розріже.
3. Не завжди (особливо в платформі 8.3 в керованих формах) працює правило шрифтів True Type. Правило "що бачу, то друкую" в 1С працює погано, дуже часто на екрані все поміщається в комірку, на папері обрізається, і навпаки, на екрані вилазить за межі, на папері все ок.
4. Редагувати отриманий табличний документ засобами 1С - незручна завдання. Потрібно збереження в інший формат.
5. Слідство пункту "4" - збереження в Excel не завжди відбувається один до одного. Все ж mxl і xls - різні формати.
І тут приходить в голову думка, а що якщо виводити на екран не табличний макет, а документ Microsof Word, вже заповнений потрібними даними!
Ця схема відмінно підходить, коли ми формуємо всякого роду тексти договорів (трудової, на закупівлю.).
Ну що, приступимо?
Крок перший - дивимося попередню статтю і беремо від туди зразок.
Крок другий - готуємо шаблон документа.
Тут я Вам хучу запропонувати технологію працюючу через змінні документа DocVariable. Для початку відкриваємо MS Word пишемо в ньому текст нашого договору. У моєму прикладі це буде трудовий договір складається з одного абзацу.
Після складання самого договору, будемо визначатися з тим, що у нас буде заповнюватися в ньому саме. Тобто виявляти змінну частину документа. Пропоную друкувати договір з довідника співробітники. Як номер договору будемо друкувати табельний, як дати - дату прийому. Так само виведемо ПІБ прийнятого співробітника, коротка назва організації і повне. Я на зображенні червоним виділи то, що ми перетворимо в змінні.
Починаємо розміщувати змінні. Прибираємо номер договору і додаємо на його місце змінну. Для цього меню вставка / експрес блоки / поле
У вікні вибираємо тип поля DocVariavle і присвоюємо йому осмислене латинське ім'я tabelNum. Тиснемо ОК.
На екрані Ви швидше за все нічого не побачите, але не поспішайте повторювати операцію. Просто у Вас режим не відображає коди полів. Для того, щоб побачити код поля натисніть Alt + F9.
Таким чином ми замінюємо весь червоний текст змінними документа.
Крок третій - створення макета.
Тепер зберігаємо файл на диск і повертаємося в 1С. В обробці Гуркало наш макет зі словами "Привіт світ". Додаємо новий макет з типом "двійкові дані" і вантажимо в нього наш документ MS Word. Не забудьте закрити документ в ворде, а то 1С і Word ругануться на спільний доступ до файлу.
Крок четвертий - програмуємо.
Ліземо в модуль обробки. Тут є нюанс, який треба знати. Команда друку виконується на клієнті, а отримуємо дані ми на сервері. На сервері у нас може бути відсутня програма MS Word, яким ми створимо документ, відповідно документ ми формуємо на клієнті. Так само ми не виводимо табличний документ. Подумавши про ці нюансів кидаємося в бій.
Насамперед стираємо процедуру друку з модуля обробки і процедуру формування макета. Після цього відкриваємо процедуру СведеніяОВнешнейОбработке () і правимо рядок з додаванням команди наступним чином:
ДобавітьКоманду (ТабліцаКоманд, "Привіт світ", "Макет", "ВизовКліентскогоМетода", Істина, "");
Так само правимо прівзку зовнішньої друкованої форми:
І відключимо безпечний режим, тому що зовнішні компоненти в безпечному режимі не доступні:
Тепер закриваємо модуль обробки і додаємо в обробку основну форму. Переходимо в модуль форми.
Спочатку створимо функцію, яка нам поверне структуру корисних властивостей. Тут все залежить від того, наскільки складний макет ви задумали і звідки Ви будите заповнювати параметри. Швидше за все тут буде текст запиту і повернення його результатів. Ось шматок коду, який вийшов у мене:
Ще нам потрібно отримати OLE об'єкт MS Word. Сунути йому наш шаблон і заповнити в ньому змінні. Шаблон ми можемо отримати тільки в контектсте сервера, тому пишемо коротку серверну функцію:
На сервері
Функція ПолучітьМакетСервер ()
Повернення РеквізітФормиВЗначеніе ( "Об'єкт"). ПолучітьМакет ( "Макет");
КонецФункціі
Ну тепер пишемо процедуру друку.
Процедура Друк (ІдентіфікаторКоманди, МассівОб'ектов) Експорт
Для Кожного співробітник З МассівОб'ектов Цикл
Дані = ПолучітьДанние (співробітник);
якщо дані <> Не визначено Тоді
Word = Новий COMОб'ект ( "Word.Application");
Макет = ПолучітьМакетСервер ();
временнийПуть = КаталогВременнихФайлов ();
імяВременногоФайла = временнийПуть + "gph.doc";
Макет.Запісать (імяВременногоФайла);
ТекДок = Word.Documents.ADD (імяВременногоФайла);
ТекДок.Variables ( "tabelNum"). Value = Данние.Табельний;
ТекДок.Variables ( "orgNameS"). Value = Данние.ОргКртако;
ТекДок.Variables ( "DocDate"). Value = Данние.Дата;
ТекДок.Variables ( "fio"). Value = Данние.ФІО;
ТекДок.Variables ( "orgNameLong"). Value = Данние.ОргДлінно;
ТекДок.Fields.Update ();
Word.ActiveWindow.View.ShowFieldCodes = False;
Word.Visible = Істина;
КонецЕсли;
КонецЦікла;
КонецПроцедури
1. Отримуємо дані
2. Якщо дані отримані виконуємо алгоритми формування
3. Створюємо COM об'єкт MS Word
4. Отримуємо макет
5. отримуємо каталог тимчасових файлів
6. Зберігаємо туди наш макет під довільним ім'ям
7. Створюємо документ MS Word вказуючи в якості параметра Template наш макет.
8-12. Заповнюємо змінні документа даними
13. Оновлюємо поля документа
14. Ховаємо коди полів (аналог Alt + F9)
15. Показуємо (напевно зайве, тому що команда add вже зробив його видимим за замовчуванням)
Викладіть будь ласка обробку А то я намагався зробити договір поставки ну ніяк не виходить. Запускаю обробку, а вона навіть за кодом не проходить в налагодженні!
Добрий день. В даному методі "вставки" не використовуються, є інший метод, де використовується буфер обміну в парі з пошуком і заміною входжень. Він описаний в іншій статті. Там можна щось придумати зі зміною шрифту, наприклад виділити символи з N по M і задати їм форматування.
Тут ми просто змінним документа задаємо текстове значення, без формату і формат визначається форматом шрифту самої змінної.
Якщо ви працюєте з об'єктною моделлю, то створюєте структуру:
дані = Новий Структура ( "Ки1, Кі2, Кі3)
Для Кожного стрКі З Контр.КІ Цикл
Якщо стрКі.Тіп = тип1 І стрКІ.Від = вид1 Тоді
данние.КІ1 = стрКі.Предствал ення;
ІначеЕслі.
КонецЦікла;
Цитую Антон Філоненко:
Якщо ви працюєте з об'єктною моделлю, то створюєте структуру:
дані = Новий Структура ( "Ки1, Кі2, Кі3)
Для Кожного стрКі З Контр.КІ Цикл
Якщо стрКі.Тіп = тип1 І стрКІ.Від = вид1 Тоді
данние.КІ1 = стрКі.Предстваленіе;
ІначеЕслі.
КонецЦікла;
Спасибі, Антон.
Я, взагалі-то, так і робив, але через те, що писав не "данние.КІ1 =", а просто "Ки1 =", отримував помилку.
Тепер все працює чудово!
Щиро Дякую!
Антон, здрастуйте.
Ще одна проблема виникла:
Всі дані витягуються коректно, але при запуску обробки в клієнт-серверно м режимі вискакує помилка:
": Помилка при виклику методу контексту (Add)
ТекДок = Word.Documents.ADD (імяВременногоФайла);
по причині:
Відбулася виняткова ситуація (Microsoft Word): Помилка в Word. "
З чим це може бути пов'язано і як з цим боротися?
Перезавантаження не допомогла, Word відкривається і дає в ньому працювати нормально.
У файловому варіанті бази - працює.
Дякуємо
Якщо лається тільки в серверній базі треба думати чим відрізняється контекст сервера від клієнта.
Перше на що слід звернути увагу, де цей рядок коду розташована? У статті я писав, що це клієнтська процедура (НаКліенте), а значить різниці бути не повинно файлова або НЕ файлова.
Друге, я б посомтрел що за шлях у змінній "імяВременногоФ Айла", чи існує він там і чи є у користувача вінди права на цей каталог. Додайте рядок коду Повідомити (імяВре менногоФайла) перед цим рядком.
Третє, я б переконався, що файл в макеті є документом word і формат відповідає розширенню (doc і docx - різні формати)
Цитую Антон Філоненко:
Якщо лається тільки в серверній базі треба думати чим відрізняється контекст сервера від клієнта.
Перше на що слід звернути увагу, де цей рядок коду розташована? У статті я писав, що це клієнтська процедура (НаКліенте), а значить різниці бути не повинно файлова або НЕ файлова.