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