В типовых конфигурациях на обычных формах, таких как Управление торговлей 10.3, часто возникает задача превратить обычный отчет в интерактивное рабочее место. Типичный сценарий: пользователь формирует отчет по остаткам, видит дефицит и хочет прямо в этом же окне проставить количество товара для заказа, а затем нажатием одной кнопки сформировать документы. Рассмотрим подробнее, как реализовать этот функционал, используя возможности Системы компоновки данных (СКД) и механизмы Табличного документа.
Для начала проанализируем структуру нашего отчета. Нам необходимо, чтобы в итоговом результате появилась колонка, куда пользователь будет вносить данные. Рассмотрим, как это сделать:
КоличествоВЗаказ.0.После формирования отчета эта колонка будет выведена, но по умолчанию она будет защищена от редактирования, так как Результат отчета обычно выводится в режиме «Только просмотр».
Разберем, как разрешить пользователю редактировать конкретные ячейки. После того как метод СкомпоноватьРезультат() выполнил свою работу, нам нужно программно донастроить полученный ТабличныйДокумент. Выясним причину, почему ввод не работает: это свойства ТолькоПросмотр и Защита.
Проанализируем пример кода, который нужно разместить в модуле формы отчета после формирования результата:
ЭлементыФормы.Результат.ТолькоПросмотр = Ложь;
// Определяем область, которую можно редактировать (например, нашу колонку)
// Можно перебрать колонки и для нужного индекса установить Защита = Ложь
Для НомерСтроки = 1 По ЭлементыФормы.Результат.ВысотаТаблицы Цикл
Ячейка = ЭлементыФормы.Результат.Область(НомерСтроки, НомерКолонкиЗаказа);
Ячейка.Защита = Ложь;
КонецЦикла;
Чтобы система «понимала», что пользователь что-то ввел, мы будем использовать событие ПриИзмененииСодержимогоОбласти элемента формы ПолеТабличногоДокумента. Рассмотрим подробнее этот механизм. В этом событии нам доступен параметр Область, который указывает на измененную ячейку. Однако просто получить число недостаточно — нам нужно знать, к какой номенклатуре оно относится.
Посмотрим на пример обработки события:
Процедура РезультатПриИзмененииСодержимогоОбласти(Элемент, Область)
// Проверяем, что изменение произошло в нужной нам колонке
Если Область.Лево = НомерКолонкиЗаказа Тогда
ВведенноеЗначение = Область.Текст;
// Здесь можно сразу записывать данные в соответствие (ТЗ),
// чтобы не терять их при прокрутке или переформировании
КонецЕсли;
КонецПроцедуры
Это самый важный этап. В табличном документе номенклатура представлена текстом, и искать объект по наименованию — плохая практика. Проанализируем, как использовать ДанныеРасшифровки. При выводе отчета СКД заполняет свойство Расшифровка у каждой ячейки специальным идентификатором.
Чтобы получить ссылку на объект Номенклатура из строки, где была изменена ячейка, используем следующий алгоритм:
ДанныеРасшифровкиКомпоновкиДанных, чтобы извлечь значения полей.Разберем пример кода для получения ссылки:
// Получаем расшифровку из ячейки с номенклатурой (допустим, это колонка 1)
ИдРасшифровки = ЭлементыФормы.Результат.Область(Область.Верх, 1).Расшифровка;
Если ТипЗнч(ИдРасшифровки) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
Данные = ДанныеРасшифровки.Элементы[ИдРасшифровки];
Если ТипЗнч(Данные) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
Для Каждого Поле Из Данные.ПолучитьПоля() Цикл
Если Поле.Поле = "Номенклатура" Тогда
СсылкаНаТовар = Поле.Значение;
// Теперь у нас есть ссылка на объект Номенклатура!
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
Когда пользователь нажимает кнопку «Создать заказ», нам необходимо обойти весь табличный документ и собрать все строки, где заполнено количество. Рассмотрим, как это сделать эффективно.
Проанализируем ситуацию с группировками: если в отчете есть иерархия (например, по Поставщику), нам нужно запоминать текущего поставщика при обходе строк сверху вниз. Выясним, как построить цикл:
Процедура КнопкаСоздатьЗаказНажатие(Кнопка)
ТЗ_ДляЗаказа = Новый ТаблицаЗначений;
ТЗ_ДляЗаказа.Колонки.Добавить("Номенклатура");
ТЗ_ДляЗаказа.Колонки.Добавить("Количество");
Для Сч = 1 По ЭлементыФормы.Результат.ВысотаТаблицы Цикл
ОбластьКоличества = ЭлементыФормы.Результат.Область(Сч, НомерКолонкиЗаказа);
ЧислоЗаказа = Число(ОбластьКоличества.Текст);
Если ЧислоЗаказа > 0 Тогда
// Извлекаем номенклатуру через расшифровку, как показано выше
Товар = ПолучитьТоварИзРасшифровки(Сч);
НоваяСтрока = ТЗ_ДляЗаказа.Добавить();
НоваяСтрока.Номенклатура = Товар;
НоваяСтрока.Количество = ЧислоЗаказа;
КонецЕсли;
КонецЦикла;
// Создаем документ ЗаказПоставщику и заполняем его из ТЗ_ДляЗаказа
Если ТЗ_ДляЗаказа.Количество() > 0 Тогда
СоздатьДокументЗаказа(ТЗ_ДляЗаказа);
КонецЕсли;
КонецПроцедуры
При реализации данного метода стоит учитывать несколько важных моментов:
Таблицу Значений на форме при каждом изменении ячейки, а после переформирования программно заполнять колонку «Заказ» из этой таблицы.ТипЗначения как Число. Это позволит избежать ошибок при преобразовании строки в число.Таблицей Значений, в которую данные попадают через событие ПриИзмененииСодержимогоОбласти.ИдентификаторРасшифровки относится именно к детальной записи, а не к итоговому значению или группировке.Таким образом, мы рассмотрели полноценный механизм превращения статичного отчета в интерактивный инструмент для оперативной работы менеджера. Использование Расшифровки позволяет надежно связать данные на экране с объектами базы данных, что делает решение устойчивым и профессиональным.