Переход с файловой версии базы данных на клиент-серверный вариант (SQL) часто сопровождается неприятными сюрпризами. Код, который годами стабильно работал в файловом режиме, внезапно начинает выдавать ошибки: «Ошибка отображения типов» или «Интерактивные операции недоступны». Давайте подробно разберем, почему это происходит, в чем заключается разница между режимами работы платформы и как правильно адаптировать код для работы в «честном» клиент-серверном окружении.
Рассмотрим ситуацию, когда разработчик пытается открыть форму документа непосредственно из серверной процедуры. В файловом варианте (особенно при использовании Толстого клиента) это может сработать, но в клиент-серверном варианте на SQL-сервере это принципиально невозможно. Проанализируем типичный ошибочный код:
&НаСервере
Процедура ОткрытьДокументНаСервере(СсылкаНаДокумент)
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
// ОШИБКА: Сервер не умеет показывать окна!
ДокОбъект.ПолучитьФорму().Открыть();
КонецПроцедуры
Почему это не работает: Серверный процесс 1С (кластер серверов) — это фоновая служба, у которой нет графического интерфейса. Он «не знает», что такое монитор, мышь или окно. Когда вы вызываете метод Открыть() на сервере, платформа выбрасывает исключение «Интерактивные операции недоступны».
Как исправить: Разделим логику. На сервере мы должны выполнять только вычислительные операции или получение данных, а открытие форм всегда оставлять на стороне клиента. Разберем правильный подход:
&НаКлиенте
Процедура ВыборСтроки(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Получаем ссылку (она доступна и на клиенте, и на сервере)
ТекущиеДанные = Элементы.СписокДокументов.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
// Открываем форму прямо на клиенте
ПараметрыФормы = Новый Структура("Ключ", ТекущиеДанные.Ссылка);
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", ПараметрыФормы);
КонецЕсли;
КонецПроцедуры
Вторая частая проблема — попытка передать объект типа ТаблицаЗначений с сервера на клиент. Проанализируем ситуацию: серверная функция формирует таблицу и возвращает её в массиве или структуре.
&НаСервере
Функция ПолучитьДанныеДляКлиента()
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Наименование");
// ... заполнение таблицы ...
Результат = Новый Массив;
Результат.Добавить(Истина); // Булево
Результат.Добавить(ТЗ); // ОШИБКА: ТаблицаЗначений не передается на Тонкий клиент
Возврат Результат;
КонецФункции
Выясним причину ошибки: В платформе 1С существует жесткое разграничение типов данных. Тип ТаблицаЗначений предназначен для обработки данных на стороне сервера или в Толстом клиенте. В Тонком клиенте этого типа просто не существует. Когда сервер пытается отправить массив, содержащий таблицу значений, клиентское приложение не может «понять» этот тип и выдать ошибку «Ошибка отображения типов» (отсутствует отображение для типа XML).
Почему в файловой версии работало? Скорее всего, запуск производился в режиме Толстого клиента. В этом режиме клиент и сервер работают в одном адресном пространстве памяти, и глубокая сериализация (преобразование в XML/JSON для передачи по сети) не требуется. SQL-версия всегда подразумевает строгое разделение, даже если сервер и клиент на одном ПК.
Если нам необходимо вернуть результат расчетов с сервера в виде таблицы, рассмотрим три основных способа решения задачи:
ЗначениеВДанныеФормы().Посмотрим на пример преобразования таблицы в массив структур:
&НаСервере
Функция ПолучитьДанныеБезопасно()
ТЗ = СоздатьИЗаполнитьТаблицу(); // Ваша серверная функция
МассивРезультат = Новый Массив;
Для Каждого СтрокаТЗ Из ТЗ Цикл
НоваяСтруктура = Новый Структура;
Для Каждого Колонка Из ТЗ.Колонки Цикл
НоваяСтруктура.Вставить(Колонка.Имя, СтрокаТЗ[Колонка.Имя]);
КонецЦикла;
МассивРезультат.Добавить(НоваяСтруктура);
КонецЦикла;
Возврат МассивРезультат; // Массив структур успешно уйдет на Тонкий клиент
КонецФункции
Интересно заметить, что ТабличныйДокумент (в отличие от ТаблицаЗначений) передается между сервером и клиентом без ошибок. Это связано с тем, что данный тип сериализуем и доступен в Тонком клиенте для отображения. Однако помните о производительности: передача документа на 100 000 строк может «подвесить» сеть. В таких случаях лучше сохранять документ на сервере во временный файл и передавать клиенту только путь к нему.
Чтобы избежать подобных проблем в будущем, проанализируем следующие правила гигиены кода:
&НаКлиенте и &НаСервере. Помните, что клиент не видит ДокументОбъект или СправочникОбъект — он работает только со Ссылками или ДаннымиФормы.Таким образом, ошибки «отображения типов» и «интерактивных операций» — это не баги платформы или SQL, а следствие нарушения архитектуры управляемого приложения. Следуя принципу «сервер считает — клиент показывает», вы создадите стабильное и быстрое решение, работающее в любых условиях.