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

В этой статье разберём 5 проверенных способов передачи ТЗ с сервера на клиент, их плюсы и минусы, а также критические ошибки, которые приводят к потере данных или зависанию сеансов. Особое внимание уделим нюансам работы с фоновыми заданиями, HTTP-сервисами и внешними хранилищами, которые часто становятся источником проблем. Если вы администрируете или разрабатываете в , эти методы сэкономят вам часы отладки.

———

1. Почему стандартные методы 1С не работают для передачи ТЗ

В классической архитектуре 1С:Предприятие 8 сервер и клиент обмениваются данными через контекст выполнения: серверные процедуры не могут напрямую вызвать клиентский код, а клиентские — не имеют доступа к серверным объектам. Это ограничение заложено в платформу для обеспечения безопасности и стабильности. Однако когда речь идёт о техническом задании (например, списке действий для пользователя или параметрах для отчёта), требуется передать структурированные данные "вверх" — с сервера на клиент.

Основные причины, почему стандартные подходы не подходят:

  • 🔹 Ограничения контекста: Методы вроде ПоказатьОповещениеПользователя() работают только в клиентском контексте, но их нельзя вызвать из серверного кода напрямую.
  • 🔹 Асинхронность: Фоновые задания выполняются на сервере, а результат нужно показать пользователю в клиентском сеансе, который может быть уже закрыт.
  • 🔹 Безопасность: Платформа блокирует прямую передачу сложных объектов (например, Структура или ТаблицаЗначений) между контекстами без явной сериализации.

⚠️ Внимание: Попытка обойти ограничения через Выполнить() с передачей серверного объекта в клиентский код приведёт к ошибке "Недопустимый тип значения параметра (Ожидался простой тип)". Это одно из самых распространённых исключений при работе с ТЗ.

Чтобы передать ТЗ корректно, нужно использовать промежуточные механизмы: временные хранилища, HTTP-сервисы или события платформы. Далее рассмотрим каждый способ подробно.

2. Способ 1: Временное хранилище (ХранилищеЗначения)

Самый простой и надёжный метод для передачи небольших объёмов данных — временное хранилище значений (ХранилищеЗначения). Оно позволяет сохранить ТЗ на сервере под уникальным ключом, а затем извлечь его на клиенте. Этот способ подходит для одноразовых задач, когда данные нужны только одному пользователю.

Алгоритм работы:

  1. На сервере формируете ТЗ (например, в виде Структуры или JSON).
  2. Сохраняете его во временное хранилище с уникальным именем (например, "ТЗ_ДляПользователя_"+ИдентификаторСеанса()).
  3. На клиенте извлекаете данные по этому ключу и удаляете запись из хранилища.

Пример кода для сервера:

ТЗ = Новый Структура();

ТЗ.Вставить("Действие", "Обновить справочник контрагентов");

ТЗ.Вставить("Параметры", Новый Структура("ДатаНачала, 20260101"));

Хранилище = Новый ХранилищеЗначения();

Хранилище.Вставить("ТЗ_ДляПользователя_" + ИдентификаторСеанса(), ТЗ);

На клиенте:

Хранилище = Новый ХранилищеЗначения();

ТЗ = Хранилище.Получить("ТЗ_ДляПользователя_" + ИдентификаторСеанса());

Если ТЗ <> Неопределено Тогда

// Обработка ТЗ

Сообщить(ТЗ.Действие);

КонецЕсли;

⚠️ Внимание: Временное хранилище очищается при перезапуске сервера или по таймауту (по умолчанию — 60 минут). Не используйте его для долговременного хранения ТЗ.

📊 Какой способ передачи ТЗ вы используете чаще?
Временное хранилище
HTTP-сервисы
Файловое хранилище
События платформы
Другой

3. Способ 2: HTTP-сервисы для передачи ТЗ

Если ТЗ нужно передать между разными информационными базами или в веб-клиент, удобно использовать HTTP-сервисы. Этот метод универсален и работает даже при распределённой архитектуре. Сервер публикует ТЗ как ресурс, а клиент обращается к нему по URL.

Преимущества HTTP-сервисов:

  • 🌐 Работает через интернет (подходит для облачных решений).
  • 🔄 Поддерживает асинхронные запросы.
  • 📦 Можно передавать большие объёмы данных (в отличие от временного хранилища).

Пример настройки HTTP-сервиса для передачи ТЗ:

  1. Создайте HTTP-сервис в конфигураторе с методом ПолучитьТЗ().
  2. В методе сформируйте ТЗ и верните его в виде JSON:
Функция ПолучитьТЗ(ИдентификаторПользователя)

ТЗ = Новый Структура();

ТЗ.Вставить("Задача", "Проверка остатков");

ТЗ.Вставить("Приоритет", 1);

Возврат JSON.Записать(ТЗ);

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

На клиенте выполните запрос:

URL = "http://сервер/1c_http/ws/ТЗСервис.1cws?ws=ПолучитьТЗ&user=123";

Ответ = HTTPСоединение.Получить(URL);

ТЗ = JSON.Прочитать(Ответ.ПолучитьТекст());

⚠️ Внимание: При использовании HTTP-сервисов обязательно настройте аутентификацию (например, через токены или базовую авторизацию), чтобы предотвратить утечку данных.

Настроена ли аутентификация на сервере?

Проверен ли формат данных (JSON/XML)?

Указан ли корректный URL сервиса?

Обработаны ли возможные ошибки соединения?

-->

4. Способ 3: Файловое хранилище (общий каталог или FTP)

Для передачи крупных ТЗ (например, с большими таблицами данных) подходит файловое хранилище. Сервер сохраняет ТЗ в файл (например, в формате JSON или XML), а клиент считывает его по готовности. Этот метод надёжен, но требует доступа к общей папке или FTP-серверу.

Как организовать обмен:

  1. Сервер формирует ТЗ и сохраняет его в файл с уникальным именем (например, ТЗ_20260515_12345.json).
  2. Клиент периодически проверяет папку на наличие новых файлов.
  3. После обработки файл удаляется или архивируется.

Пример кода для сервера:

ТЗ = Новый Структура();

ТЗ.Вставить("Данные", ТаблицаЗначений);

ИмяФайла = КаталогОбмена + "ТЗ_" + Формат(ТекущаяДата(), "ДЛГГГГММДД") + ".json";

JSON.Записать(ИмяФайла, ТЗ);

На клиенте:

Файлы = НайтиФайлы(КаталогОбмена + "*.json");

Для Каждого Файл Из Файлы Цикл

ТЗ = JSON.Прочитать(Файл.ПолноеИмя);

// Обработка ТЗ

УдалитьФайлы(Файл.ПолноеИмя);

КонецЦикла;

📌 Полезный совет: Используйте блокировку файлов (например, через Файл.Занять()), чтобы избежать конфликтов при одновременном доступе нескольких клиентов.

Что будет если не удалять обработанные файлы?

С течением времени каталог обмена переполнится устаревшими файлами, что замедлит поиск новых ТЗ. Кроме того, при повторной обработке одного и того же файла возможны дублирование действий или ошибки (например, повторное создание документа).

5. Способ 4: События платформы (ПодпискаНаСобытие)

Если ТЗ нужно передать в реальном времени, можно использовать механизм событий платформы. Сервер инициирует событие, а клиент подписывается на него. Этот способ подходит для уведомлений или срочных задач.

Как это работает:

  • 📡 Сервер вызывает ОповеститьОЖданииСобытия() с уникальным именем события и данными ТЗ.
  • 🖥️ Клиент подписывается на это событие через ПодписатьсяНаСобытие().
  • 🔄 При срабатывании события клиент получает ТЗ в обработчике.

Пример кода:

// На сервере:

ОповеститьОЖданииСобытия("НовоеТЗ", ТЗ, Ложь);

// На клиенте:

Процедура ПодписатьсяНаТЗ()

ПодписатьсяНаСобытие("НовоеТЗ", "ОбработатьТЗ");

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

Процедура ОбработатьТЗ(ТЗ) Экспорт

Сообщить("Получено ТЗ: " + ТЗ.Действие);

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

⚠️ Внимание: События платформы работают только в рамках одного сеанса. Если клиент переподключится, подписка сбросится, и ТЗ будет потеряно. Для долговременных задач используйте другие методы.

6. Способ 5: Обмен через базу данных (регистры сведений)

Для интеграции ТЗ в бизнес-процессы удобно использовать регистры сведений. Сервер записывает ТЗ в регистр, а клиент периодически опрашивает его на наличие новых записей. Этот метод надёжен и поддерживает историю изменений.

Пример структуры регистра:

ИзмерениеРесурсОписание
ПользовательТЗ (Строковый)Идентификатор пользователя, для которого предназначено ТЗ
ДатаСозданияСтатус (Перечисление)Дата и время создания записи
-ДанныеТЗ (ХранилищеЗначения)Сериализованное ТЗ в двоичном формате

Код для записи ТЗ на сервере:

Движение = РегистрыСведений.ТЗПользователей.СоздатьМенеджерЗаписи();

Движение.Пользователь = ТекущийПользователь();

Движение.ДатаСоздания = ТекущаяДата();

Движение.Статус = Перечисления.СтатусыТЗ.Новое;

Движение.ДанныеТЗ = Новый ХранилищеЗначения(ТЗ);

Движение.Записать();

На клиенте:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ДанныеТЗ

ИЗ РегистрСведений.ТЗПользователей

ГДЕ Пользователь = &Пользователь

И Статус = &Статус";

Запрос.УстановитьПараметр("Пользователь", ТекущийПользователь());

Запрос.УстановитьПараметр("Статус", Перечисления.СтатусыТЗ.Новое);

Результат = Запрос.Выполнить();

Если Результат.Пустой() Тогда

Возврат;

КонецЕсли;

ТЗ = Результат[0].ДанныеТЗ.Получить();

📌 Ключевой вывод: Регистры сведений идеальны для ТЗ, которые нужно хранить длительно или анализировать историю выполнения. Однако они требуют дополнительной настройки прав доступа.

7. Типичные ошибки и как их избежать

При передаче ТЗ с сервера на клиент программисты часто сталкиваются с одними и теми же проблемами. Вот самые распространённые из них и способы их решения:

  • 🚫 Потеря данных при асинхронных операциях: Если ТЗ формируется в фоновом задании, а клиентский сеанс закрывается до его завершения, данные теряются. Решение: Используйте ЖурналРегистрации или уведомления по email для отслеживания статуса.
  • 🚫 Ошибки сериализации сложных объектов: Платформа не умеет автоматически конвертировать объекты вроде ДокументОбъект или СправочникОбъект в JSON. Решение: Преобразуйте объекты в структуры или таблицы значений перед передачей.
  • 🚫 Конфликты при параллельном доступе: Если несколько клиентов пытаются прочитать одно и то же ТЗ из файла или хранилища, возможны ошибки блокировки. Решение: Используйте механизмы блокировок (Файл.Занять() или Транзакция в СУБД).

⚠️ Внимание: При передаче ТЗ через HTTP-сервисы или файловое хранилище всегда проверяйте целостность данных. Например, если файл ТЗ повреждён, его чтение может привести к падению клиента. Добавьте обработку исключений:

Попытка

ТЗ = JSON.Прочитать(ИмяФайла);

Исключение

Сообщить("Ошибка чтения ТЗ: " + ОписаниеОшибки());

Возврат Неопределено;

КонецПопытки;

8. Сравнение способов передачи ТЗ

Чтобы выбрать оптимальный метод, сравним все рассмотренные способы по ключевым критериям:

Способ Скорость Надёжность Сложность реализации Когда использовать
Временное хранилище ⚡ Быстро ⚠️ Средняя (очищается при перезапуске) ⭐ Низкая Для одноразовых ТЗ в одном сеансе
HTTP-сервисы 🐢 Медленно (зависит от сети) ✅ Высокая ⭐⭐ Средняя Для распределённых систем или веб-клиента
Файловое хранилище ⚡ Быстро ✅ Высокая (при резервировании) ⭐⭐ Средняя Для больших ТЗ или интеграции с внешними системами
События платформы ⚡ Мгновенно ⚠️ Низкая (только для текущего сеанса) ⭐ Низкая Для уведомлений в реальном времени
Регистры сведений ⚡ Быстро ✅ Высокая ⭐⭐⭐ Высокая Для ТЗ с историей или сложной логикой обработки

📌 Ключевой вывод: Для большинства задач оптимальным будет временное хранилище (простота) или регистры сведений (надёжность). HTTP-сервисы стоит использовать только при необходимости межсистемного обмена.

———

FAQ: Частые вопросы по передаче ТЗ в 1С

Можно ли передать ТЗ напрямую из серверной процедуры в клиентскую без промежуточных хранилищ?

Нет, платформа 1С:Предприятие не поддерживает прямой вызов клиентского кода из серверного контекста. Любая передача данных требует промежуточного механизма: временного хранилища, файла, HTTP-сервиса или события. Попытка обойти это ограничение через Выполнить() приведёт к ошибке.

Как передать ТЗ размером более 100 МБ?

Для крупных ТЗ (например, с большими таблицами или двоичными данными) используйте файловое хранилище или FTP. Разбейте данные на части, если это возможно. Временное хранилище и HTTP-сервисы не предназначены для таких объёмов — они могут привести к переполнению памяти или таймаутам.

Что делать, если ТЗ не доходит до клиента?

Проверьте следующие моменты:

  1. Убедитесь, что ключ временного хранилища или имя файла указаны корректно (учтите регистр!).
  2. Для HTTP-сервисов проверьте логи сервера на ошибки (например, 403 Forbidden или 500 Internal Error).
  3. Если используете события, убедитесь, что клиент успевает подписаться до отправки ТЗ.
  4. Проверьте права доступа: клиент должен иметь разрешения на чтение временного хранилища, файлов или регистров.

Как защитить ТЗ от несанкционированного доступа?

Используйте следующие меры безопасности:

  • Для HTTP-сервисов: настройте авторизацию (например, через токены или базовую аутентификацию).
  • Для файлового хранилища: ограничьте доступ к папке на уровне ОС или используйте шифрование.
  • Для временного хранилища: формируйте уникальные ключи с привязкой к сессии или пользователю (например, "ТЗ_" + УникальныйИдентификатор() + "_" + ТекущийПользователь()).
  • В регистрах сведений настройте права так, чтобы пользователи видели только свои ТЗ.

Можно ли передать ТЗ между разными информационными базами?

Да, для этого подходят:

  • HTTP-сервисы (универсальный способ).
  • Обмен через файлы (например, выгружаете ТЗ в JSON на сетевой диск, а другая база его забирает).
  • План обмена (если базы связаны через распределённую информационную базу).

Временное хранилище и события платформы для межбазового обмена не подходят.