Как отследить добавление записей в таблицу SQL 1С, выполненное сторонним приложением

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с клиент-серверными базами данных 1С иногда возникают ситуации, когда сторонние системы записывают данные напрямую в таблицы MS SQL Server, минуя объектную модель 1С. Основная сложность заключается в том, что платформа 1С не знает о существовании этих записей, так как не срабатывают стандартные события конфигуратора, такие как ПередЗаписью или ПриЗаписи. В данной статье мы подробно разберем, как решить эту задачу, рассмотрим технические нюансы хранения GUID и предложим несколько эффективных стратегий мониторинга.

Почему 1С «не видит» прямые изменения в SQL

Прежде чем переходить к решениям, проанализируем ситуацию. Платформа 1С — это не просто надстройка над базой данных, а полноценный сервер приложений с собственной логикой кэширования. Когда сторонняя база данных выполняет команду INSERT INTO непосредственно в таблицу справочника (например, _Reference18X1), сервер приложений 1С об этом не уведомляется. В результате:

  1. Кэш объектов: Если пользователь уже открывал этот список в программе, новая запись может не появиться в интерфейсе немедленно, так как 1С берет данные из локального кэша.
  2. Бизнес-логика: Все проверки, подписки на события и автозаполнение полей, прописанные в конфигураторе, игнорируются.
  3. Целостность: При прямой записи легко нарушить структуру индексов или итогов.

Способ 1. Использование «флага» и регламентного задания

Рассмотрим наиболее надежный и часто используемый метод, который обсуждался на форуме. Суть заключается в том, чтобы создать механизм оповещения 1С о появлении новых данных через специальный маркер.

Для реализации этого метода нам потребуется изменить структуру справочника, добавив в него новый реквизит, например, НоваяЗапись (тип Булево), и обязательно проиндексировать его. Процесс будет выглядеть следующим образом:

  1. Стороннее приложение при выполнении INSERT устанавливает значение этого поля в TRUE (в SQL это будет 1).
  2. В 1С создается регламентное задание, которое запускается с высокой периодичностью (например, каждые 10–30 секунд).
  3. Регламентное задание выбирает все записи, где НоваяЗапись = Истина.
  4. После обработки каждой записи 1С сбрасывает флаг в Ложь.

Пример запроса для регламентного задания в 1С:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	СправочникТест.Ссылка КАК Ссылка
    |ИЗ
    |	Справочник.ТестовыйСправочник КАК СправочникТест
    |ГДЕ
    |	СправочникТест.НоваяЗапись = ИСТИНА";

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

Пока Выборка.Следующий() Цикл
    // Выполняем необходимую логику обработки
    Объект = Выборка.Ссылка.ПолучитьОбъект();
    Объект.НоваяЗапись = Ложь;
    Объект.Записать(); 
КонецЦикла;

Способ 2. Решение проблемы GUID и уникальных идентификаторов

Один из критических моментов при прямой записи в SQL — это генерация поля _IDRRef. Как отмечалось в дискуссии, 1С использует уникальные идентификаторы (UUID), но хранит их в SQL в бинарном виде BINARY(16).

Важное замечание: 1С использует специфический порядок байтов. Если вы просто используете NEWID() в SQL, вы получите «битый» идентификатор, который будет некорректно отображаться в 1С. Разберем по шагам, как правильно генерировать GUID на стороне SQL:

Стандартный GUID в SQL имеет структуру AAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE. Для корректной работы в 1С части этого GUID должны быть переставлены. Обычно это реализуется через сложную конвертацию. Рассмотрим пример функции на T-SQL для создания «правильного» идентификатора:


DECLARE @Guid UNIQUEIDENTIFIER = NEWID();
DECLARE @BinaryGuid BINARY(16);

SET @BinaryGuid = CAST(
    SUBSTRING(CAST(@Guid AS BINARY(16)), 13, 4) +
    SUBSTRING(CAST(@Guid AS BINARY(16)), 11, 2) +
    SUBSTRING(CAST(@Guid AS BINARY(16)), 9, 2) +
    SUBSTRING(CAST(@Guid AS BINARY(16)), 1, 8) 
AS BINARY(16));

-- Теперь @BinaryGuid можно вставлять в поле _IDRRef

Если проигнорировать этот момент, вы рискуете получить дубли или ошибки при попытке обращения к объекту из кода 1С через ПолучитьСсылку(Новый УникальныйИдентификатор(...)).

Способ 3. SQL-триггеры и внешние уведомления

Если регламентное задание «раз в минуту» работает слишком медленно, а бизнес-требования требуют моментальной реакции, проанализируем вариант использования SQL-триггеров.

Хотя напрямую вызвать код 1С из SQL-триггера невозможно, можно использовать механизм SQLCLR или системные хранимые процедуры для отправки HTTP-запроса к 1С. Многие разработчики жалуются, что «не получается авторизоваться из SQL». Это решается использованием заголовка Authorization.

Посмотрим на пример логики триггера, который дергает HTTP-сервис 1С:

  1. На таблицу _Reference18X1 вешается триггер AFTER INSERT.
  2. Внутри триггера создается объект MSXML2.ServerXMLHTTP.
  3. Выполняется POST запрос к опубликованному HTTP-сервису 1С с передачей ID новой записи.

Пример (требует включения Ole Automation Procedures):


CREATE TRIGGER [dbo].[tr_OnInsert_1C_Record]
ON [dbo].[_Reference18X1]
AFTER INSERT
AS
BEGIN
    DECLARE @Object INT;
    DECLARE @Status INT;
    EXEC sp_OACreate 'MSXML2.ServerXMLHTTP', @Object OUT;
    EXEC sp_OAMethod @Object, 'open', NULL, 'POST', 'http://yourserver/base/hs/integration/notify', 'false';
    EXEC sp_OAMethod @Object, 'setRequestHeader', NULL, 'Authorization', 'Basic <Base64String>';
    EXEC sp_OAMethod @Object, 'send', NULL, '{"status": "new"}';
    EXEC sp_OADestroy @Object;
END

Внимание: Использование триггеров на таблицах 1С является «грязным» хаком. При обновлении конфигурации таблицы могут пересоздаваться, и триггер будет удален. Всегда делайте резервные копии скриптов создания таких триггеров.

Способ 4. Использование SQL Server Change Data Capture (CDC)

Если вы не хотите менять структуру таблиц 1С (добавлять флаги) и не хотите рисковать с триггерами, рекомендуем рассмотреть технологию CDC. Это встроенный механизм SQL Server, который фиксирует все изменения в выбранных таблицах и записывает их в отдельные системные таблицы.

Разберем преимущества этого подхода:

В этом случае 1С раз в несколько секунд может опрашивать таблицу изменений CDC, что гораздо быстрее, чем делать SELECT по всей таблице справочника.

Риски нарушения лицензионного соглашения

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

Рекомендация: Если есть возможность, все же убедите сторонних разработчиков использовать Web-сервисы или HTTP-сервисы. Проблема авторизации из T-SQL, упомянутая в теме, обычно связана с неправильной кодировкой учетных данных в формате Base64 или настройками брандмауэра. Использование стандартных API 1С гарантирует, что все GUID будут созданы правильно, а кэш сервера приложений обновится мгновенно.

Выводы и итоги

Подведем итоги нашего исследования:

  1. Самый простой и безопасный способ отловить событие — использование индексированного булева поля-флага и регламентного задания.
  2. При генерации _IDRRef на стороне SQL обязательно учитывайте порядок байтов, специфичный для 1С.
  3. Для мгновенной реакции можно использовать SQL-триггеры, но помните о риске их удаления при реструктуризации базы 1С.
  4. Всегда проверяйте поле _Version. 1С использует его для контроля версий объектов. Если вы оставите его пустым или запишете некорректное значение, пользователь может столкнуться с ошибкой «Данные изменены или удалены другим пользователем».
← На главную