К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как сообщить (передать) таблицу значений в 1С

Как сообщить и передать таблицу значений в 1С: передача в процедуры, между клиентом и сервером, в форму и по COM. Примеры кода, ограничения, типичные ошибки.

Таблица значений — один из самых востребованных объектов встроенного языка 1С, и задача «сообщить» её, то есть передать из одного места в другое, возникает постоянно: из серверной процедуры на клиент, из формы в общий модуль, из одной информационной базы в другую. Проблема в том, что таблица значений — объект серверный, и напрямую она доступна не везде.

Способ передачи зависит от направления: внутри одного контекста (клиент или сервер) таблица передаётся как обычный параметр, между клиентом и сервером потребуется промежуточное представление — массив структур или сериализация, а между разными базами — обмен через файл, строку XML или COM-соединение. Ниже разобраны все рабочие варианты с примерами кода.

Что нужно понять перед передачей таблицы значений

Объект «ТаблицаЗначений» существует только на сервере (и в толстом клиенте). В тонком и веб-клиенте такого типа нет: там доступны лишь массивы, структуры и данные форм. Поэтому первый вопрос — откуда и куда нужно передать данные.

Второй момент — объём. Таблица на десятки тысяч строк, переданная через сериализацию или временное хранилище, создаст заметную нагрузку и может привести к ошибкам по памяти или таймаутам вызовов. Для больших объёмов лучше пересматривать архитектуру: обрабатывать данные на сервере порциями, не передавая их целиком.

Передача таблицы в процедуру или функцию общего модуля

Самый простой случай — оба участка кода работают в одном контексте, например оба на сервере. Таблица значений передаётся как обычный параметр. Поскольку это ссылочный объект, изменения внутри процедуры отразятся на исходной таблице, если не передать копию.

// Серверный общий модуль

Функция ПолучитьТаблицуТоваров() Экспорт

Запрос = Новый Запрос("ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.Номенклатура");

Возврат Запрос.Выполнить().Выгрузить();

КонецФункции

Процедура ОбработатьТаблицу(ТаблицаДанных) Экспорт

Для Каждого СтрокаТаблицы Из ТаблицаДанных Цикл

// обработка строки

КонецЦикла;

КонецПроцедуры

Если исходная таблица должна остаться нетронутой, передайте её копию: ОбработатьТаблицу(ИсходнаяТаблица.Скопировать()). Метод Скопировать() создаёт полную независимую копию, включая структуру колонок.

Передача таблицы значений с сервера на клиент

Напрямую вернуть объект ТаблицаЗначений из серверной процедуры в тонкий клиент нельзя — платформа выдаст ошибку о недопустимом типе. Стандартное решение — преобразовать таблицу в массив структур, где каждая структура повторяет одну строку.

&НаСервереБезКонтекста

Функция ПолучитьДанныеНаСервере()

Таблица = Запрос.Выполнить().Выгрузить();

Результат = Новый Массив;

Для Каждого СтрокаТЗ Из Таблица Цикл

СтруктураСтроки = Новый Структура;

Для Каждого Колонка Из Таблица.Колонки Цикл

СтруктураСтроки.Вставить(Колонка.Имя, СтрокаТЗ[Колонка.Имя]);

КонецЦикла;

Результат.Добавить(СтруктураСтроки);

КонецЦикла;

Возврат Результат;

КонецФункции

На клиенте полученный массив обходится обычным циклом, значения доступны через точку: Строка.Наименование. Учитывайте ограничение: имена колонок должны быть допустимыми идентификаторами (начинаться с буквы, без пробелов), иначе вставка в структуру вызовет ошибку.

Порядок действий
  1. 1
    Сформируйте таблицу значений на сервере (запрос, программное заполнение)
  2. 2
    Преобразуйте её в массив структур построчно
  3. 3
    Верните массив из серверной функции на клиент
  4. 4
    На клиенте обойдите массив и используйте данные
  5. 5
    Проверьте объём: при больших таблицах оцените время вызова

Передача таблицы между клиентом и сервером через реквизит формы

Когда таблица нужна в форме — например, для отображения или редактирования — правильный путь не массив структур, а реквизит формы типа «ТаблицаЗначений». Платформа сама сериализует такой реквизит при передаче контекста между клиентом и сервером.

Добавьте реквизит формы с типом ТаблицаЗначений и колонками нужных типов. Затем на сервере заполните его из готовой таблицы через метод ЗначениеВРеквизитФормы:

&НаСервере

Процедура ЗагрузитьТаблицуВФорму()

Таблица = ПолучитьТаблицуТоваров(); // серверная функция

ЗначениеВРеквизитФормы(Таблица, "ТаблицаТоваров");

КонецПроцедуры

&НаКлиенте

Процедура ОтправитьНаСервер(Команда)

ОбработатьНаСервере();

КонецПроцедуры

&НаСервере

Процедура ОбработатьНаСервере()

Таблица = РеквизитФормыВЗначение("ТаблицаТоваров");

// работа с таблицей как с обычным объектом

КонецПроцедуры

Обратное преобразование выполняется методом РеквизитФормыВЗначение. Это самый удобный способ для управляемых форм: данные остаются типизированными, доступна привязка к элементу «Таблица» на форме, а платформа берёт на себя маршалинг данных.

Типичные ошибки
01
Попытка вернуть ТаблицаЗначений напрямую из серверной процедуры в тонкий клиент — ошибка недопустимого типа; нужен массив структур или реквизит формы
02
Колонки с именами, недопустимыми для ключей структуры (с пробелами, начинающиеся с цифры) — ошибка при Вставить(); переименуйте колонки
03
Передача таблицы без Скопировать() с последующей неожиданной модификацией исходных данных в вызывающем коде
04
Пересылка таблицы на сотни тысяч строк между клиентом и сервером — таймауты и расход памяти; данные надо обрабатывать на сервере

Передача таблицы между базами: сериализация и COM

Для обмена между разными информационными базами объект нужно превратить в переносимое представление. Вариантов несколько.

ЗначениеВСтрокуВнутр

Функции ЗначениеВСтрокуВнутр(Таблица) и ЗначениеИзСтрокиВнутр(Строка) сериализуют объект во внутренний формат платформы. Строку можно сохранить в файл, передать через веб-сервис или хранилище значений. Ограничение: формат совместим только между платформами 1С и не является стандартом для внешних систем.

// База-источник

СтрокаДанных = ЗначениеВСтрокуВнутр(ТаблицаТоваров);

// База-приёмник

ТаблицаТоваров = ЗначениеИзСтрокиВнутр(СтрокаДанных);

XML через XDTO или универсальные механизмы

Для обмена с внешними системами таблицу выгружают в XML или JSON построчно, формируя структуру вручную. Это трудоёмко, но даёт контроль над форматом и совместимость с любыми приёмниками.

COM-соединение

При соединении через V83.COMConnector таблица значений может передаваться между базами напрямую как COM-объект, если обработка выполняется в контексте соединения. Однако COM-подключение работает только в Windows-окружении и требует установленного коннектора соответствующей версии платформы.

Сравнение вариантов

Параметр процедуры

Один контекст (сервер-сервер). Самый быстрый способ, но изменения видны вызывающему коду без Скопировать()

Массив структур

Сервер → тонкий клиент. Универсально, но теряется типизация колонок и требуется ручное преобразование

Реквизит формы

Клиент ↔ сервер в управляемой форме. Сохраняет типы, удобен для отображения, но привязан к форме

ЗначениеВСтрокуВнутр

Обмен 1С ↔ 1С через файлы или сервисы. Просто, но формат закрытый

COM-соединение

Прямой обмен между базами. Только Windows, зависимость от версии коннектора

Как проверить, что таблица передана корректно

После передачи убедитесь, что данные не потерялись и не исказились. Минимальный набор проверок: количество строк совпадает с источником, типы значений в колонках сохранены, ссылочные поля не превратились в строки.

Для контроля удобно вывести в журнал или сообщением контрольные значения: Сообщить("Передано строк: " + Таблица.Количество()) до и после передачи. При обмене между базами полезно сравнить контрольную сумму по ключевой числовой колонке — например, итог по сумме документа.

Контрольные точки

Как проверить результат

Количество строк после передачи
Норма

Совпадает с количеством в источнике

Тревожный признак

Строк меньше — потери при сериализации или отборе

Типы значений в колонках
Норма

Ссылки остались ссылками, даты — датами

Тревожный признак

Ссылки превратились в строки представления

Итог по числовой колонке
Норма

Сумма совпадает с исходной таблицей

Тревожный признак

Расхождение — ошибка преобразования типов

Ограничения и риски при передаче больших таблиц

Передача таблицы между клиентом и сервером — это сериализация каждой строки и сетевой вызов. При десятках тысяч строк время вызова заметно растёт, а в веб-клиенте возможны таймауты. Признак проблемы — «зависание» формы при нажатии кнопки загрузки.

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

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

Итог

Что важно запомнить

Внутри одного контекста таблица передаётся обычным параметром. На тонкий клиент — только через массив структур или реквизит формы. Между базами — через ЗначениеВСтрокуВнутр, XML или COM. Большие таблицы не передают целиком: обработку выполняют на сервере, а результат проверяют по количеству строк, типам и контрольным итогам.

Частые вопросы о передаче таблицы значений

Можно ли вернуть таблицу значений из серверной процедуры в тонкий клиент?

Нет, напрямую нельзя: тип ТаблицаЗначений недоступен в тонком клиенте, и платформа выдаст ошибку. Преобразуйте таблицу в массив структур или используйте реквизит формы типа ТаблицаЗначений — платформа сама передаст его содержимое.

Изменится ли исходная таблица, если передать её в процедуру?

Да. Таблица значений — ссылочный объект, поэтому все изменения внутри процедуры отразятся на оригинале. Чтобы этого избежать, передавайте копию: ИсходнаяТаблица.Скопировать().

Как передать таблицу значений в другую базу 1С без COM?

Сериализуйте её функцией ЗначениеВСтрокуВнутр, сохраните строку в файл или передайте через веб-сервис, а в базе-приёмнике восстановите через ЗначениеИзСтрокиВнутр. Для обмена с не-1С системами формируйте XML или JSON построчно.

Почему при передаче массивом структур возникает ошибка на Вставить()?

Имя колонки таблицы не является допустимым идентификатором: содержит пробелы, начинается с цифры или включает спецсимволы. Ключи структуры должны быть корректными именами переменных — переименуйте колонки перед преобразованием.

Что делать, если таблица слишком большая и вызов «зависает»?

Не передавайте её на клиент. Выполните всю обработку на сервере и верните только итог: количество строк, суммы, перечень ошибок. Для просмотра данных используйте динамический список вместо таблицы значений.

Сохраняются ли типы колонок при передаче через реквизит формы?

Да, реквизит формы типа ТаблицаЗначений сохраняет состав и типы колонок, заявленные в структуре реквизита. При этом колонки, которых нет в описании реквизита, при загрузке через ЗначениеВРеквизитФормы будут отброшены — описание реквизита должно соответствовать передаваемой таблице.