При работе с обычными формами в 1С начинающие разработчики часто сталкиваются с ситуацией, когда данные, автоматически рассчитанные перед записью элемента справочника, визуально отображаются на форме, но при повторном открытии карточки поле ввода оказывается пустым. Рассмотрим, почему возникает такая проблема, разберем типичные ошибки и выясним, как правильно записывать значения перечислений в базы данных 1С.
Проанализируем базовый пример кода, с которым возникла проблема при записи элемента справочника Абоненты:
Процедура ПередЗаписью(Отказ)
СправочникОбъект.ДоговорТОНомер = СокрЛП(СправочникОбъект.ДоговорТОНомер);
СправочникОбъект.Наименование = СформироватьНаименование();
ЭлементыФормы.Наименование.Значение = СправочникОбъект.Наименование;
Если СправочникОбъект.ДоговорТОДата < ТекущаяДата() И ТекущаяДата() < СправочникОбъект.ДоговорТОДатаОкончания Тогда
СтатусДоговораНаТО2 = Перечисления.СтатусДоговораНаТО.Действует;
Иначе
СтатусДоговораНаТО2 = Перечисления.СтатусДоговораНаТО.НеДействует;
КонецЕсли;
КонецПроцедуры
В данном коде можно выделить сразу две ключевые ошибки, препятствующие сохранению данных:
СтатусДоговораНаТО2 = ... создает локальную переменную формы. Значение записывается в оперативную память на время работы процедуры, после чего уничтожается. Данные не попадают в структуру реквизитов самого справочника и не сохраняются в базе данных.ЭлементыФормы.Наименование.Значение = ... меняет текст только в поле ввода на форме. В платформе 1С визуальные элементы (поля ввода) служат лишь отображением данных. При записи объекта платформа сохраняет значения именно реквизитов объекта, а не текущих состояний полей ввода.Для того чтобы значение из перечисления сохранилось в базе данных, необходимо обращаться непосредственно к реквизиту реквизитного объекта СправочникОбъект (в обычных формах) или Объект (в управляемых формах).
Разберем по шагам правильное присвоение значений перечисления:
Процедура ПередЗаписью(Отказ)
// Подготовка текстовых полей и системных реквизитов
СправочникОбъект.ДоговорТОНомер = СокрЛП(СправочникОбъект.ДоговорТОНомер);
СправочникОбъект.Наименование = СформироватьНаименование();
СправочникОбъект.ПоследнееИзменениеПользователь = ИмяПользователя();
СправочникОбъект.ПоследнееИзменениеДата = ТекущаяДата();
// Проверка заполнения обязательных полей
Если НЕ ЗначениеЗаполнено(ФИО) Тогда
Сообщить("Введите ФИО абонента!");
Отказ = Истина;
Возврат;
КонецЕсли;
// Присвоение значения перечисления непосредственно реквизиту объекта
Если СправочникОбъект.ДоговорТОДата < ТекущаяДата() И ТекущаяДата() < СправочникОбъект.ДоговорТОДатаОкончания Тогда
СправочникОбъект.СтатусДоговораНаТО = Перечисления.СтатусДоговораНаТО.Действует;
Иначе
СправочникОбъект.СтатусДоговораНаТО = Перечисления.СтатусДоговораНаТО.НеДействует;
КонецЕсли;
// Проверка незаполненных дат
Если НЕ ЗначениеЗаполнено(СправочникОбъект.ДоговорТОДата) И НЕ ЗначениеЗаполнено(СправочникОбъект.ДоговорТОДатаОкончания) Тогда
СправочникОбъект.СтатусДоговораНаТО = Перечисления.СтатусДоговораНаТО.ПустаяСсылка();
КонецЕсли;
КонецПроцедуры
В процессе поиска решения иногда обращаются к элементам перечисления по их порядковому номеру (индексу):
// ОПАСНЫЙ КОД!
СправочникОбъект.СтатусДоговораНаТО = Перечисления.СтатусДоговораНаТО[0];
Рассмотрим, почему такой подход категорически не рекомендуется использовать в разработке:
[0] начнет указывать на совершенно другое значение.Правило: Всегда обращайтесь к значениям перечислений через прямые имя-идентификаторы: Перечисления.ИмяПеречисления.ИмяЗначения.
При проектировании логики автоматической установки статусов на основе даты обратите внимание на следующие особенности:
ТекущаяДата() и физически записывается в реквизит справочника, он актуален только в момент записи. На следующий день статус в базе останется прежним, пока пользователь вручную не перезапишет элемент. Для динамических статусов рекомендуется вычислять значение «на лету» при открытии формы или использовании регламентных заданий.Дата(1, 1, 1) используйте системную функцию 1С ЗначениеЗаполнено(). Это предохраняет от ошибок при работе с необязательными полями ввода.