Как реализовать контроль уникальности номера документа по организации в 1С:Бухгалтерия 3.0 на управляемых формах?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

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

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

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

Метод 1: Проверка уникальности номера документа в обработчике события «ПриЗаписи»

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

  1. Место размещения кода:

    Нам необходимо открыть модуль объекта того документа, для которого требуется реализовать контроль уникальности. В нашем случае, поскольку речь идет о 1С:Бухгалтерия 3.0, это может быть любой документ, например, «Реализация товаров и услуг» или «Поступление товаров и услуг». В модуле объекта найдите или создайте процедуру обработчика события ПриЗаписи. Это событие происходит непосредственно перед записью объекта в базу данных, что идеально подходит для нашей проверки.

  2. Создание запроса для поиска дубликатов:

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

    Используем следующий пример кода:

    
    // Проверяем, что документ не помечен на удаление.
    // Если документ помечен, мы не должны проверять уникальность его номера,
    // так как он уже не участвует в активном учете.
    Если ЭтотОбъект.ПометкаУдаления Тогда
        Возврат;
    КонецЕсли;
    
    // Создаем новый объект запроса
    Запрос = Новый Запрос;
    
    // Формируем текст запроса
    Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |    ДокументСсылка.Ссылка
    |ИЗ
    |    Документ.МойДокумент КАК ДокументСсылка
    |ГДЕ
    |    ДокументСсылка.Номер = &Номер
    |    И ДокументСсылка.Организация = &Организация
    |    И ДокументСсылка.Ссылка <> &ТекущийДокумент";
    
    // Устанавливаем параметры запроса.
    // &Номер - текущий номер документа, который мы проверяем.
    Запрос.УстановитьПараметр("Номер", ЭтотОбъект.Номер);
    // &Организация - текущая организация документа.
    Запрос.УстановитьПараметр("Организация", ЭтотОбъект.Организация);
    // &ТекущийДокумент - ссылка на сам текущий документ.
    // Это позволяет исключить его из поиска, чтобы он не был найден как дубликат самого себя при изменении.
    Запрос.УстановитьПараметр("ТекущийДокумент", ЭтотОбъект.Ссылка);
    
    // Выполняем запрос и получаем результат
    Результат = Запрос.Выполнить().Выбрать();
    
    // Если Результат.Следующий() возвращает Истина, это означает, что был найден как минимум один дубликат
    Если Результат.Следующий() Тогда
        // Устанавливаем Отказ = Истина, чтобы предотвратить запись документа
        Отказ = Истина;
                
        // Создаем сообщение пользователю, информируя его о проблеме
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Документ с таким номером '" + ЭтотОбъект.Номер + "' уже существует для данной организации!";
        // Мы можем указать поле, на которое должен быть установлен курсор пользователя
        // Это помогает пользователю быстрее понять, какое поле требует исправления.
        Сообщение.Поле = "Номер"; 
        Сообщение.Сообщить();
    КонецЕсли;
    

    Пояснения к коду:

    • ВЫБРАТЬ ПЕРВЫЕ 1: Эта конструкция используется для оптимизации запроса. Как только система находит первый дубликат, она прекращает дальнейший поиск, что значительно ускоряет работу, особенно при большом объеме данных.
    • Документ.МойДокумент: Замените «МойДокумент» на фактическое имя типа документа в вашей конфигурации (например, Документ.РеализацияТоваровУслуг).
    • ЭтотОбъект.Номер, ЭтотОбъект.Организация, ЭтотОбъект.Ссылка: Эти свойства объекта документа позволяют получить текущие значения номера, организации и ссылки на изменяемый или создаваемый документ.
    • Отказ = Истина: Эта переменная, доступная в обработчике ПриЗаписи, позволяет отменить операцию записи. Если ей присвоить значение Истина, документ не будет записан.
    • СообщениеПользователю: Используется для вывода информационного сообщения пользователю с описанием причины отказа в записи. Свойство Поле позволяет указать, к какому полю на форме относится сообщение, и курсор пользователя будет автоматически установлен в это поле.
    • Важный нюанс: Если пользователь изменит организацию в документе, но оставит прежний номер, система все равно будет проверять уникальность номера по новой организации. Если в новой организации такой номер уже занят, будет выдана ошибка. Нам следует проинформировать пользователей об этой особенности или предусмотреть механизм автоматического изменения номера при смене организации, если это требуется по бизнес-логике.
  3. Производительность:

    Использование ВЫБРАТЬ ПЕРВЫЕ 1 существенно снижает нагрузку на базу данных, так как запрос завершается сразу после нахождения первого подходящего элемента. Индексы по полям "Номер" и "Организация" в таблице документов в СУБД (которые обычно создаются по умолчанию для этих реквизитов) также значительно ускоряют выполнение такого запроса.

Метод 2: Использование уникального индекса в базе данных

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

  1. Принцип работы:

    Мы создаем уникальный индекс по полям, которые должны быть уникальными в совокупности. В нашем случае это будут поля "Номер" и "Организация" для таблицы документов в базе данных. Когда 1С попытается записать документ с номером и организацией, которые уже существуют в базе данных (и при этом не являются ссылкой на тот же самый документ), СУБД автоматически выдаст ошибку, еще до того, как 1С успеет завершить операцию записи.

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

Метод 3: Использование специализированных объектов и механизмов 1С

В некоторых конфигурациях 1С, особенно в более крупных и сложных, таких как 1С:ERP, 1С:КА или 1С:Управление торговлей, могут присутствовать общие модули или объекты, предназначенные для управления нумерацией документов и контроля уникальности. Например, могут использоваться механизмы, агрегирующие информацию о номерах документов или предоставляющие функции для централизованной проверки.

  1. Принцип:

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

  2. Преимущества:
    • Использование штатных механизмов: если такие объекты существуют, их применение предпочтительнее, так как они разрабатываются вендором и поддерживаются при обновлениях.
    • Гибкость: Часто позволяют настроить правила уникальности без прямого изменения кода документа.
  3. Недостатки:
    • Сложность: Для небольших задач внедрение таких механизмов может быть избыточным и сложным.
    • Доступность: В 1С:Бухгалтерия 3.0 такие развитые механизмы могут отсутствовать или быть ограниченными по функциональности по сравнению с более крупными конфигурациями.

Заключение

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

Если же мы имеем дело с очень высокими требованиями к производительности и абсолютной гарантией целостности данных, а также готовы к сложностям сопровождения, мы можем рассмотреть вариант с созданием уникального индекса в базе данных. Однако, такой подход требует глубоких знаний СУБД и осторожности при внедрении.

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

← На главную