gifts2017

Форматированный документ в 1С

Опубликовал Сергей Гуков (SirYozha) в раздел Программирование - Работа с интерфейсом

Начиная с версии 8.2.11 в платформе появился новый объект – Форматированный документ. Так как не нашел на Инфостарте ни одного упоминания об этой функциональности, решил опубликовать небольшую статейку о том, что это за объект и какой функционал он добавляет.

Начиная с версии 8.2.11 в платформе появился новый объект – Форматированный документ. Так как не нашел на Инфостарте ни одного упоминания об этой функциональности, решил опубликовать небольшую статейку о том, что это за объект и какой функционал он добавляет. 

Прошу учесть, что это моя первая публикация. Итак, начнем…

Предназначение

Форматированный документ предназначен для оформление текста. Его можно выделить жирным, подчеркнуть, увеличить/уменьшить шрифт, центрировать и т.д. Также можно добавить картинку. Т.е. в 1С теперь можно отформатировать текст, примерно, как в MS Word и др. подобным программам. Это может быть удобно при оформлении различных договоров или, например, при редактировании электронного письма. Таким образом, у нас есть возможность привести текстовый документ в тот вид, который мы пожелаем.

Общий вид

В синтакс-помощнике есть описание.
Объект
ФорматированныйДокумент (FormattedDocument) имеет одноименный тип данных, который поддерживает функционирование данного объекта и имеет следующие методы:

Вставить (Insert)
Добавить (Add)
Записать (Write)
ПолучитьHTML (GetHTML)
ПолучитьЗакладкуКонца (GetEndBookmark)
ПолучитьЗакладкуНачала (GetBeginBookmark)
ПолучитьЗакладкуПоПозиции (GetPositionBookmark)
ПолучитьПозициюПоЗакладке (GetBookmarkPosition)
ПолучитьТекст (GetText)
Удалить (Delete)
УстановитьHTML (SetHTML)


Доступен во всех типах приложения: Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение. Нельзя указать новый тип данных в качестве типа реквизита.

Есть одна важная особенность этого типа. Нельзя задавать тип «Форматированный документ» для реквизита объекта (справочника, документа и др.). Но есть возможность указывать его для реквизитов формы.

 

реквизит объекта реквизит формы

Возникает вопрос, как же нам сохранить те изменения при форматировании текста, которые сделал пользователь? Для этого применяется специальный объект «ХранилищеЗначения», который может содержать в себе любой тип данных, в том числе и «форматированный документ». Таким образом, в базе данных сам объект будет храниться как «Хранилище значения», далее при открытии формы необходимо будет извлечь объект из хранилища, отобразить его на форме используя тип «ФорматированныйДокумент». Если пользователь решит сохранить изменения, то при записи объекта нужно снова взять объект «форматированный документ» и записать его в хранилище.

Пример работы

Возьмем за основу каркасную конфигурацию, создадим в ней справочники «Контрагенты» и «Договоры». Установим справочник «Договоры» подчиненным справочнику «Контрагенты» и создадим реквизит «Текст» с типом ХранилищеЗначения.

Создадим форму элемента справочника «Договоры» и добавим на нее новый реквизит, который назовем «ТекстДоговора», укажем тип данных «ФорматированныйДокумент». Обратите внимание, что реквизит «Текст» с типом «ХранилищеЗначения» на форму поместить нельзя.
Создадим также командную панель (меню) содержащую необходимые кнопки для управления форматированным документом. Для этого надо добавить в форму «Группа – Командная панель» и указать в свойстве «Источник команд» реквизит формы «ТекстДоговора» с типом ФорматированныйДокумент.

Настройка ФД в конфигураторе

Запускаем отладчик, проверяем, что у нас получилось…

Все бы хорошо, но есть некоторые проблемы:

Во-первых, если ввести текст и отформатировать его должным образом, то признак модифицированности для формы не возникает. Таким образом, случайно нажав на кнопку закрытия формы, система не задавая вопросов закрывает ее без всякого сохранения.
Для того чтобы подобные неприятности не случались, необходимо установить флаг у свойства «Сохраняемые данные» реквизита формы «ТекстДоговора». В результате, при любом изменении данных в реквизите «ТекстДоговора», будет устанавливаться признак модифицированности формы, а при ее закрытии система спросит: «Сохранить изменения?».

Во-вторых. Попытаемся закрыть форму и сохранить введенные данные. Заново открыв сохраненный договор, видим что текст введенный в форму договора отсутствует. Почему так происходит?

Все дело в том, что мы делаем изменения в реквизите формы, который у нас никак не связан с реквизитом объекта. Давайте настроим связь между реквизитом формы «Текст договора» с типом данных «ФорматированныйДокумент» и реквизитом объекта «Текст» с типом «ХранилищеЗначения».

Пропишем эту связь программно в модуле формы. Опишем алгоритм.

1. При открытии формы, необходимо будет обратиться к реквизиту объекта «Текст», чтобы прочитать из него данные и записать их в форматированный документ «Текст договора».
2. При записи объекта, берем содержимое форматированного документа и помещаем его в реквизит объекта «Текст» с типом «ХранилищеЗначения».

Таким образом у нас будет возникать эффект, что все изменения производимые пользователем, будут сохраняться в базе данных.

Нам понадобятся следующие обработчики событий:

 - событие ПриЧтенииНаСервере(ТекущийОбъект)

оно удобно тем, что при ошибочном внесении изменений в данные формы, можно нажать кнопку «Перечитать» и вернутся к исходным данным.

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
 
ТекстДоговора = ТекущийОбъект.Текст.Получить();
КонецПроцедуры

 - событие ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
 
ТекущийОбъект.Текст = Новый ХранилищеЗначения(ТекстДоговора);
КонецПроцедуры


Т.к. реквизит Текст у нас имеет тип «ХранилищеЗначений», надо учесть нюансы работы с ним… В случае чтения объекта используем метод Получить(), а в случае записи используем конструктор объекта Новый ХранилищеЗначения(, ).

На этом пока всё. В следующий раз попробую рассказать про использование шаблонов для вставки параметров в текст форматированного документа, например, вместо %Контрагент% вставлять наименование контрагента.

Благодарю за внимание!

 

upd

Полезные ссылки указаны товарищем Evg-Lylyk

http://www.1c-pro.ru/index.php?showto...entry92729
http://v8.1c.ru/overview/Term_000000785.htm
 

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Игорь Исхаков (Ish_2) 02.09.10 07:59
Не проверял , но написано хорошо !
2. Александр Рытов (Арчибальд) 02.09.10 08:01
Уважаю популяризаторов :)
4. Владимир Поздняков (Red_Devil) 02.09.10 09:32
ИМХО плагиат ...
пересказ с видео курсов "Профессиональное программирование" ?)
5. Reaper_1c Reaper_1c (Reaper_1C) 02.09.10 10:26
И ни один из популяризаторов не говорит о том, что изменение содержания и форматирования содержания на уровне встроенного языка не реализовано. Хотите управлять программно - разгадывайте формат хранения документа в HTML и собирайте документ тегами вручную...
Serega-artem; nano1c; SirYozha; Evg-Lylyk; +4 Ответить 1
6. Андрей Данилюк (DanilaDru) 02.09.10 10:29
Да..... а когда этого не было приходилось tinymce крутить. Надо будет попробовать. Спасибо.
7. Armando Armando (Armando) 02.09.10 10:41
Сделали бы они человеческий макет с типа ФорматированныйДокумент...
8. Михаил Ражиков (tango) 02.09.10 11:09
9. Сергей Гуков (SirYozha) 02.09.10 13:38
(4) Red_Devil, скажем так, о "форматированном документе" действительно узнал из курса "Профессиональное программирование в 1С 8.2" от двух замечательных авторов Евгения Гилева и Фарита Насипова. Но не вижу ничего страшного в том, чтобы поделиться знаниями с другими людьми.

(5) Программная обработка форматированного документа реализована слабо, согласен...

(8) Ну это врядли! ;)
10. Андрей Д. (detec) 02.09.10 14:22
А нельзя ли ссылки на картинки дать не с ЖЖ, а с самого инфостарта или более-менее благонадёжного сайта? У меня на работе порезан ЖЖ, в частности.
11. Valery Mikh (Robbi) 02.09.10 15:47
Спасибо. Полезная статья.
Замечена некорректная работа с текстом, вставленным из Word - вот пример если его попробовать залить:

Ошибка преобразования данных XDTO:... НачалоСвойства: fmtd Форма: Элемент Тип: {http://www.w3.org/2001/XMLSchema}anyType
по причине: ...
Ошибка отображения типов:...
Отображение типа 'РасширенноеИмяXML' в тип '{http://v8.1c.ru/8.1/data/ui}Color'
12. Valery Mikh (Robbi) 02.09.10 15:58
(11) И в web-клиенте использование проблематично... :( а в толстом пока вообще не понял как сделать
13. Гилев Евгений (coach) 03.09.10 07:09
(13) В чем проблемы? Управляемые формы в толстом клиенте доступны.
14. Valery Mikh (Robbi) 03.09.10 09:23
(14) Я понадеялся что и в обычную форму можно запихать. Нельзя - но это и не столь важно.
Важнее то, что скопированный и вставленный текст невозможно корректно править! Это очень плохо, т.к. была цель сохранять некую информацию с документов word и просто с браузера копипастом. Сегодня ещё поэкспериментирую.
15. sound sound (sound) 05.09.10 00:13
Прошу учесть, что это моя первая публикация.


Побольше бы таких первых публикаций :)
alexdarh; adhocprog; +2 Ответить
16. RomDron (RomDron) 07.09.10 10:21
На данный момент обьект работает не стабильно и ОЧЕНЬ медленно. Попробуйте вставить туда 5 фото и проверить время открытия в тонком клиенте. При большом количесте инфы часть ее теряется при сохранении. Форматирование тоже иногда слетает. Сам пользуюсь, но только от того, что не хочу использовать внешние компоненты.
iZhenius; Robbi; +2 Ответить
17. pau74 (pau74) 08.09.10 03:51
Пользуюсь форматированным документом как шаблоном печатной формы договора
Спасибо за публикацию
18. pau74 (pau74) 08.09.10 04:12
Вопрос:
Поддерживает ли форматированный документ многомерные списки?
В процессе редактирования не получилось.
Увеличение уровня отступа выполняется, а дальнейшее уменьшение уровня отступа начинает нумерацию сначала.
19. Эстер Коган (e.kogan) 08.09.10 10:10
Я вот одного не понимаю: а что, в 8.1 с полем HTML документа никто не работал? По описанию - практически ничем не отличается. Разве что картинку можно теперь вставить без геморроя.
DanilaDru; +1 Ответить
20. Андрей Данилюк (DanilaDru) 24.02.11 12:59
Докрутил форматированный документ у себя. http://danila.org.ua/?p=619

Что было замечено при программном переносе данных с сайта в форматированный документ.
Получаю html документ с сайта, выбираю нужный кусок. В html-коде присутствует следующее:
"font-size: 10pt; color: black; line-height: 150%; font-family: Arial" Патент №
"font-size: 10pt; color: black; line-height: 150%; font-family: Arial" Дата регистрации

После выполнения у форматированного документа УстановитьHTML()
"line-height: 150%" заменяется на "line-height: 150" (съедается процент) и следовательно очень большие интервалы у меня между строк

Так что лучше использовать "line-height: 1.5".
21. Саша (TbSasha) 02.03.11 01:27
А у меня почему то «Командная панель» не активная и не получается форматировать текст? «Источник команд» реквизита формы «ТекстДоговора» с типом ФорматированныйДокумент я указал.
Да и текст введенный в «ТекстДоговора» не сохраняется. Процедуры в модуль формы добавил. Что может быть не так?
22. Adapter Бахтыреев (adapter) 09.09.11 12:26
Если использовать ПолеформатированногоДокумента в управляемой форме, запущенной в обычном режиме, то картинки не отображаются. Сохраняешь стр на диск как html, а они там есть.
23. Виктор Родыгин (rodygin) 10.12.11 11:41
Ок. Ну допустим, сделали в форматированном документе шаблон, например, договора. А как его на печать вывести?
24. aleec bard (alexvbard) 22.06.12 22:19
И есть ли возможность подставлять значения в форматированный документ?
25. Adapter Бахтыреев (adapter) 25.06.12 12:17
Начиная с 15 релиза платформы форматированный документ в тексте HTML теперь еще содержит и определение стилей CSS по умолчанию, причем с ошибками - убирает полосы прокрутки. Пожелание по исправлению 1С приняли, возможно даже сделают содержании таблицы стилей отдельным реквизитом. Пока следует таблицу править программно при открытии.
26. John Smith (PiccaHut001) 12.09.12 19:05
есть ошибки, пока пользоваться нет смысла
27. Александр Доровских (Requiem) 18.10.12 12:31
А картинки я как понимаю тоже в том же реквизите с типом "ХранилищеЗначения" хранятся?
28. Александр Савошин (Ctrl P) 21.11.12 13:53
Публикации 2 года, а где же обещанные:

"В следующий раз попробую рассказать про использование шаблонов для вставки параметров в текст форматированного документа, например, вместо %Контрагент% вставлять наименование контрагента."

идея сначала понравилась, но за 2 года так этот объект и не получил развития...
29. Сергей Болбачан (sergbsv) 31.01.13 10:56
(25) adapter, Как можно вставлять (использовать) таблицы ?
30. Adapter Бахтыреев (adapter) 01.02.13 20:36
таблицу стилей CSS?

//на сервере
 ФормДок.ПолучитьHTML(HTML, Структура);

//на клиенте
	ТекстПоиска = "
	|<style type=""text/css"">
	|body{margin:0px;padding:8px;overflow:hidden;width:100%;height:100%;}
	|p{line-height:1.15;margin:0px;}
	|ol,ul{margin-top:0px;margin-bottom:0px;}
	|img{border: none;}
	|</style>";
	HTML = СтрЗаменить(HTML,ТекстПоиска,"");
	
	ЭтаФорма.текст_хтмл = HTML;

...Показать Скрыть


Вместо "" можете вставить свое определение стилей
31. Андрей Шишков (oks-nt) 01.04.13 12:50
При сохранении/восстановлении значения через форматированный документ терялись переносы строк. Абзацы сохранялись, а если в тексте были символы переноса строки, они терялись.

Оказалось, что после вставки из Word символы переноса строк в HTML превращались в тэг </br>. При открытии этот тэг удалялся. Очевидно, как закрывающий тэг без открывающего считался ошибочным.

Вылечивается например ПередЗаписью примерно так:

ТекстОригинал.ПолучитьHTML(ТекущийОбъект.ТекстОригинал, мСтруктураОригинал);
ТекущийОбъект.ТекстОригинал = СтрЗаменить(ТекущийОбъект.ТекстОригинал, "</br>", "
");
32. Дмитрий Николайчук (dimetra2008) 28.05.13 07:53
В толстом клиенте не получается такое настроить...
33. Андрей (Arven) 21.08.13 16:55
34. Александр Тарасинский (axxell) 12.02.14 13:53
(30) adapter,
Тут даже не нужна своя таблица стилей и достаточно добавить 1 строку, например, при открытии формы с объектом html
ТекстHTML = СтрЗаменить(ТекстHTML, "overflow:hidden", "overflow:auto");
35. John Smith (PiccaHut001) 14.10.14 17:53
(34) axxell, сколько извращений, спасибо 1С
36. zak555 (zak555) 09.02.15 13:02
Как ФорматированныйДокумент сохранить, как excel файл или в pdf?
37. Марина Фёдоровна (izabella_romanova) 21.04.15 15:49
спасибо большое за публикацию. оказалось полезной)
38. Кирилл Щербаков (Rik30) 29.05.15 10:33
А можно пример получить? Не получается сделать
39. Константин Рыбаков (pyrkin_vanya) 05.06.15 10:43
40. mc2 10.07.15 17:48
(31) oks-nt,
Большое спасибо! Долго не мог понять в чем дело. Кстати, эту ошибку метода ПолучитьHTML исправили в 8.3.5.1068
В младших релизах вместо вызова

ФорматДок.ПолучитьHTML(Текст, Картинки);


надо использовать функцию:

Функция ПолучитьHTML(ФорматДок, Текст, Картинки) Экспорт
     ФорматДок.ПолучитьHTML(Текст, Картинки);
     Возврат СтрЗаменить(Текст, "</br>", "");
КонецФункции
...Показать Скрыть
41. Дмитрий Ли (Shaka13) 27.08.15 20:55
Спасибо, хороший материал, как раз в тему!
Попробовал на 8.3.6 все работает, жду обещанных продолжений по этой теме :)
42. Дмитрий Ли (Shaka13) 27.08.15 21:06
но вот тут http://v8.1c.ru/overview/Term_000000785.htm
написано:
Форматированный документ нельзя сохранить в виде файла, но поддерживается его экспорт в текстовый файл или файл HTML.

это нужно делать дополнительную обработку, т.к. я нигде не нашел такой возможности?
43. Дмитрий Ли (Shaka13) 27.08.15 23:55
и еще вопрос, а как сделать в печатную форму, данный объект не выводится в нее?
44. Александр Космачев (greystone) 23.09.15 09:58
таблицы не вставляются, например в конце договора надо вставить реквизиты
45. Nicholas Mikuslas (Nicholas) 26.10.15 11:53
(22) adapter, столкнулся с подобной ситуацией.
Но дело оказалось немного в другом.
Если получать данные на клиенте, то картинки не отображаются, если на сервере - все ок.

Например, вот так не работает:

&НаКлиенте
Процедура СписокПриАктивацииСтроки(Элемент)
    ФорматированныеДокумент = Элемент.ТекущаяСтрока.ДетальноеОписание.Получить();
КонецПроцедуры


И даже так не работает:

&НаСервере
Функция ПолучитьДетальноеОписаниеНаСервере(Код)
    Возврат Справочники.Справочник.НайтиПоКоду(Код).ДетальноеОписание.Получить();
КонецФункции

&НаКлиенте
Процедура СписокПриАктивацииСтроки(Элемент)
    ФорматированныеДокумент = ПолучитьДетальноеОписаниеНаСервере(Элемент.ТекущиеДанные.Код);
КонецПроцедуры
...Показать Скрыть


Работает только так:

&НаСервере
Процедура ПолучитьДетальноеОписаниеНаСервере(Код)
    ФорматированныеДокумент = Справочники.Справочник.НайтиПоКоду(Код).ДетальноеОписание.Получить();
КонецПроцедуры

&НаКлиенте
Процедура СписокПриАктивацииСтроки(Элемент)
    ПолучитьДетальноеОписаниеНаСервере(Элемент.ТекущиеДанные.Код);
КонецПроцедуры
...Показать Скрыть

Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа