Итак, что мы имеем? Поставлена задача доработать типовой отчет "Продажи" в конфигурации "Бухгалтерия предприятия 3.0".
Необходимо сделать так, чтобы этот отчет выводил помимо двух показателей "Количество" и "Сумма" третий показатель - "Вес".
Разработка и тестирование производились на релизе На релизе 3.0.99.21 конфигурации "Бухгалтерия предприятия".
Что нам для этого нужно? С чего начать?
Прежде всего начнем с того что не требует программирования - добавим дополнительный реквизит "Вес" в справочник "Номенклатура". Процедура стандартная, и думаю, всем знакомая. Поэтому останавливаться на этом не буду.
Идем дальше. Добавляем в конфигурацию расширение. Меню -Конфигурация - Расширение конфигурации.
Назовем его "АдаптацияОтчетаПродажи". Префикс - "Старт_". Назначение - "Адаптация".
Снимем признак "Безопасный режим" в расширении.
Найдем в конфигурации нужный нам отчет "Продажи" и добавим его в расширение.
Также нам необходимо заимствовать в расширение следующие реквизиты отчета:
НачалоПериода, КонецПериода, Периодичность, РазмещениеДополнительныхПолей, ПоказательКоличество, ПоказательСумма.
Последние два реквизита - это признаки включения в отчет соответствующих показателей.
Поскольку нам необходимо добавить в отчет вывод нашего показателя "Вес", добавим еще один реквизит - ПоказательВес.
Добавим также еще один очень важный реквизит - ТекущаяСхемаКомпоновкиДанных. Тип реквизита Строка(80).
Комментарий "Наименование текущей используемой схемы компоновки данных".
Этот реквизит присутствует в некоторых других отчетах конфигурации, но в отчете "Продажи" его нет.
Зачем он нужен? Расскажу позже.
Также необходимо заимствовать в отчет табличные части Группировка и ДополнительныеПоля, а также их реквизиты Использование, Представление, ТипГруппировки.
Кроме этого, заимствуем форму отчета. Нам понадобится ее изменить.
Также добавляем макет - Схему компоновки данных. Для этого просто копируем в расширение макет "СхемаКомпоновкиДанных" типового отчета "Прдажи", и даем ему имя Старт_СхемаКомпоновкиДанных.
Почему мы именно копируем макет СКД, а не заимствуем его из отчета конфигурации?
Потому что расширения в 1С пока не умеют работать с заимствованной схемой компоновки.
Что делаем дальше? Подправим немного нашу заимствованную форму отчета.
Находим в элементах формы группу "ГруппаПоказатели". Видим что в этой группе есть элементы ПоказательКоличество и ПоказательСумма. Нам нужно здесь же разместить элемент ПоказательВес, связанный с добавленным нами ранее реквизитом отчета.
В правом верхнем окне формы раскрываем ветку реквизита Отчет, и... очень удивляемся.
Мы не видим там наш добавленный ранее реквизит отчета ПоказательВес. Что же делать?
Многих новичков, только начинающих работать с расширениями, этот вопрос ставит в тупик.
Для того чтобы наш реквизит появился, необходимо в правом верхнем окне формы выбрать реквизит Отчет и нажать на нем правой кнопкой мыши. В появившемся контекстном меню выбрать пункт "Добавить в расширение".
После этого мы сможем вывести наш добавленный реквизит на форму.
Добавим обработчик события "ПриИзменении" для элемента ПоказательВес.
&НаКлиенте
Процедура Старт_ПоказательВесПриИзмененииПосле(Элемент)
Если Не ЗначениеЗаполнено(ИдентификаторЗадания) Тогда
ОбщегоНазначенияКлиентСервер.УстановитьСостояниеПоляТабличногоДокумента(Элементы.Результат, "НеАктуальность");
КонецЕсли;
КонецПроцедуры
Также нам нужно будет внести некоторые изменения в модуль типовой формы отчета.
Для этого откроем форму отчета, найдем процедуру УстановитьНастройкиПоУмолчанию() и нажмем правую кнопку мыши на ее заголовке. Из контекстного меню выберем "Добавить в расширение".
В открывшемся окне "Тип вызова" выбираем "Вызывать вместо (с контролем)".
Такой тип вызова позволит нам использовать новые возможности расширений, описанные здесь.
Эти возможности доступны в релизах платформы начиная с 8.3.15.1489.
Они позволяют нам вносить "точечные" изменения в типовой код за счет использования инструкция препроцессора
#Вставить и #КонецВставить, #Удалить и #КонецУдалить.
Итак, измененный код процедуры УстановитьНастройкиПоУмолчанию() будет выглядеть следующим образом:
&НаСервере
&ИзменениеИКонтроль("УстановитьНастройкиПоУмолчанию")
Процедура Старт_УстановитьНастройкиПоУмолчанию()
БухгалтерскиеОтчетыВызовСервера.УстановитьНастройкиПоУмолчанию(ЭтотОбъект);
Отчет.ПоказательСумма = Истина;
Отчет.ПоказательКоличество = Истина;
#Вставка
Отчет.ПоказательВес = Истина;
#КонецВставки
КонецПроцедуры
Также нам потребуется внести изменения в функцию ПодготовитьПараметрыОтчетаНаСервере() модуля формы.
Делаем это также как и в предыдущем случае. Измененный код функции будет выглядеть следующим образом:
Функция Старт_ПодготовитьПараметрыОтчетаНаСервере()
&НаСервере
&ИзменениеИКонтроль("ПодготовитьПараметрыОтчетаНаСервере")
Функция Старт_ПодготовитьПараметрыОтчетаНаСервере()
МенеджерОтчета = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ЭтотОбъект.ИмяФормы);
ПараметрыОтчета = МенеджерОтчета.ПустыеПараметрыКомпоновкиОтчета();
ПараметрыОтчета.НачалоПериода = Отчет.НачалоПериода;
ПараметрыОтчета.КонецПериода = Отчет.КонецПериода;
ПараметрыОтчета.ПоказательСумма = Отчет.ПоказательСумма;
ПараметрыОтчета.ПоказательКоличество = Отчет.ПоказательКоличество;
#Вставка
ПараметрыОтчета.ПоказательВес = Отчет.ПоказательВес;
#КонецВставки
ПараметрыОтчета.Организация = Отчет.Организация;
ПараметрыОтчета.ВключатьОбособленныеПодразделения = Отчет.ВключатьОбособленныеПодразделения;
ПараметрыОтчета.Периодичность = Отчет.Периодичность;
ПараметрыОтчета.РазмещениеДополнительныхПолей = Отчет.РазмещениеДополнительныхПолей;
ПараметрыОтчета.Группировка = Отчет.Группировка.Выгрузить();
ПараметрыОтчета.ДополнительныеПоля = Отчет.ДополнительныеПоля.Выгрузить();
ПараметрыОтчета.ВыводитьДиаграмму = ВыводитьДиаграмму;
ПараметрыОтчета.ВыводитьЗаголовок = ВыводитьЗаголовок;
ПараметрыОтчета.ВыводитьПодвал = ВыводитьПодвал;
ПараметрыОтчета.ВыводитьПримечания = ВыводитьПримечания;
ПараметрыОтчета.МакетОформления = МакетОформления;
ПараметрыОтчета.РежимРасшифровки = Отчет.РежимРасшифровки;
ПараметрыОтчета.ДанныеРасшифровки = ДанныеРасшифровки;
ПараметрыОтчета.КлючТекущегоВарианта = КлючТекущегоВарианта;
ПараметрыОтчета.СхемаКомпоновкиДанных = ПолучитьИзВременногоХранилища(СхемаКомпоновкиДанных);
ПараметрыОтчета.ИдентификаторОтчета = БухгалтерскиеОтчетыКлиентСервер.ПолучитьИдентификаторОбъекта(ЭтотОбъект);
ПараметрыОтчета.НастройкиКомпоновкиДанных = Отчет.КомпоновщикНастроек.ПолучитьНастройки();
ПараметрыОтчета.Вставить("ПоказательОпределятьСуммуПоОплате", КлючТекущегоВарианта = "ПродажиПоКонтрагентамПоОплате");
Возврат ПараметрыОтчета;
КонецФункции
Понадобятся еще некоторые изменения в модуле отчета и в модуле менеджера отчета, но о них расскажу позже.
А сейчас перейдем к самому главному: модификации Схемы компоновки отчета.
Что нам рекомендует фирма 1С при доработке типовых отчетов на СКД через расширения?
Она предлагает два варианта:
- Заимствовать отчет и создать для него собственную схему компоновки данных.
- Доработать исходную схему компоновки данных отчета. Для этого ее нужно скопировать (не заимствовать!) из конфигурации, назначить основной для заимствованного отчета и изменить так, как вам нужно.
Первый вариант отпадает. Собственная СКД нам не нужна. Нам достаточно доработать исходную СКД отчета.
Пойдем по второму варианту, но назначать схему основной для заимствованного отчета не будем, это все равно бесполезно.
Потом вы узнаете почему.
Фирма 1С не рассмотрела третий возможный вариант доработки типового отчета на СКД с помощью расширений.
Третий вариант представлен в следующей публикации: "Пример доработки типового отчета в БП 3.0".
Его суть заключается в программной модификации СКД.
Мы начинаем модифицировать нашу Схему компоновки и сразу же натыкаемся на множество ошибок, пути исправления которых не всегда очевидны. Эти ошибки связаны с тем что в нашем расширении не хватает некоторых объектов метаданных расширяемой конфигурации на которые есть ссылки в схеме компоновки отчета.
Эти ошибки не критичны, и в общем-то даже не являются ошибками. В режиме 1С:Предприятия наш доработанный отчет будет "видеть" все эти отсутствующие объекты метаданных конфигурации, и будет нормально работать.
Но если вы хотите чтобы "все было красиво" еще на этапе разработки расширения, то придется немного повозиться для исправления этих ошибок.
Ошибка первая:
Ну, тут как бы все очевидно. необходимо заимствовать в расширение справочник НоменклатурныеГруппы.
Также нам понадобится заимствовать в расширение справочники Номенклатура и некоторые другие объекты метаданных чтобы не было подобных ошибок.
Ошибка вторая:
С чем она связана? Ну, видимо с тем что мы заимствовали в расширение регистр бухгалтерии Хозрасчетный, но не заимствовали его ресурс Сумма. Также нужно заимствовать ресурс Количество.
Необходимо также позаимствовать измерения Организация и Подразделение.
Ошибка третья:
Для исправления этой ошибки и других подобных ошибок нам нужно предпринять сразу несколько действий.
- Заимствовать в расширение следующие объекты:
план видов характеристик ВидыСубконтоХозрасчетные, план счетов Хозрасчетный.
- Для плана видов характеристик назначить типы как на скриншоте ниже.
- Для плана счетов указать виды субконто и их количество как на скриншоте ниже.
- Для регистра бухгалтерии Хозрасчетный указать план счетов Хозрасчетный.
Ошибка четвертая:
Для устранения этой ошибки установим в свойствах регистра бухгалтерии Хозрасчетный признак "Корреспонденция".
Ошибка пятая:
Исправить ошибку нам поможет установка свойства Владельцы у справочника ДоговорыКонтрагентов.
Ну что же, все ошибки побороли. Теперь займемся модификацией нашей Схемы компоновки.
Модификация совсем несложная. Добавим вычисляемое поле Вес.
В выражении поля пропишем следующее:
УправлениеСвойствами.ЗначениеСвойства(Номенклатура, "Вес_1e023769e20845f7836529edef6a3da9")*Количество
Где "Вес_1e023769e20845f7836529edef6a3da9" - это идентификатор нашего дополнительного реквизита Вес.
Затем добавляем наше вычисляемое поле в ресурсы:
Далее для каждого варианта отчета добавляем наш ресурс Вес в выбранные поля группировки Таблица.
И еще один очень важный момент. Для того чтобы у нас корректно выводился отчет в разных комбинациях показателей Количество, Сумма и Вес, нам необходимо доработать макет отчета.
Здесь у нас первые четыре макета - из типового отчета. Все следующие добавлены.
Что еще остается сделать? Осталось внести некоторые изменения в модуль отчета и в модуль менеджера отчета.
В модуле отчета меняем процедуру ОпределитьНастройкиФормы()
Здесь мы подменяем типовую схему компоновки отчета на нашу собственную.
&ИзменениеИКонтроль("ОпределитьНастройкиФормы")
Процедура Старт_ОпределитьНастройкиФормы(Форма, КлючВарианта, Настройки)
Настройки.События.ПередЗагрузкойНастроекВКомпоновщик = Истина;
#Удаление
СхемаКомпоновкиДанных = ПолучитьМакет("СхемаКомпоновкиДанных");
#КонецУдаления
#Вставка
СхемаКомпоновкиДанных = ПолучитьМакет("Старт_СхемаКомпоновкиДанных");
#КонецВставки
КонецПроцедуры
Но эта подмена не сработала бы если бы мы ранее не добавили в наш отчет реквизит ТекущаяСхемаКомпоновкиДанных.
Именно по наличию этого реквизита в модуле БухгалтерскиеОтчетыКлиентСервер проверяется необходимость подмены схемы компоновки отчета:
// Проверяет в форме отчета применение нескольких рабочих схем компоновки данных.
// Критерий проверки - наличие реквизита ТекущаяСхемаКомпоновкиДанных объекта отчета.
//
// Параметры:
// Форма - ФормаКлиентскогоПриложения - форма отчета.
//
// Возвращаемое значение:
// Булево - Истина, если отчет использует несколько рабочих схем компоновки данных.
//
Функция ОтчетПоддерживаетНесколькоСхемКомпоновкиДанных(Форма) Экспорт
Если Не ОтчетИспользуетОтложеннуюИнициализациюКомпоновщикаНастроек(Форма) Тогда
Возврат Ложь; // Не поддерживается несколько схем компоновки данных без отложенной инициализации компоновщика.
КонецЕсли;
Возврат ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(Форма, "Отчет")
И ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(Форма.Отчет, "ТекущаяСхемаКомпоновкиДанных");
КонецФункции
Теперь нам осталось поменять некоторые процедуры и функции в модуле менеджера отчета. Займемся этим.
&ИзменениеИКонтроль("ПолучитьНаборПоказателей")
Функция Старт_ПолучитьНаборПоказателей()
НаборПоказателей = Новый Массив;
НаборПоказателей.Добавить("Сумма");
НаборПоказателей.Добавить("Количество");
#Вставка
НаборПоказателей.Добавить("Вес");
#КонецВставки
Возврат НаборПоказателей;
КонецФункции
Все внесенные изменения заключены в инструкции препроцессора #Вставить и #КонецВставить, #Удалить и #КонецУдалить.
Полный текст изменений в модуле менеджера отчета
&ИзменениеИКонтроль("ПолучитьНаборПоказателей")
Функция Старт_ПолучитьНаборПоказателей()
НаборПоказателей = Новый Массив;
НаборПоказателей.Добавить("Сумма");
НаборПоказателей.Добавить("Количество");
#Вставка
НаборПоказателей.Добавить("Вес");
#КонецВставки
Возврат НаборПоказателей;
КонецФункции
&ИзменениеИКонтроль("ПередКомпоновкойМакета")
Процедура Старт_ПередКомпоновкойМакета(ПараметрыОтчета, Схема, КомпоновщикНастроек)
КомпоновщикНастроек.Настройки.Выбор.Элементы.Очистить();
СчетаКассы = Новый Массив;
СчетаКассы.Добавить(ПланыСчетов.Хозрасчетный.Касса); // 50
СчетаКассы.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСРозничнымиПокупателями); // 62.Р
СчетаКассы.Добавить(ПланыСчетов.Хозрасчетный.ПродажиПоПлатежнымКартам); //57.03
СчетаКассы = БухгалтерскийУчет.СформироватьМассивСубсчетов(СчетаКассы);
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "СчетаКассы", СчетаКассы);
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "СчетаВыручки", БухгалтерскийУчетПовтИсп.СчетаВИерархии(ПланыСчетов.Хозрасчетный.Выручка));
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "ДоговорыПоСертификатам", ДоговорыПоСертификатам(ПараметрыОтчета.Организация));
Периодичность = БухгалтерскиеОтчетыКлиентСервер.ПолучитьЗначениеПериодичности(ПараметрыОтчета.Периодичность, ПараметрыОтчета.НачалоПериода, ПараметрыОтчета.КонецПериода);
#Удаление
СхемаЭталон = ПолучитьМакет("СхемаКомпоновкиДанных");
#КонецУдаления
#Вставка
СхемаЭталон = ПолучитьМакет("Старт_СхемаКомпоновкиДанных");
#КонецВставки
ТекстЗапроса = СхемаЭталон.НаборыДанных.Продажи.Запрос;
ПериодичностьОтчета = Новый Соответствие;
ПериодичностьОтчета.Вставить(6, "ДЕНЬ");
ПериодичностьОтчета.Вставить(9, "МЕСЯЦ");
ПериодичностьОтчета.Вставить(10, "КВАРТАЛ");
ПериодичностьОтчета.Вставить(11, "ПОЛУГОДИЕ");
ПериодичностьОтчета.Вставить(12, "ГОД");
Схема.НаборыДанных.Продажи.Запрос = СтрЗаменить(ТекстЗапроса, ".ПериодДень", ".Период" + ПериодичностьОтчета.Получить(Периодичность));
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "Периодичность", Периодичность);
Если ЗначениеЗаполнено(ПараметрыОтчета.НачалоПериода) Тогда
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "НачалоПериода", НачалоДня(ПараметрыОтчета.НачалоПериода));
КонецЕсли;
Если ЗначениеЗаполнено(ПараметрыОтчета.КонецПериода) Тогда
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "КонецПериода", КонецДня(ПараметрыОтчета.КонецПериода));
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "ПараметрПериод", КонецДня(ПараметрыОтчета.КонецПериода));
Иначе
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "ПараметрПериод", КонецДня(ТекущаяДатаСеанса()));
КонецЕсли;
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "ОпределятьСуммуПоОплате", ПараметрыОтчета.ПоказательОпределятьСуммуПоОплате);
СчетаДенежныхСредств = Новый Массив;
СчетаДенежныхСредств.Добавить(ПланыСчетов.Хозрасчетный.Касса);
СчетаДенежныхСредств.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСРозничнымиПокупателями);
СчетаДенежныхСредств.Добавить(ПланыСчетов.Хозрасчетный.РасчетныеСчета);
СчетаДенежныхСредств.Добавить(ПланыСчетов.Хозрасчетный.ВалютныеСчета);
СчетаДенежныхСредств.Добавить(ПланыСчетов.Хозрасчетный.ПродажиПоПлатежнымКартам);
СчетаДенежныхСредств = БухгалтерскийУчет.СформироватьМассивСубсчетов(СчетаДенежныхСредств);
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "СчетаДенежныхСредств", СчетаДенежныхСредств);
СчетаРасчетовСПокупателями = Новый Массив;
СчетаРасчетовСПокупателями.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСПокупателямиИЗаказчиками);
СчетаРасчетовСПокупателями.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСПрочимиПокупателямиИЗаказчиками);
СчетаРасчетовСПокупателями.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСПрочимиПокупателямиИЗаказчикамиВал);
СчетаРасчетовСПокупателями.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСПрочимиПокупателямиИЗаказчикамиУЕ);
СчетаРасчетовСПокупателями.Добавить(ПланыСчетов.Хозрасчетный.РасчетыСРазнымиДебиторамиИКредиторами);
СчетаРасчетовСПокупателями = БухгалтерскийУчет.СформироватьМассивСубсчетов(СчетаРасчетовСПокупателями);
БухгалтерскиеОтчетыКлиентСервер.УстановитьПараметр(КомпоновщикНастроек, "СчетаРасчетовСКонтрагентами", СчетаРасчетовСПокупателями);
ВыводитьДиаграмму = Неопределено;
Если НЕ ПараметрыОтчета.Свойство("ВыводитьДиаграмму", ВыводитьДиаграмму) Тогда
ВыводитьДиаграмму = Истина;
КонецЕсли;
Таблица = Неопределено;
ДиаграммаСумма = Неопределено;
ДиаграммаКоличество = Неопределено;
Для Каждого ЭлементСтруктуры Из КомпоновщикНастроек.Настройки.Структура Цикл
Если ЭлементСтруктуры.Имя = "Таблица" Тогда
Таблица = ЭлементСтруктуры;
ИначеЕсли ЭлементСтруктуры.Имя = "ДиаграммаСумма" Тогда
ДиаграммаСумма = ЭлементСтруктуры;
ИначеЕсли ЭлементСтруктуры.Имя = "ДиаграммаКоличество" Тогда
ДиаграммаКоличество = ЭлементСтруктуры;
КонецЕсли;
КонецЦикла;
Если ДиаграммаСумма <> Неопределено Тогда
Если ВыводитьДиаграмму И ПараметрыОтчета.ПоказательСумма Тогда
ДиаграммаСумма.Точки.Очистить();
ГруппировкаПериод = ДиаграммаСумма.Точки.Добавить();
ПолеГруппировки = ГруппировкаПериод.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеГруппировки.Использование = Истина;
ПолеГруппировки.Поле = Новый ПолеКомпоновкиДанных("Период");
ПолеГруппировки.ТипДополнения = БухгалтерскиеОтчетыВызовСервера.ПолучитьТипДополненияПоИнтервалу(Периодичность);
ПолеГруппировки.НачалоПериода = НачалоДня(ПараметрыОтчета.НачалоПериода);
ПолеГруппировки.КонецПериода = КонецДня(ПараметрыОтчета.КонецПериода);
ГруппировкаПериод.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
ПорядокПериод = ГруппировкаПериод.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
ПорядокПериод.Поле = ПолеГруппировки.Поле;
// Группировка
ДиаграммаСумма.Серии.Очистить();
Для Каждого ПолеВыбраннойГруппировки Из ПараметрыОтчета.Группировка Цикл
Если ПолеВыбраннойГруппировки.Использование Тогда
Группировка = ДиаграммаСумма.Серии.Добавить();
ЗаполнитьГруппировкуДиаграммы(ПолеВыбраннойГруппировки, Группировка);
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
ДиаграммаСумма.Использование = Ложь;
КонецЕсли;
КонецЕсли;
Если ДиаграммаКоличество <> Неопределено Тогда
Если ВыводитьДиаграмму И ПараметрыОтчета.ПоказательКоличество Тогда
ДиаграммаКоличество.Точки.Очистить();
ГруппировкаПериод = ДиаграммаКоличество.Точки.Добавить();
ПолеГруппировки = ГруппировкаПериод.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеГруппировки.Использование = Истина;
ПолеГруппировки.Поле = Новый ПолеКомпоновкиДанных("Период");
ПолеГруппировки.ТипДополнения = БухгалтерскиеОтчетыВызовСервера.ПолучитьТипДополненияПоИнтервалу(Периодичность);
ПолеГруппировки.НачалоПериода = НачалоДня(ПараметрыОтчета.НачалоПериода);
ПолеГруппировки.КонецПериода = КонецДня(ПараметрыОтчета.КонецПериода);
ГруппировкаПериод.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
ПорядокПериод = ГруппировкаПериод.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
ПорядокПериод.Поле = ПолеГруппировки.Поле;
// Группировка
ДиаграммаКоличество.Серии.Очистить();
Для Каждого ПолеВыбраннойГруппировки Из ПараметрыОтчета.Группировка Цикл
Если ПолеВыбраннойГруппировки.Использование Тогда
Группировка = ДиаграммаКоличество.Серии.Добавить();
ЗаполнитьГруппировкуДиаграммы(ПолеВыбраннойГруппировки, Группировка);
Прервать;
КонецЕсли;
КонецЦикла;
Иначе
ДиаграммаКоличество.Использование = Ложь;
КонецЕсли;
КонецЕсли;
Если Таблица <> Неопределено Тогда
Таблица.Колонки.Очистить();
ГруппировкаПериод = Таблица.Колонки.Добавить();
ПолеГруппировки = ГруппировкаПериод.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеГруппировки.Использование = Истина;
ПолеГруппировки.Поле = Новый ПолеКомпоновкиДанных("Период");
ПолеГруппировки.ТипДополнения = БухгалтерскиеОтчетыВызовСервера.ПолучитьТипДополненияПоИнтервалу(Периодичность);
ПолеГруппировки.НачалоПериода = НачалоДня(ПараметрыОтчета.НачалоПериода);
ПолеГруппировки.КонецПериода = КонецДня(ПараметрыОтчета.КонецПериода);
ГруппировкаПериод.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
ПорядокПериод = ГруппировкаПериод.Порядок.Элементы.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
ПорядокПериод.Поле = ПолеГруппировки.Поле;
// Группировка
Таблица.Строки.Очистить();
Группировка = Таблица.Строки;
Для Каждого ПолеВыбраннойГруппировки Из ПараметрыОтчета.Группировка Цикл
Если ПолеВыбраннойГруппировки.Использование Тогда
Если ТипЗнч(Группировка) = Тип("КоллекцияЭлементовСтруктурыТаблицыКомпоновкиДанных") Тогда
Группировка = Группировка.Добавить();
Иначе
Группировка = Группировка.Структура.Добавить();
КонецЕсли;
БухгалтерскиеОтчетыВызовСервера.ЗаполнитьГруппировку(ПолеВыбраннойГруппировки, Группировка);
ПолеОтбора = Новый ПолеКомпоновкиДанных("Сумма");
НовыйЭлемент = Группировка.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйЭлемент.Использование = Истина;
НовыйЭлемент.ЛевоеЗначение = ПолеОтбора;
НовыйЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
НовыйЭлемент.ПравоеЗначение = 0;
ПараметрВыводитьОтбор = Группировка.ПараметрыВывода.Элементы.Найти("ВыводитьОтбор");
ПараметрВыводитьОтбор.Использование = Истина;
ПараметрВыводитьОтбор.Значение = ТипВыводаТекстаКомпоновкиДанных.НеВыводить;
КонецЕсли;
КонецЦикла;
#Удаление
Если ПараметрыОтчета.ПоказательКоличество И ПараметрыОтчета.ПоказательСумма
И НЕ ПараметрыОтчета.ПоказательОпределятьСуммуПоОплате Тогда
ГруппировкаКолонки = Таблица.Колонки;
Для Каждого ПолеВыбраннойГруппировки Из ГруппировкаКолонки Цикл
Если ПолеВыбраннойГруппировки.Использование Тогда
ПолеВыбраннойГруппировки.Имя = "ПериодКоличествоИСумма";
КонецЕсли;
КонецЦикла;
КонецЕсли;
#КонецУдаления
#Вставка
Если НЕ ПараметрыОтчета.ПоказательОпределятьСуммуПоОплате Тогда
Если ПараметрыОтчета.ПоказательКоличество И ПараметрыОтчета.ПоказательСумма И ПараметрыОтчета.ПоказательВес Тогда
ГруппировкаКолонки = Таблица.Колонки;
Для Каждого ПолеВыбраннойГруппировки Из ГруппировкаКолонки Цикл
Если ПолеВыбраннойГруппировки.Использование Тогда
ПолеВыбраннойГруппировки.Имя = "ПериодКоличествоИСуммаИВес";
КонецЕсли;
КонецЦикла;
ИначеЕсли ПараметрыОтчета.ПоказательКоличество И ПараметрыОтчета.ПоказательСумма Тогда
ГруппировкаКолонки = Таблица.Колонки;
Для Каждого ПолеВыбраннойГруппировки Из ГруппировкаКолонки Цикл
Если ПолеВыбраннойГруппировки.Использование Тогда
ПолеВыбраннойГруппировки.Имя = "ПериодКоличествоИСумма";
КонецЕсли;
КонецЦикла;
ИначеЕсли ПараметрыОтчета.ПоказательКоличество И ПараметрыОтчета.ПоказательВес Тогда
ГруппировкаКолонки = Таблица.Колонки;
Для Каждого ПолеВыбраннойГруппировки Из ГруппировкаКолонки Цикл
Если ПолеВыбраннойГруппировки.Использование Тогда
ПолеВыбраннойГруппировки.Имя = "ПериодКоличествоИВес";
КонецЕсли;
КонецЦикла;
ИначеЕсли ПараметрыОтчета.ПоказательСумма И ПараметрыОтчета.ПоказательВес Тогда
ГруппировкаКолонки = Таблица.Колонки;
Для Каждого ПолеВыбраннойГруппировки Из ГруппировкаКолонки Цикл
Если ПолеВыбраннойГруппировки.Использование Тогда
ПолеВыбраннойГруппировки.Имя = "ПериодСуммаИВес";
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЕсли;
#КонецВставки
ПолеКоличество = Новый ПолеКомпоновкиДанных("Количество");
ПолеСумма = Новый ПолеКомпоновкиДанных("Сумма");
#Вставка
ПолеВес = Новый ПолеКомпоновкиДанных("Вес");
#КонецВставки
Для Каждого ЭлементВыбора Из Таблица.Выбор.Элементы Цикл
Если ЭлементВыбора.Поле = ПолеКоличество Тогда
ЭлементВыбора.Использование = ПараметрыОтчета.ПоказательКоличество И НЕ ПараметрыОтчета.ПоказательОпределятьСуммуПоОплате;
КонецЕсли;
Если ЭлементВыбора.Поле = ПолеСумма Тогда
ЭлементВыбора.Использование = ПараметрыОтчета.ПоказательСумма;
КонецЕсли;
#Вставка
Если ЭлементВыбора.Поле = ПолеВес Тогда
ЭлементВыбора.Использование = ПараметрыОтчета.ПоказательВес;
КонецЕсли;
#КонецВставки
КонецЦикла;
КонецЕсли;
// Дополнительные данные
БухгалтерскиеОтчетыВызовСервера.ДобавитьДополнительныеПоля(ПараметрыОтчета, КомпоновщикНастроек);
БухгалтерскиеОтчетыВызовСервера.ДобавитьОтборПоОрганизации(ПараметрыОтчета, КомпоновщикНастроек);
КонецПроцедуры
&ИзменениеИКонтроль("ЗаполнитьПараметрыРасшифровкиОтчета")
Процедура Старт_ЗаполнитьПараметрыРасшифровкиОтчета(Адрес, Расшифровка, ПараметрыРасшифровки)
// Инициализируем список мунктов меню
СписокПунктовМеню = Новый СписокЗначений();
// Заполниим соответствие полей которые мы хотим получить из данных расшифровки
СоответствиеПолей = Новый Соответствие;
ДанныеОтчета = ПолучитьИзВременногоХранилища(Адрес);
ЗначениеРасшифровки = ДанныеОтчета.ДанныеРасшифровки.Элементы[Расшифровка];
Если ТипЗнч(ЗначениеРасшифровки) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
Для Каждого ПолеРасшифровки ИЗ ЗначениеРасшифровки.ПолучитьПоля() Цикл
Если ЗначениеЗаполнено(ПолеРасшифровки.Значение) Тогда
ПараметрыРасшифровки.Вставить("ОткрытьОбъект", Истина);
ПараметрыРасшифровки.Вставить("Значение", ПолеРасшифровки.Значение);
Возврат;
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Укажем что открывать объект сразу не нужно
ПараметрыРасшифровки.Вставить("ОткрытьОбъект", Ложь);
Если ДанныеОтчета = Неопределено Тогда
ПараметрыРасшифровки.Вставить("СписокПунктовМеню", СписокПунктовМеню);
Возврат;
КонецЕсли;
// Прежде всего интересны данные группировочных полей
Для Каждого Группировка Из ДанныеОтчета.Объект.Группировка Цикл
Если Группировка.Использование Тогда
СоответствиеПолей.Вставить(Группировка.Поле);
КонецЕсли;
КонецЦикла;
СоответствиеПолей.Вставить("Период");
// Инициализация пользовательских настроек
ПользовательскиеНастройки = Новый ПользовательскиеНастройкиКомпоновкиДанных;
ДополнительныеСвойства = ПользовательскиеНастройки.ДополнительныеСвойства;
ДополнительныеСвойства.Вставить("РежимРасшифровки", Истина);
ДополнительныеСвойства.Вставить("Организация", ДанныеОтчета.Объект.Организация);
ДополнительныеСвойства.Вставить("НачалоПериода", ДанныеОтчета.Объект.НачалоПериода);
ДополнительныеСвойства.Вставить("КонецПериода", ДанныеОтчета.Объект.КонецПериода);
ДополнительныеСвойства.Вставить("ВыводитьЗаголовок", ДанныеОтчета.Объект.ВыводитьЗаголовок);
ДополнительныеСвойства.Вставить("ВыводитьПодвал", ДанныеОтчета.Объект.ВыводитьПодвал);
ДополнительныеСвойства.Вставить("МакетОформления", ДанныеОтчета.Объект.МакетОформления);
ДополнительныеСвойства.Вставить("Периодичность", ДанныеОтчета.Объект.Периодичность);
ДополнительныеСвойства.Вставить("ВыводитьДиаграмму", Ложь);
ДополнительныеСвойства.Вставить("ПоказательКоличество", ДанныеОтчета.Объект.ПоказательКоличество);
ДополнительныеСвойства.Вставить("ПоказательСумма", ДанныеОтчета.Объект.ПоказательСумма);
#Вставка
ДополнительныеСвойства.Вставить("ПоказательВес", ДанныеОтчета.Объект.ПоказательВес);
#КонецВставки
ДополнительныеСвойства.Вставить("КлючТекущегоВарианта", ДанныеОтчета.Объект.КлючТекущегоВарианта);
ДополнительныеСвойства.Вставить("ОчищатьТаблицуГруппировок", Истина);
ДополнительныеСвойства.Вставить("ПоказательОпределятьСуммуПоОплате",ДанныеОтчета.Объект.ПоказательОпределятьСуммуПоОплате);
// Получаем соответствие полей доступных в расшифровке
Данные_Расшифровки = БухгалтерскиеОтчеты.ПолучитьДанныеРасшифровки(ДанныеОтчета.ДанныеРасшифровки, СоответствиеПолей, Расшифровка);
Договор = Данные_Расшифровки.Получить("Договор");
Если ЗначениеЗаполнено(Договор) Тогда
ДополнительныеСвойства.Вставить("Организация", Договор.Организация);
КонецЕсли;
Период = Данные_Расшифровки.Получить("Период");
Если ЗначениеЗаполнено(Период) Тогда
Периодичность = БухгалтерскиеОтчетыКлиентСервер.ПолучитьЗначениеПериодичности(ДанныеОтчета.Объект.Периодичность, ДанныеОтчета.Объект.НачалоПериода, ДанныеОтчета.Объект.КонецПериода);
ДополнительныеСвойства.Вставить("Периодичность", Периодичность);
ДополнительныеСвойства.Вставить("КонецПериода", КонецДня(БухгалтерскиеОтчетыКлиентСервер.КонецПериода(Период, Периодичность)));
ДополнительныеСвойства.Вставить("НачалоПериода", НачалоДня(БухгалтерскиеОтчетыКлиентСервер.НачалоПериода(Период, Периодичность)));
КонецЕсли;
ОтборПоЗначениямРасшифровки = ПользовательскиеНастройки.Элементы.Добавить(Тип("ОтборКомпоновкиДанных"));
ОтборПоЗначениямРасшифровки.ИдентификаторПользовательскойНастройки = "Отбор";
Для Каждого ЗначениеРасшифровки Из Данные_Расшифровки Цикл
Если ЗначениеРасшифровки.Ключ <> "Период" Тогда
БухгалтерскиеОтчетыКлиентСервер.ДобавитьОтбор(ОтборПоЗначениямРасшифровки, ЗначениеРасшифровки.Ключ, ЗначениеРасшифровки.Значение);
КонецЕсли;
КонецЦикла;
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.ЗагрузитьНастройки(ДанныеОтчета.ДанныеРасшифровки.Настройки);
КомпоновщикНастроек.Инициализировать(
Новый ИсточникДоступныхНастроекКомпоновкиДанных(ДанныеОтчета.Объект.СхемаКомпоновкиДанных));
МассивПолей = БухгалтерскиеОтчетыВызовСервера.ПолучитьМассивПолейРасшифровки(
Расшифровка, ДанныеОтчета.ДанныеРасшифровки, КомпоновщикНастроек, Истина);
Для Каждого Отбор Из МассивПолей Цикл
Если ТипЗнч(Отбор) = Тип("ГруппаЭлементовОтбораКомпоновкиДанных")
И Отбор.Представление = "###ОтборПоОрганизацииСОП###" Тогда
Для Каждого ЭлементОтбора Из Отбор.Элементы Цикл
Если ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация") Тогда
ДополнительныеСвойства.Вставить("Организация", ЭлементОтбора.ПравоеЗначение);
ДополнительныеСвойства.Вставить("ВключатьОбособленныеПодразделения", Истина);
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипЗнч(Отбор) = Тип("ЭлементОтбораКомпоновкиДанных") Тогда
Если Отбор.Представление = "###ОтборПоОрганизации###" Тогда
ДополнительныеСвойства.Вставить("Организация", Отбор.ПравоеЗначение);
ДополнительныеСвойства.Вставить("ВключатьОбособленныеПодразделения", Ложь);
ИначеЕсли Отбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Подразделение")
И Отбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно Тогда
ДополнительныеСвойства.Вставить("Подразделение", Отбор.ПравоеЗначение);
Иначе
БухгалтерскиеОтчетыКлиентСервер.ДобавитьОтбор(
ОтборПоЗначениямРасшифровки, Отбор.ЛевоеЗначение, Отбор.ПравоеЗначение, Отбор.ВидСравнения);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Группировка = Новый Массив();
ЕстьГруппировкаПоДокументу = Ложь;
Для Каждого СтрокаГруппировки Из ДанныеОтчета.Объект.Группировка Цикл
Если СтрокаГруппировки.Использование Тогда
СтрокаДляРасшифровки = Новый Структура("Использование, Поле, Представление, ТипГруппировки");
ЗаполнитьЗначенияСвойств(СтрокаДляРасшифровки, СтрокаГруппировки);
Группировка.Добавить(СтрокаДляРасшифровки);
Если СтрокаГруппировки.Поле = "Документ" Тогда
ЕстьГруппировкаПоДокументу = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если НЕ ЕстьГруппировкаПоДокументу Тогда
СтрокаДляРасшифровки = Новый Структура();
СтрокаДляРасшифровки.Вставить("Использование", Истина);
СтрокаДляРасшифровки.Вставить("Поле", "Документ");
СтрокаДляРасшифровки.Вставить("Представление", "Документ");
СтрокаДляРасшифровки.Вставить("ТипГруппировки", 0);
Группировка.Добавить(СтрокаДляРасшифровки);
КонецЕсли;
ДополнительныеСвойства.Вставить("Группировка", Группировка);
СписокПунктовМеню.Добавить("Продажи", "Продажи");
НастройкиРасшифровки = Новый Структура();
НастройкиРасшифровки.Вставить("Продажи", ПользовательскиеНастройки);
ДанныеОтчета.Вставить("НастройкиРасшифровки", НастройкиРасшифровки);
ПоместитьВоВременноеХранилище(ДанныеОтчета, Адрес);
ПараметрыРасшифровки.Вставить("СписокПунктовМеню", СписокПунктовМеню);
КонецПроцедуры
// Обработчик обновления на версию 3.0.76.5
// Включает вывод показателя "Вес" в отчете для всех пользователей в текущих пользовательских настройках отчета.
// Не обрабатывает пользовательские настройки, явно сохраненные пользователем.
//
Процедура ВключитьПоказательВес() Экспорт
ВариантыОтчета = ВариантыНастроек();
ОтборНастроек = Новый Структура("КлючОбъекта");
Для Каждого ВариантОтчета Из ВариантыОтчета Цикл
ОтборНастроек.КлючОбъекта = СтрШаблон("Отчет.Продажи/%1/ТекущиеПользовательскиеНастройки", ВариантОтчета.Имя);
ВыборкаНастроек = ХранилищеСистемныхНастроек.Выбрать(ОтборНастроек);
Пока ВыборкаНастроек.Следующий() Цикл
ПользовательскиеНастройки = ВыборкаНастроек.Настройки;
Если ТипЗнч(ПользовательскиеНастройки) <> Тип("ПользовательскиеНастройкиКомпоновкиДанных") Тогда
Продолжить;
КонецЕсли;
Если Не ПользовательскиеНастройки.ДополнительныеСвойства.Свойство("ДанныеОтчета")
Или Не ТипЗнч(ПользовательскиеНастройки.ДополнительныеСвойства.ДанныеОтчета) = Тип("ХранилищеЗначения") Тогда
Продолжить;
КонецЕсли;
ДанныеОтчета = ПользовательскиеНастройки.ДополнительныеСвойства.ДанныеОтчета.Получить();
Если ТипЗнч(ДанныеОтчета) <> Тип("Структура") Или Не ДанныеОтчета.Свойство("ПоказательВес") Тогда
Продолжить;
КонецЕсли;
ДанныеОтчета.ПоказательВес = Истина;
ПользовательскиеНастройки.ДополнительныеСвойства.ДанныеОтчета = Новый ХранилищеЗначения(ДанныеОтчета);
ХранилищеСистемныхНастроек.Сохранить(
ВыборкаНастроек.КлючОбъекта, ,
ПользовательскиеНастройки, ,
ВыборкаНастроек.Пользователь);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
// Возвращает имя схемы компоновки данных, которую необходимо использовать при указанных параметрах отчета.
// Соответствует имени макета отчета, содержащего необходимую схему.
//
// Параметры:
// ПараметрыВыбораСхемы - Структура - значения параметров отчета,
// определяющих выбор используемой схемы компоновки данных.
// См. НовыеПараметрыВыбораСхемыКомпоновкиДанных.
//
// Возвращаемое значение:
// Строка - имя используемой схемы компоновки данных при данных параметрах.
//
Функция ТекущаяСхемаКомпоновкиДанных(ПараметрыВыбораСхемы) Экспорт
Возврат "Старт_СхемаКомпоновкиДанных";
КонецФункции
// Конструктор коллекции параметров, влияющих на выбор используемой схемы компоновки данных.
//
// Возвращаемое значение:
// Структура:
// * Организация - СправочникСсылка.Организации
// * НачалоПериода - Дата
// * КонецПериода - Дата
//
Функция НовыеПараметрыВыбораСхемыКомпоновкиДанных() Экспорт
ПараметрыВыбораСхемы = Новый Структура;
ПараметрыВыбораСхемы.Вставить("Организация", Справочники.Организации.ПустаяСсылка());
ПараметрыВыбораСхемы.Вставить("НачалоПериода", '00010101');
ПараметрыВыбораСхемы.Вставить("КонецПериода", '00010101');
Возврат ПараметрыВыбораСхемы;
КонецФункции
Ну вот и все. Наш отчет готов.
Готовое расширение конфигурации с отчетом прикрепляю к публикации.