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

07.12.11

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

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

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

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

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

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


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


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


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


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


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


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


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


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

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

См. также

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

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

12000 руб.

02.09.2020    166753    923    403    

899

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

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

18.10.2024    11049    sergey279    18    

65

Запросы Программист Платформа 1С v8.3 Запросы Конфигурации 1cv8 Бесплатно (free)

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

11.10.2024    6083    XilDen    36    

82

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

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

16.08.2024    8774    user1840182    5    

28

Математика и алгоритмы Запросы Программист Платформа 1С v8.3 Запросы Бесплатно (free)

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    2657    ivanov660    9    

22

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

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

15.05.2024    9891    implecs_team    6    

48

Запросы Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

11.04.2024    3567    andrey_sag    10    

37
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
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. Поручик 4659 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 9 08.12.11 12:14 Сейчас в теме
ДЕйствительно, тожк пока не сталкивался, чтобы в реквизит загрузить не получалось. Но да, на всякий случай, в закладки закину, пожалуй...
13. Арах 14.12.11 08:28 Сейчас в теме
а можно еще проще... да ошибка "Нельзя изменять поле, содержащее объект данных формы". присутствует но решается очень просто.

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