gifts2017

Использование внешних наборов данных в системе компоновки данных.

Опубликовал Андрей Скляров (coder1cv8) в раздел Программирование - Практика программирования

В этой статье я хотел бы рассмотреть несколько неявных моментов, с которыми разработчик сталкивается при использовании набора данных типа «объект».

Напомню, что наборы данных в СКД бывают 3-х видов:

- Запрос;

- Объект;

- Объединение.

Так что же такое «Объект»? Объект – это «внешний» набор данных, таблица, которая может быть загружена данными результата запроса, другой таблицы значений, набора записей и т.д. Главная сложность, при использовании набора данных «объект», заключается в том, что перед формированием собственно отчета, разработчику необходимо заполнить этот объект, а следовательно, и вывод отчета, и использование возможностей «расшифровки» СКД приходиться реализовывать программным путем.

Итак, представим следующую, гипотетическую задачу: нам необходимо сравнить остатки товара по складам в 2-х базах 1С, текущей и внешней (данные из которой получаем с помощью СОМ-соединения). Предполагается, что элементы справочника «Склады» в этих двух базах синхронизированы по коду.

Создаем новый отчет, открываем схему компоновки данных и на закладке «Наборы данных», добавляем два набора: Запрос и Объект. Запрос – это получение остатков в текущей базе, а Объект – это таблица в которую будут помещены данные из внешней базы.

Рис 1

Так как задача гипотетическая, то упростим текст запроса до получения общего остатка по складу без разделения на номенклатуру, ед. измерения и т.д. Таким образом, текст запроса следующий:

ВЫБРАТЬ

            ТоварыНаСкладахОстатки.Склад КАК Склад,

            СУММА(ТоварыНаСкладахОстатки.КоличествоОстаток) КАК ОстатокЭтаБаза

ИЗ

            РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки

СГРУППИРОВАТЬ ПО

            ТоварыНаСкладахОстатки.Склад

 

 

 

Для набора данных «Объект» добавляем имя «ВнешниеДанные» и поля: «КодСклада» (по этому полю будет выполняться связь наборов данных) и «ОстатокВнешняяБаза».

 

Рис 2

Далее, на закладке «Связи наборов данных», описываем связь наших наборов данных. В целом, связи наборов данных, аналогичны связям таблиц в конструкторе запросов, за исключением того, что в СКД соединение может быть только ЛЕВЫМ.

Заполняем поля следующим образом:

1. Источник связи: Запрос;

2. Приемник связи: Объект;

3. Выражение источник: Склад.Код;

4. Выражение приемник: КодСклада.

Рис 3

 

Теперь, на вкладке «Настройки», добавим вывод детальных записей. Для этого щелкните правой кнопкой на «Отчет», выберите «Новая группировка» и, не выбирая никакого поля, нажмите «ОК».

Здесь же добавим в «Выбранные поля»: Склад, ОстатокЭтаБаза и ОстатокВнешняяБаза.

Рис 4

На этом конструирование отчета завершено, пора переходить непосредственно к программированию!

Сгенерируем основную форму отчета и на верхней командной панели формы, добавим кнопку «Загрузить внешние данные».

Рис 5

Добавим в наш отчет табличную часть «ВнешниеДанные», с реквизитами «КодСклада» и «ОстатокВнешняяБаза», в которую будут выгружаться данные из внешней базы перед передачей процессору компоновки данных.

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

 

 

Рис 6

Далее реализуем загрузку данных из внешней базы с помощью СОМ-соединения, подробно описывать эту процедуру я не буду, так как это не относиться к теме данной статьи, а просто приведу её код:

 

Процедура ДействияФормыЗагрузитьВнешниеДанные(Кнопка)

            ВнешниеДанные.Очистить();

            Попытка

                        КОМ=Новый COMОбъект("V81.COMConnector");

                        База=КОМ.Connect("Srvr=server;Ref=Base;Usr=user;Pwd=password");

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

                        |ВЫБРАТЬ

                        |           Склад.Код КАК КодСклада,

                        |           СУММА(КоличествоОстаток) КАК ОстатокВнешняяБаза

                        |ИЗ

                        |           РегистрНакопления.ТоварыНаСкладах.Остатки

                        |СГРУППИРОВАТЬ ПО

                        |           Склад";

                        Запрос=База.NewObject("Запрос");

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

                        Выборка=Запрос.Выполнить().Выбрать();

                        Пока Выборка.Следующий() Цикл

                                   НовСтр=ВнешниеДанные.Добавить();

                                   ЗаполнитьЗначенияСвойств(НовСтр,Выборка);

                        КонецЦикла;

            Исключение

                        Сообщить(ОписаниеОшибки(),СтатусСообщения.Внимание);

            КонецПопытки;

            База=Неопределено;

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

 

Затем переопределим нажатие кнопки «Сформировать»:

 

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

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

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

 

Программный вывод отчета в системе компоновки данных реализуем с помощью типового алгоритма, который детально рассмотрен в соответствующей литературе и на дисках ИТС. Единственное на что бы я хотел обратить внимание – это расширение формы отчета ДанныеРасшифровки. При компоновке макета, необходимо передать эту переменную в метод «Выполнить» компоновщика макета, иначе расшифровка (это то, что происходит по двойному клику на ячейке табличного документа) доступна не будет. Так же передаем ДанныеРасшифровки процессору компоновки при инициализации.

 

Процедура ВывестиОтчет()

            ЭлементыФормы.Результат.Очистить();

            Если ВнешниеДанные.Количество()=0 Тогда

                        Предупреждение("Внешние данные не загружены. Нажмите кнопку <Загрузить внешние данные>");

                        Возврат;

            КонецЕсли;

            ВнешниеНаборыДанных=Новый Структура;

            ВнешниеНаборыДанных.Вставить("ВнешниеДанные",ВнешниеДанные);

            КомпоновщикМакета=Новый КомпоновщикМакетаКомпоновкиДанных;

            Настройки=КомпоновщикНастроек.ПолучитьНастройки();

            МакетКомпоновки=КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных,Настройки,ДанныеРасшифровки);

           

            ПроцессорКомпоновки=Новый ПроцессорКомпоновкиДанных;

            ПроцессорКомпоновки.Инициализировать(МакетКомпоновки,ВнешниеНаборыДанных,ДанныеРасшифровки);

           

            ДокументРезультат=ЭлементыФормы.Результат;

            ПроцессорВывода=Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;

            ПроцессорВывода.УстановитьДокумент(ДокументРезультат);

           

            ПроцессорВывода.НачатьВывод();

           

            Пока Истина Цикл

                        ЭлементРезультата=ПроцессорКомпоновки.Следующий();

                        Если ЭлементРезультата=Неопределено Тогда

                                   Прервать;

                        Иначе

                                   ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);

                        КонецЕсли;

            КонецЦикла;

           

            ПроцессорВывода.ЗакончитьВывод();

           

            ДокументРезультат.ОтображатьСетку=Ложь;

            ДокументРезультат.ОтображатьЗаголовки=Ложь;

            ДокументРезультат.Показать();      

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

 

Проверим работу отчета в режиме «Предприятие».

 

Рис 7

Отчет работает. Но есть одно НО. При попытке отфильтровать, упорядочить, оформить и т.д. возникает ошибка исполнения: «Не найден внешний набор данных ВнешниеДанные». Дело в том, что фильтрация, упорядочивание и пр. по сути, являются установкой настроек отчета и переформированием результата. А так как используется внешний набор данных, необходимо передавать его при инициализации процессора компоновки. С учетом этого, определим для поля табличного документа «Результат», процедуру «ОбработкаРасшифровки»:

 

 

Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)


            Перем ВыполненноеДействие;


            СтандартнаяОбработка=Ложь;


            ОбработкаРасшифровки=Новый ОбработкаРасшифровкиКомпоновкиДанных(ДанныеРасшифровки,Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));


        НастройкиРасшифровки=ОбработкаРасшифровки.Выполнить(Расшифровка,ВыполненноеДействие);


            Если НастройкиРасшифровки<>Неопределено Тогда


КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиРасшифровки);


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


            КонецЕсли;


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

 

 

Здесь, «ВыполненноеДействие» - это переменная, куда помещается выбранное пользователем действие. «НастройкиРасшифровки» - это настройки, полученные вследствие выбора пользователя. То есть, если пользователь выбрал действие, влияющее на настройки компоновки данных, то мы устанавливаем новые настройки и формируем отчет заново.

Вот теперь наш гипотетический отчет полностью готов к работе!

 

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Андрей Скляров (coder1cv8) 10.12.08 14:28
Эта... А как теперь код выделить в тексте?!... Какими тегами?...
2. Василий Демидов (Душелов) 10.12.08 14:35
Код
//Как и раньше - code в квадратных скобках
Показать полностью
3. Василий Демидов (Душелов) 10.12.08 14:36
Хорошая статья, для меня даже своевременная ;)
4. Андрей Скляров (coder1cv8) 10.12.08 14:45
(2) Если бы как раньше, я бы не спрашивал! )
Вот смотри, первый запрос в теги заключил - толку ноль! (
5. Василий Демидов (Душелов) 10.12.08 15:05
(4) Предлагаю по этому поводу наябедничать Доржи ;)
6. Роман Петров (PeRom) 11.12.08 16:28
Отлично!
А про программное управление СКД (ПроцессорКомпановки, ОбработкаРасшифровки и тд) где можно поподробней почитать?
7. Андрей Скляров (coder1cv8) 11.12.08 16:39
(6) "1С:Предприятие от 8.0 к 8.1", у Хрусталевой тоже говорят про СКД хорошо написано (правда я всё бумажного варианта не дождусь), ну и диски ИТС.
8. Роман Петров (PeRom) 11.12.08 22:43
7 Про СКД то говорят, а вот про программное управление мало чего есть :(
Но и меня сейчас на клюшках подзагрузили, 8-кой пока в фоновом режиме занимаюсь.
9. Андрей Скляров (coder1cv8) 12.12.08 08:48
(8) Тут главное понять механизм, а уж нюансы реализации можно и в СП уточнить! )
10. rasswet (rasswet) 18.12.08 10:13
по больше бы таких подробных статей. мегареспект!
11. rasswet (rasswet) 18.12.08 10:14
побольше бы таких подробных статей. мегареспект!
12. Mikhail Kim (KMA82) 18.12.08 15:12
(8)как уже было сказано: "...у Хрусталёвой хорошо написано..."
книгу (эл. вариант) не очень хорошего качества, но читаемо, можно взять отсюда http://ifolder.ru/9620253
13. Mikhail Kim (KMA82) 18.12.08 15:24
(7) тоже жду, можешь пока посмотреть эл.вариант(качество не очень, но читать можно). ссылка выше
14. Андрей Скляров (coder1cv8) 18.12.08 15:59
(13) Спасибо! Электронный вариант у меня давно есть... ;)
Не люблю просто с монитора читать...
15. Андрей Скляров (coder1cv8) 18.12.08 16:02
+(14) А вообще, на курсы по СКД записался, в общеобразовательных целях так сказать... )
16. Андрей Скляров (coder1cv8) 18.12.08 16:05
(11) Лучше бы мегаплюс поставил! :D А то на первую страницу так и не вылезет статья... )
17. rasswet (rasswet) 18.12.08 18:21
(16) фаерфокс притупливает, ещё и но-скрипт :)
З.ы. Мегаплюс ставлю!
18. Alexandr (maloi_a) 19.12.08 13:34
Поставил +, себя не вижу.
У меня колонка "Остаток внешние данные" выводится как целое число, хотя в табличной части "ВнешниеДанные" "ОстатокВнешняяБаза" описал как Число(15,3).
19. Alexandr (maloi_a) 19.12.08 13:34
Вот появился после комментария.
20. Андрей Скляров (coder1cv8) 19.12.08 13:59
(18) Нужно в наборе данных указывать для поля тип значения.
(19) Это с кэшем тут всё эксперементируют! )
21. Alexandr (maloi_a) 20.12.08 07:37
(20) Это противоречит "мягкой типизации" 1С. Вообще-то я могу не знать типа, который получаю.
22. Андрей Скляров (coder1cv8) 20.12.08 09:03
(21) Почему же противоречит?... Если ты указываешь тип в наборе данных, то значения в строках приводятся именно к этому типу, если нет - то тип любой. Это как с ТаблицейЗначений, можно добавлять колонки уже типизированными, а можно и нет... Я просто хочу сказать, что тип в колонке таблицы из которой загружаем набор данных, роли не играет. Важен именно тип в наборе.
23. Лавр (sea-man) 24.12.08 11:45
Еще бы во внешние наборы источники данных ADO добавили - цены бы им не было))
А так - приходится извращаться через подсовывание виртуальных таблиц...
24. Андрей Скляров (coder1cv8) 25.12.08 09:37
(23) Я думаю, дальнейшее развитие СКД пойдет как раз по такому пути. Недаром ведь кроме наборов, есть "Источники данных", где пока редактируется только имя.
25. adrian96 (adrian) 29.04.09 15:29
(0) Делаю НаборДанных - Объект , передаю ТаблицуЗначений

При вызеве процедуры Процедура ВывестиОтчет()
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки,ВнешниеНаборыДанных,ДанныеРасшифровки) - в этом месте ошибка «Не найден внешний набор данных ВнешниеДанные» в чем дело?
26. Андрей Скляров (coder1cv8) 29.04.09 19:26
(25) Так написано же по-русски все! ) «Не найден внешний набор данных ВнешниеДанные» Что здесь еще можно добавить?... Нет его в структуре ВнешниеНаборыДанных.

27. Bolik (Bolik) 30.06.09 10:26
Можно ли во внешних наборах, использовать характеристики также, как они используются в наборе данных - запрос?
28. Сергей Лунев (luns) 30.06.09 10:30
(27) Да. Если тип значения поля задан, то оно также будет связываться с описанием характеристик.
29. Bolik (Bolik) 30.06.09 10:32
(28) А как же тогда описать характеристики в этом случае?
30. Сергей Лунев (luns) 30.06.09 10:35
Точно так же.
Принцип действия характеристик заключается в следующем:
Мы как бэ говорим компоновке: вот поле с типом значения "СправочникСсылка.Номенклатура" и вот описания его характеристик. После этого компоновка для все полей с таким типом даст возможность выбора характеристик. Т.е. характеристики привязываются не к конкретному полю/полям из наборов данных а к типу значения.
31. Bolik (Bolik) 30.06.09 10:44
(30) Проблема в том, что в запросе есть ключевое слово "ХАРАКТЕРИСТИКИ" и харакетристики описываются в наборе данных-запрос, а в самой компоновке они не описываются. Если описать 2 источника и в наборе данных запрос описать только характеристики - они подхватятся и для набора-объект?
32. Сергей Лунев (luns) 30.06.09 10:54
(31) Нет. Опишите типы полей для набора данных объект и опишите характеристики ТОЧНО ТАК ЖЕ как и для набора данных запрос.
33. Bolik (Bolik) 30.06.09 11:05
(32) А можно точно ткнуть - где это сделать? )) В конструкторе СКД не нашел, где можно для набора-объект описать характеристики
34. Сергей Лунев (luns) 30.06.09 11:38
(33) Это я туплю )))) нельзя блин..
35. Bolik (Bolik) 30.06.09 11:40
(34) А может можно как-то в наборе-запрос использовать таблицу значений, например через временные таблицы или еще как хитро? )))
36. Сергей Лунев (luns) 30.06.09 11:43
вообще я думаю что если сделать набор-заглушку с описанием характеристик то возможно в наборе объект подхватиться..
37. poZZitive erm (poZZitive) 14.10.09 07:51
Ошибка. Нужно задать схему компановки данных. иначе не находит куда вставлять внешнийнаборданных и вываливается с ошибкой.

СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
	Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
38. Олег (666Oleg666) 03.11.09 15:28
Большое спасибо
То что надо а я думал все кодом делать (Сверку 1С и Биллинга)
39. it-kostya (it-kostya) 10.08.11 16:05
Прикольно то прикольно. Только возвращаемое значение из внешней базы COM-объект. Неудобно блин. Особенно когда с документами нужно работать
40. Сергей Т (sergei_tekh) 21.09.11 13:51
А в строке:
МакетКомпоновки=КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных,Настройки,ДанныеРасшифровки);

что нужно передавать в переменную ДанныеРасшифровки?
41. Sergey Ivanov (sergb1979) 15.02.12 12:57
в 8.2.14 добавили метаданные "внешние данные"
42. Евгений Т (Eugenio) 21.01.14 19:25
=======
С учетом этого, определим для поля табличного документа «Результат», процедуру «ОбработкаРасшифровки»:
=======
А не подскажете, как это сделать в неуправляемой форме? На какие кнопки нажимать? :)
43. Михаил Петрович (Mishka_78) 24.02.15 11:47
день добрый! coder1cv8 перезалейте пожалуйста скрины в статью. Похоже фотохостинг www.picamatic.com "закруглился". Спасибо.
Alien_job; Noxie41; Platinum78; Rokov; elga666; ReN; redtram; u_n_k_n_o_w_n; Мах; martian; +10 Ответить
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа