Бывают такие моменты, когда необходимо таблицу значений передать с сервера на клиент, увы, Мутабельные значения и т.д.
В тоже время есть возможность перекидывать все это добро через Хранилище, чем собственно разработчики часто пользуются.
Но сегодня я бы хотел вынести на Вашу критику вот такой пример переноса.
Сильно не пинайте.
Все мы сталкивались с ситуацией, когда необходимо с сервера передать данные на клиент. И далеко не всегда это примитивные типы.
Об одном из таких типов я бы сегодня и хотел поговорить.
Речь сегодня о таблицы значений.
Данный тип является мутабельным и при попытке выполнить это действия мы получим ошибку:
{Справочник.НастройкиЗаполненияОбъектов1СДокументооборота.МодульОбъекта(33)}: Ошибка при вызове метода контекста (ПолучитьПрокси)
Прокси = ИнтеграцияС1СДокументооборотВызовСервера.ПолучитьПрокси();
по причине:
Попытка передачи мутабельного значения результата метода ПолучитьПрокси ().
(текст ошибки в каждом случае свой)
Сегодня я выношу на Вашу критику и обозрение один из вариантов решения этой проблемы, а именно преобразование в Массив(может передаваться) из структур и обратно в таблицу.
Функция «ПреобразоватьТаблицуЗначенийВМассив» выполняется на сервере перед передачей данных, а «ПреобразоватьМассивВТаблицуЗначений» уже на клиенте соответственно.
Код этих функций:
// Функция преобразует ТаблицуЗначений в Массив из структур.
//
Функция ПреобразоватьТаблицуЗначенийВМассив(тзДанные) Экспорт
мсДанные = Новый Массив;
// Запишем в массив
Для Каждого СтрокаТЗ Из тзДанные Цикл
стСтрокаТаблицы = Новый Структура;
Для Каждого ИмяКолонки Из тзДанные.Колонки Цикл
стСтрокаТаблицы.Вставить(ИмяКолонки.Имя, СтрокаТЗ[ИмяКолонки.Имя]);
КонецЦикла;
мсДанные.Добавить(стСтрокаТаблицы);
КонецЦикла;
Возврат мсДанные;
КонецФункции // ПреобразоватьТаблицуЗначенийВМассив()
// Функция преобразует Массив из структур в ТаблицуЗначений.
//
Функция ПреобразоватьМассивВТаблицуЗначений(мсДанные) Экспорт
тзДанные = Новый ТаблицаЗначений;
Для Каждого ЭлементМассива Из мсДанные Цикл
// Рисуем колонки для таблицы
Если тзДанные.Колонки.Количество() = 0 Тогда
Для Каждого ЗначениеСтруктуры Из ЭлементМассива Цикл
тзДанные.Колонки.Добавить(ЗначениеСтруктуры.Ключ);
КонецЦикла;
КонецЕсли;
// Добавляем данные в таблицу
НоваяСтрока = тзДанные.Добавить();
Для Каждого ЗначениеСтруктуры Из ЭлементМассива Цикл
НоваяСтрока[ЗначениеСтруктуры.Ключ] = ЗначениеСтруктуры.Значение;
КонецЦикла;
КонецЦикла;
Возврат тзДанные;
КонецФункции // ПреобразоватьМассивВТаблицуЗначений()
ОбщегоНазначения.ТаблицаЗначенийВМассив(Таблица)
не? )
1. Автор посмотри (0) — сравни. У тебя не оптимально.
2. Функция ПреобразоватьМассивВТаблицуЗначений(мсДанные) — не будет работать в тонком клиенте
&НаСервереБезКонтекста
&НаКлиентеБезКонтекста
(1) AlX0id, опять велосипед изобретаю))
А в обратку кстати какой метод? «МассивВТаблицуЗначений» не нашел…
Попробовал можно воспользоваться, но при большой таблице чертовски медленно
А почему не ЗначениеВСтрокуВнутр ?
(6) gaglo, никто не говорил, что данный вариант — это универсальные методы, которые должны быть у каждого и пользоваться надо только ими)
Это всего лишь один из возможных подходов к решению задач. Кстати как упоминалось в (5) далеко не самый оптимальный. Однако есть вероятность, что кто-то сочтет его полезным для себя.
(4)
А обратно лично я не нашел ) Пришлось писать )
(8) AlX0id, тогда половина кода не «велосипед» 🙂
(9) barankin, таблица значений с сервера не передается, а вот список значений передаваться должен.
Хотя недавно у меня тоже не передавался, что странно, так как точно помню, что можно было… так же пришлось делать через массив.
(4) Мутабельные значения — немножко другая тема..
если у вас модуль серверный и не стоит галка вызов сервера и наоборот… то конечно будет эта тема..
А так для тонкого клиента есть функционал: ДанныеФормыВЗначение и ЗначениеВДанныеФормы
Об этом даже рассказывает Андрей Габец в тестовом доступе УЦ3 , отрывок из курса Оперативных задач
Передача массива структур с клиента на сервер в общем-то очевидна и давно известна.
А вот подобный код в статье публиковать не стОит.
Вложенные циклы по колонкам внутри перебора таблицы выглядят несколько неразумно.
На самом деле, если конечно подумать, и посмотреть как ТЗ отображается в XML, то и решение придет как бы само 🙂
(6) gaglo,
ЗначениеИзСтрокиВнутр() на тонком клиенте не работает.
Нормально работает, сам пользуюсь, правда преобразую ТЗ в структуру массивов. Массив тоже можно пинать между клиентом и сервером.
Вот если бы кто написал функции по переводу тз в массив структур с двумя требованиями:
1) обход данного массива так же как и ТЗ (есть)
2) преобразование данного массива в ТЗ с сохранением типов колонок
А то в крайних случаях приходится проходиться по колонке, смотреть все типы и строить ОписаниеТипов для конструктора ТЗ по собранным данным… Медленно и не всегда верно. Особенно если таблица пустая. Колонки потеряли, типы потеряли. Ну это так, мысли о высоком.
(7) — не ответ, а вот (14) — ответ. Спасибо.
(13) Верно, хотя сериализация тоже не всякая прокатывает, особенно если в таблице разности и хитрости понапиханы. Да и городить огород иногда нерационально.
(18) Понапихай всего разного и посмотри как сериализуется
Грубо говоря, сериализуется ВСЕГДА одинаково, как прописано в xsd-схеме ядра платформы.
скользкая тема, если в таблице есть значения Null — в этом случае в тонком клиенте и WEB-клиенте код отрабатывает по разному.
(19) Некоторые вещи просто НЕ сериализуются. Иногда — противореча СП, например, «РазмерКартинки». А схему самой 1С я видел, так вот, теоретически должное иногда практически не выходит. Ну, xsd 1С — вообще отдельная история, здесь это оффтоп )))
А в чем соль, так сказать?
Функция ПреобразоватьМассивВТаблицуЗначений(мсДанные)
Всеравно передает ТЗ с сервера и всеравно вызывает ошибку…
Или я деревянный или чушь какая-то
(22) realEvgenius
Вариант 1.
1. С помощью ПреобразоватьТаблицуЗначенийВМассив() делаем массив, который гоняем между клиентом и сервером.
2. Обрабатываем его (это уже сами выбираете как)
3. Передаете на клиент обратно МАССИВ, который затем преобразуете в Таблицу значений с помощью ПреобразоватьМассивВТаблицуЗначений().
Вариант 1,5.
1. Делаем массив с помощью ПреобразоватьТаблицуЗначенийВМассив()
2. Получаем на сервере, преобразуем в Таблицу значений с помощью ПреобразоватьМассивВТаблицуЗначений()
3. Работаем с Таблицей значений
З.Ы. Мне надо было для второго варианта.
(23) Вопрос Как в процедуре, которая идет после &НаКлиенте Использовать Таб значений как её туда передать? Ответ — никак. ПреобразоватьМассивВТаблицуЗначений() Это на сервере запускать? Оно возвращает Таб значений (Возврат тзДанные), которую нельзя передать в мою процедуру, которая выполняется на клиенте. Ибо система ругается.
Смысл этих обработок? Таб значений передать на клиента нельзя. Преобразовываем её в массив, передаем массив на клиента, предаем массив функции ПреобразоватьМассивВТаблицуЗначений(), которая по идее должна дать таб знач и получаем туже ошибку. Наверное, я — деревянный, что-то не понимаю
(24) realEvgenius
Обе функции кладутся в общий модуль, где проставлены галочки «Клиент» и » Сервер», назовем его «ОбщегоНазначенияКлиентСервер»
Показать
Я не знаю что тут еще можно добавить
Аааа…. В общий модуль… А я ж в томже модуле мучаю…
попробую
(25) как у вас получилось?
то сразу ошибка.
Как таблица значений может быть на клиенте? Нечего передавать по сути, так как сразу возникает ошибка… Я так понял таблица значений не может существовать на клиенте
Тип не определен (ТаблицаЗначений)
тзДанные = Новый <<?>>ТаблицаЗначений; (Проверка: Тонкий клиент)
Вот ведь парадокс…. Тип таблица значений на клиенте не определен, а реквизит формы типа «таблица значений» возможен и работает. Сдается мне это вопрос религиозного характера!
(28) logos, посмотрите отладчиком, какой тип у этого реквизита. Удивитесь.
Они ограничили передачи ТаблицыЗначений, потому что хз что туда можно напихать. Было бы лучше не ограничивать таблицу, а ограничивать типы передаваемых данных
Коллеги, я сейчас решаю озвученную в теме задачу.
Пишу обработку заполнения табличной части (с вызовом клиентского метода).
Юзер указывает ссылку на документ, по которой я на сервере собираю ТЗ, а потом эту ТЗ возвращаю на клиент, чтобы заполнить ТЧ своего документа.
Понимаю, что можно тупо упаковать строки в структуры,, а их в массив, и этот массив вернуть на клиент.
но тут в (12) сказано
это применимо в моей задаче или проще массив из структур швырнуть на клиент?
Спасибо. Помогло.
Можно передавать массив, элементы которого — массивы выгруженных колонок таблицы.
Правда таблица значений доступна только на толстом клиенте.
Показать
(31) ДанныеФормыВЗначение и ЗначениеВДанныеФормы нельзя открывать от контекста формы. Бесконтекстные вызовы не отработают.
(6) Пыталась сравнивать этой функций две тз, одна была выгружена из результата запроса, другая сформирована в цикле, и они НЕ были одинаковыми. Сравнила полученный текст, разница, как я поняла в индексах. А вот сравнив массивы, полученные из этих тз, я получила верный результат сравнения.
Гораздо эффективнее будет работать так (нет двойных циклов и меньше объем данных при сериализации):
Показать