При интеграции сторонних аналитических систем или построении внешней отчетности разработчики периодически сталкиваются с задачей прямого чтения данных из таблиц СУБД MS SQL Server в обход серверного контекста 1С. В типовой конфигурации 1C:Бухгалтерия 3.0 данные бухгалтерского учета хранятся в регистре бухгалтерии. Попытка получить актуальные количественные и суммовые остатки простым запросом к одной физической таблице обычно приводит к тупику: в основной таблице движений нет готовых итогов, в таблицах субконто отсутствуют ресурсы, а номенклатура представлена в виде бинарных ссылок.
Разберем внутреннюю архитектуру хранения регистра бухгалтерии в реляционной базе данных, выясним алгоритм расчета срезов итогов и проанализируем доступные пути решения этой задачи.
Платформа 1С:Предприятие при работе с регистром бухгалтерии создает не одну общую таблицу, а целый набор связанных физических таблиц в базе данных:
_AccRg...): содержит первичные строки проводок, даты, ссылки на документы-регистраторы, номера записей в наборе, счета дебета и кредита, а также общие суммовые ресурсы._AccRgED...): в них выносятся значения аналитики (субконто дебета и кредита), если они имеют составной тип или не помещаются в основную таблицу. Значения хранятся в виде типов данных и бинарных ссылок binary(16)._AccRgAT...): содержат агрегированные остатки и обороты в разрезе счетов и общих измерений регистра без детализации по субконто._AccRgOpt): хранит служебные отметки о дате, по которую рассчитаны итоги, и флаги включения разделения итогов.Количественный учет включается как дополнительный признак учета на счете. Если для счета количественный учет активен, платформа заполняет соответствующие колонки ресурсов количества в таблицах итогов и движений. Если учет отключен, соответствующие поля остаются пустыми или равными нулю.
Рассмотрим, как 1С формирует виртуальную таблицу Остатки на определенную дату и время. Платформа не пересчитывает все проводки от начала ведения учета и не хранит остаток на каждую отдельную секунду:
Составить прямой SQL-запрос вручную с учетом всех соединений и группировок таблиц итогов крайне трудоемко. Чтобы воспроизвести поведение платформы, применим следующий подход:
SQL:BatchCompleted, RPC:Completed).РегистрыБухгалтерии.Хозрасчетный.Остатки())._AccRgAT... и _AccRgED... с добором дельты из таблицы движений.Для сопоставления физических имен таблиц SQL с объектами метаданных в среде 1С выполним вызов встроенной функции:
СтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных();
Эта функция вернет таблицу со списком соответствий всех объектов конфигурации и их полей именам в СУБД.
Прежде чем внедрять чтение остатков напрямую из MS SQL, проанализируем технические ограничения и риски:
_IDRRef представлена в формате binary(16). Порядок байтов в SQL не совпадает со строковым представлением GUID в стандарте 1С, что требует специального алгоритма перестановки байтов при соединении со справочниками._AccRgOpt вернет недостоверные данные.WITH (NOLOCK) или без включенного версионирования строк (READ_COMMITTED_SNAPSHOT) может вызывать взаимные блокировки с работающими пользователями.Чтобы избежать описанных проблем и получать гарантированно корректные остатки, рекомендуется использовать стандартные механизмы платформы:
РегистрыБухгалтерии.Хозрасчетный.Остатки на языке 1С и отдает результат внешней системе в формате JSON. Это гарантирует актуальность среза итогов и корректную работу с субконто.V83.COMConnector для программного выполнения встроенных запросов и передачи выборки во внешнее приложение.