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