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