В процессе реальной эксплуатации ERP-систем (будь то «1С:Управление торговлей», «1С:ERP» или «1С:Комплексная автоматизация») разработчики и аналитики часто сталкиваются с так называемым человеческим фактором. Пользователи из-за спешки, невнимательности или банального двойного клика могут повторно ввести документ на основании уже отработанного заказа или возврата. Яркий пример — создание нескольких документов Расходный кассовый ордер (РКО) на основании одного и того же Возврата товаров от клиента, что приводит к повторной выдаче денежных средств и головной боли для бухгалтерии.
В этой статье мы подробно разберем, как раз и навсегда решить проблему дублирования подчиненных документов. Мы изучим как мощные типовые механизмы конфигурации, позволяющие настроить жесткий контроль без программирования, так и программные методы с использованием расширений управляемых форм.
Прежде чем приступать к написанию программного кода, проанализируем возможности типового решения. Разработчики фирмы 1С уже заложили в архитектуру систем механизмы контроля превышения лимитов и объемов отгрузки. Рассмотрим два ключевых сценария.
Сценарий А. Защита от избыточных выплат по Возвратам (Ремонт кейса с РКО)
Если кассиры или операторы умудряются вводить несколько РКО на основании одного возврата, превышая общую сумму долга, нам поможет казначейский контроль заявок. Пошагово выполним следующие настройки:
Выясним, как теперь изменится логика работы системы. Пользователь физически больше не сможет создать РКО напрямую на основании документа возврата. Цепочка документов станет строго регламентированной:
Заявка на расходование ДС.Сценарий Б. Контроль превышения объемов отгрузки (Заказ клиента -> Реализация)
Для цепочки отгрузки товаров в программе также предусмотрен встроенный логический контроль:
Закрыт, что автоматически исключает его из списка документов, доступных для оформления отгрузки.Если бизнес-требования диктуют жесткое правило: «На один документ-основание может быть введен строго один подчиненный документ», нам потребуется использовать механизм расширений. Это позволит сохранить конфигурацию на поддержке и гарантировать корректность учета.
Наиболее надежный программный способ контроля — перехват события заполнения в модуле объекта создаваемого документа. Этот метод сработает всегда, независимо от того, вводит ли пользователь документ интерактивно кнопкой из формы или документ создается обработкой в фоне.
Разберем по шагам алгоритм создания проверки:
РеализацияТоваровУслуг) и добавим в его модуль объекта обработчик события ОбработкаЗаполнения с аннотацией &Перед.Посмотрим на пример реализации данного кода:
&Перед("ОбработкаЗаполнения")
Процедура Расш1_ПередОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
// Проверяем, что заполнение происходит на основании Заказа клиента
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказКлиента") Тогда
// Формируем запрос для поиска существующих некорректных дублей
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
| Реализация.Ссылка КАК Ссылка,
| Реализация.Номер КАК Номер,
| Реализация.Дата КАК Дата
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.ДокументОснование = &ДокументОснование
| И Реализация.ПометкаУдаления = ЛОЖЬ";
Запрос.УстановитьПараметр("ДокументОснование", ДанныеЗаполнения);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// Если документ найден, генерируем жесткое исключение
ТекстОшибки = СтрШаблон(
"Внимание! На основании этого заказа уже создана Реализация № %1 от %2.
|Повторное создание документов запрещено правилами документооборота!",
Выборка.Номер,
Формат(Выборка.Дата, "ДФ=dd.MM.yyyy")
);
ВызватьИсключение ТекстОшибки;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важный нюанс: Обратите внимание на использование конструкции ВызватьИсключение. Поскольку в стандартной процедуре ОбработкаЗаполнения отсутствует параметр Отказ, генерация системного исключения — это самый надежный способ гарантированно прервать транзакцию создания документа, не позволив открыться его форме на клиенте.
Иногда жесткое прерывание через ошибку выглядит слишком грубым для пользователей. Рассмотрим альтернативный, более дружелюбный интерфейсный подход. Мы можем выполнить проверку непосредственно при создании формы нового документа. Если дубликат обнаружен, мы не просто заблокируем операцию, а предложим пользователю сразу открыть уже существующий документ.
Для этого выполним следующие действия:
РасходныйКассовыйОрдер).ПриСозданииНаСервере с аннотацией &После.Отказ = Истина и выведем пользователю предупреждение.Проанализируем структуру программного кода для формы документа:
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Проверка актуальна только для новых (еще не записанных) документов
Если Объект.Ссылка.Пустая() И Параметры.Свойство("ЗначениеЗаполнения") Тогда
ДокументОснование = Параметры.ЗначениеЗаполнения;
// Проверяем тип документа-основания (например, Возврат товаров от клиента)
Если ТипЗнч(ДокументОснование) = Тип("ДокументСсылка.ВозвратТоваровОтКлиента") Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
| РКО.Ссылка КАК Ссылка
|ИЗ
| Документ.РасходныйКассовыйОрдер КАК РКО
|ГДЕ
| РКО.ДокументОснование = &ДокументОснование
| И РКО.ПометкаУдаления = ЛОЖЬ";
Запрос.УстановитьПараметр("ДокументОснование", ДокументОснование);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
// Формируем навигационную ссылку для удобного открытия
СсылкаНаДокумент = ПолучитьНавигационнуюСсылку(Выборка.Ссылка);
// Выводим информативное сообщение пользователю
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
СтрШаблон("В базе уже существует РКО по данному возврату! Оформление дубликата отменено."),
,,,
Отказ
);
// Блокируем открытие формы новой копии
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Использование параметра Отказ = Истина аккуратно предотвращает отрисовку и открытие формы. В сочетании с выводом понятного сообщения через ОбщегоНазначенияКлиентСервер.СообщитьПользователю это обеспечивает высокий уровень юзабилити системы и защищает учет от дублирующихся транзакций.
Таким образом, мы рассмотрели как организационно-методические приемы предотвращения ошибок ввода (через казначейские лимиты и заявки), так и технические варианты жесткого программного контроля в коде 1С. Выбор конкретного метода зависит от архитектуры вашей базы данных и критичности бизнес-процесса.