Как настроить отображение и редактирование записей регистра сведений на форме элемента справочника?

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

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

Почему табличное поле регистра остается пустым

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

В этой ситуации возникают следующие сложности:

  1. Отсутствие установленного отбора: Без явного указания отбора табличное поле либо пытается отобразить все подряд записи регистра (если тип данных — список), либо не считывает данные вовсе (если используется набор записей без параметров отбора).
  2. Проблема несохраненного объекта: Если форма открыта для создания нового элемента (ЭтоНовый() = Истина), ссылка в базе данных еще не сформирована (Ссылка.Пустая() = Истина). Попытка наложить отбор по пустой ссылке приведет к некорректным данным или ошибкам платформы.
  3. Несоответствие измерений отбору: При ручном добавлении новой строки в табличную часть измерение, связывающее запись со справочником, остается пустым. При попытке записи набора платформа генерирует ошибку несовпадения значений отбора и полей записи.

Выбор механизма: список регистра или набор записей

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

  1. РегистрСведенийСписок: Табличное поле подключается к динамическому списку регистра. В этом случае пользователь редактирует записи напрямую в базе данных. Как только курсор переходит на другую строку, изменение фиксируется в регистре. Главный минус — разрушение целостности: если пользователь изменит строку регистра, а затем закроет форму справочника кнопкой «Закрыть» без сохранения самого элемента, изменения в регистре все равно останутся в базе.
  2. РегистрСведенийНаборЗаписей: На форме размещается набор записей. Данные считываются при открытии формы и хранятся в оперативной памяти формы. Фиксация в базе данных происходит синхронно с сохранением самого элемента справочника. Этот вариант является наиболее надежным и транзакционно правильным.

Разберем подробнее реализацию через РегистрСведенийНаборЗаписей.

Пошаговая настройка через набор записей

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

  1. Разместите на форме табличное поле. В свойствах укажите тип значения: РегистрСведенийНаборЗаписей.<ИмяРегистра>.
  2. Добавьте командную панель, свяжите ее с табличным полем и настройте автоматическое заполнение кнопок.
  3. Колонку измерения, в которой хранится ссылка на текущий справочник, рекомендуется скрыть или установить для нее свойство ТолькоПросмотр = Истина, чтобы пользователь не мог случайно отвязать строку от текущего элемента.

Инициализация отбора и чтение данных при открытии формы

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


Процедура ПриОткрытии()

    Если ЭтоНовый() Тогда
        // Для нового элемента отбор накладывать нельзя, так как ссылки еще нет
        ЭлементыФормы.ТабличноеПолеРегистр.Доступность = Ложь;
    Иначе
        // Накладываем отбор по текущей ссылке и читаем записи
        ЗаписиРегистра = ЭлементыФормы.ТабличноеПолеРегистр.Значение;
        ЗаписиРегистра.Отбор.Номенклатура.Установить(Ссылка);
        ЗаписиРегистра.Прочитать();
    КонецЕсли;

КонецПроцедуры

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

Автоматическое заполнение измерений при добавлении строк

Разберем ситуацию, когда пользователь нажимает кнопку «Добавить» в табличном поле. Чтобы не возникало ошибки при последующем сохранении, измерение каждой новой строки должно быть заполнено ссылкой на текущий объект справочника. Для этого используем событие табличного поля ПриНачалеРедактирования.


Процедура ТабличноеПолеРегистрПриНачалеРедактирования(Элемент, НоваяСтрока, Клонирование)

    Если НоваяСтрока Тогда
        // Заполняем измерение связи текущим элементом справочника
        Элемент.ТекущиеДанные.Номенклатура = Ссылка;
    КонецЕсли;

КонецПроцедуры

Сохранение набора записей в базу данных

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

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


Процедура ПриЗаписи(Отказ)

    Если Отказ Тогда
        Возврат;
    КонецЕсли;

    ЗаписиРегистра = ЭлементыФормы.ТабличноеПолеРегистр.Значение;

    // Гарантируем корректность отбора перед записью
    ЗаписиРегистра.Отбор.Номенклатура.Установить(Ссылка);

    // Проверяем заполнение измерений во всех строках
    Для Каждого Запись Из ЗаписиРегистра Цикл
        Запись.Номенклатура = Ссылка;
    КонецЦикла;

    Попытка
        ЗаписиРегистра.Записать(Истина);
    Исключение
        Отказ = Истина;
        Сообщить("Не удалось сохранить записи регистра: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

После первой успешной записи нового элемента справочника табличное поле можно разблокировать в событии ПослеЗаписи:


Процедура ПослеЗаписи()

    ЭлементыФормы.ТабличноеПолеРегистр.Доступность = Истина;

КонецПроцедуры

Альтернативное решение: редактирование через Таблицу значений

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

  1. В процедуре ПриОткрытии записи регистра считываются запросом или методом СрезПоследних/Выгрузить в промежуточную таблицу значений.
  2. Пользователь свободно добавляет, изменяет и удаляет строки без прямого взаимодействия со структурами регистра.
  3. В процедуре ПриЗаписи создается объект РегистрСведенийНаборЗаписей, устанавливается отбор по ссылке, набор загружается из таблицы значений методом Загрузить() и записывается в базу.

Такой способ полностью изолирует базу данных от незафиксированных пользовательских правок и гарантирует отмену всех действий при закрытии формы без сохранения.

← На главную