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