"Анализ списка инвентаризаций одним махом."
Опубликовано Вт 28 Октябрь 2014 в "Программирование"
Теги: Практика программирования 1С, Обработка, Запрос,
Постановка задачи
После того как мы сделали ряд инвентаризаций и по результатам ввели документы, оказалось, что найти документ какую то конкретную инвентаризацию, что бы потом быстро что то поправить, в оприходованиях или списаниях целая задача. Было решено набросать набросать обработку которая будет: показывать все инвентаризации документы которые введены на ее основании * номенклатуру остаток которой был исправлен этими документами. При двойном щелчке по документу получаем сам документ, двойном щелчке по номенклатуре получаем историю движению по регистру хранения остатков. Цели ясны, задачи определены, приступаем.
Получение нужных данных.
Вот сам запрос:
ВЫБРАТЬ ОприходованиеТоваров.Ссылка КАК Ссылка, ОприходованиеТоваров.ИнвентаризацияТоваровНаСкладе КАК ИнвентаризацияТоваровНаСкладе, ОприходованиеТоваров.ИнвентаризацияТоваровНаСкладе.Дата КАК ИнвентаризацияТоваровНаСкладеДата ИЗ Документ.ОприходованиеТоваров КАК ОприходованиеТоваров ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ СписаниеТоваров.Ссылка, СписаниеТоваров.ИнвентаризацияТоваровНаСкладе, СписаниеТоваров.ИнвентаризацияТоваровНаСкладе.Дата ИЗ Документ.СписаниеТоваров КАК СписаниеТоваров УПОРЯДОЧИТЬ ПО ИнвентаризацияТоваровНаСкладеДата УБЫВ ИТОГИ ПО ИнвентаризацияТоваровНаСкладе
Далее мы выполняем запрос и обходим его по группировкам.
Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выборка.Следующий() Цикл
СтрокаИнвентаризация = СписокДокументов.Строки.Добавить();
СтрокаИнвентаризация.Док = Выборка.ИнвентаризацияТоваровНаСкладе;
СтрокаИнвентаризация.Картинко = ?(СтрокаИнвентаризация.Док.Проведен, 1, ?(СтрокаИнвентаризация.Док.ПометкаУдаления, 2, 0));
СкладскиеДокументы = Выборка.Выбрать();
Пока СкладскиеДокументы.Следующий() Цикл
СтрокаСклад = СтрокаИнвентаризация.Строки.Добавить();
СтрокаСклад.Док = СкладскиеДокументы.Ссылка;
СтрокаСклад.Картинко = ?(СтрокаСклад.Док.Проведен, 1, ?(СтрокаСклад.Док.ПометкаУдаления, 2, 0));
ВсегоПройдетПоДокументу = 0;
Для Каждого СтрокаДокумента Из СтрокаСклад.Док.Товары Цикл
СтрокаСТоваром = СтрокаСклад.Строки.Добавить();
СтрокаСТоваром.Док = СтрокаДокумента.Номенклатура;
СтрокаСТоваром.Количество = СтрокаДокумента.Количество;
ВсегоПройдетПоДокументу = ВсегоПройдетПоДокументу + СтрокаДокумента.Количество;
КонецЦикла;
СтрокаСклад.Количество = ВсегоПройдетПоДокументу;
КонецЦикла;
КонецЦикла;
Готово! Теперь у нас есть вот такого вида форма

Вывод картинки отображающей статус для каждого документа.
Следует заметить, что для наглядности в дереве отмечается статус документов(проведен, не проведен, помечен на удаление), как вы поняли в выше приведенном коде за этот момент отвечает вот эта строка:
Для начала определимся с самой картинкой, вот она:СтрокаСклад.Картинко = ?(СтрокаСклад.Док.Проведен, 1, ?(СтрокаСклад.Док.ПометкаУдаления, 2, 0));

КартинкиСтрок
у колонки для которой мы хотим отображать эту картинку.
1. Указать у нужной колонки свойство ДанныеКартинки
. Указав данное свойство, мы фактически добавили еще одну колонку в которой будет храниться индекс отображаемой картинки
1. Заполнить свойство ДанныеКартинки
при добавлении строки.
Формирование отчета СКД из существующего макета.
Так как у нас просто есть схема которая лежит в макете, внешней обработки, то нам надо програмно: Загрузить схему в компоновщик макета. Инициализировать настройки на основании, нашей схемы. * Установить параметры отчета.
Вроде бы все достаточно просто, но на понимание того как это должно происходить, может уйти достаточно много времени. После детального изучения вопроса, была найдена статья откуда была выдернута вот эта процедура
Процедура ПолучитьДанныеНаОснованииСКД(СКД, ОбъектДляЗагрузки, ИсполняемыеНастройки = Неопределено, СтруктураПараметров = Неопределено,
РасшифровкаСКД = Неопределено, МакетКомпоновки = Неопределено, ВнешниеНаборыДанных = Неопределено) Экспорт
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Если ТипЗнч(ОбъектДляЗагрузки) = Тип("ПолеТабличногоДокумента") ИЛИ ТипЗнч(ОбъектДляЗагрузки) = Тип("ТабличныйДокумент") Тогда
ТипГенератора = Тип("ГенераторМакетаКомпоновкиДанных");
Иначе
ТипГенератора = Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений");
КонецЕсли;
Если ИсполняемыеНастройки = Неопределено Тогда
ИсполняемыеНастройки = СКД.НастройкиПоУмолчанию;
КонецЕсли;
Если СтруктураПараметров <> Неопределено Тогда
КоллекцияЗначенийПараметров = ИсполняемыеНастройки.ПараметрыДанных.Элементы;
Для каждого Параметр Из СтруктураПараметров Цикл
НайденноеЗначениеПараметра = КоллекцияЗначенийПараметров.Найти(Параметр.Ключ);
Если НайденноеЗначениеПараметра <> Неопределено Тогда
НайденноеЗначениеПараметра.Использование = Истина;
НайденноеЗначениеПараметра.Значение = Параметр.Значение;
КонецЕсли;
КонецЦикла;
КонецЕсли;
МакетКомпоновкиСКД = КомпоновщикМакета.Выполнить(СКД, ИсполняемыеНастройки, РасшифровкаСКД, МакетКомпоновки, ТипГенератора);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновкиСКД, ВнешниеНаборыДанных, РасшифровкаСКД);
Если ТипЗнч(ОбъектДляЗагрузки) = Тип("ПолеТабличногоДокумента") ИЛИ ТипЗнч(ОбъектДляЗагрузки) = Тип("ТабличныйДокумент") Тогда
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ОбъектДляЗагрузки);
Иначе
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ОбъектДляЗагрузки);
КонецЕсли;
ПроцессорВывода.ОтображатьПроцентВывода = Истина;
ПроцессорВывода.Вывести(ПроцессорКомпоновки, Истина);
КонецПроцедуры
ее суть проста: на входе макет, на выходе табличный документ. Теперь когда мы умеем формировать табличный документ на основе макета, мы можем одним легким движением, добавить расшифровку движений по складу для номенклатуры которая есть в нашем отчете. Приступаем.
Формирование истории движений конкретной номенклатуру по событию ни форме.
Когда возникают вопросы: "А в чем дело, почему у меня тосола -15 банок, я ведь все правильно делал", самое время пожать плечами и молча ткнуть пользователя в историю движений. Тут нам и поможет наш отчет на СКД. Мысль следующая: когда мы щелкаем на поле два раза по какой то номенклатуре, инициализируется простейший отчет на СКД который выводит все движения по таблице остатки и обороты регистра ТоварыВРознице
. Отчет достаточно простой постороенный вот на таком запросе.
ВЫБРАТЬ ТоварыВРозницеОстаткиИОбороты.Период, ТоварыВРозницеОстаткиИОбороты.Регистратор, ТоварыВРозницеОстаткиИОбороты.КоличествоНачальныйОстаток, ТоварыВРозницеОстаткиИОбороты.КоличествоПриход, ТоварыВРозницеОстаткиИОбороты.КоличествоРасход, ТоварыВРозницеОстаткиИОбороты.КоличествоКонечныйОстаток ИЗ РегистрНакопления.ТоварыВРознице.ОстаткиИОбороты( , , Регистратор, , Номенклатура = &Номенклатура И Склад = &Склад) КАК ТоварыВРозницеОстаткиИОборотыя думаю вы натыкаете его мышкой за 2 минуты. Перед тем как продолжить, я хотел бы попросить читателя если он еще не разобрался, понять что табличное поле и табличный документ это абсолютно разные сущности. Табличное поле, может быть списком значений, таблицей значений или деревом значений. Табличный документ это объект для формирования печатных форм, он имеет структуру схожую с excel но схожесть чисто внешняя.
Подготовительные действия.
Добавляем макет в обработку, указываем тип макета "Схема компоновки данных". Теперь можно им пользоваться в самой обработке. Можно сразу вывести отчет в табличный документ и на этом расслабиться, но тогда в нем не будет работать расшифровка, что бы в отчете работала расшифровка, табличный документ должен находиться на какой нибудь форме. Поэтому нам нужна форма и мы ее добавим как произвольную форму для обработки и поместим на нее табличный документ куда и будем выводить наш отчет. На этом все подготовительные действия закончены.
Вывод отчета из подготовленного макета в подготоваленную форму.
Далее нам нужен план действий, приблизительно следующего вида, когда пользователь щелкает по строке табличного поля на форме, то:
1. Если он щелкает по строке указывающей на документ, от открывается форма документа.
1. Если он щелкает по номенклатуре, то нам нужно
1. Загрузить макет формирующий историю движений.
1. Получить форму отчета, с табличным документом куда мы будем грузить отчет и реквизитом ОбработчикРасшифровки
произвольного типа куда мы будем передавать расшифровку.
1. Вывести на основании макета отчет в полученную форму и настроить обработку расшифровки.
Вешаем на событие 'Выбор' табличного поля, следующую процедуру:
Процедура СписокДокументовВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(ВыбраннаяСтрока.Док)) Тогда
ВыбраннаяСтрока.Док.ПолучитьФорму().Открыть();
Иначе
СхемаКомпоновкиДанных = ПолучитьМакет("ОтчетПоДвижениямНоменклатуры");
СтруктураПараметров = Новый Структура();
СтруктураПараметров.Вставить("НачалоПериода", ТекущаяДата() - 31556926);
СтруктураПараметров.Вставить("КонецПериода", ТекущаяДата());
СтруктураПараметров.Вставить("Номенклатура", ЭлементыФормы.СписокДокументов.ТекущаяСтрока.Док);
СтруктураПараметров.Вставить("Склад", ЭлементыФормы.СписокДокументов.ТекущаяСтрока.Родитель.Док.Склад);
Расшифровка = Новый ДанныеРасшифровкиКомпоновкиДанных;
ФормаОтчета = ПолучитьФорму("ИсторияДвижений");
ПолучитьДанныеНаОснованииСКД(СхемаКомпоновкиДанных, ФормаОтчета.ЭлементыФормы.ПолеТабличногоДокумента1, СхемаКомпоновкиДанных.НастройкиПоУмолчанию, СтруктураПараметров, Расшифровка);
ФормаОтчета.ОбработчикРасшифровки = Новый ОбработкаРасшифровкиКомпоновкиДанных(Расшифровка, Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));
ФормаОтчета.Открыть();
КонецЕсли;
КонецПроцедуры
которая реализует почти все кроме пункта 2.3. Остался последний штрих, добавить в открываюмую форму обработку расшифровки. Для этого используем событие ОбработкаРасшифровки
где укажем следующий код:
ОбработчикРасшифровки.Выполнить(Расшифровка);
СтандартнаяОбработка = Ложь;
Теперь расшифровка должна работать как и собственно сама обработка.
Заключение
как обычно почти весь код приведен и снабжен комментариями, но если у вас не получается собрать аленький цветочек можно скачать обработку на инфостарте