gifts2017

Как передать на сервер мутабельное значение

Опубликовал Evil Grym (Evilgrym) в раздел Программирование - Практика программирования

Перевод выполнения кода с клиента на сервер. Метод для ленивых и торопящихся.

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

СПРАВКА:

Мутабельный тип (англ. Mutable type) - сложный тип данных в объектно-ориентированном программировании, значения которого (как правило - объекты) после своего создания допускают изменение своих свойств.
1С: Подробнее о типах данных 1С:Предприятие: http://v8.1c.ru/overview/CommonCommTypes.htm
1С: XML-сериализация, механизм (XML Serialization, Mechanism): http://v8.1c.ru/overview/Term_000000318.htm
tanka495: Клиент- серверные вызовы: http://infostart.ru/public/86838/

 

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

Решаем эту проблему через помещение  структуры во временное хранилище.

 

Конкретный пример:

Бухгалтерия 2.0, общий модуль учета НДС, нужно добиться того, чтобы книги покупок и продаж учитывали самописные документы, при этом сохранилась возможность относительно нетрудоемкого обновления конфигурации.

Есть функция,  в которую передается СтруктураПараметров.  Попытка передачи на сервер структуры приводит к ошибке передачи мутабельного значения.

Функция ПолучитьЗаписиКнигиПродаж(СписокСчетовФактур, СтруктураПараметров) Экспорт
    
    // Переводим выполнение функции на сервер   // GtG  //  22.04.2015 12:00:46 
    АдресМЗначения=ПоместитьВоВременноеХранилище(Неопределено);
    ПоместитьВоВременноеХранилище(СтруктураПараметров,АдресМЗначения);

    Возврат АС_УЧЕТ_НДС.ПолучитьЗаписиКнигиПродаж_серверная(СписокСчетовФактур,АдресМЗначения);
    
    //---------------<Отключено совсем>---------------------------// GtG // 22.04.2015 14:18:05
    ..... тут идет километр родного 1с-овского кода
 КонецФункции

    
Далее, в чисто серверный модуль (в конкретном случае АС_УЧЕТ_НДС)  копируем исходную процедуру (модифицируем функционал при желании).

 

Функция ПолучитьЗаписиКнигиПокупок_Серверная(СписокСчетовФактур, АдресМутабельногоЗначенияВоВременномХранилище) Экспорт

    СтруктураПараметров = ПолучитьИзВременногоХранилища(АдресМутабельногоЗначенияВоВременномХранилище);
   ...далее идет текст исходной функции
КонецФункции

Если в ходе работы процедуры/функции на сервере передаваемое мутабельное значение должно быть изменено - помещаем его во временное хранилище по тому же адресу АдресМутабельногоЗначенияВоВременномХранилище и после выполнения функции/процедуры в исходном модуле считываем из временного хранилища.

См. также

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

Комментарии

1. Гость 14.08.15 17:28
Структура эта изменяется функцией, в которую передается как параметр, плюс ко всему, 1С считает этот тип мутабельным по определению.


Синтакс-помощник
Структура (Structure)
Доступность:

Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение.
Возможен обмен с сервером.
Yashazz; dj_serega; siddy; proGAll; serg_gres; baton_pk; +6 Ответить
2. Андрей Карпов (karpik666) 16.08.15 13:41
1. Начнем с того, что мутабельный тип ни при каких условиях не должны передаваться на сервер, на это и мутабельный тип, что если он все таки будет передаваться, то он может быть в это время изменен. И данные будут не актуальными. Такие ошибки обычно делают новички, но это является как раз ошибкой.
2. "Много букф" в статье, а по сути, чтобы передать с клиента на сервер большой объем данных используйте функцию "ПоместитьВоВременноеХранилище". И в коде не совсем понятно зачем использовано 2 раза "поместитьВоВременноеХранилище", когда можно было обойтись одним.
3. Evil Grym (Evilgrym) 17.08.15 13:21
(2) karpik666, ну , корабель теориии обычно разбивается вдрызг о скалы практики.
4. Сергей Цепелев (cepeleva-ludmila) 18.08.15 09:50
а можно передать значение через строку
Функция ПолучитьЗаписиКнигиПродаж(СписокСчетовФактур, СтруктураПараметров) Экспорт
    
    // Переводим выполнение функции на сервер   // GtG  //  22.04.2015 12:00:46 

   СтрокаМутабельныхПараметров = ЗначениеВстрокуВнутр(СтруктураПараметров);

    Возврат АС_УЧЕТ_НДС.ПолучитьЗаписиКнигиПродаж_серверная(СтрокаМутабельныхПараметров );
    
    //---------------<Отключено совсем>---------------------------// GtG // 22.04.2015 14:18:05
    ..... тут идет километр родного 1с-овского кода
 КонецФункции
    
...Показать Скрыть

Далее, в чисто серверный модуль (в конкретном случае АС_УЧЕТ_НДС) копируем исходную процедуру (модифицируем функционал при желании).



Функция ПолучитьЗаписиКнигиПокупок_Серверная(СтрокаМутабельныхПараметров ) Экспорт

СтруктураПараметров = ЗначениеИзСтрокиВнутр(СтрокаМутабельныхПараметров );
...далее идет текст исходной функции
КонецФункции
5. Сергей Цепелев (cepeleva-ludmila) 18.08.15 09:50
Я конечно понимаю что это не правильно с точки зрения 1с, но это выход
6. Evil Grym (Evilgrym) 18.08.15 19:13
(5) cepeleva-ludmila, но далее идет вход через выход в виде результата запроса в 230тысячстрок, который нет желания обрабатывать самому и нужно подпихнуть в стандартный 1свский код. При этом нужно обойтись минимумом дописок. Максимум в пару тройку строк.
7. Ярослав Радкевич (WKBAPKA) 19.08.15 15:44
можно еще фиксированной структурой перенести, не?
8. Сергей Цепелев (cepeleva-ludmila) 01.09.15 10:25
(6) Evilgrym, и результат то стандартный 1с объект результат запроса получаешь и обходишь
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа