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