Перевод старых баз 1С:Предприятие 7.7 на современные версии SQL Server (например, 2008 R2 и выше) часто сопровождается неожиданным поведением стандартных механизмов. Одной из самых распространенных проблем является некорректная работа так называемых «черных запросов» при фильтрации по бухгалтерским счетам. Проанализируем ситуацию: отчет выполняется без ошибок, но результат оказывается пустым, хотя данные в базе точно есть. Как только мы убираем условие по счету — данные появляются. В этой статье мы подробно разберем причины этой ошибки и найдем способы её решения.
Для начала проанализируем ситуацию с технической стороны. В 1С 7.7 за выполнение встроенных запросов отвечает библиотека Query.dll. При работе с SQL-версией этот движок транслирует запрос с внутреннего языка 1С на язык T-SQL. Проблема заключается в том, что генератор запросов 1С 7.7 создавался в эпоху MS SQL 6.5 и 7.0. Современные версии SQL Server используют другие алгоритмы оптимизации и более строгую проверку типов данных.
Когда мы пишем в запросе Условие (ТекСчет В ФильтрПоСчету), система пытается сопоставить идентификаторы счетов. В SQL-версии счета хранятся в виде специфических строковых идентификаторов (в кодировке Base36). Оператор В для счетов в 1С 7.7 подразумевает не просто равенство, а проверку иерархии (вхождение в группу или субсчета). На новых версиях SQL трансляция этого условия в WHERE ... LIKE или вложенные подзапросы часто отрабатывает некорректно, возвращая пустое множество строк.
Самый быстрый способ вернуть работоспособность отчету — это принудительное изменение режима выполнения запроса. Рассмотрим, как это сделать. В объекте Запрос существует малодокументированный, но крайне важный метод ВключитьSQL().
Если мы установим значение параметра в 0, 1С перестанет пытаться выполнить запрос силами SQL-сервера. Рассмотрим пример кода:
ТекстЗапроса = "
|Период с ВыбНачПериода по ВыбКонПериода;
|ТекСчет = Операция.Счет;
|Сумма = Операция.Сумма;
|Условие (ТекСчет В ФильтрПоСчету);
|Группировка ТекСчет;";
Запрос = СоздатьОбъект("Запрос");
// Отключаем трансляцию в T-SQL для обхода ошибки
Запрос.ВключитьSQL(0);
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
// Обработка результатов
КонецЕсли;
Важно понимать последствия: при вызове ВключитьSQL(0) 1С выгружает все необходимые данные из таблиц SQL во временные файлы на локальном компьютере (в папку пользователя) и обрабатывает их локально, имитируя работу DBF-версии. Разберем плюсы и минусы этого метода:
Посмотрим на ситуацию под другим углом. Если нам не нужна иерархия (проверка субсчетов), а нужно сравнение с конкретным счетом, можно попробовать изменить само условие. Как отмечают опытные разработчики, SQL-версия иногда «капризничает», если в списке значений для оператора В находится только один элемент.
Попробуем заменить оператор В на прямое сравнение, если это допустимо логикой отчета:
// Вместо Условие (ТекСчет В ФильтрПоСчету)
// Если ФильтрПоСчету — это конкретный счет, а не список
Условие (ТекСчет = ФильтрПоСчету);
Если же нам все-таки нужен список, проследим, чтобы в объекте СписокЗначений было более одного элемента, либо используйте явный перебор субсчетов, добавляя их в список перед выполнением запроса. Это иногда помогает генератору Query.dll построить более адекватный план выполнения.
Проанализируем самый надежный и профессиональный метод решения проблем с SQL-базами 7.7. Использование «черных запросов» в 2024 году — это путь накопления технических ошибок. Профессиональное сообщество давно выработало стандарт: использование внешних компонент, таких как 1С++.
Прямые запросы позволяют писать текст на чистом T-SQL, минуя кривые механизмы трансляции 1С. В этом случае мы сами контролируем, как соединяются таблицы проводок (_1SOPER) и планов счетов (_1SACC). Для работы с бухгалтерскими итогами в 1С++ существуют специальные классы (например, ПоставщикДанных), которые умеют эффективно вычислять остатки и обороты.
Преимущества прямого запроса:
Query.dll.Разберем еще один нюанс, упомянутый в обсуждении. При переходе на SQL часто ломаются привычные скрипты выгрузки данных через Конфигуратор (ошибка «Информационная база уже открыта 1С:Конфигуратором»).
Выясним причину: 1С:Предприятие 7.7 при попытке выгрузки (.dat или .zip) требует эксклюзивного доступа к базе. Любое активное соединение или даже «зависший» процесс в диспетчере задач блокируют этот процесс.
Правильное решение для SQL-базы: забудьте про выгрузки через Конфигуратор для целей резервного копирования. Используйте средства SQL Server Management Studio (SSMS). Настройте Maintenance Plan (план обслуживания) для создания Full Backup базы данных по расписанию. Это работает «на лету», не требует выгона пользователей и выполняется в разы быстрее. Конфигуратор стоит использовать только для сохранения самого файла конфигурации (1cv7.md).
Подведем итог: если ваш отчет на SQL выдает пустой результат по счету, первым делом попробуйте Запрос.ВключитьSQL(0). Если производительность станет неприемлемой — это явный сигнал к внедрению прямых запросов через 1С++.