Интеграция Power BI и 1С — это способ превратить таблицы из вашей учётной базы в интерактивный визуальный отчёт: с отборами по годам, менеджерам, городам и номенклатуре, который открывается даже с телефона. В этой статье я разберу, как подключить 1С к Power BI тремя разными способами — напрямую через OData, через выгрузку во внешний MS SQL и через облачный Azure SQL — покажу реальный код обработки и модуля 1С, скрипты создания таблиц и M-запросы Power BI, а в конце объясню, какой способ выбрать под вашу задачу.
Что вы узнаете
- Чем интеграция 1С с Power BI полезна руководителю и аналитику и что в итоге получается на экране
- Как опубликовать стандартный интерфейс OData из 1С и вытащить данные прямо в Power BI
- Как выгружать данные из 1С в MS SQL через внешние источники данных — объектной моделью и хранимой процедурой
- Как поднять облачный Azure SQL и залить туда документы вместе с табличной частью
- Как настроить связи таблиц и собрать интерактивный отчёт «Анализ продаж»
- Какой из трёх способов выбрать под лицензии, безопасность и облако
Зачем связывать 1С и Power BI
Привет, на связи Илья Низамов. Ситуация, знакомая почти всем, кто ведёт учёт в 1С: у руководителя есть цифры, но они лежат в отчётах-таблицах. Чтобы понять, какой менеджер работает хорошо, какое подразделение убыточно и в каком городе проседают продажи, нужно сидеть и глазами разбирать колонки чисел. Таблицы — это хорошо и точно, но плохо считывается картина в целом.
Power BI решает ровно эту боль: он берёт данные из 1С и показывает их визуально — круговые диаграммы по менеджерам, продажи на карте городов, срезы по годам и месяцам, отбор по конкретному контрагенту или номенклатуре. Всё интерактивно: двигаешь срез — графики пересчитываются. И это работает не только на десктопе, но и в мобильном приложении Power BI: поставил руководителю на телефон, опубликовал отчёт — он заходит и смотрит онлайн-цифры без всякого мобильного клиента 1С.
Ниже — тот самый отчёт в миниатюре. Подвигайте срезы по году и менеджеру: продажи по городам пересчитаются вживую, ровно как в настоящем Power BI поверх данных 1С.
Сразу видно, что Москва тянет основной объём, а одно из подразделений в европейском городе — заведомо убыточное. Такой отчёт руководителю читать в разы приятнее, чем простыню в таблице.
Три способа интеграции: что выбрать
Данные в Power BI из 1С можно получить по-разному, и выбор способа зависит от ваших ограничений. Я в курсе показываю три, и они закрывают почти все реальные ситуации:
- OData напрямую. Публикуем стандартный интерфейс OData на веб-сервере и Power BI читает базу 1С по HTTP. Ноль дополнительного кода, но каждый отчёт держит открытым сеанс 1С и требует опубликованной базы.
- Выгрузка в локальный MS SQL. Через внешние источники данных 1С пишет консолидированные данные в отдельную базу MS SQL, а Power BI берёт их оттуда. Способ экономит лицензии 1С и снимает нагрузку с рабочей базы.
- Облачный Azure SQL. Тот же механизм выгрузки, но приёмник — облачная база Azure SQL. Отчёт доступен откуда угодно, свой сервер поднимать не нужно, базу 1С наружу публиковать не надо.
Чтобы не гадать, отметьте ограничения вашей задачи — виджет подскажет, с какого способа начать.
Дальше пройдём по всем трём по порядку — с публикацией, кодом и сборкой отчёта.
Готовим рабочее место и демобазу
Для примеров я собрал демобазу на основе типовых справочников: организации, контрагенты, договоры, подразделения, номенклатура, менеджеры и документ «Реализация товаров и услуг». Продажи мы будем строить именно по этому документу — у него есть шапка с реквизитами-срезами и табличная часть с номенклатурой, количеством и ценами.
Чтобы не заполнять базу вручную, в демобазе есть общая команда «Сформировать демоданные» и общий модуль, который наполняет базу случайными документами. Логика простая: собираем в массивы ссылки на заполненные справочники, а потом в цикле создаём сто документов со случайными комбинациями и разнесённой по времени датой — чтобы потом было что фильтровать по месяцам и годам.
Процедура СформироватьДемоДанные() Экспорт
СписокОрганизаций = ПолучитьСписокОрганизаций();
КоличествоОрганизаций = СписокОрганизаций.Количество() - 1;
СписокКонтрагентов = ПолучитьСписокКонтрагентов();
КоличествоКонтрагентов = СписокКонтрагентов.Количество() - 1;
СписокМенеджеров = ПолучитьСписокМенеджеров();
КоличествоМенеджеров = СписокМенеджеров.Количество() - 1;
СписокНоменклатуры = ПолучитьСписокНоменклатуры();
КоличествоНоменклатуры = СписокНоменклатуры.Количество() - 1;
НачальнаяДатаДокументов = НачалоМесяца(ТекущаяДата());
Для Счетчик = 1 По 100 Цикл
ДанныеЗаполнения = Новый Структура;
ДанныеЗаполнения.Вставить("Организация", ПолучитьСлучайнуюОрганизация(СписокОрганизаций, КоличествоОрганизаций));
ДанныеЗаполнения.Вставить("Контрагент", ПолучитьСлучайногоКонтрагента(СписокКонтрагентов, КоличествоКонтрагентов));
ДанныеЗаполнения.Вставить("Менеджер", ПолучитьСлучайногоМенеджера(СписокМенеджеров, КоличествоМенеджеров));
ДанныеЗаполнения.Вставить("Товары", СформироватьТаблицуТовары(СписокНоменклатуры, КоличествоНоменклатуры));
ДанныеЗаполнения.Вставить("СуммаДокумента", ДанныеЗаполнения.Товары.Итог("Сумма"));
НовДок = Документы.РеализацияТоваровИУслуг.СоздатьДокумент();
НовДок.Дата = НачальнаяДатаДокументов;
НовДок.УстановитьНовыйНомер();
ЗаполнитьЗначенияСвойств(НовДок, ДанныеЗаполнения);
Для Каждого Строка Из ДанныеЗаполнения.Товары Цикл
НовСтр = НовДок.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НовСтр, Строка);
КонецЦикла;
НовДок.Записать();
НачальнаяДатаДокументов = НачальнаяДатаДокументов + 3600 * 24 * 14;
КонецЦикла;
КонецПроцедуры
Обратите внимание на пару подходов, которые я использую здесь. Во-первых, ЗаполнитьЗначенияСвойств — он копирует одноимённые поля из структуры в объект и из строки таблицы в строку документа, так что не нужно вручную присваивать каждый реквизит. Во-вторых, дата каждого следующего документа сдвигается на две недели вперёд — так сто документов растягиваются на пару лет, и потом в отчёте есть что резать по годам и месяцам.
Отдельная деталь — свой генератор случайного числа. В серверном контексте 1С нет привычного Randomize, поэтому я получаю случайность из GUID: беру Новый УникальныйИдентификатор, оставляю только цифры и перевожу шестнадцатеричную строку в дробное число от 0 до 1, а затем масштабирую в нужный диапазон. Приём неочевидный, но надёжный и не требует внешних зависимостей.
Способ 1. OData: Power BI читает базу 1С напрямую
Самый быстрый способ — стандартный интерфейс OData. Начиная с версии 8.3.5 платформа умеет отдавать данные по протоколу OData без единой строчки кода: нужно только опубликовать базу на веб-сервере и указать, какие объекты выставить наружу.
В демобазе для этого есть специальная обработка «Редактирование состава стандартного интерфейса OData»: в ней один раз отмечаем справочники и документы, которые хотим отдавать, и сохраняем. Если публикуете регистры — там же можно добавить и их. Дальше идём в «Администрирование → Публикация на веб-сервере» и публикуем интерфейс OData на локальном Apache (если не умеете настраивать веб-сервер — у меня есть отдельный урок по публикации базы 1С на Apache, ссылку оставлю в перелинковке).
После публикации по адресу вида http://localhost/powerbi/odata/standard.odata/ открывается XML со списком всех выставленных сущностей. Каждому справочнику и документу соответствует своя лента. Именно эти адреса мы и будем добавлять в Power BI.
Чтобы не собирать адрес ленты руками и не ошибиться в префиксе (Catalog_ для справочника, Document_ для документа, а табличная часть документа — отдельная лента с суффиксом), я сделал конструктор. Заполните поля объекта — получите готовый URL и M-запрос для Power BI.
Дальше в Power BI жмём «Получить данные → Другое → Канал OData», вставляем адрес и подключаемся. Под капотом Power BI формирует запрос на языке M. Вот как выглядит реальный запрос к справочнику организаций из моего отчёта:
shared Организации = let
Источник = OData.Feed("http://localhost/powerbi/odata/standard.odata/Catalog_Организации", null, [Implementation="2.0"])
in
Источник;
Одна тонкость: поля в OData приходят с типовыми английскими именами. Наименование справочника лежит в поле Description. Чтобы в отчёте оно читалось по-человечески, я сразу переименовываю колонку — тоже средствами M:
shared Контрагенты = let
Источник = OData.Feed("http://localhost/powerbi/odata/standard.odata/Catalog_Контрагенты", null, [Implementation="2.0"]),
Переименовано = Table.RenameColumns(Источник,{{"Description", "Контрагент"}})
in
Переименовано;
Так добавляем все нужные ленты: организации, контрагенты, подразделения, номенклатуру, договоры, менеджеров и сам документ реализации. Важный момент — документ реализации состоит из двух лент: шапка (Document_РеализацияТоваровУслуг) и табличная часть (Document_РеализацияТоваровУслуг_Товары). Их Power BI тянет отдельно, и связывать их придётся вручную.
После загрузки переходим в «Модель данных». Здесь для программиста 1С кроется главный порог входа: в 1С связи между справочниками и документами платформа прячет от нас, а в Power BI (как и в любой реляционной СУБД) их надо настроить руками. Связи идут через ссылки: у каждой ленты есть поле Ref_Key — это, по сути, наша ссылка из 1С. Берём ссылку организации и связываем её с полем Организация_Key в документе реализации, тип связи — один ко многим (одна организация встречается во многих документах). Так же связываем контрагентов, менеджеров, номенклатуру, а табличную часть — с шапкой документа через Ref_Key.
Если вы никогда не работали с реляционными базами, стоит почитать теорию про связи «один к одному», «один ко многим» и «многие ко многим» — без этого модель данных будет казаться магией. На деле 1С делает ровно то же самое, просто автоматически.
Собираем отчёт «Анализ продаж»
Когда таблицы связаны, начинается самое приятное — визуализация. Логика везде одинаковая: кидаем на холст визуальный элемент, в него — измерение (менеджер, город, номенклатура) и меру (сумму документа). Пара приёмов, которые делают отчёт живым:
- Круговая диаграмма по менеджерам. Измерение — наименование менеджера, значение — сумма документа. В настройках диаграммы включаем метки, чтобы прямо на секторах были видны и сумма, и процент от общего дохода. Сразу понятно, кто из менеджеров тянет выручку, а кто отстаёт.
- Срезы по годам и месяцам. Power BI автоматически распознаёт поле даты документа и позволяет сделать срез. Ставим срез по годам сверху, по месяцам — снизу, включаем в настройках среза режим «между / список», чтобы можно было выбирать диапазон или отдельные месяцы.
- Продажи на карте. Берём поле города (у меня это сегмент), тип визуализации — карта. В «Размер» кладём сумму — и на карте пузырями видно, где продаж больше. Москва — крупный пузырь, убыточный европейский город — крошечный.
- Формат чисел. Мелочь, но важная: у суммы документа по умолчанию стоит общий формат. Включаем «десятичное число» и отображение в тысячах — отчёт сразу выглядит опрятнее.
Отдельно стоит опубликовать отчёт в облачный сервис Power BI, чтобы он открывался с телефона. При первой публикации сервис попросит зарегистрироваться — здесь нюанс: для России регистрация сейчас закрыта, при регистрации нужно указать другую страну. После публикации не забудьте собрать макет для мобильного устройства: в Power BI есть отдельный режим «Макет телефона», куда перетаскиваются те же визуализации, но компонуются под вертикальный экран.
Полный разбор с публикацией, мобильным макетом и всеми настройками визуализаций — в видео ниже.
Способ 2. Выгрузка в MS SQL через внешние источники данных
OData хорош скоростью старта, но у него два минуса: базу 1С надо публиковать в сеть, и каждый отчёт занимает сеанс 1С. Не всем это подходит — кто-то не может опубликовать базу наружу, кому-то жалко лицензии. Решение — выгружать данные из 1С в отдельную базу MS SQL, а Power BI цеплять уже к ней. Плюс мы получаем консолидированное хранилище, в котором можно копить историю.
Работать с внешней СУБД из 1С позволяет механизм внешних источников данных. Сначала на стороне SQL Server создаём базу и таблицы. Я предпочитаю делать это скриптом — так нагляднее и вам будет проще повторить:
CREATE DATABASE powerbi;
GO
USE powerbi;
GO
-- Сводная таблица продаж (шапка документа)
CREATE TABLE dbo.Sales
(_IDRRef nchar(36) PRIMARY KEY NOT NULL,
_Date_Time datetime2 NOT NULL,
Organization nvarchar(150) NULL,
Unit nvarchar(150) NULL,
Partner nvarchar(150) NULL,
Contract nvarchar(150) NULL,
Manager nvarchar(150) NULL,
PriceAll numeric(15,2) NULL)
GO
-- Табличная часть документа
CREATE TABLE dbo.SalesRow
(_IDRRef nchar(36) NOT NULL,
Nomenclature nvarchar(150) NULL,
Number numeric(10) NULL,
Price numeric(15,2) NULL,
Amount numeric(15,2) NULL)
GO
Ключевой момент — поле _IDRRef типа nchar(36). Это уникальный идентификатор документа из 1С, приведённый к строке из 36 символов. По нему мы связываем запись в SQL с документом в 1С: если документ перезаписали — в SQL находим ту же строку по _IDRRef и обновляем, а не плодим дубли.
Параметры подключения к SQL я храню в константах базы (сервер, логин, пароль, имя базы, строка соединения) и заполняю их через форму констант. Само подключение к внешнему источнику делаю программно в общем модуле PowerBIСервер:
Функция ПодключитьсяКMSSQL() Экспорт
ПараметрыСоединения = ВнешниеИсточникиДанных.SQLEXPRESS.ПолучитьОбщиеПараметрыСоединения();
ПараметрыСоединения.ИмяПользователя = Константы.Логин.Получить();
ПараметрыСоединения.Пароль = Константы.Пароль.Получить();
ПараметрыСоединения.СтрокаСоединения = Константы.СтрокаСоединения.Получить();
ПараметрыСоединения.СУБД = "MSSQLServer";
Попытка
ВнешниеИсточникиДанных.SQLEXPRESS.УстановитьОбщиеПараметрыСоединения(ПараметрыСоединения);
ВнешниеИсточникиДанных.SQLEXPRESS.УстановитьСоединение();
Исключение
ОбщегоНазначения.СообщениеПользователю("Ошибка подключения к MS SQL" + Символы.ПС + ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
Здесь важно обязательно указать СУБД = "MSSQLServer" в параметрах соединения. Если этого не сделать, вы сможете только читать данные из внешнего источника, а записывать через объектную модель — нет.
Дальше — сама выгрузка. Я сделал два варианта записи, и это осознанный подход: показать разницу между объектной моделью и хранимой процедурой.
Вариант первый — объектная модель. Для программиста 1С он самый привычный: работа с внешней таблицей ничем не отличается от работы со справочником или документом. Пытаемся получить ссылку по идентификатору; если запись есть — берём объект и обновляем, если нет — создаём новый:
Функция ВыгрузитьДокументВMSSQL(СсылкаНаДокумент) Экспорт
УникальныйИдентификатор = Строка(СсылкаНаДокумент.УникальныйИдентификатор());
СсылкаНаОбъект = ВнешниеИсточникиДанных.SQLEXPRESS.Таблицы.dbo_Sales.ПолучитьСсылку(УникальныйИдентификатор);
Если ЗначениеЗаполнено(СсылкаНаОбъект._IDRRef) Тогда
ДокументSQL = СсылкаНаОбъект.ПолучитьОбъект();
Иначе
ДокументSQL = ВнешниеИсточникиДанных.SQLEXPRESS.Таблицы.dbo_Sales.СоздатьОбъект();
ДокументSQL._IDRRef = УникальныйИдентификатор;
КонецЕсли;
ДокументSQL._Date_Time = СсылкаНаДокумент.Дата;
ДокументSQL.Organization = Строка(СсылкаНаДокумент.Организация);
ДокументSQL.Partner = Строка(СсылкаНаДокумент.Контрагент);
ДокументSQL.Manager = Строка(СсылкаНаДокумент.Менеджер);
ДокументSQL.Unit = Строка(СсылкаНаДокумент.Подразделение);
ДокументSQL.PriceAll = СсылкаНаДокумент.СуммаДокумента;
ДокументSQL.Записать();
КонецФункции
Вариант второй — хранимая процедура. Здесь вся логика «найти и обновить или добавить» уезжает на сторону SQL Server, а 1С только передаёт параметры. Со стороны 1С код становится совсем коротким:
Функция ВыгрузитьДокументВMSSQL_ХранимаяПроцедура(СсылкаНаДокумент) Экспорт
УникальныйИдентификатор = Строка(СсылкаНаДокумент.УникальныйИдентификатор());
Попытка
ВнешниеИсточникиДанных.SQLEXPRESS.dbo_AddDoc(
УникальныйИдентификатор,
СсылкаНаДокумент.Дата,
Строка(СсылкаНаДокумент.Организация),
Строка(СсылкаНаДокумент.Подразделение),
Строка(СсылкаНаДокумент.Контрагент),
Строка(СсылкаНаДокумент.Договор),
Строка(СсылкаНаДокумент.Менеджер),
СсылкаНаДокумент.СуммаДокумента);
Исключение
ОбщегоНазначения.СообщениеПользователю(ОписаниеОшибки());
КонецПопытки;
КонецФункции
А вот сама хранимая процедура на T-SQL. Логика «обнови, если есть, иначе вставь» — классический upsert:
CREATE PROCEDURE dbo.AddDoc
(
@_IDRRef nchar(36),
@_Date_Time datetime2,
@Organization nvarchar(150),
@Unit nvarchar(150),
@Partner nvarchar(150),
@Contract nvarchar(150),
@Manager nvarchar(150),
@PriceAll numeric(15,2)
)
AS
BEGIN
IF(EXISTS (SELECT Sales._IDRRef FROM Sales WHERE _IDRRef = @_IDRRef))
BEGIN
UPDATE Sales
SET _Date_Time = @_Date_Time, Organization = @Organization, Unit = @Unit,
Partner = @Partner, Contract = @Contract, Manager = @Manager, PriceAll = @PriceAll
WHERE _IDRRef = @_IDRRef
END
ELSE
BEGIN
INSERT INTO Sales(_IDRRef, _Date_Time, Organization, Unit, Partner, Contract, Manager, PriceAll)
VALUES (@_IDRRef, @_Date_Time, @Organization, @Unit, @Partner, @Contract, @Manager, @PriceAll)
END
END
GO
Какой вариант лучше? Объектная модель нагляднее и проще в отладке, хранимая процедура — быстрее на больших объёмах и переносит логику на сервер БД. В учебной базе разница незаметна, на проде — выбирайте по нагрузке.
Массовую выгрузку я вешаю на общую команду, которая обходит все документы запросом и по каждому дёргает выгрузку. Именно такую команду потом можно поставить на регламентное задание — и данные в SQL, а значит и в Power BI, будут обновляться по расписанию сами. Это и есть главный смысл способа: одно регламентное задание вместо постоянно открытого сеанса 1С.
Процедура ВыгрузитьДокументыВMSSQL() Экспорт
Если НЕ ПараметрыПодключенияЗаполнены() Тогда
Возврат;
КонецЕсли;
Если ПодключитьсяКMSSQL() = Ложь Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровИУслуг.Ссылка КАК Ссылка
|ИЗ
| Документ.РеализацияТоваровИУслуг КАК РеализацияТоваровИУслуг";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ВыгрузитьДокументВMSSQL(Выборка.Ссылка);
КонецЦикла;
КонецПроцедуры
В Power BI подключение к своей базе SQL даже проще, чем к OData: «Получить данные → База данных SQL Server», указываем сервер и базу, выбираем таблицу Sales — и данные уже готовы к визуализации, без ручной настройки связей (у сводной таблицы они не нужны).
Способ 3. Облачный Azure SQL
Третий способ — та же выгрузка через внешние источники, но приёмник вынесен в облако Microsoft Azure. Плюсы: не нужен свой сервер, отчёт доступен откуда угодно, а базу 1С не приходится публиковать наружу. При регистрации Azure даёт бесплатный лимит на пробный период — этого достаточно, чтобы всё попробовать.
Порядок такой: в консоли Azure создаём SQL-сервер (задаём короткое имя, логин и обязательно сложный пароль), затем базу данных. После создания важно не забыть про два шага, на которых обычно спотыкаются:
- Файрвол. По умолчанию Azure не пускает никого. Нужно в настройках сервера добавить свой IP-адрес клиента — иначе даже через Management Studio не подключиться.
- Драйвер ODBC. Для подключения из 1С через внешний источник нужен ODBC Driver для SQL Server. Скачиваем актуальную версию (у меня 17-я) — и внимание: в строке подключения Azure по умолчанию подставляет версию 13, её нужно вручную исправить на установленную.
Таблицы создаём тем же скриптом, что и для локального MS SQL. А вот выгрузка табличной части здесь отличается — и это самый интересный код во всём курсе. Дело в том, что в табличной части документа одна и та же номенклатура может встречаться в нескольких строках, а нам в аналитике нужны сгруппированные данные. Поэтому перед записью я группирую строки запросом, а потом переписываю набор записей:
// Записываем табличную часть в Azure SQL: сначала группируем, потом перезаписываем набор
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровИУслугТовары.Номенклатура КАК Номенклатура,
| СУММА(РеализацияТоваровИУслугТовары.Количество) КАК Количество,
| МАКСИМУМ(РеализацияТоваровИУслугТовары.Цена) КАК Цена,
| СУММА(РеализацияТоваровИУслугТовары.Сумма) КАК Сумма
|ИЗ
| Документ.РеализацияТоваровИУслуг.Товары КАК РеализацияТоваровИУслугТовары
|ГДЕ
| РеализацияТоваровИУслугТовары.Ссылка = &Ссылка
|СГРУППИРОВАТЬ ПО
| РеализацияТоваровИУслугТовары.Номенклатура,
| РеализацияТоваровИУслугТовары.Ссылка";
Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
РезультатЗапроса = Запрос.Выполнить();
// Чистим старые строки этого документа: отбор по идентификатору + запись пустого набора
НаборЗаписей = ВнешниеИсточникиДанных.SQLAZURE.Таблицы.dbo_SalesRow.СоздатьНаборЗаписей();
НаборЗаписей.Отбор._IDRRef.Установить(УникальныйИдентификатор);
НаборЗаписей.Записать();
// Пишем сгруппированные строки менеджером записи
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
НоваяЗапись = ВнешниеИсточникиДанных.SQLAZURE.Таблицы.dbo_SalesRow.СоздатьМенеджерЗаписи();
НоваяЗапись._IDRRef = УникальныйИдентификатор;
НоваяЗапись.Nomenclature = Строка(Выборка.Номенклатура);
НоваяЗапись.Number = Выборка.Количество;
НоваяЗапись.Price = Выборка.Цена;
НоваяЗапись.Amount = Выборка.Сумма;
НоваяЗапись.Записать();
КонецЦикла;
Здесь табличная часть работает как регистр сведений: у неё есть измерения (_IDRRef и номенклатура), по которым мы сначала очищаем старые записи документа, а потом добавляем новые. Честно скажу: запрос выполняется для каждого документа в цикле, и это не самый оптимальный подход — на большом объёме я бы группировал сразу все документы одним запросом. Но для понимания учебной задачи так нагляднее, и это осознанный компромисс.
Подключение Azure к Power BI: «Получить данные → в поиске Azure → База данных SQL Azure», указываем имя облачного сервера и базу, вводим учётные данные. Тут приятный бонус — Power BI при загрузке сам определяет связь «один ко многим» между шапкой и табличной частью, так что модель почти не приходится настраивать вручную.
Так какой способ выбрать
Если свести три способа в одну картину:
- OData — когда нужен результат сегодня и нет своего SQL-сервера. Минус: сеанс 1С на каждый отчёт и публикация базы в сеть.
- Локальный MS SQL — когда жалко лицензии и мощность рабочей базы, нужно копить историю и считать на стороне БД. Плюс регламентное задание вместо онлайна.
- Azure SQL — когда отчёт нужен из любой точки без своего сервера и без публикации базы 1С наружу.
На практике эти способы не конкурируют, а дополняют друг друга: начать можно с OData, чтобы быстро показать руководителю ценность, а под нагрузку и историю — перейти на выгрузку в SQL. Механизм внешних источников данных при этом один и тот же, меняется только приёмник.
Если хотите системно разобраться в интеграции 1С с внешними системами — не только с Power BI, но и с SQL, веб-сервисами и сайтами — это большой отдельный курс. А ниже расскажу, куда идти дальше тем, кто уже наигрался с отчётами.
Похожие статьи
- ИИ-агент для 1С на LangGraph: диалог с данными базы
- 1С и JavaScript/Node.js: интеграция через поле HTML и веб-сервисы
- 1С и Kafka: REST-сервис и интеграция через события
- Сервер взаимодействия 1С в Docker: установка и настройка
От отчётов к ИИ-агенту над данными 1С
Power BI отвечает на вопрос «что произошло»: показывает срезы, диаграммы, динамику. Но следующий логичный шаг для аналитика — не смотреть на готовые графики, а спрашивать данные на естественном языке: «покажи топ-5 убыточных подразделений за прошлый квартал» или «какие контрагенты снизили закупки». Это уже территория ИИ-агентов над данными 1С.
Технически это тот же путь, что мы прошли выше: агент получает доступ к данным 1С (через тот же OData или выгрузку в SQL), а поверх него работает языковая модель, которая переводит вопрос человека в запрос к данным и формулирует ответ. Именно этому — как построить ИИ-агента, который работает с вашей базой 1С через LangChain, RAG и MCP-серверы — посвящён мой флагманский курс «ИИ-агент для 1С: LangChain, RAG и MCP-серверы». Если вы уже умеете вытаскивать данные из 1С для аналитики, это ваш следующий уровень: превратить статичные отчёты в диалог с данными.
Все демобазы, скрипты и отчёты из этой статьи можно скачать в блоге, а если что-то не заработает — задавайте вопросы, разберём.