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