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