Выгрузка данных из 1С во внешнюю систему: от выбора протокола до работающего запроса

· 9 мин

Содержание

Чтобы подключить выгрузку из 1С во внешнюю систему, чаще всего делают так: в расширении конфигурации создают HTTP-сервис, который отдаёт JSON, публикуют базу на веб-сервере (Apache или IIS) и заводят отдельного пользователя для обмена. Сайт, маркетплейс-коннектор или BI-система потом просто шлёт запрос GET http://сервер/база/hs/... и получает данные. Если программировать нельзя, выручает стандартный интерфейс OData, а для скриптов на той же машине — COM-соединение.

Выбор зависит от того, кто инициирует обмен и где стоит получатель. Внешний сервис в интернете — HTTP. Отчётная система, которой нужны «сырые» справочники и регистры, — OData. Скрипт на Python или PowerShell в локальной сети — COM.

Какой способ выгрузки выбрать под задачу

Сначала определитесь с архитектурой: кто кого вызывает, как часто и сколько данных уходит за раз. От этого зависит всё остальное — права, публикация, нагрузка.

СпособКогда подходитЧто нужноОграничения
HTTP-сервис (REST, JSON)Сайт, мобильное приложение, свой коннектор к маркетплейсуРасширение или доработка, веб-серверНужен программист 1С
Стандартный интерфейс ODataBI, Power BI, выгрузка справочников без доработокПубликация + настройка состава интерфейсаОтдаёт объекты «как есть», бизнес-логику не добавить
Web-сервис (SOAP)Партнёр требует WSDL, корпоративная шинаДоработка, веб-серверТяжелее в отладке, чем REST
COM-соединениеСкрипт или другая база 1С в той же сети, WindowsЗарегистрированный comcntr.dllТолько Windows, только локальная сеть, держит сеанс
Файлы (XML, JSON, CSV) по расписаниюПолучатель забирает файлы из папки или FTPРегламентное заданиеНет мгновенного ответа, нужна чистка папки

💡 Банки и ЭДО в типовых конфигурациях подключаются штатными сервисами (DirectBank, 1С:ЭДО), там свой HTTP писать не нужно. Свой сервис нужен там, где типового механизма нет.

Для выгрузки «наружу» почти всегда побеждает HTTP-сервис: внешняя система вызывает 1С сама, когда ей нужно, а 1С отвечает только тем, что вы разрешили. Дальше разбираем именно этот вариант, а COM и OData — отдельными блоками.

Пользователь и права для подключения выгрузки

Интеграция никогда не должна работать от имени живого бухгалтера или администратора. Заведите технического пользователя:

  1. В БП 3.0, ЗУП 3.1, УТ 11 откройте Администрирование → Настройки пользователей и прав → Пользователи.
  2. Создайте пользователя, например exchange_site, включите Вход в программу разрешен.
  3. Оставьте только аутентификацию 1С:Предприятия, задайте длинный пароль.
  4. Выдайте права через профиль групп доступа или отдельную роль из расширения.

Самый чистый путь — роль в том же расширении, где лежит HTTP-сервис. В ней дайте право Чтение только на те объекты, которые сервис выгружает: например, справочник Номенклатура, регистр цен и остатков. Записи, удаления и интерактивных прав этой роли не нужно.

Не выдавайте интеграционному пользователю роль «Полные права». Пароль от него хранится в настройках внешней системы, часто в открытом виде. Утечка такого пароля — это доступ ко всей базе через веб.

📌 Что ещё проверить по пользователю:

  • 🔒 пароль не истекает по политике паролей, иначе обмен встанет через N дней;
  • 🧾 в журнале регистрации отбор по этому пользователю сразу показывает всю активность обмена;
  • 🔑 если ограничения доступа на уровне записей (RLS) включены, проверьте, что пользователь видит нужные организации и склады.

Как сделать выгрузку из 1С через HTTP-сервис

Типовую конфигурацию не снимайте с поддержки: HTTP-сервис создаётся в расширении. Расширения доступны с платформы 8.3.6, а HTTP-сервисы в них работают на всех актуальных платформах 8.3.2x.

Создание сервиса и шаблона URL

  1. В конфигураторе: Конфигурация → Расширения конфигурации, добавьте новое расширение.
  2. В дереве расширения найдите ветку Общие → HTTP-сервисы, добавьте сервис.
  3. Задайте Корневой URL, например api.
  4. Добавьте шаблон URL, например /products, и в нём метод GET. Платформа создаст обработчик в модуле сервиса.

Итоговый адрес будет таким: http://srv/trade/hs/api/products. Сегмент hs платформа добавляет сама — его часто забывают при тестировании.

Параметры в пути задают в фигурных скобках: шаблон /products/{code} даёт доступ к значению через Запрос.ПараметрыURL.Получить("code"). Параметры после знака вопроса читают из Запрос.ПараметрыЗапроса.

Код обработчика: выборка и JSON

Пример отдаёт товары с ценами порциями. Названия регистров замените на свои: в разных конфигурациях цены лежат в разных регистрах.

Функция ProductsGET(Запрос)

    Лимит = 500;
    ПараметрЛимит = Запрос.ПараметрыЗапроса.Получить("limit");
    Если ЗначениеЗаполнено(ПараметрЛимит) Тогда
        Лимит = Мин(Число(ПараметрЛимит), 5000);
    КонецЕсли;

    ПоследнийКод = Запрос.ПараметрыЗапроса.Получить("after");
    Если ПоследнийКод = Неопределено Тогда
        ПоследнийКод = "";
    КонецЕсли;

    ТекстЗапроса =
    "ВЫБРАТЬ ПЕРВЫЕ 500
    |    Ном.Код КАК Код,
    |    Ном.Наименование КАК Наименование,
    |    Ном.Артикул КАК Артикул
    |ИЗ
    |    Справочник.Номенклатура КАК Ном
    |ГДЕ
    |    НЕ Ном.ЭтоГруппа
    |    И НЕ Ном.ПометкаУдаления
    |    И Ном.Код > &ПоследнийКод
    |УПОРЯДОЧИТЬ ПО
    |    Код";
    ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "ПЕРВЫЕ 500",
        "ПЕРВЫЕ " + Формат(Лимит, "ЧГ=0"));

    ЗапросДанных = Новый Запрос(ТекстЗапроса);
    ЗапросДанных.УстановитьПараметр("ПоследнийКод", ПоследнийКод);
    Выборка = ЗапросДанных.Выполнить().Выбрать();

    Массив = Новый Массив;
    Пока Выборка.Следующий() Цикл
        Элемент = Новый Структура;
        Элемент.Вставить("code", СокрЛП(Выборка.Код));
        Элемент.Вставить("name", Выборка.Наименование);
        Элемент.Вставить("sku", Выборка.Артикул);
        Массив.Добавить(Элемент);
    КонецЦикла;

    Запись = Новый ЗаписьJSON;
    Запись.УстановитьСтроку();
    ЗаписатьJSON(Запись, Новый Структура("items", Массив));

    Ответ = Новый HTTPСервисОтвет(200);
    Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    Ответ.УстановитьТелоИзСтроки(Запись.Закрыть());
    Возврат Ответ;

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

Внешняя система вызывает /products?limit=1000, берёт код последнего товара и следующий раз шлёт /products?limit=1000&after=00-00001234. Пустой массив items — сигнал, что всё выгружено.

💡 Не отдавайте наружу ссылки 1С в виде строки. Для сопоставления используйте код, артикул или УникальныйИдентификатор() ссылки — он не меняется при переименовании элемента.

Какой формат поля отдавать

Сопоставление полей
Код номенклатуры→code (строка, без пробелов СокрЛП)
Наименование→name
Артикул→sku
Цена из регистра цен→price (число, точка как разделитель)
Остаток по складу→stock (число)
Уникальный идентификатор ссылки→id (строка GUID)

ЗаписатьJSON сам пишет числа с точкой и экранирует кавычки, поэтому JSON вручную через конкатенацию строк собирать не нужно.

Публикация базы на веб-сервере для выгрузки

HTTP-сервис начинает отвечать только после публикации. Веб-сервер и модуль расширения веб-сервера 1С должны стоять на одной машине, разрядность модуля — как у веб-сервера.

Публикация из конфигуратора

  1. Запустите конфигуратор от имени администратора Windows: публикация пишет в настройки Apache или IIS.
  2. Администрирование → Публикация на веб-сервере.
  3. Укажите имя публикации (оно станет частью URL), веб-сервер и каталог.
  4. На вкладке HTTP-сервисов отметьте Публиковать HTTP-сервисы по умолчанию или конкретно ваш сервис из расширения.
  5. Нажмите Опубликовать, для Apache перезапустите службу.

Перезапуск Apache или пула IIS обрывает все веб-сеансы: пользователей веб-клиента, других интеграций. Делайте это вне рабочего времени или предупредите заранее.

Публикация без конфигуратора: webinst

На сервере без графического интерфейса пригодится утилита webinst из каталога bin платформы:

cd "C:\Program Files\1cv8\8.3.24.1586\bin"
webinst -publish -apache24 -wsdir trade -dir "C:\inetpub\trade" -connstr "Srvr=srv1c;Ref=trade;" -confPath "C:\Apache24\conf\httpd.conf"

Номер платформы в пути подставьте свой. Для IIS вместо -apache24 указывают -iis, параметр -confPath тогда не нужен.

В каталоге публикации появится файл default.vrd. В нём за HTTP-сервисы отвечает строка:

<httpServices publishByDefault="true"/>

Если сервис отдаёт 404, первым делом откройте этот файл и проверьте, что строка есть.

Проверка соединения

Проверяйте не браузером, а curl — так видны код ответа и заголовки:

curl -i -u exchange_site:Пароль "http://srv/trade/hs/api/products?limit=5"

Ответ HTTP/1.1 200 OK и JSON в теле — публикация работает. Для внешних систем в интернете ставьте публикацию за HTTPS: при базовой аутентификации логин и пароль идут в каждом запросе.

COM-соединение: выгрузка в соседнюю базу или скрипт

COM-соединение подходит, когда получатель стоит в той же сети и работает под Windows: другая база 1С, обработка на Python через pywin32, скрипт PowerShell. Веб-сервер тут не нужен.

Сначала зарегистрируйте компоненту той же разрядности, что и вызывающая программа. Команду выполняют в командной строке от имени администратора:

regsvr32 "C:\Program Files\1cv8\8.3.24.1586\bin\comcntr.dll"

Подключение из другой базы 1С:

Коннектор = Новый COMОбъект("V83.COMConnector");
База = Коннектор.Connect("Srvr=""srv1c"";Ref=""trade"";Usr=""exchange_site"";Pwd=""Пароль"";");
Выборка = База.Справочники.Номенклатура.Выбрать();

Для файловой базы строка подключения начинается с File="путь к каталогу базы".

Каждое обращение к объекту через COM — межпроцессный вызов. Цикл по 50 тысячам элементов с чтением реквизитов «через точку» тянется часами. Выполните запрос на стороне базы-источника и забирайте результат одним массивом или строкой JSON.

Ошибка создания объекта V83.COMConnector («класс не зарегистрирован») обычно означает неверную разрядность comcntr.dll или регистрацию от другой версии платформы после обновления.

Ошибки и журнал выгрузки

Отлаживать обмен проще, когда сервис сам пишет, что произошло. Оберните тело обработчика в Попытка … Исключение и фиксируйте ошибку в журнале регистрации:

Исключение
    ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
    ЗаписьЖурналаРегистрации("Выгрузка.Сайт", УровеньЖурналаРегистрации.Ошибка,,, ТекстОшибки);
    Ответ = Новый HTTPСервисОтвет(500);
    Ответ.УстановитьТелоИзСтроки("{""error"":""internal""}");
    Возврат Ответ;
КонецПопытки;

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

Диагностика: выберите симптом

Для регулярного обмена полезен собственный маленький регистр сведений «Журнал выгрузки»: время, адресат, число записей, длительность. Журнал регистрации со временем чистят, а такой регистр остаётся историей для разборов с подрядчиком сайта.

Большие объёмы: как выгружать быстро и не вешать базу

Выгрузка 200 тысяч позиций одним запросом съест память рабочего процесса и упрётся в таймаут веб-сервера. Три приёма решают это почти всегда.

🚀 Порции по ключу. Пример выше уже так работает: ПЕРВЫЕ N + условие Код > &ПоследнийКод + сортировка. В отличие от пропуска «первых K записей», этот способ не замедляется к концу списка.

🔁 Только изменения. Полную выгрузку делают один раз. Дальше заводят план обмена в расширении, включают в состав нужные объекты, и платформа сама регистрирует изменённые элементы. Сервис отдаёт только их, а после подтверждения от получателя удаляет регистрацию методом ПланыОбмена.УдалитьРегистрациюИзменений.

⚡ Один запрос вместо обращений через точку. Цены и остатки соединяйте с номенклатурой в тексте запроса (ЛЕВОЕ СОЕДИНЕНИЕ к срезу последних и остаткам), а не дочитывайте в цикле по каждому товару.

Ещё несколько настроек:

Что настроитьГдеЭффект
Повторное использование сеансовСвойство HTTP-сервиса в конфигуратореНе тратится время на открытие сеанса на каждый запрос
Таймаут на стороне клиентаНастройки внешней системыПорция в 1000–5000 записей должна укладываться в 30–60 секунд
РасписаниеВнешняя система или регламентное заданиеПолные выгрузки — ночью, изменения — каждые 5–15 минут

Если сервис отдаёт файлы или большие JSON, проверьте лимиты размера ответа и таймауты прокси перед Apache: nginx и балансировщики по умолчанию рвут долгие ответы раньше, чем 1С успевает их сформировать.

Частые вопросы

Нужна ли отдельная лицензия 1С для HTTP-сервиса?
Сеанс веб-сервиса или HTTP-сервиса использует клиентскую лицензию, как и обычный пользователь. Если лицензий впритык, обмен может не подключиться в рабочее время — закладывайте одну лицензию под интеграцию.
Можно ли выгружать из 1С:Фреш или облака?
Публиковать свои HTTP-сервисы можно только там, где у вас есть доступ к веб-серверу. В облачных сервисах возможности зависят от провайдера: уточняйте, разрешены ли расширения и OData.
Как подключить OData без программиста?
Опубликуйте базу с флагом стандартного интерфейса OData и задайте состав объектов, доступных через него, специальной обработкой или программно методом УстановитьСоставСтандартногоИнтерфейсаOData. Адрес — /odata/standard.odata/ после имени публикации.
Слетит ли выгрузка после обновления конфигурации?
Расширение переживает обновление, но если в типовой изменили имя реквизита, который читает сервис, расширение может перестать применяться. После каждого обновления проверяйте запросом curl, что сервис отвечает 200.
Чем REST-выгрузка лучше обмена файлами?
Получатель берёт данные сразу, видит код ответа и может повторить запрос. При обмене файлами ошибка часто обнаруживается только тогда, когда на сайте неделю висят старые цены.