Доброго времени суток)) Знаю, что этот вопрос уже многоразово поднимался в интернете, но помогите с передачей выборки на клиент.Многие пишут, что нужно передавать ТЗ, некоторые -о массиве, есть мнение о передачи структуры. как правильно и с наименьшими затратами времени? В моем случае,пытаюсь заполнить ТЧ результатом выборки. Заранее спасибо
---
Вот так правильно:

```1c
    &НаСервере
    Процедура ЗаполнитьТоварыПоОснованию(ДокументОснование)
    Запрос = Новый Запрос();
    Запрос.УстановитьПараметр("Ссылка",ДокументОснование);
    Запрос.Текст = "ВЫБРАТЬ
    | РеализацияТоваровУслугТовары.Ссылка,
    | РеализацияТоваровУслугТовары.НомерСтроки,
    | РеализацияТоваровУслугТовары.ЕдиницаИзмерения,
    | РеализацияТоваровУслугТовары.Количество,
    | РеализацияТоваровУслугТовары.КоличествоМест,
    | РеализацияТоваровУслугТовары.Коэффициент,
    | РеализацияТоваровУслугТовары.Номенклатура,
    | РеализацияТоваровУслугТовары.СерияНоменклатуры,
    | РеализацияТоваровУслугТовары.Склад,
    | РеализацияТоваровУслугТовары.СтавкаНДС,
    | РеализацияТоваровУслугТовары.Сумма,
    | РеализацияТоваровУслугТовары.СуммаНДС,
    | РеализацияТоваровУслугТовары.СчетУчетаБУ,
    | РеализацияТоваровУслугТовары.Цена,
    | РеализацияТоваровУслугТовары.ЗаказПокупателя
    |ИЗ
    | Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
    |ГДЕ
    | РеализацияТоваровУслугТовары.Ссылка = &Ссылка";
    Объект.Товары.Загрузить( Запрос.Выполнить().Выгрузить() );
    КонецПроцедуры
```

обращаю внимание, что:
1. это не функция, а процедура (т.к. возврат значения не предусмотрен)
2. при заполнении тч в цикле необходимо сначало очистить эту тч
3. гораздо быстрее отработает метод загрузить()
4. "ЭтаФорма.Товары.Добавить()" - я думаю, коллекция "товары" принадлежит объекту (это чисто предположение), но даже если не так, "этаФорма." писать не нужно (писать можно просто "Товары.Добавить()")
---
Находила,что на сервере доступна форма. пробовала писать
```1c
    &НаСервере
    Функция ЗаполнитьТоварыПоОснованию(ДокументОснование)
    Запрос = Новый Запрос();
    Запрос.УстановитьПараметр("Ссылка",ДокументОснование);
    Запрос.Текст = "ВЫБРАТЬ
    | РеализацияТоваровУслугТовары.Ссылка,
    | РеализацияТоваровУслугТовары.НомерСтроки,
    | РеализацияТоваровУслугТовары.ЕдиницаИзмерения,
    | РеализацияТоваровУслугТовары.Количество,
    | РеализацияТоваровУслугТовары.КоличествоМест,
    | РеализацияТоваровУслугТовары.Коэффициент,
    | РеализацияТоваровУслугТовары.Номенклатура,
    | РеализацияТоваровУслугТовары.СерияНоменклатуры,
    | РеализацияТоваровУслугТовары.Склад,
    | РеализацияТоваровУслугТовары.СтавкаНДС,
    | РеализацияТоваровУслугТовары.Сумма,
    | РеализацияТоваровУслугТовары.СуммаНДС,
    | РеализацияТоваровУслугТовары.СчетУчетаБУ,
    | РеализацияТоваровУслугТовары.Цена,
    | РеализацияТоваровУслугТовары.ЗаказПокупателя
    |ИЗ
    | Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
    |ГДЕ
    | РеализацияТоваровУслугТовары.Ссылка = &Ссылка";
    Выборка = Запрос.Выполнить().Выбрать();
    Для каждого строкаВыб из Выборка Цикл
    Стр = ЭтаФорма.Товары.Добавить();
    Стр.Номенклатура = строкаВыб.Номенклатура;
    Стр.Количество = строкаВыб.Количество;
    Стр.Цена = строкаВыб.Цена;

    КонецЦикла;
    КонецФункции // ЗаполнитьТоварыПоОснованию()
```

получила ошибку : {Документ.ВозвратТоваровОтПокупателя.Форма.ФормаДокументаУправляемая.Форма(1015)}: Ошибка при установке значения атрибута контекста (Выборка)
 Выборка = Запрос.Выполнить().Выбрать();
по причине:
Нельзя изменять поле, содержащее объект данных формы
---
В чем состоит задача? Если заполнить форму по результату запроса -однозначно выборку в структуру и форму открываете с параметрами этой структуры
---
есть кнопка "заполнить" - по ней запрос - и заполнение ТЧ полученными данными. как получить структуру по такой общирной выборке?
---
А может надо так:
Пока Выборка.Следующий() Цикл

Выборка не является коллекцией!!
---
получаю все ту же ошибку
---
С наименьшими затратами - создаете на форме реквизит с типом таблица значений (имя Товары, колонки Номенклатура, Количество, Цена), далее

Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Стр = Товары.Добавить();
        Стр.Номенклатура = строкаВыб.Номенклатура;
        Стр.Количество = строкаВыб.Количество;
        Стр.Цена = строкаВыб.Цена;

    КонецЦикла;

Если получаете ошибку, у вас где-то на форме уже есть переменная выборка (реквизит скорее всего). Переименуйте.
---
подскажите,а где лучше создать колонки?
---
короче, в реквизитах создаём коллекцию с типом "ТаблицаЗначений" без колонок, элемент формы не создаём.
(т.к. программно удалять можно только программно добавленные реквизиты и элементы)

потом на сервере, после выполнения запроса:

```1c
    //динамически обновляем реквизиты формы для принятия нашей ТЗ

    МассивДобавляемыхРеквизитов = Новый Массив;
    МассивУдаляемыхРеквизитов = Новый Массив;
    ИдКоллекции="Коллекция1";
    ИдТаблицы="Таблица1";
    КоллФормы=РеквизитФормыВЗначение(ИдКоллекции);

    Для каждого ТекКол из КоллФормы.Колонки Цикл
    МассивУдаляемыхРеквизитов.Добавить(ИдКоллекции+"."+ТекКол.Имя);
    КонецЦикла;

    Для каждого ТекКол из ТабРез.Колонки Цикл
    МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(ТекКол.Имя,ТекКол.ТипЗначения,ИдКоллекции));
    КонецЦикла;

    ЭтаФорма.ИзменитьРеквизиты(МассивДобавляемыхРеквизитов,МассивУдаляемыхРеквизитов);
    ЗначениеВРеквизитФормы(ТабРез,ИдКоллекции);

    // теперь динамически обновляем элементы формы

    ЭлТаб=Элементы.Найти(ИдТаблицы);
    Если ЭлТаб<>Неопределено Тогда
    Элементы.Удалить(ЭлТаб);
    КонецЕсли;
    ЭлТаб=Элементы.Добавить(ИдТаблицы,Тип("ТаблицаФормы"));
    ЭлТаб.ПутьКДанным=ИдКоллекции;
    ЭлТаб.Отображение=ОтображениеТаблицы.Список;
    Для каждого ТекКол из ТабРез.Колонки Цикл
    ЭлКол=Элементы.Добавить(ИдТаблицы+ТекКол.Имя,Тип("ПолеФормы"),ЭлТаб);
    ЭлКол.Вид=ВидПоляФормы.ПолеВвода;
    ЭлКол.ПутьКДанным=ИдКоллекции+"."+ТекКол.Имя;
    КонецЦикла;
```
---
Вот так правильно:

```1c
    &НаСервере
    Процедура ЗаполнитьТоварыПоОснованию(ДокументОснование)
    Запрос = Новый Запрос();
    Запрос.УстановитьПараметр("Ссылка",ДокументОснование);
    Запрос.Текст = "ВЫБРАТЬ
    | РеализацияТоваровУслугТовары.Ссылка,
    | РеализацияТоваровУслугТовары.НомерСтроки,
    | РеализацияТоваровУслугТовары.ЕдиницаИзмерения,
    | РеализацияТоваровУслугТовары.Количество,
    | РеализацияТоваровУслугТовары.КоличествоМест,
    | РеализацияТоваровУслугТовары.Коэффициент,
    | РеализацияТоваровУслугТовары.Номенклатура,
    | РеализацияТоваровУслугТовары.СерияНоменклатуры,
    | РеализацияТоваровУслугТовары.Склад,
    | РеализацияТоваровУслугТовары.СтавкаНДС,
    | РеализацияТоваровУслугТовары.Сумма,
    | РеализацияТоваровУслугТовары.СуммаНДС,
    | РеализацияТоваровУслугТовары.СчетУчетаБУ,
    | РеализацияТоваровУслугТовары.Цена,
    | РеализацияТоваровУслугТовары.ЗаказПокупателя
    |ИЗ
    | Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
    |ГДЕ
    | РеализацияТоваровУслугТовары.Ссылка = &Ссылка";
    Объект.Товары.Загрузить( Запрос.Выполнить().Выгрузить() );
    КонецПроцедуры
```

обращаю внимание, что:
1. это не функция, а процедура (т.к. возврат значения не предусмотрен)
2. при заполнении тч в цикле необходимо сначало очистить эту тч
3. гораздо быстрее отработает метод загрузить()
4. "ЭтаФорма.Товары.Добавить()" - я думаю, коллекция "товары" принадлежит объекту (это чисто предположение), но даже если не так, "этаФорма." писать не нужно (писать можно просто "Товары.Добавить()")
---
doom2good,
Не рассказывайте сказки, или рассказывайте их правильно :)
Марина имеет ввиду передачу данных с клиента на сервер в УФ (хотя и это не четко обозначено).
Существуют несколько способов передачи данных с Клиента (вообще здесь "клиент" - всего лишь Форма, но 1С нравится умничать) на Сервер:
1. Через ВременноеХранилище.
Быстро и надежно, можно передавать от реквизита до всего Объекта.
2. РеквизитФормыВЗначение - можно сохранять и передавать все, вплоть до самого Объекта.
3. Использование в модуле формы комбинированной компиляции НаКлиенте и НаСервере: из процедуры НаКлиенте вызывается процедура НаСервере, а т.к. обе они - в модуле формы, то у в обеих доступна переменная Объект.
Тут же - и обмен через общедоступные переменные (в зависимости от расположения этих процедур и видимости для них общих переменных).
4 Издевательство способ через поиск Объекта (Формы) по его GUID (ключу Формы) и работа с этой формой.
Если у вас вариант 3 - то это не значит, что любая процедура НаСервере, расположенная где угодно, будет работать так.
Вопрос же о передаче "в массиве или в структуре" - укладывается уже в эти варианты передачи.
И зависит непосредственно от скорости обработки самих этих типов данных в 1С (где-то быстрее Массив, где-то удобнее Структура), а не от способа их передачи с клиента на сервер.
---
AlexO,
Не рассказывайте сказки, или рассказывайте их правильно
я так и не понял, что здесь сказка и что неправильно
Марина имеет ввиду передачу данных с клиента на сервер в УФ (хотя и это не четко обозначено).
я так понял, она ничего не имеет в виду, а просто пытается решить задачу корявым способом.

ИМХО: либо задача поставлена неправильно, либо передача с клиента на сервер тут вообще не причем.
---
передача с клиента на сервер мне в данный момент не нужна, нужно с сервера передать на клиент результат запроса
---
sweety-twetty, а зачем он там нужен? чтобы обойти его и заполнить таблицу формы? так её и на сервере можно заполнить.
В упр формах главное правило: на клиенте - работа с пользователем, работа с данными - всегда на сервере.
---
sweety-twetty, (9) принципиально игнорируем?
---
andrewks,
Есть проще вариант. в типовых есть:

```1c
    // Преобразует таблицу значений в массив.
    // Может использоваться для передачи на клиента данных, полученных
    // на сервере в виде таблицы значений в том случае, если таблица
    // значений содержит только такие значения, которые могут
    // быть переданы на клиента
    //
    // Полученный массив содержит структуры, каждая из которых повторяет
    // структуру колонок таблицы значений.
    //
    // Не рекомендуется использовать для преобразования таблиц значений
    // с большим количеством строк.
    //
    // Параметры: ТаблицаЗначений
    // Возвращаемое значение: Массив
    //
    Функция ТаблицаЗначенийВМассив(ТаблицаЗначений) Экспорт

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

    КонецФункции
```

(модуль ОбщегоНазначения)
---
действительно есть такая конструкция, спасибо
---
sweety-twetty,
в моей помощи уже не нуждаетесь? :)
---
,(24) конечно, мне нужна Ваша помощь.В текущий момент просто заполняю ТЧ на сервере. Объект доступен на сервере тоже
---
sweety-twetty,
Объект доступен на сервере
Объект ДОСТУПЕН на сервере только как общая переменная.
Либо как переданный параметр.
---
sweety-twetty,
заполняю ТЧ на сервере. Объект доступен на сервере тоже
Об этом я и писал в (10) и (14). Так и надо делать, это правильно!))
---
так и делаю, спасибо.Считаю что тема исчерпала себя, надеюсь возражений нет
---
sweety-twetty, так зачем всё таки нужна передача таблицы на клиент?
---
doom2good, у меня код длиннее потому, что уже с визуализацией юзеру на форме
---
не игнорирую, простите. Просто хотелось бы разобраться в коде, который будет написан. Не хочу просто копировать бездумно.
---
doom2good,
либо передача с клиента на сервер тут вообще не причем.
в такой непонятной ситуации я тоже пас :)
(13) sweety-twetty,
передача с клиента на сервер мне в данный момент не нужна, нужно с сервера передать на клиент результат запроса
а это не передача данных разве с клиента на сервер, и обратно? (при том, что даже у меня указано - клиентом у 1С в УФ является форма :) )
(15) doom2good,
Кстати, результат запроса ну хоть в лепёшку расшибись
о чем и написано в ( 11) :)
---
doom2good,
3. гораздо быстрее отработает метод загрузить()
не "метод Загрузить работает быстрее", а само применение запроса супротив перебора коллекции работает быстрее.
А загрузить - всего лишь приложение к запросу.
Где-то и обход Коллекции ТЗ обоснован и оптимален.
(17) doom2good,
Есть проще вариант. в типовых есть:
это вариант номер 3 из ( 11).
(19) sweety-twetty,
действительно есть такая конструкция
да уж :)
(20) andrewks,
 у меня код длиннее потому, что уже с визуализацией юзеру на форме
у вас вообще вариант 2 из ( 11) - РеквизитФормыВЗначение.
Все описано в ( 11), а это - уже нюансы реализаций этих вариантов :)
Коллекцией ли, запросом - и то, и другое идет через общую переменную или через РеквизитФормыВЗначение, а то и ПоместитьВоВременноеХранилище или вызов функции ОбщегоМодуля, как в ( 17).
---
Кстати, результат запроса ну хоть в лепёшку расшибись, никак не передашь на клиент:
РезультатЗапроса (QueryResult)
Доступность:
Сервер, толстый клиент, внешнее соединение.
ну или можно передать, но работать это будет тока в толстом клиенте. а это неправильный подход (тогда вообще использование упр форм теряет смысл)