Одной из наиболее частых задач при кастомизации конфигураций на платформе 1С:Предприятие 8.3 является отображение актуальных остатков непосредственно в форме списка справочника Номенклатура. Это значительно упрощает работу менеджеров по продажам или кладовщиков, позволяя видеть наличие товара без необходимости открывать дополнительные отчеты или карточку каждой позиции.
В этой статье мы подробно разберем, почему простые решения вроде функции в событии ПриАктивацииСтроки работают неэффективно, и проанализируем два профессиональных подхода к решению задачи: использование произвольного запроса в динамическом списке и программную обработку события ПриПолученииДанныхНаСервере.
Рассмотрим ситуацию, с которой часто сталкиваются начинающие разработчики: создание серверной функции, которая выполняет запрос к регистру остатков и вызывается при каждом перемещении курсора по списку. Разберем, в чем заключаются основные минусы такого подхода:
Вместо этого мы проанализируем более современные и правильные методы работы с механизмом ДинамическийСписок.
Этот метод считается классическим. Мы изменим текст запроса, который система использует для получения данных справочника, добавив в него левое соединение с виртуальной таблицей остатков. Рассмотрим этот процесс по шагам.
Во-первых, откроем форму списка номенклатуры и выберем свойства основного реквизита Список. Установим флаг Произвольный запрос и перейдем в конструктор запроса. Нам нужно дополнить стандартный текст следующим образом:
ВЫБРАТЬ
СправочникНоменклатура.Ссылка КАК Ссылка,
СправочникНоменклатура.Наименование КАК Наименование,
СправочникНоменклатура.Артикул КАК Артикул,
ЕСТЬNULL(ТиповойОстатки.КоличествоОстаток, 0) КАК ОстатокТовара
ИЗ
Справочник.Номенклатура КАК СправочникНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Типовой.Остатки(&Период, Счет = &Счет, , ) КАК ТиповойОстатки
ПО СправочникНоменклатура.Ссылка = ТиповойОстатки.Субконто1
Разберем важные моменты этого запроса:
&Период и &Счет (или фильтра по складу) обязательно для корректности данных.Чтобы параметры заработали, проанализируем код в процедуре ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Список.Параметры.УстановитьЗначениеПараметра("Период", ТекущаяДата());
Список.Параметры.УстановитьЗначениеПараметра("Счет", ПланыСчетов.Типовой.Товары);
КонецПроцедуры
Преимущества метода: Работает стандартная сортировка и отбор по колонке «ОстатокТовара». Недостатки: На очень больших справочниках соединение с виртуальными таблицами в динамическом списке может замедлять скроллинг.
Этот способ стал доступен в платформе 8.3.10 и выше. Он позволяет программно «дообогатить» данные, которые сервер уже подготовил для отправки на клиент. Это работает быстрее, так как запрос выполняется не для всей таблицы, а только для тех строк, которые реально видны на экране пользователя в данный момент.
Выясним причину эффективности этого метода: система передает в процедуру только ключи (ссылки) отображаемых строк. Мы можем собрать их, выполнить один компактный запрос и распределить значения по строкам. Посмотрим на реализацию:
&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
// Получаем массив ссылок на товары, которые сейчас отрисовываются на экране
МассивТоваров = Строки.ПолучитьКлючи();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТиповойОстатки.Субконто1 КАК Номенклатура,
| ТиповойОстатки.КоличествоОстаток КАК Остаток
|ИЗ
| РегистрБухгалтерии.Типовой.Остатки(&Дата, Счет = &Счет, , Субконто1 В (&МассивТоваров)) КАК ТиповойОстатки";
Запрос.УстановитьПараметр("МассивТоваров", МассивТоваров);
Запрос.УстановитьПараметр("Дата", ТекущаяДата());
Запрос.УстановитьПараметр("Счет", ПланыСчетов.Типовой.Товары);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// Находим нужную строку в переданной коллекции и заполняем данные
СтрокаСписка = Строки[Выборка.Номенклатура];
СтрокаСписка.Данные["ОстатокТовара"] = Выборка.Остаток;
КонецЦикла;
КонецПроцедуры
Важное примечание: Для работы этого кода в самом ДинамическомСписке на форме должна быть добавлена колонка (путь к данным) с именем ОстатокТовара. Это может быть либо реквизит справочника, либо специально созданное Вычисляемое поле в настройках компоновки данных списка.
Проанализируем ситуацию с производительностью: метод ПриПолученииДанныхНаСервере идеален, если расчет остатков сложный (например, нужно учитывать резервы по разным регистрам или рассчитывать свободный остаток по сложной формуле). Однако помните, что по таким «вычисляемым» программно полям не будет работать автоматическая сортировка платформы.
Независимо от выбранного способа, рассмотрим рекомендации, которые помогут избежать ошибок в учете:
&Склад).ОстатокТовара меньше или равен 0, можно окрашивать текст строки в серый цвет. Это делается на закладке «Условное оформление» в свойствах формы без написания кода.Разберем типичную ошибку: обращение к Субконто1 без проверки типа счета. В регистрах бухгалтерии порядок субконто может меняться. Надежнее использовать настройки компоновки данных или проверять, что первым субконто на счете 41 является именно Номенклатура.
Таким образом, мы проанализировали основные пути решения задачи. Выбор между произвольным запросом и событием получения данных зависит от ваших приоритетов: нужна ли пользователю сортировка по колонке остатка или важна максимальная скорость работы интерфейса при сложных расчетах.