В процессе разработки и сопровождения сложных конфигураций, таких как 1С:ERP Управление предприятием, программисты часто сталкиваются с необходимостью изменить логику стандартных проверок. Одной из наиболее частых задач является отключение или обход проверки заполнения определенного реквизита в табличной части документа (например, АналитикаРасходов в документе Заказ поставщику), когда типовые настройки не позволяют этого сделать. Рассмотрим подробно, как реализовать такой обход программно, не снимая документ с поддержки, и разберем внутренние механизмы платформы и конфигурации.
Прежде чем переходить к коду, разберем, как платформа 1С инициирует проверку. Когда пользователь нажимает кнопку «Провести», платформа вызывает событие ОбработкаПроверкиЗаполнения. В этот метод передается массив ПроверяемыеРеквизиты, который содержит пути к данным, требующим обязательного заполнения. Эти пути формируются на основе свойств реквизитов в конфигураторе (свойство «Проверка заполнения» установлено в значение «Выдавать ошибку»).
Проанализируем стандартный подход: чтобы платформа «забыла» о необходимости проверки конкретного поля, нам нужно программно удалить путь к этому полю из массива. Путь к реквизиту табличной части обычно выглядит как ИмяТабличнойЧасти.ИмяРеквизита.
Поскольку документ стоит на поддержке, лучшим инструментом для внесения изменений будет расширение — также поможет расширение для настройки контроля ввода данных. Мы создадим программный обработчик, который перехватит стандартную логику. Выясним, как это сделать правильно:
ЗаказПоставщику). В некоторых случаях для этого документа полезно отключение даты запрета для заказов поставщику.ОбработкаПроверкиЗаполнения с аннотацией &После или &Вместо.ПроверяемыеРеквизиты. Если нужно менять интерфейс, поможет динамическая модификация форм в расширении.Рассмотрим пример кода, который удаляет проверку аналитики расходов для всех строк табличной части Товары:
&Вместо("ОбработкаПроверкиЗаполнения")
Процедура Расш1_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// Сначала вызываем стандартную логику, если используем &Вместо
ПродолжитьВызов(Отказ, ПроверяемыеРеквизиты);
// Находим индекс нужного реквизита в массиве
ПорядковыйНомер = ПроверяемыеРеквизиты.Найти("Товары.АналитикаРасходов");
// Если реквизит найден — удаляем его из списка обязательных
Если ПорядковыйНомер <> Неопределено Тогда
ПроверяемыеРеквизиты.Удалить(ПорядковыйНомер);
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию глубже. В 1С:ERP проверка аналитики часто происходит не только на уровне платформы, но и на уровне бизнес-логики в общих модулях. Даже если вы удалите реквизит из массива ПроверяемыеРеквизиты, специализированные процедуры могут выдать ошибку. Это связано с тем, что проверка аналитики жестко завязана на выбранную Статью расходов.
В ERP существует механизм ПланыВидовХарактеристик.СтатьиРасходов.ПроверитьЗаполнениеАналитик. Эта функция вызывается в конце модуля документа. Если в статье расходов указано, что аналитика обязательна (например, при распределении на внеоборотные активы), система проигнорирует ваши изменения в массиве ПроверяемыеРеквизиты.
Чтобы обойти это в расширении, нам нужно найти место вызова этой проверки. Обычно это выглядит так:
// В типовом коде ERP
МассивНепроверяемыхРеквизитов = Новый Массив;
// ... заполнение массива ...
ПланыВидовХарактеристик.СтатьиРасходов.ПроверитьЗаполнениеАналитик(ЭтотОбъект, Новый Структура("Товары"), МассивНепроверяемыхРеквизитов, Отказ);
Для корректного обхода в расширении нам следует добавить реквизит в МассивНепроверяемыхРеквизитов перед вызовом типовой функции. Посмотрим на правильную реализацию:
&ИзменениеИКонтроль("ОбработкаПроверкиЗаполнения")
Процедура Расш1_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
// ... существующий код подготовки массивов ...
МассивНепроверяемыхРеквизитов.Добавить("Товары.АналитикаРасходов");
// Важно вставить удаление до того, как типовой код очистит ПроверяемыеРеквизиты
ОбщегоНазначения.УдалитьНепроверяемыеРеквизитыИзМассива(ПроверяемыеРеквизиты, МассивНепроверяемыхРеквизитов);
// #Вставка
// Если мы хотим полностью пропустить проверку аналитики ПВХ:
// Возврат;
// #КонецВставки
КонецПроцедуры
Часто возникает задача: проверять заполнение реквизита не во всей колонке, а только в определенных строках (например, если СтатьяРасходов заполнена определенным образом) — для этого подойдёт обработка управления обязательностью заполнения реквизитов. Стандартный массив ПроверяемыеРеквизиты не позволяет делать строковую проверку — он работает по принципу «проверять всю колонку или нет».
Разберем алгоритм для реализации выборочной проверки (похожим образом работает проверка заполнения данных нового сотрудника):
ПроверяемыеРеквизиты, чтобы платформа не выдавала системную ошибку.СообщениеПользователю, привязывая его к конкретной ячейке.Посмотрим на пример такой реализации:
Процедура ПроверитьАналитикуПоСтрокам(ТЧ_Товары, ПроверяемыеРеквизиты, Отказ)
// Удаляем из системной проверки
ПорядковыйНомер = ПроверяемыеРеквизиты.Найти("Товары.АналитикаРасходов");
Если ПорядковыйНомер <> Неопределено Тогда
ПроверяемыеРеквизиты.Удалить(ПорядковыйНомер);
КонецЕсли;
// Ручная проверка
Для Каждого Стр Из ТЧ_Товары Цикл
// Например, проверяем только для услуг
Если Стр.Номенклатура.ТипНоменклатуры = Перечисления.ТипыНоменклатуры.Услуга Тогда
Если Не ЗначениеЗаполнено(Стр.АналитикаРасходов) Тогда
ТекстОшибки = "Для услуг необходимо заполнить аналитику расходов в строке " + Стр.НомерСтроки;
ОбщегоНазначенияКлиентСервер.СообщитьОшибку(ТекстОшибки, , "Товары[" + (Стр.НомерСтроки - 1) + "].АналитикаРасходов", , Отказ);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Если задача стоит в том, чтобы провести документ программно из какой-то внешней обработки, минуя все проверки (включая проверку заполнения), можно воспользоваться свойством ОбменДанными.Загрузка. Рассмотрим этот вариант:
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
ДокументОбъект.ОбменДанными.Загрузка = Истина;
Попытка
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Важный момент: использование этого флага отключает не только проверку заполнения, но и практически все обработчики событий (ПередЗаписью, ПриЗаписи и т.д.), что может привести к нарушению целостности данных в ERP. Пользуйтесь этим методом с осторожностью и только для разовых технических операций.
Если вы применили все программные методы, но система все равно требует заполнения, выясним, нет ли скрытых настроек. В ERP АналитикаРасходов является реквизитом с составным типом данных. В Плане видов характеристик Статьи расходов для каждой статьи задается «Тип аналитики расходов». Если этот тип жестко задан, программный код системы будет искать его заполнение в запросах при проведении (для формирования движений по регистру ПрочиеРасходы).
Рекомендация: Всегда проверяйте связь реквизита в конфигураторе. Если на реквизите стоит проверка заполнения на уровне метаданных, то в расширении стоит зайти в свойства этого реквизита и установить «Проверка заполнения» в значение «Не проверять». Это самый простой и надежный способ, который имеет приоритет над программным изменением массива ПроверяемыеРеквизиты.
Подводя итог, наиболее правильным и современным способом решения задачи является использование расширения с переопределением процедуры ОбработкаПроверкиЗаполнения и корректная модификация массива реквизитов с учетом специфики бизнес-логики ERP.