Почему реквизиты формы в табличной части слетают при записи формы в 1С:Предприятии 8.3?

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

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

Представьте ситуацию: вы разрабатываете управляемую форму для документа, справочника или другого объекта. Для временных расчетов, отметок пользователя или хранения неперсистентных данных вы добавляете на форму новые реквизиты. Некоторые из них размещаете непосредственно на форме, другие — внутри табличной части. При попытке записать объект, вы замечаете, что реквизиты в табличной части сбрасываются, а реквизиты, находящиеся за ее пределами, остаются нетронутыми. В чем же дело?

Понимание природы реквизитов: "синие" и "красные"

Для того чтобы полностью осознать корень проблемы, нам необходимо четко различать два ключевых типа реквизитов в контексте 1С:Предприятия 8:

  1. Реквизиты объекта (часто отображаются синим цветом в конфигураторе)
  2. Это основные, персистентные реквизиты, которые являются частью структуры метаданных конкретного объекта (например, документа, справочника, регистра сведений). Их значения физически хранятся в базе данных. Когда вы записываете объект, значения этих реквизитов сохраняются в соответствующие поля таблиц базы данных. При последующем открытии формы или перечитывании объекта из базы, эти значения автоматически восстанавливаются. Мы обращаемся к ним через основной реквизит формы, как правило, называемый Объект.

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

Почему "красные" реквизиты в табличной части слетают?

Основная причина потери значений "красных" реквизитов в табличной части кроется в жизненном цикле данных управляемой формы и объекта. Давайте проанализируем ситуацию:

  1. Запись объекта в базу данных: Когда мы нажимаем кнопку "Записать" или "Провести" на форме, система 1С выполняет операцию записи основного объекта (например, документа) в базу данных. В этот момент сохраняются только те данные, которые являются частью метаданных объекта, то есть его "синие" реквизиты и данные его табличных частей, определенные как реквизиты объекта. "Красные" реквизиты формы, по определению, не являются частью объекта и в базу данных не попадают.
  2. Перечитывание объекта или обновление формы: После успешной записи объекта, система 1С, как правило, перечитывает данные объекта из базы данных для актуализации информации на форме. Это необходимо, например, для отображения автоматически присвоенного номера документа, даты, или других полей, которые могли быть изменены в процессе записи (например, в обработчиках события ПередЗаписью или ПриЗаписи).
  3. Особенности табличных частей на форме: Табличная часть на форме является элементом управления, который отображает коллекцию данных. Эта коллекция данных может быть напрямую связана с табличной частью объекта (например, Объект.Товары) или быть отдельной таблицей значений формы. Если табличная часть формы связана с табличной частью объекта, то при перечитывании объекта система фактически обновляет или пересоздает эту коллекцию данных формы на основе данных из базы.
  4. Потеря "красных" реквизитов: Именно в момент перечитывания или обновления коллекции данных табличной части формы происходит очистка значений "красных" реквизитов. Поскольку эти реквизиты существуют только на форме и не имеют аналогов в базе данных, они просто не перезаполняются. Система считает, что это "новая" или "обновленная" коллекция данных, и "красные" реквизиты, не имеющие постоянного источника в базе, обнуляются или получают свои значения по умолчанию. Реквизиты формы, расположенные вне табличной части, не подвергаются этому циклу обновления коллекции, так как они не привязаны к элементу коллекции, и поэтому их значения сохраняются.

Таким образом, суть проблемы в том, что "красные" реквизиты в табличной части являются частью временной коллекции данных формы, которая после записи объекта обновляется из постоянного хранилища (базы данных), игнорируя временные данные, не имеющие аналогов в этом хранилище.

Решения проблемы

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

1. Идеальное решение: Сделать реквизиты "синими" (хранить в базе данных)

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

  1. Откройте конфигуратор: Запустите 1С:Предприятие в режиме конфигуратора.
  2. Найдите объект: В дереве метаданных найдите тот объект (документ, справочник и т.д.), для которого вы создаете форму.
  3. Перейдите к табличной части: Разверните узел объекта и найдите нужную табличную часть (например, "Товары").
  4. Добавьте новый реквизит табличной части: Щелкните правой кнопкой мыши по табличной части и выберите "Добавить" -> "Реквизит".
  5. Настройте реквизит: Дайте реквизиту осмысленное имя (например, ДополнительнаяКолонка), выберите нужный тип данных (например, Число, Строка, Булево).
  6. Обновите форму: После сохранения изменений в конфигурации, откройте вашу форму в режиме предприятия. Перетащите новый реквизит из списка реквизитов объекта (он будет "синим") в табличную часть на форме. В процессе отладки визуального расположения вам может помочь редактор форм в режиме предприятия, который позволяет анализировать свойства элементов без постоянного переключения в конфигуратор.

После этих действий ваш реквизит станет "синим", будет сохраняться вместе с объектом в базе данных и не будет "слетать" при записи формы, поскольку он станет частью персистентных данных объекта.

2. Альтернативное решение для временных данных: Ручное сохранение и восстановление в обработчиках формы

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

Мы будем использовать обработчики событий формы ПередЗаписьюНаСервере и ПослеЗаписиНаСервере:

  1. Создайте временный реквизит формы для хранения данных:
  2. Нам потребуется временное хранилище на самой форме для сохранения данных "красных" реквизитов перед записью объекта. Создадим новый реквизит формы, например, с именем ВременныеДанныеТЧ, тип ХранилищеЗначения или Произвольный (Массив, Структура, ТаблицаЗначений).

  3. Сохранение значений в ПередЗаписьюНаСервере:
  4. В этом обработчике, который выполняется перед непосредственной записью объекта в базу данных, мы итерируемся по строкам табличной части на форме, извлекаем значения наших "красных" реквизитов и сохраняем их во временный реквизит формы.

    Пример концептуального кода для ПередЗаписьюНаСервере:

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

3. Использование механизмов сохранения данных настроек формы

Для некоторых сценариев, когда "красные" реквизиты должны сохраняться между открытиями формы для конкретного пользователя, можно использовать встроенный механизм или развернуть полноценную подсистему предопределенных настроек, которая обеспечит более гибкое управление данными формы.

  1. Включите свойство СохранениеДанныхВНастройках для формы:
  2. Откройте свойства вашей управляемой формы. Найдите свойство СохранениеДанныхВНастройках и установите его в значение Истина.

  3. Создайте реквизит формы для хранения данных табличной части:
  4. Создайте новый реквизит формы (например, НастройкиТабличнойЧасти) с типом ХранилищеЗначения. Установите флаг "Сохранять данные в настройках".

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

Заключение

Проблема "слетающих" реквизитов в табличной части обусловлена механизмом обновления коллекций управляемой формы. Если данные должны храниться в базе, всегда добавляйте реквизиты в метаданные объекта. Если же данные временные, используйте программные методы сохранения.

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

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

← На главную