Tuesday, February 22, 2011

Игры с построителем отчета в 1с

Необходимо было сделать отчет с анализатором остатков по дням, решил долго не мучатся и сделать через ПостроительОтчета в 1С. Необходимые поля:
1. Номенклатура+артикул
2. Дни (анализ делаем за каждый день)
3. Заказано (какое количество номенклатуры было заказано за период)
4. Отгружено (Считай приходные накладные)
5. Возврат (сколько вернули)
6. Остаток товара на конец дня
7. Маленький такой анализ % возврата.

Вид картинкой:


А теперь сам код:

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
НачалоПериода = началоМесяца(ТекущаяДата());
КонецПериода = КонецДня(ТекущаяДата());
ОтчетИнициализация();

КонецПроцедуры

Процедура ПриЗакрытии()

//СохранитьЗначение("НастройкаВнешниеОбработкиВнешняяОбработка3Отчет_bc39e421-f272-414c-9c50-d1bfb9a20f26", ПостроительОтчетаОтчет.ПолучитьНастройки());

КонецПроцедуры

Процедура ДействияФормыОтчетНастройка(Кнопка)
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_НАСТРОЙКА(Отчет)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

Форма = ВнешняяОбработкаОбъект.ПолучитьФорму("ОтчетНастройка");
//ПостроительОтчетаОтчет.ИзмеренияКолонки.Добавить("Дата");
//ПостроительОтчетаОтчет.ИзмеренияКолонки.Удалить(ПостроительОтчетаОтчет.ИзмеренияКолонки[0]);
Форма.ПостроительОтчета = ПостроительОтчетаОтчет;
Настройка = ПостроительОтчетаОтчет.ПолучитьНастройки();
Если Форма.ОткрытьМодально() = Истина Тогда
ОтчетВывести();
Иначе
ПостроительОтчетаОтчет.УстановитьНастройки(Настройка);
КонецЕсли;

//}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_НАСТРОЙКА
КонецПроцедуры

Процедура ДействияФормыОтчетСформировать(Кнопка)
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА(Отчет)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

ОтчетВывести();

//}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА
КонецПроцедуры

Процедура ОтчетВывести()
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ВЫПОЛНИТЬ(Отчет)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
//ОтчетИнициализация();
ЭлементыФормы.ПолеТабличногоДокумента.Очистить();

ПостроительОтчетаОтчет.Параметры.Вставить("КонецПериода", КонецПериода);
ПостроительОтчетаОтчет.Параметры.Вставить("Контрагент", Контрагент);
ПостроительОтчетаОтчет.Параметры.Вставить("НачалоПериода", НачалоПериода);
ПостроительОтчетаОтчет.Параметры.Вставить("ПодразделениеКомпании", ПодразделениеКомпании);
ПостроительОтчетаОтчет.ТекстЗаголовка = "Анализ заказов по " + ПодразделениеКомпании.Наименование +Символы.ПС
+ " контрагент " + Контрагент.Наименование
+" период с  " + Формат(НачалоПериода,"ДФ=dd.MM.yyyy")+ " по " + Формат(КонецПериода,"ДФ=dd.MM.yyyy");

ПостроительОтчетаОтчет.Выполнить();
ПостроительОтчетаОтчет.РазмещениеИзмеренийВСтроках = ТипРазмещенияИзмерений.Вместе;
ПостроительОтчетаОтчет.РазмещениеРеквизитовИзмеренийВСтроках = ТипРазмещенияРеквизитовИзмерений.Отдельно;
ПостроительОтчетаОтчет.РазмещениеРеквизитовИзмеренийВКолонках = ТипРазмещенияРеквизитовИзмерений.Отдельно;

ПостроительОтчетаОтчет.МакетОформления = ПолучитьМакетОформления(СтандартноеОформление.Песок);



Макет=ПостроительОтчетаОтчет.Макет;
Область = Макет.Область();
Область.ШиринаКолонки = 10;
Линия = Новый Линия(ТипЛинииЯчейкиТабличногоДокумента.Сплошная,1);
ТекущаяОбласть = Неопределено;

ТекущаяОбласть = Макет.НайтиТекст("Номенклатура", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 70;
ТекущаяОбласть.Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Артикул", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть.Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Заказано", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть .Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Отгружено", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть .Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Возврат", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть .Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("Остаток", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 8;
ТекущаяОбласть .Обвести(Линия,Линия,Линия,Линия);
КонецЕсли;

ТекущаяОбласть = Макет.НайтиТекст("ПроцентВозврата", ТекущаяОбласть, Макет.Область());
Если ТекущаяОбласть <> Неопределено Тогда
ТекущаяОбласть.ШиринаКолонки  = 0;
ТекущаяОбласть.Видимость=Ложь;

КонецЕсли;

ПостроительОтчетаОтчет.Макет = Макет;



ПостроительОтчетаОтчет.Вывести(ЭлементыФормы.ПолеТабличногоДокумента);
ЭлементыФормы.ПолеТабличногоДокумента.ФиксацияСверху=5;
ЭлементыФормы.ПолеТабличногоДокумента.ФиксацияСлева=3;
//}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ВЫПОЛНИТЬ
КонецПроцедуры

Процедура ОтчетИнициализация()
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ИНИЦИАЛИЗАЦИЯ(Отчет)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
Текст = "";
СчДней=Формат(НачалоПериода,"ДФ=yyyyMMdd");
ДатаЦикла=КонецДня(НачалоПериода);

Текст =
"ВЫБРАТЬ
|   &Д"+СчДней+" КАК Период,
|   ПартииТоваровКомпанииОстатки.Номенклатура,
|   ПартииТоваровКомпанииОстатки.Номенклатура.Артикул Как Артикул,
|   ПартииТоваровКомпанииОстатки.КоличествоОстаток КАК Остаток
|   ПОМЕСТИТЬ ТемпОст
|ИЗ
|   РегистрНакопления.ПартииТоваровКомпании.Остатки(&Д"+СчДней+",СкладКомпании.Подразделение=&ПодразделениеКомпании И Партия.Контрагент=&Контрагент) КАК ПартииТоваровКомпанииОстатки
|   ";

ПостроительОтчетаОтчет.Параметры.Вставить("Д"+СчДней, началоПериода);
Пока ДатаЦикла <= КонецПериода  Цикл

ДатаЦикла=КонецДня(ДатаЦикла+2);
СчДней = Формат(ДатаЦикла,"ДФ=yyyyMMdd");

Текст = Текст +
"
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ
|   &Д"+СчДней+" КАК Период,
|   ПартииТоваровКомпанииОстатки.Номенклатура,
|   ПартииТоваровКомпанииОстатки.Номенклатура.Артикул,
|   ПартииТоваровКомпанииОстатки.КоличествоОстаток
|ИЗ
|   РегистрНакопления.ПартииТоваровКомпании.Остатки(&Д"+СчДней+",СкладКомпании.Подразделение=&ПодразделениеКомпании И Партия.Контрагент= &Контрагент) КАК ПартииТоваровКомпанииОстатки
|";
ПостроительОтчетаОтчет.Параметры.Вставить("Д"+СчДней, ДатаЦикла);
КонецЦикла;
СчДней= Формат(КонецПериода,"ДФ=yyyyMMdd");
Текст = Текст+
"
|;
|ВЫБРАТЬ
|   ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ЗаказПоставщикуТовары.Ссылка.Дата, ДЕНЬ), ДЕНЬ, 1) КАК Дата,
|   ЗаказПоставщикуТовары.Номенклатура КАК Номенклатура,
|   ЗаказПоставщикуТовары.Номенклатура.Артикул КАК Артикул,
|   СУММА(ЗаказПоставщикуТовары.Количество) КАК Заказано,
|   СУММА(0) КАК Отгружено,
|   СУММА(0) КАК Возврат,
|   СУММА(0) КАК Остаток,
|   СУММА(0) КАК ПроцентВозврата
|ИЗ
|   Документ.ЗаказПоставщику.Товары КАК ЗаказПоставщикуТовары
|ГДЕ
|   ЗаказПоставщикуТовары.Ссылка.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ) И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
|   И ЗаказПоставщикуТовары.Ссылка.Контрагент = &Контрагент
|   И ЗаказПоставщикуТовары.Ссылка.Проведен
|   И ЗаказПоставщикуТовары.Ссылка.ПодразделениеКомпании = &ПодразделениеКомпании
|
|СГРУППИРОВАТЬ ПО
|   ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ЗаказПоставщикуТовары.Ссылка.Дата, ДЕНЬ), ДЕНЬ, 1),
|   ЗаказПоставщикуТовары.Номенклатура,ЗаказПоставщикуТовары.Номенклатура.Артикул
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|   НАЧАЛОПЕРИОДА(ПоступлениеТоваровТовары.Ссылка.Дата, ДЕНЬ),
|   ПоступлениеТоваровТовары.Номенклатура,
|   ПоступлениеТоваровТовары.Номенклатура.Артикул,
|   СУММА(0),
|   СУММА(ПоступлениеТоваровТовары.Количество),
|   СУММА(0),
|   СУММА(0),
|   СУММА(0)
|ИЗ
|   Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
|ГДЕ
|   ПоступлениеТоваровТовары.Ссылка.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ) И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
|   И ПоступлениеТоваровТовары.Ссылка.Контрагент = &Контрагент
|   И ПоступлениеТоваровТовары.Ссылка.Проведен
|   И ПоступлениеТоваровТовары.Ссылка.ПодразделениеКомпании = &ПодразделениеКомпании
|
|СГРУППИРОВАТЬ ПО
|   НАЧАЛОПЕРИОДА(ПоступлениеТоваровТовары.Ссылка.Дата, ДЕНЬ),
|   ПоступлениеТоваровТовары.Номенклатура,ПоступлениеТоваровТовары.Номенклатура.Артикул
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|   НАЧАЛОПЕРИОДА(ВозвратПоставщикуТовары.Ссылка.Дата, ДЕНЬ),
|   ВозвратПоставщикуТовары.Номенклатура,
|   ВозвратПоставщикуТовары.Номенклатура.Артикул,
|   СУММА(0),
|   СУММА(0),
|   СУММА(ВозвратПоставщикуТовары.Количество),
|   СУММА(0),
|   СУММА(0)
|ИЗ
|   Документ.ВозвратПоставщику.Товары КАК ВозвратПоставщикуТовары
|ГДЕ
|   ВозвратПоставщикуТовары.Ссылка.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&НачалоПериода, ДЕНЬ) И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
|   И ВозвратПоставщикуТовары.Ссылка.Контрагент = &Контрагент
|   И ВозвратПоставщикуТовары.Ссылка.Проведен
|   И ВозвратПоставщикуТовары.Ссылка.ПодразделениеКомпании = &ПодразделениеКомпании
|
|СГРУППИРОВАТЬ ПО
|   НАЧАЛОПЕРИОДА(ВозвратПоставщикуТовары.Ссылка.Дата, ДЕНЬ),
|   ВозвратПоставщикуТовары.Номенклатура,ВозвратПоставщикуТовары.Номенклатура.Артикул
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|   НАЧАЛОПЕРИОДА(ТемпОст.Период, ДЕНЬ),
|   ТемпОст.Номенклатура,
|   ТемпОст.Артикул,
|   СУММА(0),
|   СУММА(0),
|   СУММА(0),
|   СуММА(ТемпОст.Остаток),
|   СУММА(0)
|ИЗ
|   ТемпОст КАК ТемпОст
|СГРУППИРОВАТЬ ПО
|   НАЧАЛОПЕРИОДА(ТемпОст.Период, ДЕНЬ),
|   ТемпОст.Номенклатура, ТемпОст.Артикул
|
|УПОРЯДОЧИТЬ ПО
|   Дата,
|   Номенклатура
|ИТОГИ
|   СУММА(Заказано),
|   СУММА(Отгружено),
|   СУММА(Возврат),
|   ВЫразить(Среднее(Остаток) КАК ЧИсло(12,2)) КАК Остаток,
|   ВЫбор КОгда СУММА(Отгружено)=0 тогда 0 ИНАЧЕ Выразить(СУММА(Возврат)/СУММА(Отгружено)*100 КАК Число(12,2)) КОНЕЦ КАК ПроцентВозврата
|ПО
|   ОБЩИЕ,
|   Дата,
|   Номенклатура ИЕРАРХИЯ";
ПостроительОтчетаОтчет.Текст = Текст;
ПостроительОтчетаОтчет.ЗаполнитьНастройки();
ПостроительОтчетаОтчет.ЗаполнениеРасшифровки = ВидЗаполненияРасшифровкиПостроителяОтчета.ЗначенияГруппировок;
ПостроительОтчетаОтчет.ТекстЗаголовка = "Анализ заказов по " + ПодразделениеКомпании.НаименованиеПолное +Символы.ПС +" период с  " + Формат(НачалоПериода,"ДФ=dd.MM.yyyy")+ " по " + Формат(КонецПериода,"ДФ=dd.MM.yyyy");
//Настройка = ВосстановитьЗначение("НастройкаВнешниеОбработкиВнешняяОбработка3Отчет_bc39e421-f272-414c-9c50-d1bfb9a20f26");
//  Если Настройка <> Неопределено Тогда
//      ПостроительОтчетаОтчет.УстановитьНастройки(Настройка);
//  КонецЕсли;

ПостроительОтчетаОтчет.ИзмеренияСтроки.Очистить();
ПостроительОтчетаОтчет.ИзмеренияКолонки.Очистить();
ПостроительОтчетаОтчет.ИзмеренияСтроки.Добавить("Номенклатура","Номенклатура",ТипИзмеренияПостроителяОтчета.Иерархия);
ПостроительОтчетаОтчет.ИзмеренияКолонки.Добавить("Дата");
//ПостроительОтчетаОтчет.ИзмеренияСтроки.Удалить(ПостроительОтчетаОтчет.ИзмеренияСтроки[0]);
//ПостроительОтчетаОтчет.ИзмеренияКолонки.Добавить("Дата");
//ПостроительОтчетаОтчет.ИзмеренияКолонки.Удалить(ПостроительОтчетаОтчет.ИзмеренияКолонки[0]);
//}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ИНИЦИАЛИЗАЦИЯ
КонецПроцедуры

Процедура ВыбПериодНажатие(Элемент)
НастройкаПериода = Новый НастройкаПериода;
НастройкаПериода.УстановитьПериод(НачалоПериода, ?(КонецПериода='0001-01-01', КонецПериода, КонецДня(КонецПериода)));
НастройкаПериода.РедактироватьКакИнтервал = Истина;
НастройкаПериода.РедактироватьКакПериод = Истина;
НастройкаПериода.ВариантНастройки = ВариантНастройкиПериода.Период;
Если НастройкаПериода.Редактировать() Тогда
НачалоПериода = НастройкаПериода.ПолучитьДатуНачала();
КонецПериода = НастройкаПериода.ПолучитьДатуОкончания();
КонецЕсли;
ОтчетИнициализация();
КонецПроцедуры

Процедура НачалоПериодаПриИзменении(Элемент)
ОтчетИнициализация();
КонецПроцедуры

Процедура КонецПериодаПриИзменении(Элемент)
ОтчетИнициализация();
КонецПроцедуры




Основная задача отчета построить шахматкой данные за период в днях.
Основные сложности, это
1. Получить остатки за каждый день
2. Заставить построитель всегда работать правильно со строками и колонками
3. Нормализация ширины колонок.

No comments:

Post a Comment