Как сохранить форматированный документ из формы в реквизит справочника (или документа) типа "ХранилищеЗначения" в 1С:Предприятии 8.3?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с информационными системами на базе 1С:Предприятия 8.3 часто возникает необходимость хранения и отображения текста с форматированием, такого как выделение жирным шрифтом, курсивом, подчеркиванием, изменение цвета, размера, а также вставка списков и гиперссылок. Стандартным способом реализации этой задачи является использование объекта ФорматированныйДокумент в сочетании с реквизитом типа ХранилищеЗначения.

Рассмотрим по шагам, как правильно организовать сохранение форматированного текста из элемента формы в реквизит справочника (или документа) и последующее его извлечение для отображения.

Подготовка: Реквизиты и элементы формы

Прежде чем перейти к программному коду, нам необходимо правильно настроить структуру данных в конфигурации и элементы на форме.

  1. Реквизит объекта конфигурации (справочника, документа):

    Для хранения самого форматированного текста в базе данных, нам потребуется добавить новый реквизит в ваш справочник или документ. Этот реквизит должен быть типа ХранилищеЗначения. Назовем его, например, ТекстИнструкции или СодержимоеДокумента. Именно в этом реквизите будет храниться сериализованный объект ФорматированныйДокумент.

  2. Реквизит формы:

    На форме вашего объекта (например, справочника или документа), где пользователь будет вводить и просматривать форматированный текст, создайте новый реквизит формы. Важно отметить, что реквизит формы должен быть типа ФорматированныйДокумент. Назовем его, например, СодержаниеИнструкции. Этот реквизит формы будет напрямую взаимодействовать с элементом управления на форме.

  3. Элемент формы:

    Теперь добавим на форму управляемый элемент, который позволит пользователю редактировать форматированный текст. Используйте элемент типа ПолеФорматированногоДокумента. В свойствах этого элемента обязательно свяжите его с созданным реквизитом формы СодержаниеИнструкции. Для этого в свойстве "Путь к данным" укажите имя реквизита формы.

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

Шаг 1: Сохранение форматированного документа в хранилище значений

Для сохранения данных из реквизита формы в реквизит объекта при записи, мы будем использовать обработчик события ПередЗаписьюНаСервере объекта.

Проанализируем ситуацию: когда пользователь нажимает кнопку "Записать" или "ОК" на форме, система вызывает событие ПередЗаписьюНаСервере. В этот момент нам нужно взять текущее содержимое нашего реквизита формы (который имеет тип ФорматированныйДокумент) и поместить его в реквизит объекта (который имеет тип ХранилищеЗначения).

Рассмотрим пример кода:


&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    // 'СодержаниеИнструкции' - это реквизит формы с типом 'ФорматированныйДокумент'.
    // Он содержит весь форматированный текст, введенный пользователем.

    // 'ТекстИнструкции' - это реквизит объекта (справочника или документа)
    // с типом 'ХранилищеЗначения'. Он предназначен для постоянного хранения данных в базе.

    // Создаем новый объект 'ХранилищеЗначения', передавая ему наш форматированный документ
    // из реквизита формы. 'ХранилищеЗначения' автоматически сериализует объект
    // 'ФорматированныйДокумент' для хранения.
    ТекущийОбъект.ТекстИнструкции = Новый ХранилищеЗначения(СодержаниеИнструкции);

    // Важно: в отличие от некоторых других объектов, у 'ХранилищаЗначения',
    // созданного таким образом, метод 'Записать()' вызывать не нужно.
    // Присвоение значения реквизиту объекта уже 'помещает' его в хранилище,
    // а сам объект будет записан в базу данных при завершении стандартной процедуры записи объекта.
    // Строчка типа ТекущийОбъект.ТекстИнструкции.Записать(СодержаниеИнструкции);
    // в данном контексте будет ошибочной и лишней.
КонецПроцедуры

В этом коде мы используем конструктор Новый ХранилищеЗначения(), который принимает в качестве параметра значение, которое необходимо сохранить. В нашем случае это реквизит формы СодержаниеИнструкции типа ФорматированныйДокумент. Созданный объект ХранилищеЗначения затем присваивается реквизиту объекта ТекущийОбъект.ТекстИнструкции. Платформа 1С самостоятельно позаботится о сериализации и сохранении данных при записи всего объекта.

Шаг 2: Чтение форматированного документа из хранилища значений

Для загрузки и отображения форматированного текста при открытии формы, мы будем использовать обработчик события ПриЧтенииНаСервере объекта.

Разберем процесс: когда форма объекта открывается, система вызывает событие ПриЧтенииНаСервере. В этот момент объект (справочник или документ) уже загружен из базы данных, и его реквизиты доступны. Наша задача — извлечь сохраненный форматированный документ из ХранилищаЗначения и поместить его в реквизит формы для отображения.

Посмотрим на пример кода:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    // 'СодержаниеИнструкции' - это реквизит формы с типом 'ФорматированныйДокумент'.
    // В него мы будем загружать данные для отображения на форме.

    // 'ТекстИнструкции' - это реквизит объекта с типом 'ХранилищеЗначения',
    // где хранится наш форматированный текст.

    // Прежде чем пытаться получить данные, всегда полезно проверить, не пусто ли хранилище.
    // Если хранилище пустое, это означает, что текст еще ни разу не был сохранен
    // или был удален. В этом случае мы инициализируем реквизит формы пустым форматированным документом.
    Если Не ТекущийОбъект.ТекстИнструкции.Пустая() Тогда
        // Используем метод .Получить() объекта 'ХранилищеЗначения' для десериализации
        // и извлечения сохраненного объекта 'ФорматированныйДокумент'.
        СодержаниеИнструкции = ТекущийОбъект.ТекстИнструкции.Получить();
    Иначе
        // Если хранилище пустое, создаем новый пустой форматированный документ,
        // чтобы избежать ошибок и дать возможность пользователю начать ввод.
        СодержаниеИнструкции = Новый ФорматированныйДокумент;
    КонецЕсли;
КонецПроцедуры

В этом коде мы используем метод .Получить() объекта ХранилищеЗначения, чтобы десериализовать и извлечь сохраненный объект. Результат присваивается реквизиту формы СодержаниеИнструкции, который затем автоматически отобразится в элементе формы ПолеФорматированногоДокумента. Очень важно добавить проверку Не ТекущийОбъект.ТекстИнструкции.Пустая(), чтобы избежать ошибок, если в хранилище еще нет данных (например, для нового элемента справочника или документа).

Важные аспекты работы с ФорматированнымДокументом и ХранилищемЗначения

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

  1. Механизм сериализации ХранилищаЗначения:

    ХранилищеЗначения – это универсальный механизм 1С для хранения любых сериализуемых значений в базе данных. Когда мы помещаем объект ФорматированныйДокумент в ХранилищеЗначения, платформа автоматически преобразует его в бинарный формат, пригодный для хранения. При извлечении методом .Получить() происходит обратный процесс – десериализация, и мы получаем исходный объект ФорматированныйДокумент. Это обеспечивает целостность и сохранность всех настроек форматирования, включая шрифты, цвета, списки и вставленные объекты.

  2. Ограничения типов реквизитов:

    Критически важно понимать, что реквизит самого объекта конфигурации (например, справочника или документа) не может иметь тип ФорматированныйДокумент напрямую. Этот тип допустим только для реквизитов формы. Именно поэтому мы используем промежуточное звено – ХранилищеЗначения для реквизита объекта, а ФорматированныйДокумент для реквизита формы и связанного с ним элемента.

  3. Возможности форматирования ФорматированногоДокумента:

    Элемент ПолеФорматированногоДокумента предоставляет богатые возможности по редактированию текста. Мы можем:

    • Изменять шрифт, его размер и начертание (полужирный, курсив, подчеркивание, перечеркивание).
    • Устанавливать цвет фона и текста.
    • Применять различные варианты выравнивания (по левому краю, по центру, по правому краю, по ширине).
    • Регулировать отступы абзацев.
    • Использовать маркированные и нумерованные списки.
    • Вставлять изображения (которые будут храниться внутри самого ФорматированногоДокумента).
    • Добавлять гиперссылки.
    • Работать с закладками для навигации по тексту или выделения его частей.

    Все эти возможности сохраняются при преобразовании в ХранилищеЗначения и восстанавливаются при загрузке.

  4. Производительность и размер данных:

    Хранение больших объемов данных, особенно с многочисленными изображениями, внутри ХранилищаЗначения может потенциально повлиять на производительность базы данных. Это связано с тем, что данные хранятся непосредственно в таблице объекта, и при чтении всего объекта извлекается и хранимый форматированный документ.

    Однако современные версии платформы 1С постоянно оптимизируются, и для умеренных объемов данных (например, документы с несколькими десятками скриншотов) производительность может быть вполне приемлемой. Если же речь идет об очень больших документах с сотнями изображений, возможно, стоит рассмотреть альтернативные подходы, такие как хранение изображений в отдельных реквизитах типа ХранилищеЗначения (каждое изображение отдельно) или во внешних файлах со ссылками на них в форматированном тексте.

    Для большинства типовых задач по хранению инструкций, описаний или небольших отчетов, предложенный подход с ФорматированныйДокумент в ХранилищеЗначения является оптимальным.

  5. Экспорт и импорт данных:

    Напрямую сохранить ФорматированныйДокумент в виде отдельного файла (например, RTF или DOCX) платформа 1С не предоставляет. Однако, мы можем получить его содержимое в виде текстового файла или HTML. Методы ПолучитьHTML() и УстановитьHTML() объекта ФорматированныйДокумент позволяют работать с представлением документа в формате HTML, что может быть полезно для интеграции с внешними системами или для более гибкого экспорта/импорта.

  6. Альтернативные подходы (HTML):

    В некоторых случаях, если нам требуется еще большая гибкость в представлении и хранении форматированного текста (например, для сложной кастомизации стилей или интеграции со специфическими веб-компонентами), можно рассмотреть хранение форматированного текста в реквизите типа Строка неограниченной длины в формате HTML. Изображения в таком случае могут быть встроены в HTML-код с помощью кодирования Base64. Для работы с таким представлением также используются методы ПолучитьHTML() и УстановитьHTML() объекта ФорматированныйДокумент. Однако этот подход требует более глубокого понимания HTML и может быть более трудоемким в реализации, если стандартные возможности ПоляФорматированногоДокумента достаточны.

Заключение

Используя связку ФорматированныйДокумент на форме и ХранилищеЗначения в объекте, мы получаем эффективный и стандартный инструмент для работы с богатым текстом в приложениях на платформе 1С:Предприятие 8.3. Этот подход позволяет нам не только сохранять сложный форматированный контент, но и предоставлять пользователям удобный и интуитивно понятный интерфейс для его редактирования. Важно всегда помнить о правильном выборе типов реквизитов и корректно реализовывать логику сохранения и загрузки в соответствующих обработчиках событий, как мы это подробно рассмотрели.

← На главную