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