При обновлении старых конфигураций, таких как Управление торговлей 10.3, для поддержки механизмов маркировки товаров, разработчики часто сталкиваются с критическими ошибками, которые проявляются только в клиент-серверном варианте работы. Одной из таких ошибок является «Попытка передачи мутабельного значения». Давайте разберем, почему она возникает и как мы можем ее устранить.
В файловой версии платформы 1С клиент и сервер функционируют в рамках одного процесса (одного адресного пространства). Это позволяет передавать между ними практически любые типы данных, включая ссылки на сложные объекты, ТаблицыЗначений или Соответствия, без их предварительной обработки. В клиент-серверном варианте клиент (тонкий или толстый) и сервер 1С — это разные процессы, часто запущенные на разных физических машинах.
Для общения между ними используется механизм сериализации. Когда мы вызываем функцию с пометкой &НаСервере и пытаемся вернуть значение, сервер должен «упаковать» это значение в поток данных и отправить клиенту. Если в этом значении содержится «мутабельный» (изменяемый) объект, который платформа не умеет сериализовать (например, ТаблицаЗначений или COM-объект), происходит аварийная остановка с ошибкой передачи.
Ошибка указывает на модуль РазборКодаМаркировкиИССлужебныйКлиентСерверПовтИсп. Проблема кроется в методе НастройкиРазбораКодаМаркировки. Скорее всего, логика работы была перенесена из более новых конфигураций, где архитектура предполагает передачу данных в строго определенном формате, который «родная» среда УТ 10.3 не всегда готова принять.
Чтобы найти источник проблемы, нам необходимо проанализировать, что именно возвращает функция. Давайте выполним следующие шаги:
РазборКодаМаркировкиИССлужебныйВызовСервера через Конфигуратор.НастройкиРазбораКодаМаркировки.Структуры, Массива, Числа, Строки, Булево или Даты, именно это является причиной ошибки.Рассмотрим несколько стратегий, которые помогут нам победить эту проблему.
Самым надежным способом передачи данных является их предварительная конвертация в простые типы. Вместо того чтобы пытаться вернуть ТаблицуЗначений, мы можем преобразовать её в массив Структур. Каждая строка таблицы станет отдельной структурой в массиве.
Посмотрим на пример, как это можно реализовать:
// Вместо возврата ТаблицыЗначений напрямую:
РезультатМассив = Новый Массив;
Для Каждого Стр Из ВашаТаблицаЗначений Цикл
НоваяСтруктура = Новый Структура("Колонка1, Колонка2", Стр.Колонка1, Стр.Колонка2);
РезультатМассив.Добавить(НоваяСтруктура);
КонецЦикла;
Возврат РезультатМассив;
Если объем передаваемых данных слишком велик (например, длинный список кодов маркировки), оптимальным решением будет использование ВременногоХранилища. Суть метода заключается в следующем:
ПоместитьВоВременноеХранилище().ПолучитьИзВременногоХранилища().Этот метод позволяет передавать любые, даже самые сложные объекты, так как фактически по сети передается только «адрес» в памяти сервера.
Поскольку ошибка возникает при вызове метода, нам обязательно нужно использовать Отладчик. Установите точку останова в начале метода НастройкиРазбораКодаМаркировки и пошагово пройдите выполнение кода (клавиша F11). Особое внимание уделите переменным ВидыПродукции и другим аргументам, которые вы передаете в функцию. Если один из них является объектом, который не может быть сериализован, платформа выдаст ошибку сразу при попытке «прыгнуть» на сервер.
Помните, что Управление торговлей 10.3 — это конфигурация на обычных формах, и многие механизмы маркировки добавлены туда как внешние модули. При возникновении проблем с обновлением важно проверять код в местах вызовов между клиентом и сервером. В 90% случаев решение сводится к приведению возвращаемых значений к примитивным типам или структурам.