В практике разработки часто возникает задача сформировать печатную форму или аналитический отчет, основываясь не на записанных данных в базе, а на том, что пользователь только что ввел в табличную часть документа на форме. В этом материале мы подробно разберем, как передать данные из табличной части в Систему Компоновки Данных (СКД) и как правильно настроить сложные строковые отборы.
Если нам необходимо построить отчет по данным, которые находятся в оперативной памяти (например, пользователь заполнил табличную часть, но еще не нажал кнопку "Записать"), стандартный запрос к базе данных не вернет актуальной информации. В этом случае мы должны использовать механизм Внешних наборов данных.
Логика действий следующая:
ТаблицаЗначений.Разберем пример программного формирования такого отчета. Этот код позволяет создать схему и настройки "на лету", либо использовать готовый макет, передав в него данные.
// 1. Подготовка данных
// Выгружаем данные из ТЧ документа в Таблицу Значений (ТЗ)
ТЗДанные = Объект.Товары.Выгрузить(, "Номенклатура, Количество, Цена");
// 2. Инициализация СКД (если схема создается программно или загружается из макета)
СКД = Новый СхемаКомпоновкиДанных;
// Создание Набора Данных "Объект"
ИсточникДанных = СКД.ИсточникиДанных.Добавить();
ИсточникДанных.Имя = "LocalSource";
ИсточникДанных.ТипИсточникаДанных = "local";
НаборДанных = СКД.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
НаборДанных.Имя = "НаборДанных1";
НаборДанных.ИмяОбъекта = "ВнешняяТЗ"; // Важно! Это имя ключа структуры данных
НаборДанных.ИсточникДанных = "LocalSource";
// Здесь необходимо добавить поля в набор данных, соответствующие колонкам ТЗ
ПолеНоменклатура = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
ПолеНоменклатура.Поле = "Номенклатура";
ПолеНоменклатура.ПутьКДанным = "Номенклатура";
ПолеНоменклатура.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.Номенклатура");
// ... аналогично добавляем остальные поля ...
// 3. Компоновка и вывод
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СКД));
КомпоновщикНастроек.ЗагрузитьНастройки(СКД.НастройкиПоУмолчанию);
// Формируем структуру для передачи данных
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ВнешняяТЗ", ТЗДанные); // Ключ должен совпадать с ИменемОбъекта в схеме
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СКД, КомпоновщикНастроек.ПолучитьНастройки());
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
// ПЕРЕДАЕМ ВНЕШНИЕ ДАННЫЕ ВТОРЫМ ПАРАМЕТРОМ
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных);
ТаблицаРезультат = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Если документ уже сохранен в базе данных, задача решается проще. Нам не нужны внешние наборы данных. Мы используем стандартный набор данных "Запрос".
В запросе СКД мы обращаемся к табличной части документа и устанавливаем условие по Ссылке:
ВЫБРАТЬ
Товары.Номенклатура,
Товары.Количество
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Товары
ГДЕ
Товары.Ссылка = &Ссылка
При открытии отчета из формы документа нам нужно лишь передать параметр Ссылка:
// В модуле формы или при открытии отчета
ПараметрыФормы = Новый Структура("Отбор, СформироватьПриОткрытии", Новый Структура("Ссылка", Объект.Ссылка), Истина);
ОткрытьФорму("Отчет.МойОтчет.Форма", ПараметрыФормы);
Часто требуется отфильтровать данные по сложным условиям, например, по вхождению подстроки в наименование (как функция Лев() в коде 1С). Перенос логики типа Лев(Наименование, 2) = "ВП" в запрос СКД имеет свои особенности.
В языке запросов 1С для работы со строками рекомендуется использовать следующие операторы и функции:
Это самый эффективный способ поиска по шаблону. Если нужно найти наименование, начинающееся на "ВП", используем спецсимвол % (любая последовательность символов).
// Аналог Лев(Наименование, 2) = "ВП"
ГДЕ
Номенклатура.Наименование ПОДОБНО "ВП%"
Если нужно найти вхождение строки "Диафрагма" в любом месте:
ГДЕ
Номенклатура.Наименование ПОДОБНО "%Диафрагма%"
Позволяет выделить часть строки. Используется, если нужно проверить точное совпадение с определенной позиции.
// Синтаксис: ПОДСТРОКА(Строка, НачальнаяПозиция, Длина)
ГДЕ
ПОДСТРОКА(Номенклатура.Наименование, 1, 2) = "ВП"
В новых версиях платформы (при отключенном режиме совместимости с старыми версиями) в языке запросов доступны функции, аналогичные встроенному языку:
СтрНайти(Строка, ПодстрокаПоиска)Лев(Строка, ЧислоСимволов)СтрДлина(Строка)Используя эти методы, вы сможете перенести сложную логику фильтрации ("Если наименование начинается на... или содержит...") непосредственно в текст запроса СКД или в настройки отбора, избегая циклической обработки данных в коде.