При работе с управляемыми формами в системе 1С:Предприятие 8.3, разработчики часто сталкиваются с ситуацией, когда реквизиты, добавленные непосредственно на форму (не являющиеся реквизитами объекта, к которому привязана форма) и расположенные в табличной части, очищаются или "слетают" после записи формы. В то же время, аналогичные реквизиты формы, расположенные вне табличной части, сохраняют свои значения. Давайте рассмотрим эту проблему подробнее, выясним ее причины и предложим эффективные решения.
Представьте ситуацию: вы разрабатываете управляемую форму для документа, справочника или другого объекта. Для временных расчетов, отметок пользователя или хранения неперсистентных данных вы добавляете на форму новые реквизиты. Некоторые из них размещаете непосредственно на форме, другие — внутри табличной части. При попытке записать объект, вы замечаете, что реквизиты в табличной части сбрасываются, а реквизиты, находящиеся за ее пределами, остаются нетронутыми. В чем же дело?
Для того чтобы полностью осознать корень проблемы, нам необходимо четко различать два ключевых типа реквизитов в контексте 1С:Предприятия 8:
Это основные, персистентные реквизиты, которые являются частью структуры метаданных конкретного объекта (например, документа, справочника, регистра сведений). Их значения физически хранятся в базе данных. Когда вы записываете объект, значения этих реквизитов сохраняются в соответствующие поля таблиц базы данных. При последующем открытии формы или перечитывании объекта из базы, эти значения автоматически восстанавливаются. Мы обращаемся к ним через основной реквизит формы, как правило, называемый Объект.
В отличие от реквизитов объекта, это временные реквизиты. Они существуют только в контексте текущей формы, в рамках текущего сеанса работы пользователя с этой формой. Их значения не сохраняются в базе данных при записи объекта. Реквизиты формы используются для хранения промежуточных вычислений, пользовательских настроек, флагов или любой другой информации, которая нужна только для логики работы данной формы. Их преимущество в том, что они поддерживают более широкий спектр типов данных. Для ускорения разработки в некоторых случаях можно использовать добавление реквизитов и элементов на управляемые формы без кодирования, что упрощает управление интерфейсом.
Основная причина потери значений "красных" реквизитов в табличной части кроется в жизненном цикле данных управляемой формы и объекта. Давайте проанализируем ситуацию:
ПередЗаписью или ПриЗаписи).Объект.Товары) или быть отдельной таблицей значений формы. Если табличная часть формы связана с табличной частью объекта, то при перечитывании объекта система фактически обновляет или пересоздает эту коллекцию данных формы на основе данных из базы.Таким образом, суть проблемы в том, что "красные" реквизиты в табличной части являются частью временной коллекции данных формы, которая после записи объекта обновляется из постоянного хранилища (базы данных), игнорируя временные данные, не имеющие аналогов в этом хранилище.
Существует несколько подходов к решению этой проблемы, и выбор конкретного метода зависит от того, должны ли данные, которые хранятся в "красных" реквизитах табличной части, быть постоянными и сохраняться в базе данных, или же они являются временными данными, актуальными только в рамках работы пользователя с формой.
Если данные, которые вы теряете, на самом деле должны быть постоянными и сохраняться вместе с документом или объектом в базе данных, то наиболее правильным и надежным решением будет добавить эти реквизиты непосредственно в табличную часть объекта метаданных в конфигураторе.
ДополнительнаяКолонка), выберите нужный тип данных (например, Число, Строка, Булево).После этих действий ваш реквизит станет "синим", будет сохраняться вместе с объектом в базе данных и не будет "слетать" при записи формы, поскольку он станет частью персистентных данных объекта.
Если данные действительно являются временными, не должны храниться в базе данных, но при этом вам нужно, чтобы они сохранялись на время работы с формой (например, до ее закрытия), можно реализовать механизм ручного сохранения и восстановления. Этот подход требует программного вмешательства. Чтобы стандартизировать такие доработки, разработчики часто используют программное изменение форм через специализированные общие модули.
Мы будем использовать обработчики событий формы ПередЗаписьюНаСервере и ПослеЗаписиНаСервере:
Нам потребуется временное хранилище на самой форме для сохранения данных "красных" реквизитов перед записью объекта. Создадим новый реквизит формы, например, с именем ВременныеДанныеТЧ, тип ХранилищеЗначения или Произвольный (Массив, Структура, ТаблицаЗначений).
ПередЗаписьюНаСервере:В этом обработчике, который выполняется перед непосредственной записью объекта в базу данных, мы итерируемся по строкам табличной части на форме, извлекаем значения наших "красных" реквизитов и сохраняем их во временный реквизит формы.
Пример концептуального кода для ПередЗаписьюНаСервере:
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ПараметрыЗаписи)
// Инициализируем временное хранилище
ВременныеДанныеТЧ = Новый Массив;
// Предполагаем, что наша табличная часть на форме называется "Товары"
// и в ней есть "красный" реквизит "КомментарийСтроки"
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
Если СтрокаТЧ.КомментарийСтроки Заполнено() Тогда
ВременныеДанныеТЧ.Добавить(СтрокаТЧ.КомментарийСтроки);
Иначе
ВременныеДанныеТЧ.Добавить("");
КонецЕсли;
КонецЦикла;
РеквизитФормыДляХраненияВременныхДанныхТЧ = ВременныеДанныеТЧ;
КонецПроцедуры
ПослеЗаписиНаСервере:Этот обработчик выполняется после того, как объект был успешно записан в базу данных и, возможно, перечитан. Здесь мы берем сохраненные во временном реквизите данные и восстанавливаем их в соответствующие "красные" реквизиты табличной части.
Для некоторых сценариев, когда "красные" реквизиты должны сохраняться между открытиями формы для конкретного пользователя, можно использовать встроенный механизм или развернуть полноценную подсистему предопределенных настроек, которая обеспечит более гибкое управление данными формы.
СохранениеДанныхВНастройках для формы:Откройте свойства вашей управляемой формы. Найдите свойство СохранениеДанныхВНастройках и установите его в значение Истина.
Создайте новый реквизит формы (например, НастройкиТабличнойЧасти) с типом ХранилищеЗначения. Установите флаг "Сохранять данные в настройках".
ПриСохраненииДанныхВНастройкахНаСервере:
&НаСервере
Процедура ПриСохраненииДанныхВНастройкахНаСервере(Настройки)
МассивДанныхДляСохранения = Новый Массив;
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
СтруктураСтроки = Новый Структура;
СтруктураСтроки.Вставить("Номенклатура", СтрокаТЧ.Номенклатура);
СтруктураСтроки.Вставить("Пометка", СтрокаТЧ.ПользовательскаяПометка);
МассивДанныхДляСохранения.Добавить(СтруктураСтроки);
КонецЦикла;
НастройкиТабличнойЧасти = Новый ХранилищеЗначения(МассивДанныхДляСохранения);
КонецПроцедуры
ПриЗагрузкеДанныхИзНастроекНаСервере:Этот обработчик вызывается при загрузке настроек формы. Если вам нужно администрировать эти данные или очистить их при возникновении ошибок, пригодится решение для просмотра, восстановления и очистки хранилища настроек пользователя.
Проблема "слетающих" реквизитов в табличной части обусловлена механизмом обновления коллекций управляемой формы. Если данные должны храниться в базе, всегда добавляйте реквизиты в метаданные объекта. Если же данные временные, используйте программные методы сохранения.
В крупных проектах для обеспечения единообразия интерфейса у всех сотрудников может потребоваться реализация сохранения настроек формы для всех пользователей, что особенно актуально для типовых конфигураций на базе БСП.
Всегда помните о жизненном цикле реквизитов и коллекций данных на управляемой форме, чтобы создавать надежные и эффективные решения в 1С:Предприятии.