Отчет ОстаткиМатериаловПоСвойствам
Для полного завершения картины мы создадим отчет, который будет показывать нам наличие материалов с теми или иными свойствами.
Создадим новый объект конфигурации Отчет и назовем его "ОстаткиМатериаловПоСвойствам". Запустим конструктор выходной формы, и займемся конструированием запроса.
Исходными данными для нашего запроса будут являться материал, свойство и значение свойства. Причем нужно предусмотреть возможность того, что материал выбираться не будет, а будут указываться только свойство и его значение.
Таким образом, алгоритм получения результирующих данных будет распадаться на две части: сначала, по указанным свойству и его значению, нам нужно будет выбрать все наборы свойств из регистра сведений "ЗначенияСвойствНоменклатуры", которым сопоставлены указанное свойство с указанным значением. Затем, для выбранных наборов свойств и их владельцев нам нужно будет получить остатки и обороты из регистра накопления "ОстаткиМатериалов".
Для того чтобы обеспечить такую "двухуровневую" выборку данных, мы воспользуемся возможностью создания вложенных запросов.
Сначала мы создадим вторую часть нашего алгоритма – запрос к регистру накопления "ОстаткиМатериалов".[277]
Выберем виртуальную таблицу регистра накопления "ОстаткиМатериалов.ОстаткиИОбороты". В параметрах виртуальной таблицы зададим условие отбора таким, что значение измерения регистра "НаборСвойств" должно находиться в списке, передаваемом в качестве параметра "СписокСвойств":
Для формирования такого списка наборов свойств нам и понадобится вложенный запрос к регистру сведений. Но этим мы займемся позже, а сейчас продолжим работать с регистром накопления.[278]
Из виртуальной таблицы регистра накопления "ОстаткиМатериалов.ОстаткиИОбороты" выберем следующие поля:
· | "ОстаткиМатериаловОстаткиИОбороты.Материал", |
· | "ОстаткиМатериаловОстаткиИОбороты.НаборСвойств, |
· | "ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток", |
· | "ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход", |
· | "ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход", |
· | "ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток": |
После этого на закладке "Объединения/Псевдонимы" зададим псевдонимы числовых полей без слова "Количество":
На закладке "Отчет" сбросим флаг "Использовать построитель отчета", а на закладке "Выходная форма" укажем, что не нужно редактировать в форме параметр "СписокСвойств".
На этом создание первого запроса завершено. Нажмем "ОК".
Откроем модуль формы и удалим элементы текста, которые нам не понадобятся. В процедуре "ДействияФормыОстаткиМатериаловПоСвойствамСформировать" [279] удалим второй параметр при вызове процедуры "ОстаткиМатериаловПоСвойствам":
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА(ОстаткиМатериаловПоСвойствам)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
ТабДок = ЭлементыФормы.ПолеТабличногоДокумента;
ОстаткиМатериаловПоСвойствам(ТабДок);
//}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА
КонецПроцедуры
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ(ОстаткиМатериаловПоСвойствам)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
Макет = ОтчетОбъект.ПолучитьМакет("ОстаткиМатериаловПоСвойствам");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОстаткиМатериаловОстаткиИОбороты.Материал,
| ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.Материал),
| ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,
| ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.НаборСвойств),
| ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход КАК Приход,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход КАК Расход,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток
|ИЗ
| РегистрНакопления.ОстаткиМатериалов.ОстаткиИОбороты(, , , , НаборСвойств В (&СписокСвойств)) КАК ОстаткиМатериаловОстаткиИОбороты";[280]
//Запрос.УстановитьПараметр("СписокСвойств",СписокСвойств);
Результат = Запрос.Выполнить();
...
Обладая достаточными навыками написания запросов, мы могли бы вручную, вместо "&СписокСвойств" написать текст вложенного запроса. Но, поскольку мы только осваиваем язык запросов, воспользуемся более комфортным способом: создадим текст вложенного запроса при помощи конструктора, а затем просто скопируем его в нужное нам место модуля. Для этого выполним команду ТекстКонструктор запроса...
В качестве исходных данных вложенного запроса выберем таблицу регистра сведений "ЗначенияСвойствНоменклатуры". Из нее выберем единственное поле – "ЗначенияСвойствМатериалов.НаборСвойств".
Зададим условия выборки. Прежде всего, владелец набора свойств должен быть равен переданному в параметре "Материал" материалу:
ЗначенияСвойствНоменклатуры.НаборСвойств.Владелед = &Материал
Затем укажем, что вид свойства должен быть равен переданному в параметре "ВидСвойства" значению:
ЗначенияСвойствНоменклатуры.ВидСвойства = &ВидСвойства [281]
И в заключение отметим, что значение свойства также будет задаваться параметром "Значение":
ЗначенияСвойствНоменклатуры.Значение = &Значение
Вложенный запрос готов. Теперь нажмем кнопку "Запрос", расположенную в нижней части окна конструктора запроса, выделим и скопируем текст запроса в буфер обмена Windows. Закроем окно с текстом запроса и нажмем "Отмена" в конструкторе запроса. Теперь вставим текст из буфера обмена вместо параметра в созданный нами ранее запрос:
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ(ОстаткиМатериаловПоСвойствам)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
Макет = ОтчетОбъект.ПолучитьМакет("ОстаткиМатериаловПоСвойствам");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОстаткиМатериаловОстаткиИОбороты.Материал,
| ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.Материал),
| ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,
| ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.НаборСвойств),
| ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход КАК Приход,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход КАК Расход,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток
|ИЗ
| РегистрНакопления.ОстаткиМатериалов.ОстаткиИОбороты(,,,,
| НаборСвойств В
| (ВЫБРАТЬ
| ЗначенияСвойствНоменклатуры.НаборСвойств [282]
| ИЗ
| РегистрСведений.ЗначенияСвойствНоменклатуры КАК ЗначенияСвойствНоменклатуры
| ГДЕ
| ЗначенияСвойствНоменклатуры.НаборСвойств.Владелец = &Материал
| И ЗначенияСвойствНоменклатуры.ВидСвойства = &ВидСвойства
| И ЗначенияСвойствНоменклатуры.Значение = &Значение)) КАК ОстаткиМатериаловОстаткиИОбороты";
Результат = Запрос.Выполнить();
...
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ(ОстаткиМатериаловПоСвойствам)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
Макет = ОтчетОбъект.ПолучитьМакет("ОстаткиМатериаловПоСвойствам");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОстаткиМатериаловОстаткиИОбороты.Материал,
| ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.Материал),
| ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,
| ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.НаборСвойств),
| ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход КАК Приход,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход КАК Расход,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток
|ИЗ
| РегистрНакопления.ОстаткиМатериалов.ОстаткиИОбороты(,,,,
| НаборСвойств В
| (ВЫБРАТЬ
| ЗначенияСвойствНоменклатуры.НаборСвойств
| ИЗ
| РегистрСведений. ЗначенияСвойствНоменклатуры КАК ЗначенияСвойствНоменклатуры [283]
| ГДЕ
|";
Если Не Материал.Пустая() тогда
Запрос.Текст = Запрос.Текст +
"ЗначенияСвойствНоменклатуры.НаборСвойств.Владелец = &Материал И
|";
КонецЕсли;
Запрос.Текст = Запрос.Текст +
" ЗначенияСвойствНоменклатуры.ВидСвойства = &ВидСвойства
| И ЗначенияСвойствНоменклатуры.Значение = &Значение)) КАК ОстаткиМатериаловОстаткиИОбороты";
Результат = Запрос.Выполнить();
...
//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ(ОстаткиМатериаловПоСвойствам)
// Данный фрагмент построен конструктором.
// При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
Макет = ОтчетОбъект.ПолучитьМакет("ОстаткиМатериаловПоСвойствам");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОстаткиМатериаловОстаткиИОбороты.Материал,
| ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.Материал),
| ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,
| ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.НаборСвойств),
| ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход КАК Приход,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход КАК Расход,
| ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток
|ИЗ
| РегистрНакопления.ОстаткиМатериалов.ОстаткиИОбороты(,,,,
| НаборСвойств В
| (ВЫБРАТЬ
| ЗначенияСвойствНоменклатуры.НаборСвойств
| ИЗ
| РегистрСведений.ЗначенияСвойствНоменклатуры КАК ЗначенияСвойствНоменклатуры
| ГДЕ
|"; [284]
Если Не Материал.Пустая() тогда
Запрос.Текст = Запрос.Текст +
"ЗначенияСвойствНоменклатуры.НаборСвойств.Владелец = &Материал И
|";
КонецЕсли;
Запрос.Текст = Запрос.Текст +
" ЗначенияСвойствНоменклатуры.ВидСвойства = &ВидСвойства
| И ЗначенияСвойствНоменклатуры.Значение = &Значение)) КАК ОстаткиМатериаловОстаткиИОбороты";
Если Не Материал.Пустая() тогда
Запрос.УстановитьПараметр("Материал", Материал);
КонецЕсли;
Запрос.УстановитьПараметр("ВидСвойства", ВидСвойства);
Запрос.УстановитьПараметр("Значение", Значение);
Результат = Запрос.Выполнить();
...
Откроем форму отчета и разместим на ней три поля ввода:
"Материал" с типом СправочникСсылка.Номенклатура,
"ВидСвойства" с типом ПланВидовХарактеристикСсылка.СвойстваНоменклатуры,
"Значение" с типом Характеристика.СвойстваНоменклатуры:
Для поля ввода "Материал" установим свойство "Выбор групп и элементов" как "Элементы".
Для поля ввода "Значение" установим связь по типу с реквизитом "ВидСвойства". А для поля ввода "ВидСвойства" создадим обработчик события "ПриИзменении":
Значение = ВидСвойства.ТипЗначения.ПривестиЗначение(Значение);
КонецПроцедуры [286]
Сначала посмотрим, какие у нас есть материалы с сечением 2,5 мм2:
Затем посмотрим, какие у нас есть материалы черного цвета:
[287]
И в заключение, чтобы убедиться в правильности работы отчета посмотрим, сколько у нас электрических кабелей черного цвета:
Таким образом, вы убедились в том, что при использовании данной логической схемы мы имеем теперь возможность вести учет материалов в произвольном количестве разрезов свойств и их значений.
Следует заметить, что пример, рассмотренный нами в этой главе, не является законченным решением для данной конфигурации. Мы лишь продемонстрировали возможность ведения такого учета. Для того чтобы наша конфигурация могла полноценно использовать свойства материалов, необходимо внести соответствующие изменения в остальные регистры, документы и некоторые отчеты. [288]