Переход с платформы 1С 7.7 на 1С 8.3 часто вызывает трудности у разработчиков, особенно в части работы с языком запросов. Одной из типичных задач является получение данных из табличных частей документов (например, ЧекККМ) за определенный период с последующим выводом в иерархическом виде: сначала данные заголовка документа, а затем список товаров. В этой статье мы подробно разберем, как избежать синтаксических ошибок, правильно настроить фильтры по датам и эффективно обработать результаты запроса.
Проанализируем типичные ошибки, с которыми сталкиваются новички при написании своего первого запроса к табличной части. Рассмотрим ситуацию: нам нужно выбрать ответственного, сам документ, номенклатуру и сумму из табличной части Товары документа ЧекККМ.
Ошибка №1: Лишние запятые и отсутствие параметров. Часто в секции ИЗ после указания таблицы ошибочно ставится запятая, а в секции ГДЕ забывают использовать символ & перед именами параметров. Это приводит к ошибке «Ожидается имя таблицы» или «Поле не найдено».
Ошибка №2: Неправильное обращение к реквизитам «шапки» документа. Если мы делаем запрос к таблице Документ.ЧекККМ.Товары, то реквизиты самого документа (например, Дата или Ответственный) доступны только через поле Ссылка. Правильное обращение выглядит так: Товары.Ссылка.Дата.
Ошибка №3: Использование пустых ссылок. Попытка установить параметр Ссылка через метод Документы.ЧекККМ.ПолучитьСсылку() без параметров создаст «пустую ссылку», которая не соответствует ни одному реальному документу в базе. Если ваша задача — получить данные за период, фильтр по конкретной ссылке вообще не нужен.
Для того чтобы данные выводились структурировано, выясним причину использования секции СГРУППИРОВАТЬ ПО и ИТОГИ ПО. Разберем правильный пример текста запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Ссылка.Ответственный КАК Ответственный,
| Товары.Ссылка КАК Документ,
| Товары.Номенклатура КАК Номенклатура,
| СУММА(Товары.Сумма) КАК Сумма
|ИЗ
| Документ.ЧекККМ.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Дата МЕЖДУ &ДатаНач И &ДатаКон
|СГРУППИРОВАТЬ ПО
| Товары.Ссылка,
| Товары.Ссылка.Ответственный,
| Товары.Номенклатура
|ИТОГИ ПО
| Документ";
В этом запросе мы используем ИТОГИ ПО Документ. Это позволяет платформе подготовить результат в виде дерева, где на верхнем уровне будет сам документ, а на вложенном — строки его табличной части.
В 1С 8.x тип Дата всегда содержит время. Если вы укажете &ДатаНач как ТекущаяДата(), то в выборку попадут только документы, созданные ровно в эту секунду. Рассмотрим, как правильно задать границы периода для получения данных за «сегодня»:
// Правильная установка начала и конца дня
Запрос.УстановитьПараметр("ДатаНач", НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаКон", КонецДня(ТекущаяДата()));
Использование функции НачалоДня() гарантирует, что время будет установлено в 00:00:00, а КонецДня() — в 23:59:59. Это критически важно для корректной работы условия МЕЖДУ.
Теперь разберем, как правильно вывести полученные данные на экран. Если в запросе использовались ИТОГИ, обычный линейный обход выборки не подойдет. Нам нужно использовать метод Выбрать с параметром ОбходРезультатаЗапроса.ПоГруппировкам.
Проанализируем алгоритм вывода:
РезультатЗапроса = Запрос.Выполнить();
// Получаем выборку по документам (верхний уровень итогов)
ВыборкаПоДокументам = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаПоДокументам.Следующий() Цикл
// Выводим информацию о чеке
Сообщить("Чек: " + Строка(ВыборкаПоДокументам.Документ) + " (Ответственный: " + ВыборкаПоДокументам.Ответственный + ")");
// Получаем вложенную выборку по товарам для текущего документа
ВыборкаПоТоварам = ВыборкаПоДокументам.Выбрать();
Пока ВыборкаПоТоварам.Следующий() Цикл
// Выводим детализацию по каждой строке
Сообщить(" Товар: " + ВыборкаПоТоварам.Номенклатура + " на сумму: " + ВыборкаПоТоварам.Сумма + " руб.");
КонецЦикла;
КонецЦикла;
При работе с документами ЧекККМ в реальной базе стоит учитывать специфику бизнес-логики. Проанализируем несколько важных моментов:
1. Статус документа. Чеки могут быть пробиты, аннулированы или просто отложены. Чтобы не выводить лишнюю информацию, добавим в секцию ГДЕ фильтр по статусу (обычно это Товары.Ссылка.СтатусЧекККМ = ЗНАЧЕНИЕ(Перечисление.СтатусыЧековККМ.Пробит)).
2. Пометка удаления. Всегда полезно исключать документы, помеченные на удаление, добавив условие И НЕ Товары.Ссылка.ПометкаУдаления.
3. Производительность. Обращение через точку (Товары.Ссылка.Ответственный) на больших объемах данных может работать медленно, так как вызывает неявное соединение таблиц. Если в отчете участвуют тысячи документов, лучше использовать соединение (JOIN) таблиц в тексте запроса или обращаться к регистрам накопления (например, Продажи), так как они специально оптимизированы для быстрого получения итогов по проданным товарам.
4. Архивация. Помните, что после закрытия смены чеки часто архивируются (удаляются их табличные части), а данные переносятся в документ Отчет о розничных продажах. Если ваш запрос возвращает пустой результат за прошлые дни — проверьте наличие данных в этом документе или в регистрах.
Рассмотренный нами подход с использованием ИТОГИ ПО является классическим инструментом 1С для создания иерархических отчетов и позволяет быстро и наглядно представить данные из табличных частей документов.