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