При разработке в среде 1С:Предприятие 8.3 начинающие разработчики часто сталкиваются с ситуацией, когда добавленная на форму таблица значений (ТЗ) исправно заполняется данными, но после закрытия и повторного открытия документа оказывается пустой. Рассмотрим природу этой проблемы и разберем несколько эффективных способов реализации сохранения данных.
Прежде всего, выясним причину такого поведения системы. В 1С существует четкое разделение между данными объекта (которые хранятся в базе данных) и данными формы (которые существуют только в оперативной памяти, пока открыто окно). Если вы создаете таблицу значений непосредственно в редакторе формы (в колонке «Реквизиты»), она становится реквизитом формы, а не документа. Проанализируем ситуацию: при нажатии кнопки «Записать» система автоматически сохраняет только те данные, которые входят в состав Объект. Все остальные реквизиты формы игнорируются, так как платформа «не знает», в какую таблицу базы данных их поместить.
Самый правильный и надежный способ — использовать механизм табличных частей документа. Если вы работаете в расширении, вы можете добавить новую табличную часть к заимствованному документу. Рассмотрим алгоритм действий:
ТоварыДляОбработки.В этом случае 1С берет на себя всю работу по сохранению и чтению данных. Нам не нужно писать ни одной строчки кода для того, чтобы данные оставались в базе после закрытия формы. Это стандартный путь, который гарантирует целостность данных и возможность построения отчетов по этой таблице в будущем.
Иногда использование табличной части документа нецелесообразно (например, если данных слишком много или они носят технический характер). В такой ситуации проанализируем вариант с использованием Регистра сведений. Разберем по шагам, как организовать связь между формой документа и регистром:
Создадим регистр сведений (например, ДанныеДокументовРасширения). В измерениях обязательно укажем ссылку на наш документ с включенным свойством «Ведущее». Это обеспечит автоматическое удаление записей при удалении самого документа. Программная реализация потребует использования серверных обработчиков формы.
Для записи данных используем обработчик ПередЗаписьюНаСервере:
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Создаем набор записей регистра
НаборЗаписей = РегистрыСведений.ДанныеДокументовРасширения.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ДокументСсылка.Установить(ТекущийОбъект.Ссылка);
// Переносим данные из таблицы значений на форме (РеквизитТЗ) в набор записей
Для Каждого СтрокаТЗ Из РеквизитТЗ Цикл
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.ДокументСсылка = ТекущийОбъект.Ссылка;
ЗаполнитьЗначенияСвойств(НоваяЗапись, СтрокаТЗ);
КонецЦикла;
НаборЗаписей.Записать();
КонецПроцедуры
Для чтения данных при открытии используем обработчик ПриЧтенииНаСервере:
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// Читаем данные из регистра
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ * ИЗ РегистрСведений.ДанныеДокументовРасширения
|ГДЕ ДокументСсылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", ТекущийОбъект.Ссылка);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
// Заполняем реквизит формы из таблицы значений
ЗначениеВРеквизитФормы(РезультатЗапроса, "РеквизитТЗ");
КонецПроцедуры
Если структура таблицы часто меняется или данные не требуют сложного анализа, мы можем применить метод «упаковки» таблицы в одну строку. Для этого создадим у документа строковый реквизит неограниченной длины (например, ТехническиеДанныеТЗ). Посмотрим на пример реализации с использованием современных методов JSON-сериализации:
В обработчике ПередЗаписьюНаСервере превращаем таблицу в строку:
&НаСервере
Процедура СохранитьТЗвСтроку(ТекущийОбъект)
// Преобразуем данные формы в обычную таблицу значений
ТаблицаОбъект = РеквизитФормыВЗначение("РеквизитТЗ");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ТаблицаОбъект);
ТекущийОбъект.ТехническиеДанныеТЗ = ЗаписьJSON.Закрыть();
КонецПроцедуры
Важно помнить, что метод ЗначениеВСтрокуВнутр, упомянутый в некоторых обсуждениях, является устаревшим и платформенно-зависимым. Использование JSON является более гибким и современным стандартом в экосистеме 1С v8.3.
При использовании любого из вышеперечисленных методов в расширении, обратим внимание на следующие моменты:
ДанныеФормыКоллекция. Для выполнения программных манипуляций (сортировка, выгрузка в запрос) ее всегда нужно переводить в объект ТаблицаЗначений с помощью функции РеквизитФормыВЗначение().ПриЗаписиНаСервере и ПередЗаписьюНаСервере. Рекомендуется использовать ПередЗаписьюНаСервере, так как в этот момент у нас есть доступ к ТекущийОбъект, который еще не зафиксирован в базе, что позволяет корректно подготовить все связанные данные.Таким образом, мы выяснили, что «исчезновение» данных — это не ошибка системы, а следствие работы механизмов управляемых форм. Выбор конкретного метода сохранения (ТЧ, РС или сериализация) зависит от архитектуры вашего решения и требований к производительности системы.