Работа с внешними источниками данных (ВИД) в 1С:Предприятии — это мощный инструмент интеграции, позволяющий обращаться к сторонним базам данных практически так же просто, как к внутренним таблицам конфигурации. Однако стандартное подключение таблиц не всегда решает бизнес-задачи, особенно когда логика выборки данных скрыта внутри хранимых процедур на стороне СУБД. В данной статье мы подробно разберем, как настроить получение данных из хранимой процедуры, возвращающей таблицу, используя механизм таблиц-выражений.
Для начала проанализируем, что представляет собой таблица вида «Выражение» (Expression). В отличие от обычных таблиц ВИД, которые напрямую маппятся на физические таблицы или представления (view) в сторонней базе, таблица-выражение позволяет нам самим определить SQL-запрос, который будет выполнен для получения данных. Платформа 1С воспринимает текст, написанный в поле «Выражение в источнике данных», как подзапрос. При выполнении запроса в 1С итоговая SQL-конструкция будет выглядеть примерно так: SELECT ... FROM (Текст_Вашего_Выражения) AS Subquery.
Рассмотрим по шагам, как правильно настроить этот механизм в конфигураторе и коде 1С.
Прежде чем приступать к созданию таблицы, необходимо зафиксировать структуру данных. Разберем последовательность действий:
ВнешниеИсточникиДанных и открываем нужный источник.Функции можно импортировать описание хранимой процедуры из внешней базы. Это поможет платформе понять, какие параметры принимает процедура.Имя_Процедуры(&Параметр1, &Параметр2).Важно понимать, что на уровне СУБД (например, MS SQL Server или PostgreSQL) хранимые процедуры и функции работают по-разному. Если ваша задача — получить таблицу, то наиболее стабильным вариантом будет использование Table-Valued Functions (TVF). Если же вы ограничены использованием именно Stored Procedure, нам придется прибегнуть к специфическим конструкциям SQL.
Теперь создадим саму таблицу, которая будет отображать результат выполнения процедуры:
Таблицы нашего внешнего источника добавим новую таблицу.Проанализируем синтаксис для разных СУБД. Если мы работаем с PostgreSQL, вызов функции, возвращающей таблицу, выглядит максимально просто:
get_report_data(&ДатаНачала, &ДатаОкончания)
Для MS SQL Server ситуация сложнее, так как стандартный вызов EXEC нельзя вставить в подзапрос SELECT FROM (...). В этом случае мы рекомендуем либо переделать процедуру в функцию (TVF), либо использовать конструкцию OPENQUERY. Рассмотрим пример с функцией:
dbo.fn_GetSalesByPeriod(&StartDate, &EndDate)
Выясним критически важный момент: 1С не умеет динамически определять состав колонок, возвращаемых выражением. Нам необходимо вручную описать все поля в ветке Поля созданной таблицы ВИД.
Важные требования к полям:
numeric(15,2), в 1С поле должно иметь тип Число(15, 2). Если СУБД возвращает nvarchar(max), в 1С указываем Строка (неограниченная или нужной длины).ROW_NUMBER() OVER(ORDER BY ...). Это поле нужно пометить как «Поле ключа» в настройках 1С.Одной из главных сложностей является передача параметров «на лету». Мы не можем просто менять текст выражения в конфигураторе во время работы пользователя. Для этого используется механизм параметров запроса.
Разберем, как это работает. В поле «Выражение в источнике данных» мы указали параметры через амперсанд (например, &StartDate). Теперь посмотрим, как обратиться к этой таблице из встроенного языка 1С:
// Создаем новый запрос к внешнему источнику
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВнешняяТаблица.НоменклатураНаименование КАК Наименование,
| ВнешняяТаблица.КоличествоОстаток КАК Остаток
|ИЗ
| ВнешнийИсточникДанных.МояВнешняяБаза.Таблица.ПродажиПоПроцедуре КАК ВнешняяТаблица
|ГДЕ
| ВнешняяТаблица.StartDate = &ДатаНач
| И ВнешняяТаблица.EndDate = &ДатаКон";
// Устанавливаем значения параметров
Запрос.УстановитьПараметр("ДатаНач", Объект.ДатаНачала);
Запрос.УстановитьПараметр("ДатаКон", Объект.ДатаОкончания);
// Выполняем запрос и получаем результат
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Обработка данных
Сообщить("Товар: " + Выборка.Наименование + " Остаток: " + Выборка.Остаток);
КонецЦикла;
Обратите внимание: Платформа 1С самостоятельно сопоставит параметры запроса &ДатаНач с параметрами, указанными в выражении ВИД. Это позволяет выполнять динамические вызовы хранимых процедур с разными условиями фильтрации.
Проанализируем ситуацию с производительностью и ограничениями, чтобы избежать ошибок при проектировании системы:
СоздатьОбъект() или Записать() для изменения данных во внешней базе через этот механизм. Для записи данных придется использовать либо стандартные таблицы ВИД, либо прямой SQL.NULL в SQL и NULL в 1С иногда приводит к неожиданному исчезновению строк из выборки.Если настройка через метаданные кажется слишком громоздкой или СУБД накладывает специфические ограничения, существует альтернативный путь. В современных версиях платформы 8.3 доступен метод ВыполнитьЗапрос() у объекта внешнего источника данных.
Посмотрим на пример использования:
// Пример прямого запроса без описания таблиц в конфигураторе
СтрокаЗапроса = "EXEC GetReportData '" + Формат(ДатаНач, "ДФ=yyyyMMdd") + "', 10";
Результат = ВнешниеИсточникиДанных.МояВнешняяБаза.ВыполнитьЗапрос(СтрокаЗапроса);
// Результат будет возвращен в виде стандартного объекта РезультатЗапроса
Выборка = Результат.Выбрать();
Этот метод значительно гибче, так как позволяет отправлять любой текст запроса напрямую. Однако он лишает вас возможности использовать визуальный конструктор запросов 1С и типизацию полей, настроенную в метаданных.
Таким образом, мы рассмотрели основной механизм работы с хранимыми процедурами через ВИД. Использование таблиц-выражений является наиболее «правильным» с точки зрения архитектуры 1С методом, так как он позволяет интегрировать внешние данные в общую структуру метаданных и использовать стандартный механизм запросов платформы.