Как правильно проверить, записан ли элемент справочника, и открыть связанные формы в 1С 8.3

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

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

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

Разбор типичной ошибки: создание лишних элементов

Рассмотрим ситуацию, когда разработчик пытается программно создать элемент, если он еще не записан. Проанализируем фрагмент ошибочного кода:


&НаСервере
Функция ПроверкаНаНовыйЭлемент()
    Если Объект.Ссылка.Пустая() Тогда
        Номенклатура = Справочники.Номенклатура.СоздатьЭлемент();
        Номенклатура.Наименование = Объект.Наименование;
        Номенклатура.Записать(); 
        Возврат Номенклатура.Ссылка;
    КонецЕсли;
КонецФункции

Такой подход является категорически неверным по нескольким причинам:

  1. Дублирование данных: В системе создается новый элемент, который никак не связан с тем объектом, который пользователь сейчас редактирует в форме.
  2. Нарушение логики транзакций: Если пользователь нажмет «Отмена» в основной форме, «пустой» созданный элемент останется в базе.
  3. Потеря данных: Реквизиты, заполненные в форме, но еще не переданные в Объект, не попадут в созданный программно элемент.

Выясним, как сделать это правильно, используя стандартные механизмы платформы.

Способ 1: Простая проверка на пустую ссылку

Самый простой и очевидный способ — проверить наличие ссылки у объекта. Если Объект.Ссылка.Пустая() возвращает Истина, значит, элемент еще ни разу не сохранялся в базе данных.

Рассмотрим пример реализации команды для открытия списка цен:


&НаКлиенте
Процедура СписокЦен(Команда)
    // Проверяем, заполнена ли ссылка
    Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
        ПараметрыФормы = Новый Структура("Отбор", Новый Структура("Номенклатура", Объект.Ссылка));
        ОткрытьФорму("РегистрСведений.ЦеныПродажи.ФормаСписка", ПараметрыФормы);
    Иначе
        ПоказатьПредупреждение(, "Перед просмотром цен необходимо записать номенклатуру!");
    КонецЕсли;
КонецПроцедуры

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

Способ 2: Автоматическое сохранение перед действием

С точки зрения юзабилити (удобства пользователя) лучше не просто запрещать действие, а предлагать системе самой записать объект. Рассмотрим, как реализовать автоматическую запись перед переходом.

Разберем алгоритм: 1. Проверяем, изменялся ли объект или он новый. 2. Если да — вызываем стандартный метод Записать(). 3. Если запись прошла успешно — выполняем основное действие.


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

Использование метода Записать() на клиенте инициирует стандартный цикл записи со всеми проверками (включая ПередЗаписью и ПриЗаписи на сервере). Это гарантирует целостность данных.

Сравнение методов проверки: Пустая(), ЗначениеЗаполнено() и Параметры.Ключ

В сообществе разработчиков часто возникают споры о производительности и чистоте кода при проверке на «новый элемент». Проанализируем три основных подхода:

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

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

Способ 3: Использование свойств команды (Без кода)

Платформа 1С предоставляет мощные инструменты настройки интерфейса, которые позволяют минимизировать написание кода. Выясним, как настроить автоматическую проверку в свойствах команды.

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

Если условия выполняются, 1С сама предложит пользователю записать объект перед выполнением команды. Это «золотой стандарт» разработки, так как он обеспечивает единообразное поведение системы.

Передача данных в открываемую форму

При открытии формы установки цен важно не просто открыть окно, но и сразу заполнить в нем номенклатуру. Проанализируем, как это сделать через параметр ЗначенияЗаполнения.


&НаКлиенте
Процедура ОткрытьФормуЦены()
    
    ДанныеЗаполнения = Новый Структура;
    ДанныеЗаполнения.Вставить("Номенклатура", Объект.Ссылка);
    ДанныеЗаполнения.Вставить("Период", ТекущаяДата());
    
    ПараметрыФормы = Новый Структура("ЗначенияЗаполнения", ДанныеЗаполнения);
    
    ОткрытьФорму("РегистрСведений.ЦеныПродажи.ФормаЗаписи", ПараметрыФормы);
    
КонецПроцедуры

Использование структуры ЗначенияЗаполнения позволяет платформе автоматически отработать механизм заполнения в новой форме регистра. Это гораздо чище, чем пытаться обращаться к реквизитам формы напрямую через Форма.Запись.Номенклатура, что может привести к ошибкам, если состав реквизитов формы изменится.

Итоги и рекомендации

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

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

← На главную