При работе с крупными базами данных на платформе 1С:Предприятие 7.7 стандартных средств встроенного языка часто становится недостаточно для быстрого получения данных. В таких случаях разработчики прибегают к использованию прямой работы с таблицами DBF через SQL-запросы. Однако при попытке настроить соединение через стандартный Microsoft Visual FoxPro Driver (ODBC) часто возникают ошибки совместимости или пустые результаты запросов. В данной статье мы подробно разберем, как правильно организовать доступ к данным, используя компоненту 1CPP и современный провайдер OLE DB.
Разберем типичную ситуацию: при использовании стандартного драйвера ODBC (версии 6.0) многие функции SQL оказываются недоступны, а сложные вложенные запросы могут приводить к ошибкам типа State IM001. Это происходит потому, что старый драйвер FoxPro ограничен возможностями шестой версии продукта и плохо поддерживает современные стандарты.
Проанализируем альтернативу: переход на Microsoft OLE DB Provider for Visual FoxPro 9.0 (VFPOLEDB). Этот провайдер является более современным, поддерживает синтаксис FoxPro 9.0, корректно обрабатывает файлы размером более 2 Гб и значительно эффективнее работает с метаданными 1С через компоненту 1CPP.dll. Рассмотрим, как реализовать этот подход на практике.
Прежде всего, необходимо убедиться, что в системе установлен драйвер VFPOLEDB. Для работы 32-битного приложения 1С 7.7 в 64-битной среде Windows крайне важно устанавливать 32-битные версии драйверов. Если вы настраиваете ODBC, используйте утилиту по пути C:\Windows\SysWOW64\odbcad32.exe, иначе нужные драйверы просто не появятся в списке доступных.
Для начала работы загрузим внешнюю компоненту и инициализируем объект соединения. Рассмотрим пример кода:
ЗагрузитьВнешнююКомпоненту(КаталогИБ() + "1cpp.dll");
ОлеДБ = СоздатьОбъект("OLEDBData");
// Формируем строку подключения к каталогу базы данных
Соединение = "Provider=VFPOLEDB.1;Data Source=" + КаталогИБ() + ";Mode=ReadWrite;Collating Sequence=MACHINE";
Рез = ОлеДБ.Соединение(Соединение);
Если Рез = 0 Тогда
Предупреждение("Не удалось подключиться к базе через VFP OLE DB!");
КонецЕсли;
После успешного подключения крайне важно настроить параметры выполнения запросов. Движок FoxPro по умолчанию может блокировать таблицы или выдавать ошибки при попытке чтения данных, которые в данный момент открыты в 1С. Разберем основные команды настройки, которые нужно выполнить сразу после установления соединения через метод EXECSCRIPT:
1. SET ANSI OFF — отключает строгое соответствие стандартам ANSI при сравнении строк, что критично для поиска по неполному соответствию в 1С.
2. SET REPROCESS TO 60 SECONDS — определяет время ожидания при попытке доступа к заблокированной записи.
3. SET TABLEVALIDATE TO 0 — критически важная настройка. Она отключает проверку заголовка таблицы при ее открытии, что позволяет избежать конфликтов, если база уже открыта другими пользователями в 1С.
4. SET DELETED NO (или OFF) — управляет видимостью удаленных записей. В 1С записи помечаются как удаленные, но физически остаются в DBF, поэтому для получения актуальных данных нужно понимать, как этот флаг влияет на результат.
Посмотрим на реализацию настройки в коде:
Запрос = ОлеДБ.СоздатьКоманду();
Запрос.Выполнить("EXECSCRIPT('SET ANSI OFF')");
Запрос.Выполнить("EXECSCRIPT('SET REPROCESS TO 60 SECONDS')");
Запрос.Выполнить("EXECSCRIPT('SET REFRESH TO 0,-1')");
Запрос.Выполнить("Exec('SET TABLEVALIDATE TO 0')");
Компонента 1CPP позволяет использовать в тексте SQL-запроса привычные названия объектов метаданных (справочники, регистры), предваряя их символом $. Проанализируем пример запроса для получения остатков из регистра ОстаткиТМЦ:
ТекстЗапроса = "
|SELECT
| $Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура],
| $Рег.Количество as Количество
|FROM
| $Регистр.ОстаткиТМЦ as Рег
|WHERE
| $Рег.Номенклатура IN (SELECT Val FROM ВрТаблГрупп)";
В данном примере 1CPP автоматически преобразует $Регистр.ОстаткиТМЦ в реальное имя файла (например, RG123.DBF), а поля — в соответствующие идентификаторы колонок. Это избавляет программиста от необходимости знать внутреннюю структуру DBF-файлов.
Выясним причину, по которой прямая передача параметров через знак вопроса (?) в OLEDBData иногда дает сбои. Часто это связано со спецификой парсера 1CPP. Если вам нужно отфильтровать данные по конкретному объекту (например, одной номенклатурной позиции), мы можем пойти двумя путями:
УложитьСписокОбъектов создает виртуальную таблицу, к которой можно обратиться через INNER JOIN или IN (SELECT...).ID) и подставить его в строку запроса в одинарных кавычках.Рассмотрим пример с использованием списка объектов:
ВрТаблГрупп = "";
// Укладываем текущий элемент справочника во временную таблицу
Запрос.УложитьСписокОбъектов(Ном.ТекущийЭлемент, ВрТаблГрупп, "Номенклатура");
ТекстЗапроса = "
|SELECT
| $Рег.Номенклатура as [Номенклатура $Справочник.Номенклатура],
| $Рег.Количество as Количество
|FROM
| $Регистр.ОстаткиТМЦ as Рег
|WHERE
| $Рег.Номенклатура IN (SELECT Val FROM " + ВрТаблГрупп + ")";
ТЗ = Запрос.ВыполнитьИнструкцию(ТекстЗапроса);
ТЗ.ВыбратьСтроку();
Чтобы запросы отрабатывали максимально быстро, необходимо задействовать технологию Rushmore, встроенную в движок FoxPro. Для этого должны соблюдаться следующие условия:
WHERE, JOIN и ORDER BY, должны быть проиндексированы. В 1С 7.7 это обычно файлы .CDX.SET DELETED ON, для максимального ускорения в каждой таблице должен существовать индекс по выражению DELETED(). Без него FoxPro будет выполнять полное сканирование таблицы (Full Scan), что нивелирует все преимущества SQL.Если настройка драйверов OLE DB на терминальном сервере вызывает сложности из-за прав доступа или несовместимости ОС, рассмотрим альтернативу — использование компоненты 1SQLite. Она позволяет создавать SQL-запросы к DBF-файлам, используя движок SQLite, который не требует установки драйверов в систему. 1SQLite умеет индексировать таблицы 1С "на лету" в оперативной памяти, что часто оказывается даже быстрее, чем работа через FoxPro, особенно на сложных выборках с множественными соединениями.
Выбор конкретного решения зависит от сложности вашей задачи, но использование OLEDBData с провайдером VFPOLEDB.1 остается классическим и надежным способом ускорения работы 1С 7.7 в разы по сравнению со стандартными методами СводныйОстаток или перебором справочников.