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