При интеграции сторонних приложений с системой 1С:Предприятие часто возникает задача инициировать действие в 1С извне. Традиционно многие разработчики начинают поиск с механизма внешних событий, однако, как показывает практика, это не всегда самый эффективный путь, особенно если требуется не просто «уведомить» 1С, но и получить от нее результат обработки данных. В этой статье мы подробно разберем, почему HTTP-сервисы зачастую выигрывают у внешних компонент, и как реализовать оба механизма.
Рассмотрим ситуацию: внешняя программа (например, написанная на C#) должна передать в 1С идентификатор объекта (например, номер договора) и получить в ответ список файлов или статус. Механизм ОбработкаВнешнегоСобытия в 1С работает асинхронно по принципу «выстрелил и забыл». Это означает, что 1С примет сигнал, но стороннее приложение не узнает, успешно ли прошла обработка, без организации дополнительного обратного канала связи.
Именно поэтому для задач типа «запрос-ответ» наиболее предпочтительными являются HTTP-сервисы. Разберем преимущества и недостатки основных подходов.
Проанализируем самый современный и гибкий метод — создание HTTP-сервиса в 1С. Это позволит нам организовать синхронный обмен данными.
Шаг 1: Настройка веб-сервера.
Для работы HTTP-сервисов необходимо опубликовать базу на веб-сервере (IIS или Apache). Если вы используете ОС Windows, проще всего настроить IIS (Internet Information Services). После установки IIS в конфигураторе 1С выберите пункт меню «Администрирование» — «Публикация на веб-сервере».
Шаг 2: Создание объекта в конфигурации.
В дереве метаданных найдем ветку Общие -> HTTP-сервисы. Создадим новый сервис, назовем его, например, ExchangeService. В поле «Корневой URL» укажем exchange.
Шаг 3: Настройка шаблона URL и методов.
Внутри сервиса создадим «Шаблон URL» (например, getData). В шаблоне создадим метод POST. Укажем имя обработчика в модуле сервиса.
Шаг 4: Написание кода обработки в 1С.
В модуле HTTP-сервиса опишем логику приема данных и возврата результата. Проанализируем пример кода:
Функция getDataPOST(Запрос)
// Получаем данные из тела запроса (например, в формате JSON)
СтрокаДанных = Запрос.ПолучитьТелоКакСтроку();
// Предположим, нам прислали НомерДоговора
// Здесь должна быть логика поиска файлов в 1С
// ...
// Формируем ответ
Ответ = Новый HTTPСервисОтвет(200); // OK
ДанныеОтвета = Новый Структура;
ДанныеОтвета.Вставить("Статус", "Успешно");
ДанныеОтвета.Вставить("СписокФайлов", "file1.pdf, file2.doc");
// Преобразуем в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеОтвета);
Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть());
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Возврат Ответ;
КонецФункции
Для отправки данных из внешней программы воспользуемся классом HttpClient. Выясним, как выглядит минимально необходимый код для взаимодействия с нашим новым сервисом:
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
public class Program
{
public static async Task Main()
{
var client = new HttpClient();
var url = "http://yourserver/yourbase/hs/exchange/getData";
var jsonContent = "{\"ContractNumber\": \"123-А\"}";
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
try
{
var response = await client.PostAsync(url, content);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine("Ответ от 1С: " + result);
}
}
catch (Exception ex)
{
Console.WriteLine("Ошибка: " + ex.Message);
}
}
}
Если специфика задачи требует именно воздействия на открытый сеанс пользователя (например, чтобы в запущенном окне 1С внезапно открылась форма), рассмотрим вариант с внешней компонентой.
Программа на C# должна создать COM-объект, который будет загружен в 1С через команду ЗагрузитьВнешнююКомпоненту(). Для генерации события используется метод ExternalEvent.
Нюансы этого подхода:
Процедура ВнешнееСобытие(Источник, Событие, Данные)
Если Источник = "MyCSharpApp" Тогда
Сообщить("Получено событие: " + Событие + " с данными: " + Данные);
// Здесь можно открыть форму или запустить обработку
КонецЕсли;
КонецПроцедуры
Важный момент: Как было отмечено в обсуждении, если вам нужно вернуть результат обработки события обратно в C#, внешняя компонента должна иметь свойства или методы, которые 1С заполнит в процессе выполнения ВнешнееСобытие. Сторонняя программа должна будет периодически опрашивать эти свойства или ожидать изменения состояния объекта.
Разберем типичную проблему, упомянутую в обсуждении: появление иероглифов при передаче кириллицы через HTTP-сервис. Чаще всего это происходит из-за несоответствия кодировок в заголовках ответа и теле сообщения. Всегда явно указывайте charset=utf-8 в заголовке Content-Type как на стороне C#, так и на стороне 1С при формировании HTTPСервисОтвет. Если текст все равно отображается некорректно, убедитесь, что при записи JSON в 1С не используются специфические настройки кодировки Windows-1251.
Подведем итоги нашего анализа. Если ваша задача — передать данные и получить результат, HTTP-сервисы являются стандартом де-факто. Они обеспечивают стабильную работу, легко отлаживаются и не привязаны к конкретной клиентской машине. Использование внешних событий оправдано только в узких сценариях, когда необходимо интерактивное взаимодействие с текущим сеансом пользователя без возможности использования веб-технологий.