При переходе на использование прямых SQL-запросов в среде 1С:Предприятие 7.7 с помощью внешней компоненты 1С++, разработчики часто сталкиваются с трудностями при получении данных, которые выходят за рамки стандартных измерений и ресурсов. Одной из таких проблем является извлечение реквизитов регистра. В отличие от стандартного метода ВыгрузитьДвижения(), прямые запросы требуют четкого понимания структуры хранения данных в SQL-таблицах. Рассмотрим подробно, как правильно составить запрос для решения этой задачи.
Для начала проанализируем, почему стандартные метатеги, такие как $РегистрОстатки или $РегистрОбороты, не возвращают реквизиты. В архитектуре 1С 7.7 данные регистров распределены по разным физическим таблицам:
$РегистрОстатки.$Регистр.ИмяРегистра.Выясним причину ошибки автора темы. При использовании конструкции $РегистрОстатки.Партии(,,,,) компонента 1С++ генерирует сложный подзапрос к таблице итогов. Поскольку реквизиты не являются частью итогов, они просто отсутствуют в выборке. Чтобы их получить, нам нужно обращаться напрямую к таблице движений.
Разберем по шагам, как получить данные из таблицы движений. Важнейшим моментом здесь является синтаксис метатега. В отличие от виртуальных таблиц (остатков и оборотов), обращение к физической таблице $Регистр не требует скобок, так как это не функция, а прямое указание на имя таблицы в базе данных.
Рассмотрим пример правильного кода для получения всех полей регистра, включая реквизиты:
ТекстЗапроса = "
|SELECT
| *
|FROM
| $Регистр.Партии AS рег
|";
Recordset.ВыполнитьИнструкцию(ТекстЗапроса, ТаблицаРезультатов);
Обратите внимание: если вы добавите скобки после $Регистр.Партии(), SQL-сервер выдаст ошибку, так как попытается интерпретировать имя таблицы как хранимую функцию, коей она не является.
Проанализируем ситуацию глубже. В таблице движений данные хранятся в специфическом для 1С виде. Чтобы сделать результат запроса пригодным для дальнейшего использования в коде 1С, нам нужно учитывать несколько нюансов:
1. Типизация ссылочных полей. Все ссылки на справочники и документы хранятся в виде 13-символьных строк в кодировке Base36. Чтобы 1С++ автоматически преобразовала их в объекты (например, СправочникСсылка), рекомендуется использовать типизацию в самом SQL-запросе через метатег $Тип или конструкцию описания полей.
2. Связь с датой документа. В таблице движений (RA) отсутствует поле с датой. Есть только поле IDDOC (идентификатор документа). Чтобы отфильтровать движения по периоду или получить дату совершения операции, необходимо выполнить соединение (JOIN) с таблицей системного журнала _1SJOURN.
Рассмотрим пример запроса с получением даты и типизацией товара:
ТекстЗапроса = "
|SELECT
| Журнал.DATE_TIME_IDDOC as [ДатаДок],
| $Рег.Товар as [Товар $Справочник.Товары],
| $Рег.Количество as [Количество],
| $Рег.Сумма as [Сумма],
| $Рег.НомерСкидочнойКарты as [СкидочнаяКарта]
|FROM
| $Регистр.Партии AS Рег
|INNER JOIN
| _1SJOURN AS Журнал ON Журнал.IDDOC = Рег.IDDOC
|WHERE
| Журнал.DATE_TIME_IDDOC BETWEEN :НачДата AND :КонДата~
|";
Recordset.УстПараметр("НачДата", ВыбНачДата);
Recordset.УстПараметр("КонДата", ВыбКонДата);
Таблица = Recordset.ВыполнитьИнструкцию(ТекстЗапроса);
Посмотрим на пример из обсуждения, где автор использует SELECT *. Хотя это помогло ему увидеть наличие полей в Management Studio, в реальной разработке это считается плохой практикой по нескольким причинам:
LINENO, DEBORKRED) избыточно нагружает сеть и оперативную память.SELECT * компонента 1С++ не может автоматически типизировать колонки, и вы получите «сырые» идентификаторы SQL вместо объектов 1С.ТаблицыЗначений.Если ваш реквизит является ссылкой на справочник, крайне важно указать это в запросе. Например, если реквизит НомерСкидочнойКарты — это ссылка на справочник ДисконтныеКарты, запрос должен выглядеть так:
|SELECT
| $Рег.НомерСкидочнойКарты as [Карта $Справочник.ДисконтныеКарты]
|FROM
| $Регистр.Партии AS Рег
В этом случае в объекте ТаблицаРезультатов в соответствующей колонке будут лежать уже готовые объекты 1С, с которыми можно работать методами встроенного языка (например, получать их атрибуты через точку).
Подведем итог нашему анализу. Чтобы успешно извлекать реквизиты регистров в 1С 7.7 через 1С++:
$Регистр._1SJOURN по полю IDDOC.$Справочник, $Документ), чтобы упростить дальнейшую обработку данных.Следуя этим правилам, вы сможете эффективно использовать мощь прямых SQL-запросов, сохраняя при этом удобство работы с объектами метаданных 1С.