1С-Предприятие 8.0. Практическое пособие разработчика

Отчет ОстаткиМатериаловПоСвойствам


Для полного завершения картины мы создадим отчет, который будет показывать нам наличие материалов с теми или иными свойствами.

Создадим новый объект конфигурации Отчет и назовем его "ОстаткиМатериаловПоСвойствам". Запустим конструктор выходной формы, и займемся конструированием запроса.

Исходными данными для нашего запроса будут являться материал, свойство и значение свойства. Причем нужно предусмотреть возможность того, что материал выбираться не будет, а будут указываться только свойство и его значение.

Таким образом, алгоритм получения результирующих данных будет распадаться на две части: сначала, по указанным свойству и его значению, нам нужно будет выбрать все наборы свойств из регистра сведений "ЗначенияСвойствНоменклатуры", которым сопоставлены указанное свойство с указанным значением. Затем, для выбранных наборов свойств и их владельцев нам нужно будет получить остатки и обороты из регистра накопления "ОстаткиМатериалов".

Для того чтобы обеспечить такую "двухуровневую" выборку данных, мы воспользуемся возможностью создания вложенных запросов.

Сначала мы создадим вторую часть нашего алгоритма – запрос к регистру накопления "ОстаткиМатериалов".[277]

Выберем виртуальную таблицу регистра накопления "ОстаткиМатериалов.ОстаткиИОбороты". В параметрах виртуальной таблицы зададим условие отбора таким, что значение измерения регистра "НаборСвойств" должно находиться в списке, передаваемом в качестве параметра "СписокСвойств":

Для формирования такого списка наборов свойств нам и понадобится вложенный запрос к регистру сведений. Но этим мы займемся позже, а сейчас продолжим работать с регистром накопления.[278]

Из виртуальной таблицы регистра накопления "ОстаткиМатериалов.ОстаткиИОбороты" выберем следующие поля:

·"ОстаткиМатериаловОстаткиИОбороты.Материал",
·"ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,
·"ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток",
·"ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход",
·"ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход",
·"ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток":








После этого на закладке "Объединения/Псевдонимы" зададим псевдонимы числовых полей без слова "Количество":



На закладке "Отчет" сбросим флаг "Использовать построитель отчета", а на закладке "Выходная форма" укажем, что не нужно редактировать в форме параметр "СписокСвойств".

На этом создание первого запроса завершено. Нажмем "ОК".

Откроем модуль формы и удалим элементы текста, которые нам не понадобятся. В процедуре "ДействияФормыОстаткиМатериаловПоСвойствамСформировать" [279] удалим второй параметр при вызове процедуры "ОстаткиМатериаловПоСвойствам":

Процедура ДействияФормыОстаткиМатериаловПоСвойствамСформировать(Кнопка)

//{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА(ОстаткиМатериаловПоСвойствам)

   // Данный фрагмент построен конструктором.

   // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

   ТабДок = ЭлементыФормы.ПолеТабличногоДокумента;

   ОстаткиМатериаловПоСвойствам(ТабДок);

   //}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА

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

После этого в процедуре "ОстаткиМатериаловПоСвойствам" соответствующим образом изменим строку объявления процедуры и затем удалим строку, устанавливающую параметр запроса:

Процедура ОстаткиМатериаловПоСвойствам(ТабДок) Экспорт

   //{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ(ОстаткиМатериаловПоСвойствам)

   // Данный фрагмент построен конструктором.

   // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

   Макет = ОтчетОбъект.ПолучитьМакет("ОстаткиМатериаловПоСвойствам");

   Запрос = Новый Запрос;

   Запрос.Текст =

   "ВЫБРАТЬ

   |    ОстаткиМатериаловОстаткиИОбороты.Материал,

   |    ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.Материал),



   |    ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,

   |    ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.НаборСвойств),

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход КАК Приход,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход КАК Расход,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток

   |ИЗ

   |    РегистрНакопления.ОстаткиМатериалов.ОстаткиИОбороты(, , , , НаборСвойств В (&СписокСвойств)) КАК ОстаткиМатериаловОстаткиИОбороты";[280]

   //Запрос.УстановитьПараметр("СписокСвойств",СписокСвойств);

   Результат = Запрос.Выполнить();

...

Теперь мы можем перейти к созданию вложенного запроса, который будет передаваться в условие, заданное в параметре виртуальной таблицы.

Обладая достаточными навыками написания запросов, мы могли бы вручную, вместо "&СписокСвойств" написать текст вложенного запроса. Но, поскольку мы только осваиваем язык запросов, воспользуемся более комфортным способом: создадим текст вложенного запроса при помощи конструктора, а затем просто скопируем его в нужное нам место модуля. Для этого выполним команду Текст
Конструктор запроса...

В качестве исходных данных вложенного запроса выберем таблицу регистра сведений "ЗначенияСвойствНоменклатуры". Из нее выберем единственное поле – "ЗначенияСвойствМатериалов.НаборСвойств".

Зададим условия выборки. Прежде всего, владелец набора свойств должен быть равен переданному в параметре "Материал" материалу:

ЗначенияСвойствНоменклатуры.НаборСвойств.Владелед = &Материал

Затем укажем, что вид свойства должен быть равен переданному в параметре "ВидСвойства" значению:



ЗначенияСвойствНоменклатуры.ВидСвойства = &ВидСвойства [281]

И в заключение отметим, что значение свойства также будет задаваться параметром "Значение":

ЗначенияСвойствНоменклатуры.Значение = &Значение



Вложенный запрос готов. Теперь нажмем кнопку "Запрос", расположенную в нижней части окна конструктора запроса, выделим и скопируем текст запроса в буфер обмена Windows. Закроем окно с текстом запроса и нажмем "Отмена" в конструкторе запроса. Теперь вставим текст из буфера обмена вместо параметра в созданный нами ранее запрос:

Процедура ОстаткиМатериаловПоСвойствам(ТабДок) Экспорт

   //{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ(ОстаткиМатериаловПоСвойствам)

   // Данный фрагмент построен конструктором.

   // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

   Макет = ОтчетОбъект.ПолучитьМакет("ОстаткиМатериаловПоСвойствам");

   Запрос = Новый Запрос;

   Запрос.Текст =

   "ВЫБРАТЬ

   |    ОстаткиМатериаловОстаткиИОбороты.Материал,

   |    ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.Материал),

   |    ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,

   |    ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.НаборСвойств),

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход КАК Приход,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход КАК Расход,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток

   |ИЗ

   |    РегистрНакопления.ОстаткиМатериалов.ОстаткиИОбороты(,,,,

   |        НаборСвойств В



   |            (ВЫБРАТЬ

   |                ЗначенияСвойствНоменклатуры.НаборСвойств [282]

   |            ИЗ

   |                РегистрСведений.ЗначенияСвойствНоменклатуры КАК ЗначенияСвойствНоменклатуры

   |            ГДЕ

   |                ЗначенияСвойствНоменклатуры.НаборСвойств.Владелец = &Материал

   |                И ЗначенияСвойствНоменклатуры.ВидСвойства = &ВидСвойства

   |                И ЗначенияСвойствНоменклатуры.Значение = &Значение)) КАК ОстаткиМатериаловОстаткиИОбороты";

   Результат = Запрос.Выполнить();

...

Маленькая доработка, которую нам останется сделать, будет заключаться в том, чтобы предусмотреть динамическое формирование текста запроса в зависимости от того, выбрано пользователем значение материала, или нет:

Процедура ОстаткиМатериаловПоСвойствам(ТабДок) Экспорт

   //{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ(ОстаткиМатериаловПоСвойствам)

   // Данный фрагмент построен конструктором.

   // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

   Макет = ОтчетОбъект.ПолучитьМакет("ОстаткиМатериаловПоСвойствам");

   Запрос = Новый Запрос;

   Запрос.Текст =

   "ВЫБРАТЬ

   |    ОстаткиМатериаловОстаткиИОбороты.Материал,

   |    ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.Материал),



   |    ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,

   |    ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.НаборСвойств),

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход КАК Приход,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход КАК Расход,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток

   |ИЗ

   |    РегистрНакопления.ОстаткиМатериалов.ОстаткиИОбороты(,,,,

   |        НаборСвойств В

   |            (ВЫБРАТЬ

   |                ЗначенияСвойствНоменклатуры.НаборСвойств

   |            ИЗ

   |                РегистрСведений. ЗначенияСвойствНоменклатуры КАК ЗначенияСвойствНоменклатуры [283]

   |            ГДЕ

   |";

   Если Не Материал.Пустая() тогда

       Запрос.Текст = Запрос.Текст +

           "ЗначенияСвойствНоменклатуры.НаборСвойств.Владелец = &Материал И

           |";

   КонецЕсли;

   Запрос.Текст = Запрос.Текст +

   "                ЗначенияСвойствНоменклатуры.ВидСвойства = &ВидСвойства

   |                И ЗначенияСвойствНоменклатуры.Значение = &Значение)) КАК ОстаткиМатериаловОстаткиИОбороты";



   Результат = Запрос.Выполнить();

...

После этого добавим в текст модуля установку параметров запроса:

Процедура ОстаткиМатериаловПоСвойствам(ТабДок) Экспорт

   //{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ(ОстаткиМатериаловПоСвойствам)

   // Данный фрагмент построен конструктором.

   // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

   Макет = ОтчетОбъект.ПолучитьМакет("ОстаткиМатериаловПоСвойствам");

   Запрос = Новый Запрос;

   Запрос.Текст =

   "ВЫБРАТЬ

   |    ОстаткиМатериаловОстаткиИОбороты.Материал,

   |    ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.Материал),

   |    ОстаткиМатериаловОстаткиИОбороты.НаборСвойств,

   |    ПРЕДСТАВЛЕНИЕ(ОстаткиМатериаловОстаткиИОбороты.НаборСвойств),

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоНачальныйОстаток КАК НачальныйОстаток,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоПриход КАК Приход,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоРасход КАК Расход,

   |    ОстаткиМатериаловОстаткиИОбороты.КоличествоКонечныйОстаток КАК КонечныйОстаток

   |ИЗ

   |    РегистрНакопления.ОстаткиМатериалов.ОстаткиИОбороты(,,,,

   |        НаборСвойств В

   |            (ВЫБРАТЬ

   |                ЗначенияСвойствНоменклатуры.НаборСвойств

   |            ИЗ

   |                РегистрСведений.ЗначенияСвойствНоменклатуры КАК ЗначенияСвойствНоменклатуры



   |            ГДЕ

   |"; [284]

   Если Не Материал.Пустая() тогда

       Запрос.Текст = Запрос.Текст +

           "ЗначенияСвойствНоменклатуры.НаборСвойств.Владелец = &Материал И

           |";

   КонецЕсли;

   Запрос.Текст = Запрос.Текст +

   "                ЗначенияСвойствНоменклатуры.ВидСвойства = &ВидСвойства

   |                И ЗначенияСвойствНоменклатуры.Значение = &Значение)) КАК ОстаткиМатериаловОстаткиИОбороты";

   Если Не Материал.Пустая() тогда

       Запрос.УстановитьПараметр("Материал", Материал);

   КонецЕсли;

   Запрос.УстановитьПараметр("ВидСвойства", ВидСвойства);

   Запрос.УстановитьПараметр("Значение", Значение);

   Результат = Запрос.Выполнить();

...

Теперь последнее, что нам осталось сделать – это разместить в форме поля для ввода параметров запроса. [285]

Откроем форму отчета и разместим на ней три поля ввода:

"Материал" с типом СправочникСсылка.Номенклатура,

"ВидСвойства" с типом ПланВидовХарактеристикСсылка.СвойстваНоменклатуры,

"Значение" с типом Характеристика.СвойстваНоменклатуры:



Для поля ввода "Материал" установим свойство "Выбор групп и элементов" как "Элементы".

Для поля ввода "Значение" установим связь по типу с реквизитом "ВидСвойства". А для поля ввода "ВидСвойства" создадим обработчик события "ПриИзменении":

Процедура ВидСвойстваПриИзменении(Элемент)



   Значение = ВидСвойства.ТипЗначения.ПривестиЗначение(Значение);

КонецПроцедуры [286]

На этом создание отчета завершено. Запустим 1С:Предприятие в режиме отладки и посмотрим, какие результаты можно получить с помощью нашего отчета.

Сначала посмотрим, какие у нас есть материалы с сечением 2,5 мм2:



Затем посмотрим, какие у нас есть материалы черного цвета:



[287]

И в заключение, чтобы убедиться в правильности работы отчета посмотрим, сколько у нас электрических кабелей черного цвета:



Таким образом, вы убедились в том, что при использовании данной логической схемы мы имеем теперь возможность вести учет материалов в произвольном количестве разрезов свойств и их значений.

Следует заметить, что пример, рассмотренный нами в этой главе, не является законченным решением для данной конфигурации. Мы лишь продемонстрировали возможность ведения такого учета. Для того чтобы наша конфигурация могла полноценно использовать свойства материалов, необходимо внести соответствующие изменения в остальные регистры, документы и некоторые отчеты. [288]


Содержание раздела