Передача результата запроса в таблицу управляемой формы. Мой алгоритм.

07.12.11

Разработка - Запросы

Всем, кто начинает работать с 8.2 после 8.1, не сразу становится понятным, зачем было настолько усложнять работу программистам.
На сервере мы можем выполнить запрос, на управляемую форму бросить таблицу значений, но вот передать результат запроса прямо в таблицу возможности нет. Я решил слегка упростить данный момент для разработки. Вот что у меня получилось.

Как всегда - стала задача разработки проекта для работы через http. Руководство сказало - есть 8.2, там есть веб-клиент. Вперед и с песней.

До тех пор, пока на формы бросались динамические списки или таблицы привязывались к регистрам - все было вроде понятно и разработка шла хорошо, но на определенном этапе понадобилось делать выборки и забрасывать результат именно в таблицы. И тут оказалось, что сделать это выгрузкой результата в таблицу невозможно. В результате в коде начало появляться множество функций &НаСервере, которые, по сути, были идентичные. Читабельность кода от этого не повысилась.

В результате мною коллегам был предложен следующий алгоритм.

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


&НаСервере
Функция ВыполнитьЗапросВТаблицу(ЗапросТекст, СтруктураПараметров) Экспорт
    З = Новый Запрос(ЗапросТекст);
    Для каждого Параметр из СтруктураПараметров Цикл
        З.УстановитьПараметр(Параметр.Ключ, Параметр.Значение);
    КонецЦикла;
    Результат = З.Выполнить().Выгрузить();
    СтрокаСтруктуры = "";
    МассивКолонок = Новый Массив;
    Для каждого Рез из Результат.Колонки Цикл
        Если НЕ СтрокаСтруктуры = "" Тогда
            СтрокаСтруктуры = СтрокаСтруктуры + ", ";
        КонецЕсли;
        СтрокаСтруктуры = СтрокаСтруктуры + Рез.Имя;
        МассивКолонок.Добавить(Рез.Имя);
    КонецЦикла;
    МассивСтрок = Новый Массив;
    Для каждого Рез из Результат Цикл
        СтруктураСтроки = Новый Структура(СтрокаСтруктуры);
        Для каждого кол из МассивКолонок Цикл
            СтруктураСтроки.Вставить(кол, Рез[кол]);
        КонецЦикла;
        МассивСтрок.Добавить(СтруктураСтроки);
    КонецЦикла;
    Возврат МассивСтрок;
КонецФункции


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


&НаСервере
Функция ПолучитьДанныеЗапроса(ТекстЗапроса, СтруктураПараметров)
    Возврат ОбщегоНазначенияКлиентСервер.ВыполнитьЗапросВТаблицу(ТекстЗапроса, СтруктураПараметров);
КонецФункции


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


&НаКлиенте
Процедура ПоместитьДанныеЗапросаВТаблицу(ТекстЗапроса, СтруктураПараметров, _ТаблицаПолучатель)
    _РезультатЗапроса = ПолучитьДанныеЗапроса(ТекстЗапроса, СтруктураПараметров);
    _ТаблицаПолучатель.Очистить();
    Для каждого Рез из _РезультатЗапроса Цикл
        НоваяСтрока = _ТаблицаПолучатель.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, Рез);
    КонецЦикла;
КонецПроцедуры


Все. Подготовительная часть закончена. После этого для заполнения таблицы значений на управляемой форме результатом запроса нужно в коде вписать вызов последней процедуры следующим образом:


ТекстЗапроса = "ВЫБРАТЬ ... далее текст запроса ... ";
СтруктураПараметров = Новый Структура("Параметр1, Параметр2, Параметр3", ЗначениеПараметра1, ЗначениеПараметра2, ЗначениеПараметра3);
// Будем считать, что на форме есть ТаблицаЗначений с именем НашаТаблица
ПоместитьДанныеЗапросаВТаблицу(ТекстЗапроса, СтруктураПараметров, НашаТаблица);


Важно: Запрос должен быть составлен таким образом, чтобы возвращаемый результат был структурно идентичен нашей таблице значений, то есть типы значений колонок в результате запроса должны совпадать с типами значений колонок нашей таблицы значений и имена колонок в результате запроса должны совпадать с именами колонок таблицы значений.

Вот такой вот алгоритм. Код разжевывать не буду, по-моему там и так все понятно. Мега-гуру просьба не пинать сильно.

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    184667    1029    403    

967

Обновление 1С Запросы Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

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

2 стартмани

06.02.2025    2198    17    XilDen    26    

36

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

В статье приведена удобная возможность отладки исполняемого запроса динамического списка.

03.12.2024    5731    artemusII    11    

23

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    13135    sergey279    18    

66

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    8215    XilDen    36    

90

СКД Механизмы типовых конфигураций Запросы Программист Платформа 1С v8.3 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Россия Бесплатно (free)

Работая с типовыми отчетами в конфигурациях «Зарплата и управление персоналом, редакция 3», «Зарплата и кадры государственного учреждения, редакция 3» и подобных, в схемах компоновки данных можно встретить конструкции запросов, которые обращаются к некоторым виртуальным таблицам.

20.08.2024    3191    PROSTO-1C    0    

23

Запросы Программист Запросы Бесплатно (free)

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

16.08.2024    10797    user1840182    5    

29
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Stepa86 1532 07.12.11 15:36 Сейчас в теме
Я не понял, а что мешает на стороне сервера написать тзНаФорме.Загрузить( Запрос.Выполнить.Выгрузить() ) ?
2. Ivon 676 07.12.11 15:53 Сейчас в теме
(1) Ошибка с текстом "Нельзя изменять поле, содержащее объект данных формы".
3. Stepa86 1532 07.12.11 16:01 Сейчас в теме
(2) а у меня вот это нормально работает:

&НаКлиенте
Процедура ЗаполнитьТЗ(Команда)
	
	ЗаполнитьОстаткиНоменклатуры();
	
КонецПроцедуры

Процедура ЗаполнитьОстаткиНоменклатуры()
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	|	ТоварыНаСкладахОстатки.Номенклатура,
	|	ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток
	|ИЗ
	|	РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки";
	
	тзНаФорме.Загрузить( Запрос.Выполнить().Выгрузить() );
	
КонецПроцедуры
Показать
Прикрепленные файлы:
ВнешняяОбработка1.epf
user1737727; griff19; Новичок1с; lemilk; +4 Ответить
4. Ivon 676 07.12.11 16:10 Сейчас в теме
(3). А у меня стабильно выдает ошибку. Какая у тебя версия платформы? У меня 8.2.14.528.
5. Stepa86 1532 07.12.11 16:13 Сейчас в теме
(4) 8.2.14.537

ты б обновился, а то какие то старые версии 14ой ключики жгут...
6. Ivon 676 07.12.11 18:29 Сейчас в теме
(5). У тебя база файловая или серверная? А то у меня на файловой тоже отрабатывает. А вот на серверной нет.
7. Stepa86 1532 08.12.11 08:07 Сейчас в теме
(6) на серверной смотрел, да и не сталкивался я с такой ошибкой раньше ни разу ни на каких базах
8. Поручик 4674 08.12.11 09:00 Сейчас в теме
Сложно сказать, сам пока не сталкивался. На всякий случай в закладки.
9. andboss 201 08.12.11 09:49 Сейчас в теме
Ну вы даете! Все гораздо проще: создается реквизит формы "ДанныеТЗ", тип(ТаблицаЗначений) которая связана с полем на самой форме, и в серверном вызове
ТЗ = РеквизитФормыВЗначение("ДанныеТЗ") - имеем обычную ТЗ

заполняем как нам нужно
...

и возврат

ЗначениеВРеквизитФормы(ТЗ , "ДанныеТЗ");

ВСЕ!
А мат. часть учите)
avmironov; SIrina9; pm74; Alef; ram3; bayce; Liris; нормальный такой; bol; Spacer; +10 Ответить
10. Ivon 676 08.12.11 11:01 Сейчас в теме
(9). Знаю-знаю про ЗначениеВРеквизитФормы. Только вот не всегда оно срабатывает. У меня вот не захотело отрабатывать и вылетало по ошибке. Почему-то. Потому и пришлось вот так вот извращаться. Вот у Stepa86 тзНаФорме.Загрузить(Запрос.Выполнить.Выгрузить()) работает. У меня опять же выдает ошибку.

Если бы все было так просто, то не было бы так сложно.
12. Trofimov_M 09.12.11 08:47 Сейчас в теме
15. Valerich 1637 11.02.12 06:18 Сейчас в теме
(10) Попробовал, вот что получил:
Делаю внешнюю обработку (может это тоже важно, не знаю). Задача - собрать некий массив информации и вывести его в файлы определенной структуры.

В обработке добавил реквизит "Товары" с типом "ТаблицаЗначений". Из команды, которая на клиенте вызывается сервеерная функция формирования таблиц данных, которые потом буду выводить в файлы. Отображать эти таблицы на экране не обязательно, но с точки зрения понять как это можно сделать, не помешало бы.

Далее собирался вызвать несколько процедур формирования файлов.

Что имею:
Таблица значений запросом получается на "ура" - через Товары = Запрос.выполнить().Выгрузить();, где Товары, очевидно, локальная переменная.
Далее вызываю ЗначениеВРеквизитФормы( товары, "Объект.Товары");
При возврате на клиента Объект.Товары содержит нужное количество строк, но ни одной колонки.
Если далее вызываю серверную функцию, в которой пишу Товары = РеквизитФормыВЗначение("Объект.Товары"), то вижу то же самое - строки есть, а колонок (а значит и данных нужных мне) нет.

Пробовал изначально задать колонки в клиенте, но нет свойства Объект.товары.Колонки... Тупик какой-то однако.

Вывод - либо я дурак, либо одно из двух?
16. Ivon 676 13.02.12 17:19 Сейчас в теме
(15). Мой код выдает в результате массив структур, где элементы массива - строки, а элементы структуры - ячейки определенной колонки.
17. Valerich 1637 14.02.12 11:52 Сейчас в теме
(16) сорри, Вашу идею я понял, вопрос хотел задать (9)
11. necropunk 11 08.12.11 12:14 Сейчас в теме
ДЕйствительно, тожк пока не сталкивался, чтобы в реквизит загрузить не получалось. Но да, на всякий случай, в закладки закину, пожалуй...
13. Арах 14.12.11 08:28 Сейчас в теме
а можно еще проще... да ошибка "Нельзя изменять поле, содержащее объект данных формы". присутствует но решается очень просто.

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
новаяСтрока = ТзФормы.Добавить();
ЗаполнитьЗначенияСвойств(новаяСтрока , Выборка);
КонецЦикла;
Zlaya-Ferio; +1 Ответить
14. slknnk 77 14.12.11 17:29 Сейчас в теме
Чтобы не городить такой огород существуют штатные функции РеквизитФормыВЗначение(<ИмяРеквизита>, <Тип>), ЗначениеВРеквизитФормы(<Значение>, <ИмяРеквизита>).
18. DDos76 206 11.07.13 08:48 Сейчас в теме
Ну хоть посмеялся. Вспомнил как в 7.5, когда еще не было таблицы значений, сохраняли списки в списки...
19. user_2010 990 11.08.15 17:07 Сейчас в теме
Оставьте свое сообщение