Как проверить заполнение реквизитов номенклатуры в УТ 10.3 и УПП 1.3 при создании единиц измерения?

Программист 1С v8.3 (Обычные формы) Управленческий учет Торговля и дистрибуция
← На главную

В процессе разработки в конфигурациях на базе обычных форм, таких как Управление торговлей 10.3 или Управление производственным предприятием 1.3, программисты часто сталкиваются с проблемой: метод ЭтоНовый() перестает работать так, как ожидается, в момент записи элемента номенклатуры. Особенно остро это проявляется, когда пользователю нужно создать единицы измерения (хранения остатков или отчетов) до того, как карточка будет окончательно заполнена и сохранена.

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

Почему стандартная проверка ЭтоНовый() не подходит

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

После этого действия:

  1. Объект физически появляется в таблице базы данных.
  2. Ему присваивается уникальный идентификатор (UUID).
  3. Метод ЭтоНовый() во всех последующих событиях будет возвращать Ложь.

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

Решение 1: Использование ДополнительныхСвойств

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

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


Процедура ПриНажатииКнопкиВыбораЕдиницы()
    ЭтотОбъект.ДополнительныеСвойства.Вставить("ПрограммнаяЗаписьДляЕдиниц", Истина);
    // Вызов типового механизма записи
    Если Не ЭтотОбъект.Записать() Тогда
        Возврат;
    КонецЕсли;
    // ... логика открытия формы выбора единиц ...
КонецПроцедуры

Теперь проанализируем изменения, которые необходимо внести в модуль объекта номенклатуры в обработчик ПередЗаписью:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Если установлен флаг программной записи, пропускаем жесткие проверки
    Если ДополнительныеСвойства.Свойство("ПрограммнаяЗаписьДляЕдиниц") 
        И ДополнительныеСвойства.ПрограммнаяЗаписьДляЕдиниц = Истина Тогда
        Возврат;
    КонецЕсли;

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

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

Решение 2: Использование переменной мЭтоНовыйОбъект

В типовых конфигурациях УТ 10.3 и УПП 1.3 разработчики 1С уже предусмотрели механизм отслеживания состояния "новизны" карточки на уровне формы. В модуле формы часто встречается переменная мЭтоНовыйОбъект. Она инициализируется при открытии формы (если ссылка пустая) и сохраняет значение Истина до тех пор, пока пользователь не закроет форму или успешно не выполнит основное сохранение.

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


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

Решение 3: Разделение логики проверок

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

Чтобы избежать этого, опытные разработчики рекомендуют:

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

Резюме: как поступить правильно

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

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

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

← На главную