Разработчики, работающие с платформой 1С 7.7, часто сталкиваются с проблемой производительности штатного объекта БухгалтерскиеИтоги. Когда объем базы данных растет, расчет итогов за длительные периоды может занимать минуты. В данной статье мы разберем, как использовать внешнюю компоненту 1С++ и механизмы прямых запросов к SQL-серверу, чтобы сократить время выполнения операций с нескольких минут до нескольких секунд.
Для начала работы нам необходимо убедиться, что в системе установлена и зарегистрирована библиотека 1cpp.dll. Без нее выполнение прямых запросов невозможно. Основным инструментом для получения бухгалтерских данных является класс AccountsRecordset или его более современный аналог — класс ПрямойЗапрос.
Проанализируем типичную ситуацию: при попытке скачать или использовать старые обработки типа AccountsRecordsetV3.ert могут возникать вопросы по их интеграции. Важно понимать, что такие файлы можно не только держать в каталоге базы, но и встраивать непосредственно в конфигурацию как внешние отчеты или обработки.
Прямые запросы в 1С++ используют так называемые виртуальные таблицы. Это предопределенные конструкции, которые препроцессор 1С++ превращает в сложные SQL-выражения, объединяющие таблицы итогов (_1SBKTTL) и движения (_1SBKTTLC). Рассмотрим пример запроса для получения остатков и оборотов:
ТекстЗапроса = "SELECT
| Субконто1 [Субконто1 $Субконто]
| , СуммаНачальныйОстаток
| , СуммаОборот
| , СуммаКонечныйОстаток
| FROM $БИОстаткиОбороты.Основной(:НачДата, :КонДата ~,
| ,
| ДвиженияИГраницыПериода,,
| Счет = :ВыбСчет,,
| Субконто1
| ) БИОстаткиОборотыОсновной
|";
Разберем важные элементы этого запроса:
:КонДата ~) тильда означает "конец дня". Это позволяет захватить все операции, совершенные до последней секунды указанной даты включительно.УстановитьТекстовыйПараметр автоматически преобразует ссылку на счет во внутренний идентификатор, понятный SQL.ТЗ.Свернуть(), следует указывать группировку непосредственно в 7-м параметре виртуальной таблицы (после условия на счет).Многие начинающие разработчики совершают ошибку, пытаясь передать в RS.УстановитьТекстовыйПараметр("ВыбСчет", "66") просто строку. Рассмотрим, как это делать правильно:
Счет66 = СоздатьОбъект("Счет");
Счет66.НайтиПоКоду("66");
RS.УстановитьТекстовыйПараметр("ВыбСчет", Счет66.ТекущийСчет());
Метод преобразует объект в его внутреннее представление (ID), которое в базе SQL может выглядеть как 36-ричный код. Нам не нужно знать этот код, компонента сделает все за нас.
Часто требуется отобрать данные, где наименование субконто не заполнено или соответствует определенному шаблону. В прямых запросах мы работаем напрямую с таблицами справочников. Для этого нужно выполнить JOIN (соединение) с таблицей справочника и проверить поле DESCR.
Если же задача — проверить, выбрано ли субконто в принципе (проверка на пустую ссылку), используем сравнение с $ПустойИД:
// Пример условия в блоке WHERE для проверки на пустую ссылку справочника
"WHERE RIGHT(Субконто1, 9) <> $ПустойИД"
Важно помнить структуру идентификаторов в 1С 7.7:
Для удаления лишних пробелов при сравнении строк в SQL используйте комбинацию функций RTrim(LTrim(СПР.DESCR)).
Если вам нужно получить аналоги методов ВыбратьКорсчета(), КорДо() и КорКо(), мы рекомендуем использовать виртуальную таблицу $БИОборотыДтКт. Она позволяет в одном запросе выгрузить обороты между счетом и его корсчетами. Поля будут называться соответственно: СуммаОборотДт и СуммаОборотКт.
Проанализируем причину ускорения (с 4 минут до 4 секунд). Стандартный механизм 1С 7.7 при расчете итогов за период выполняет множество последовательных запросов к базе: сначала получает остатки на начало, затем выбирает обороты, а потом производит математические вычисления в памяти клиента. Прямой запрос переносит всю вычислительную нагрузку (агрегацию SUM и группировку GROUP BY) на сторону мощного SQL-сервера, который возвращает уже готовый результат в виде одной таблицы.
Хотя тема начиналась с AccountsRecordset, современные стандарты разработки в 1С 7.7 диктуют использование класса ПрямойЗапрос. Он обладает более мощным препроцессором и лучше документирован. Создание объекта выглядит следующим образом:
Запрос = СоздатьОбъект("ПрямойЗапрос");
// Далее работа идет через установку текста и параметров,
// аналогично ODBCRecordset, но с поддержкой более сложных конструкций.
Рассмотрим подробнее работу с этим классом через документацию на ресурсах сообщества (например, 1cpp.ru или script-coding.com), где описаны все 12+ параметров виртуальных таблиц бухгалтерских итогов, включая фильтры по валютам, разделителям учета и сценариям.
Важный совет: Если вы только начинаете осваивать прямые запросы, посмотрите на демонстрационные базы, такие как "Скат", где реализовано множество примеров сложных отчетов на 1С++. Это поможет быстрее понять логику взаимодействия между 1С и SQL.