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