Как правильно реализовать контроль уникальности входящих номеров документов в 1С:Бухгалтерия 3.0 с помощью расширения

Программист 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

В процессе сопровождения типовых конфигураций, таких как 1С:Бухгалтерия предприятия 3.0, часто возникает задача по ужесточению контроля вводимых данных. Одной из классических задач является проверка уникальности входящих номеров накладных и счетов-фактур от конкретного контрагента в пределах календарного года. Это необходимо для исключения дублирования первичных документов и ошибок при зачете НДС.

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

Анализ штатных возможностей конфигурации

Прежде чем приступать к разработке собственного механизма, проанализируем текущие возможности БП 3.0. В типовом решении уже реализован функционал проверки дублей, однако он часто работает в режиме предупреждения, а не жесткой блокировки. Для начала проверим настройки в разделе «Администрирование» — «Параметры учета» — «Заполнение реквизитов объектов». Если типовой логики недостаточно для ваших бизнес-требований (например, требуется блокировка записи при совпадении пары «Номер накладной + Номер СФ»), тогда переходим к созданию расширения.

Выбор архитектурного решения: Запрос против Регистра сведений

В сообществе разработчиков 1С часто возникают споры: использовать ли прямой запрос к таблицам документов или создавать вспомогательный РегистрСведений. Рассмотрим обе ситуации подробно.

Вариант 1: Использование вспомогательного регистра сведений (РС)

Идея заключается в создании регистра, где измерениями будут выступать Контрагент, НомерВходящегоДокумента и Год, а ресурсом — ссылка на сам документ. Плюсы:

Минусы:

Вариант 2: Использование прямого запроса к документам

Этот метод считается более современным и надежным для баз на SQL-платформах. Плюсы:

Практическая реализация через запрос в расширении

Разберем по шагам, как реализовать проверку с помощью прямого запроса. Мы будем использовать обработчик события ПередЗаписью в расширении для документа ПоступлениеТоваровУслуг. Нам важно убедиться, что проверка не срабатывает при обмене данными.

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


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

    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |	Поступление.Ссылка КАК Ссылка
        |ИЗ
        |	Документ.ПоступлениеТоваровУслуг КАК Поступление
        |ГДЕ
        |	Поступление.Контрагент = &Контрагент
        |	И Поступление.НомерВходящегоДокумента = &НомерВходящегоДокумента
        |	И Поступление.Дата МЕЖДУ &НачалоГода И &КонецГода
        |	И Поступление.Ссылка <> &ТекущаяСсылка";

    Запрос.УстановитьПараметр("Контрагент", Источник.Контрагент);
    Запрос.УстановитьПараметр("НомерВходящегоДокумента", Источник.НомерВходящегоДокумента);
    Запрос.УстановитьПараметр("НачалоГода", НачалоГода(Источник.Дата));
    Запрос.УстановитьПараметр("КонецГода", КонецГода(Источник.Дата));
    Запрос.УстановитьПараметр("ТекущаяСсылка", Источник.Ссылка);

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

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

Критически важный аспект: Управляемые блокировки

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

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


Блокировка = Новый БлокировкаДанных;
ЭлементБлокировки = Блокировка.Добавить("Документ.ПоступлениеТоваровУслуг");
ЭлементБлокировки.УстановитьПараметр("Контрагент", Источник.Контрагент);
ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
Блокировка.Заблокировать();

Установка исключительной блокировки по контрагенту гарантирует, что другой сеанс не сможет начать проверку уникальности для этого же контрагента, пока текущая транзакция не завершится.

Вопрос сохранности данных в расширениях

Существует опасение, что при «отвале» расширения (например, из-за изменения версии совместимости платформы при обновлении) данные могут быть потеряны. Разберем этот момент:

  1. Отключение расширения: Если расширение просто снято с активности, все его таблицы в базе данных SQL сохраняются. Как только вы исправите конфликт и подключите расширение снова, данные станут доступны.
  2. Удаление расширения: Только физическое удаление объекта расширения из списка приводит к безвозвратному удалению его таблиц из базы данных.

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

Особенности проверки входящих счетов-фактур

Посмотрим на специфику БП 3.0: СчетФактураПолученный часто является отдельным подчиненным документом. Если ваша задача — контролировать уникальность и по СФ, проверку стоит вынести в общую процедуру (подписку на событие) или реализовать аналогичный код в расширении для документа счета-фактуры.

Важно помнить, что связка «Поступление — Счет-фактура» может создаваться не одновременно. Поэтому правильнее всего анализировать уникальность именно в контексте Контрагента и Периода, обращаясь к соответствующим метаданным.

Резюме по реализации

Подводя итог нашему анализу, рекомендуем придерживаться следующего алгоритма:

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

← На главную