Передача технического задания (ТЗ) между серверной и клиентской частями 1С:Предприятие — типичная задача при разработке распределённых систем, интеграции с внешними сервисами или настройке сложных бизнес-процессов. Чаще всего проблема возникает, когда ТЗ формируется на сервере (например, в фоновом задании или при обработке данных), а исполнять его нужно на стороне клиента — в толстом, тонком или веб-клиенте. При этом стандартные механизмы 1С не всегда предоставляют прямые инструменты для такой передачи, что вынуждает программистов изобретать обходные пути.
В этой статье разберём 5 проверенных способов передачи ТЗ с сервера на клиент, их плюсы и минусы, а также критические ошибки, которые приводят к потере данных или зависанию сеансов. Особое внимание уделим нюансам работы с фоновыми заданиями, HTTP-сервисами и внешними хранилищами, которые часто становятся источником проблем. Если вы администрируете или разрабатываете в 1С, эти методы сэкономят вам часы отладки.
———
1. Почему стандартные методы 1С не работают для передачи ТЗ
В классической архитектуре 1С:Предприятие 8 сервер и клиент обмениваются данными через контекст выполнения: серверные процедуры не могут напрямую вызвать клиентский код, а клиентские — не имеют доступа к серверным объектам. Это ограничение заложено в платформу для обеспечения безопасности и стабильности. Однако когда речь идёт о техническом задании (например, списке действий для пользователя или параметрах для отчёта), требуется передать структурированные данные "вверх" — с сервера на клиент.
Основные причины, почему стандартные подходы не подходят:
- 🔹 Ограничения контекста: Методы вроде
ПоказатьОповещениеПользователя()работают только в клиентском контексте, но их нельзя вызвать из серверного кода напрямую. - 🔹 Асинхронность: Фоновые задания выполняются на сервере, а результат нужно показать пользователю в клиентском сеансе, который может быть уже закрыт.
- 🔹 Безопасность: Платформа блокирует прямую передачу сложных объектов (например,
СтруктураилиТаблицаЗначений) между контекстами без явной сериализации.
⚠️ Внимание: Попытка обойти ограничения через Выполнить() с передачей серверного объекта в клиентский код приведёт к ошибке "Недопустимый тип значения параметра (Ожидался простой тип)". Это одно из самых распространённых исключений при работе с ТЗ.
Чтобы передать ТЗ корректно, нужно использовать промежуточные механизмы: временные хранилища, HTTP-сервисы или события платформы. Далее рассмотрим каждый способ подробно.
2. Способ 1: Временное хранилище (ХранилищеЗначения)
Самый простой и надёжный метод для передачи небольших объёмов данных — временное хранилище значений (ХранилищеЗначения). Оно позволяет сохранить ТЗ на сервере под уникальным ключом, а затем извлечь его на клиенте. Этот способ подходит для одноразовых задач, когда данные нужны только одному пользователю.
Алгоритм работы:
- На сервере формируете ТЗ (например, в виде
СтруктурыилиJSON). - Сохраняете его во временное хранилище с уникальным именем (например,
"ТЗ_ДляПользователя_"+ИдентификаторСеанса()). - На клиенте извлекаете данные по этому ключу и удаляете запись из хранилища.
Пример кода для сервера:
ТЗ = Новый Структура();
ТЗ.Вставить("Действие", "Обновить справочник контрагентов");
ТЗ.Вставить("Параметры", Новый Структура("ДатаНачала, 20260101"));
Хранилище = Новый ХранилищеЗначения();
Хранилище.Вставить("ТЗ_ДляПользователя_" + ИдентификаторСеанса(), ТЗ);
На клиенте:
Хранилище = Новый ХранилищеЗначения();
ТЗ = Хранилище.Получить("ТЗ_ДляПользователя_" + ИдентификаторСеанса());
Если ТЗ <> Неопределено Тогда
// Обработка ТЗ
Сообщить(ТЗ.Действие);
КонецЕсли;
⚠️ Внимание: Временное хранилище очищается при перезапуске сервера 1С или по таймауту (по умолчанию — 60 минут). Не используйте его для долговременного хранения ТЗ.
3. Способ 2: HTTP-сервисы для передачи ТЗ
Если ТЗ нужно передать между разными информационными базами или в веб-клиент, удобно использовать HTTP-сервисы. Этот метод универсален и работает даже при распределённой архитектуре. Сервер публикует ТЗ как ресурс, а клиент обращается к нему по URL.
Преимущества HTTP-сервисов:
- 🌐 Работает через интернет (подходит для облачных решений).
- 🔄 Поддерживает асинхронные запросы.
- 📦 Можно передавать большие объёмы данных (в отличие от временного хранилища).
Пример настройки HTTP-сервиса для передачи ТЗ:
- Создайте HTTP-сервис в конфигураторе с методом
ПолучитьТЗ(). - В методе сформируйте ТЗ и верните его в виде
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-серверу.
Как организовать обмен:
- Сервер формирует ТЗ и сохраняет его в файл с уникальным именем (например,
ТЗ_20260515_12345.json). - Клиент периодически проверяет папку на наличие новых файлов.
- После обработки файл удаляется или архивируется.
Пример кода для сервера:
ТЗ = Новый Структура();
ТЗ.Вставить("Данные", ТаблицаЗначений);
ИмяФайла = КаталогОбмена + "ТЗ_" + Формат(ТекущаяДата(), "ДЛГГГГММДД") + ".json";
JSON.Записать(ИмяФайла, ТЗ);
На клиенте:
Файлы = НайтиФайлы(КаталогОбмена + "*.json");
Для Каждого Файл Из Файлы Цикл
ТЗ = JSON.Прочитать(Файл.ПолноеИмя);
// Обработка ТЗ
УдалитьФайлы(Файл.ПолноеИмя);
КонецЦикла;
📌 Полезный совет: Используйте блокировку файлов (например, через
С течением времени каталог обмена переполнится устаревшими файлами, что замедлит поиск новых ТЗ. Кроме того, при повторной обработке одного и того же файла возможны дублирование действий или ошибки (например, повторное создание документа).Файл.Занять()), чтобы избежать конфликтов при одновременном доступе нескольких клиентов.
Что будет если не удалять обработанные файлы?
5. Способ 4: События платформы (ПодпискаНаСобытие)
Если ТЗ нужно передать в реальном времени, можно использовать механизм событий платформы. Сервер инициирует событие, а клиент подписывается на него. Этот способ подходит для уведомлений или срочных задач.
Как это работает:
- 📡 Сервер вызывает
ОповеститьОЖданииСобытия()с уникальным именем события и данными ТЗ. - 🖥️ Клиент подписывается на это событие через
ПодписатьсяНаСобытие(). - 🔄 При срабатывании события клиент получает ТЗ в обработчике.
Пример кода:
// На сервере:
ОповеститьОЖданииСобытия("НовоеТЗ", ТЗ, Ложь);
// На клиенте:
Процедура ПодписатьсяНаТЗ()
ПодписатьсяНаСобытие("НовоеТЗ", "ОбработатьТЗ");
КонецПроцедуры
Процедура ОбработатьТЗ(ТЗ) Экспорт
Сообщить("Получено ТЗ: " + ТЗ.Действие);
КонецПроцедуры
⚠️ Внимание: События платформы работают только в рамках одного сеанса. Если клиент переподключится, подписка сбросится, и ТЗ будет потеряно. Для долговременных задач используйте другие методы.
6. Способ 5: Обмен через базу данных (регистры сведений)
Для интеграции ТЗ в бизнес-процессы удобно использовать регистры сведений. Сервер записывает ТЗ в регистр, а клиент периодически опрашивает его на наличие новых записей. Этот метод надёжен и поддерживает историю изменений.
Пример структуры регистра:
| Измерение | Ресурс | Описание |
|---|---|---|
Пользователь | ТЗ (Строковый) | Идентификатор пользователя, для которого предназначено ТЗ |
ДатаСоздания | Статус (Перечисление) | Дата и время создания записи |
| - | ДанныеТЗ (ХранилищеЗначения) | Сериализованное ТЗ в двоичном формате |
Код для записи ТЗ на сервере:
Движение = РегистрыСведений.ТЗПользователей.СоздатьМенеджерЗаписи();
Движение.Пользователь = ТекущийПользователь();
Движение.ДатаСоздания = ТекущаяДата();
Движение.Статус = Перечисления.СтатусыТЗ.Новое;
Движение.ДанныеТЗ = Новый ХранилищеЗначения(ТЗ);
Движение.Записать();
На клиенте:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ДанныеТЗ
ИЗ РегистрСведений.ТЗПользователей
ГДЕ Пользователь = &Пользователь
И Статус = &Статус";
Запрос.УстановитьПараметр("Пользователь", ТекущийПользователь());
Запрос.УстановитьПараметр("Статус", Перечисления.СтатусыТЗ.Новое);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат;
КонецЕсли;
ТЗ = Результат[0].ДанныеТЗ.Получить();
📌 Ключевой вывод: Регистры сведений идеальны для ТЗ, которые нужно хранить длительно или анализировать историю выполнения. Однако они требуют дополнительной настройки прав доступа.
7. Типичные ошибки и как их избежать
При передаче ТЗ с сервера на клиент программисты часто сталкиваются с одними и теми же проблемами. Вот самые распространённые из них и способы их решения:
- 🚫 Потеря данных при асинхронных операциях: Если ТЗ формируется в фоновом задании, а клиентский сеанс закрывается до его завершения, данные теряются. Решение: Используйте
ЖурналРегистрацииили уведомления по email для отслеживания статуса. - 🚫 Ошибки сериализации сложных объектов: Платформа не умеет автоматически конвертировать объекты вроде
ДокументОбъектилиСправочникОбъектвJSON. Решение: Преобразуйте объекты в структуры или таблицы значений перед передачей. - 🚫 Конфликты при параллельном доступе: Если несколько клиентов пытаются прочитать одно и то же ТЗ из файла или хранилища, возможны ошибки блокировки. Решение: Используйте механизмы блокировок (
Файл.Занять()илиТранзакцияв СУБД).
⚠️ Внимание: При передаче ТЗ через HTTP-сервисы или файловое хранилище всегда проверяйте целостность данных. Например, если файл ТЗ повреждён, его чтение может привести к падению клиента. Добавьте обработку исключений:
Попытка
ТЗ = JSON.Прочитать(ИмяФайла);
Исключение
Сообщить("Ошибка чтения ТЗ: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
8. Сравнение способов передачи ТЗ
Чтобы выбрать оптимальный метод, сравним все рассмотренные способы по ключевым критериям:
| Способ | Скорость | Надёжность | Сложность реализации | Когда использовать |
|---|---|---|---|---|
| Временное хранилище | ⚡ Быстро | ⚠️ Средняя (очищается при перезапуске) | ⭐ Низкая | Для одноразовых ТЗ в одном сеансе |
| HTTP-сервисы | 🐢 Медленно (зависит от сети) | ✅ Высокая | ⭐⭐ Средняя | Для распределённых систем или веб-клиента |
| Файловое хранилище | ⚡ Быстро | ✅ Высокая (при резервировании) | ⭐⭐ Средняя | Для больших ТЗ или интеграции с внешними системами |
| События платформы | ⚡ Мгновенно | ⚠️ Низкая (только для текущего сеанса) | ⭐ Низкая | Для уведомлений в реальном времени |
| Регистры сведений | ⚡ Быстро | ✅ Высокая | ⭐⭐⭐ Высокая | Для ТЗ с историей или сложной логикой обработки |
📌 Ключевой вывод: Для большинства задач оптимальным будет временное хранилище (простота) или регистры сведений (надёжность). HTTP-сервисы стоит использовать только при необходимости межсистемного обмена.
———
FAQ: Частые вопросы по передаче ТЗ в 1С
Можно ли передать ТЗ напрямую из серверной процедуры в клиентскую без промежуточных хранилищ?
Нет, платформа 1С:Предприятие не поддерживает прямой вызов клиентского кода из серверного контекста. Любая передача данных требует промежуточного механизма: временного хранилища, файла, HTTP-сервиса или события. Попытка обойти это ограничение через Выполнить() приведёт к ошибке.
Как передать ТЗ размером более 100 МБ?
Для крупных ТЗ (например, с большими таблицами или двоичными данными) используйте файловое хранилище или FTP. Разбейте данные на части, если это возможно. Временное хранилище и HTTP-сервисы не предназначены для таких объёмов — они могут привести к переполнению памяти или таймаутам.
Что делать, если ТЗ не доходит до клиента?
Проверьте следующие моменты:
- Убедитесь, что ключ временного хранилища или имя файла указаны корректно (учтите регистр!).
- Для HTTP-сервисов проверьте логи сервера на ошибки (например,
403 Forbiddenили500 Internal Error). - Если используете события, убедитесь, что клиент успевает подписаться до отправки ТЗ.
- Проверьте права доступа: клиент должен иметь разрешения на чтение временного хранилища, файлов или регистров.
Как защитить ТЗ от несанкционированного доступа?
Используйте следующие меры безопасности:
- Для HTTP-сервисов: настройте авторизацию (например, через токены или базовую аутентификацию).
- Для файлового хранилища: ограничьте доступ к папке на уровне ОС или используйте шифрование.
- Для временного хранилища: формируйте уникальные ключи с привязкой к сессии или пользователю (например,
"ТЗ_" + УникальныйИдентификатор() + "_" + ТекущийПользователь()). - В регистрах сведений настройте права так, чтобы пользователи видели только свои ТЗ.
Можно ли передать ТЗ между разными информационными базами?
Да, для этого подходят:
- HTTP-сервисы (универсальный способ).
- Обмен через файлы (например, выгружаете ТЗ в
JSONна сетевой диск, а другая база его забирает). - План обмена (если базы связаны через распределённую информационную базу).
Временное хранилище и события платформы для межбазового обмена не подходят.