При разработке на платформе 1С начинающие программисты часто сталкиваются с проблемой: как корректно передать данные из одного объекта в другой и почему при этом возникают ошибки «недопустимого типа» или «ошибки преобразования данных XDTO». В этой статье мы подробно разберем, как устроено взаимодействие между клиентом и сервером и как правильно реализовать задачу синхронизации данных.
Первое и самое важное правило разработки в управляемом приложении 1С: Клиент и Сервер — это разные миры. Клиент (форма) ничего не знает о базе данных напрямую, а Сервер не может «показать» пользователю интерфейс. Когда вы пытаетесь выполнить запрос к базе данных, вы находитесь на Сервере. Если вы пытаетесь вернуть результат этого запроса в процедуру, которая помечена как &НаКлиенте, платформа пытается передать этот объект (например, РезультатЗапроса) через сеть в формате XML (XDTO).
Проблема в том, что РезультатЗапроса, ВыборкаИзРезультатаЗапроса и сами объекты СправочникОбъект являются «тяжелыми» и сложными серверными структурами. Они не могут быть переданы на клиент. На клиент можно передавать только простые типы: Строку, Число, Булево, Структуру, Массив или ТаблицуЗначений (состоящую из простых типов).
Если вы видите ошибку преобразования XDTO, значит, вы пытаетесь вернуть с сервера на клиент запрещенный объект. Чтобы решить эту задачу, мы должны действовать по следующему алгоритму:
Давайте рассмотрим, как правильно перенести данные из запроса в табличную часть формы, не совершая ошибок:
Шаг 1. Получение данных на сервере.
&НаСервере
Функция ПолучитьДанныеДляЗаполнения(СерийныйНомер)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РасходкаТабличнаяЧасть1.Примечание КАК Примечание,
| РасходкаТабличнаяЧасть1.Инициатор КАК Инициатор
|ИЗ
| Справочник.Расходка.ТабличнаяЧасть1 КАК РасходкаТабличнаяЧасть1
|ГДЕ
| РасходкаТабличнаяЧасть1.Серийный = &Серийный";
Запрос.УстановитьПараметр("Серийный", СерийныйНомер);
// Возвращаем таблицу значений, которая содержит только данные
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Шаг 2. Загрузка данных в форму на клиенте.
Теперь мы вызываем функцию с клиента и загружаем результат в табличную часть объекта:
&НаКлиенте
Процедура ЗаполнитьТЧ(Команда)
Данные = ПолучитьДанныеДляЗаполнения(Объект.Серийный);
// Очищаем существующие данные и загружаем новые
Объект.ТабличнаяЧасть1.Очистить();
Объект.ТабличнаяЧасть1.Загрузить(Данные);
КонецПроцедуры
Хранить историю обслуживания техники (расходные материалы) напрямую в табличной части справочника Принтеры — решение, которое со временем приведет к раздуванию базы и проблемам с отчетностью. В профессиональной разработке 1С для таких целей используются Регистры сведений.
Почему стоит выбрать регистр?
Если данные не переносятся, проанализируйте следующее:
Загрузить() или ЗаполнитьЗначенияСвойств() требуют полного совпадения имен колонок в таблице-источнике и таблице-приемнике. Если в запросе поле называется Примечание, а в ТЧ — НПримечание, данные не попадут в нужную ячейку.Выборка.Количество(), прежде чем передавать данные дальше. Если запрос возвращает 0 записей, проблема не в передаче данных, а в условиях отбора (ГДЕ).ПередЗаписью или ПриЗаписи). Это позволяет работать с данными напрямую на сервере без необходимости передачи их на клиент.Следуя этим правилам, вы сможете избежать ошибок XDTO и построить надежную архитектуру обмена данными между справочниками в вашей конфигурации.