Как получить данные из документов через запрос в 1С 7.7: разбираем синтаксис и работу через OLE

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Переход с платформы 1С 8.х на 1С 7.7 часто вызывает у разработчиков трудности, связанные с кардинально иным подходом к написанию запросов. В седьмой версии используется так называемый «Черный запрос», имеющий свой специфический синтаксис и логику выполнения. В этой статье мы подробно разберем, как правильно извлекать данные из документов, настраивать фильтрацию по справочникам и решать проблемы, возникающие при обращении к базе 1С 7.7 из внешних приложений через OLE.

Основы построения «Черного запроса» в 1С 7.7

В отличие от 1С 8.x, где запрос пишется на языке, близком к SQL, запрос в 1С 7.7 — это текстовое описание выборки, которое обрабатывается внутренним движком платформы. Рассмотрим структуру типичного запроса. Проанализируем ситуацию: нам нужно найти все документы СправкаСчет, в которых фигурирует определенный автомобиль.

Первая и самая частая ошибка новичков — попытка выполнить запрос до того, как определены параметры для условия. Выясним причину: в 1С 7.7 текст запроса компилируется в момент вызова метода Выполнить(). Если переменная, используемая в Условие(), не определена или не содержит нужного объекта на этот момент, запрос вернет пустой результат.

Разберем правильный алгоритм действий на примере:


Процедура Сформировать()
    Перем Запрос, ТекстЗапроса, СпрАвто, ТекАвто;

    // Сначала находим объект, который будет параметром фильтрации
    СпрАвто = СоздатьОбъект("Справочник.Автомобили");
    Если СпрАвто.НайтиПоКоду("XTT316300J1017380") = 0 Тогда
        Сообщить("Автомобиль не найден по указанному коду!");
        Возврат;
    КонецЕсли;

    // Получаем конкретный элемент справочника
    ТекАвто = СпрАвто.ТекущийЭлемент();

    Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса = 
    "//{{ЗАПРОС(Сформировать)
    |Период с '01.01.2017' по '31.12.2018';
    |Док = Документ.СправкаСчет.ТекущийДокумент;
    |Авто = Документ.СправкаСчет.Автомобиль;
    |Группировка Док;
    |Условие(Авто = ТекАвто);
    |"//}}ЗАПРОС
    ;

    Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
        Возврат;
    КонецЕсли;
КонецПроцедуры

Группировка данных: как не потерять строки

В 1С 7.7 метод Запрос.Группировка() выполняет роль, аналогичную методу Выборка.Следующий() в 1С 8. Однако здесь есть критический нюанс. Если мы хотим получить список документов, мы обязаны указать группировку по самому документу. Рассмотрим подробнее: если вы укажете Группировка Автомобиль;, запрос «схлопнет» все найденные документы в одну строку для каждого автомобиля. В итоге в цикле вы увидите только первый попавшийся документ из выборки.

Важные правила группировки:

  1. Чтобы получить перечень документов, используйте конструкцию |Группировка Док; (где Док — это ссылка на ТекущийДокумент).
  2. Для обхода результатов в коде используйте Пока Запрос.Группировка("Док") = 1 Цикл.
  3. Если нужно исключить иерархию (например, в справочниках), можно добавить ключевые слова без групп.

Особенности работы через OLE (из 1С 8 в 1С 7.7)

Ситуация усложняется, когда мы пишем код в 1С 8.3, подключаемся к 1С 7.7 через COM-соединение и пытаемся выполнить там запрос. Основная проблема заключается в передаче параметров. Рассмотрим пример: переменная ТекАвто, созданная в контексте 1С 8, абсолютно неизвестна внутреннему обработчику запросов 1С 7.7. Попытка написать Условие(Автомобиль = ТекАвто) внутри строки текста запроса приведет к ошибке «Ошибка в выражении ТекАвто».

Проанализируем два способа решения этой задачи:

Способ 1: Использование строковых идентификаторов (VIN, Код, Артикул). Это самый надежный метод. Мы не передаем ссылку на объект, а передаем строку, которую запрос 1С 7.7 может сравнить самостоятельно.


// Код в 1С 8.3
ТекстЗапроса = 
"//{{ЗАПРОС(Сформировать)
|Период с '01.01.2017' по '31.12.2018';
|Док = Документ.СправкаСчет.ТекущийДокумент;
|ВинКод = Документ.СправкаСчет.Автомобиль.Код;
|Группировка Док;
|Условие(СокрЛП(ВинКод) = """ + СокрЛП(НужныйВин) + """);
|""//}}ЗАПРОС
;

Обратите внимание на использование функции СокрЛП внутри запроса. Это позволяет избежать проблем с лишними пробелами, которые часто встречаются в строковых реквизитах 1С 7.7.

Способ 2: Передача через глобальные переменные OLE-базы. Если необходимо фильтровать именно по ссылке, можно предварительно найти объект в базе 7.7 и присвоить его какой-либо переменной, доступной в глобальном контексте (например, в заголовке какой-нибудь открытой формы или через специальные функции в Глобальном модуле), но это гораздо сложнее в реализации.

Полезные советы и тонкости

Разберем еще несколько важных моментов, которые помогут вам при работе с запросами в 1С 7.7:

Подведем итог. Для успешного получения данных из 1С 7.7 запросом необходимо строго соблюдать последовательность: поиск объектов-фильтров, определение текста запроса с обязательной группировкой по нужным разрезам (документам) и корректный обход результатов через Группировка(). При работе через OLE отдавайте предпочтение строковым фильтрам (кодам), внедряя их значения прямо в текст запроса с помощью конкатенации.

← На главную