При разработке в 1С начинающие (а иногда и опытные) программисты часто сталкиваются с неочевидным поведением платформы. Выгружая результат выполнения запроса, вместо ожидаемой таблицы значений в отладчике можно внезапно увидеть тип СтрокаТаблицыЗначений. А при попытке свернуть полученную таблицу система выдает ошибку: Ошибка при вызове метода контекста (Свернуть) по причине: Неверное имя колонки. Давайте разберем эти ситуации по шагам, выясним причину такого поведения и проанализируем оптимальные способы решения проблем.
Рассмотрим первую проблему. Вы выполнили запрос, выгрузили его результат в переменную, открыли отладчик и видите, что тип значения отображается как СтрокаТаблицыЗначений, хотя вы ожидали получить саму таблицу значений.
Чаще всего эта проблема кроется не в коде, а в особенностях работы самого отладчика 1С. Проанализируем ситуацию:
ТаблицаЗначений.СтрокаТаблицыЗначений, и мы видим значения колонок исключительно для этой конкретной строки.Таким образом, если вы видите строку вместо таблицы, скорее всего, вы случайно открыли первую строку (индекс 0) в окне вычисления выражений. Сама таблица никуда не делась и сформирована корректно, просто вы просматриваете ее элементы на более глубоком уровне вложенности.
Посмотрим на другую возможную причину странного поведения результатов запроса. Часто разработчики используют конструкцию ПОМЕСТИТЬ В для создания временных таблиц. Разберем подробнее, как это влияет на выгрузку.
Если выполнить запрос, который только помещает данные во временную таблицу, и применить метод Выполнить().Выгрузить(), вы не получите таблицу с вашими данными. В результате выгрузится таблица значений с одной-единственной колонкой Количество. В ней будет указано число записей, которые были обработаны и помещены во временную таблицу.
Чтобы получить сами данные из временной таблицы в виде полноценной таблицы значений, запрос необходимо сделать пакетным (разделяя запросы символом ;). Рассмотрим пример правильной конструкции:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВТ_Исходная.Колонка1 КАК Колонка1
|ПОМЕСТИТЬ ВременнаяТаблица
|ИЗ
| &ТаблицаДанных КАК ВТ_Исходная
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Таб.Колонка1 КАК Колонка1
|ИЗ
| ВременнаяТаблица КАК Таб";
Запрос.УстановитьПараметр("ТаблицаДанных", ИсходныеДанные);
Таб_Результат = Запрос.Выполнить().Выгрузить();
При таком подходе первый запрос в пакете сформирует временную таблицу, а второй запрос выберет из нее данные. Итоговый метод Выгрузить() вернет результат последнего запроса в пакете, то есть нужную нам таблицу значений.
Теперь проанализируем вторую проблему. Допустим, мы успешно выгрузили данные в таблицу значений (назовем ее Промежуточная) и пытаемся свернуть её по колонке НомерЗамеса с помощью кода:
Промежуточная.Свернуть("НомерЗамеса");
Платформа выдает ошибку: Неверное имя колонки. Разберем основные причины, почему это происходит:
Свернуть.ВЫБРАТЬ Документ.НомерЗамеса КАК НомерПартии, то в итоговой таблице колонки НомерЗамеса не существует. Система назвала её НомерПартии.ВЫБРАТЬ. Если оно есть в базе данных, но вы забыли включить его в результат выборки, таблица значений его не будет содержать.Давайте обсудим архитектурный аспект этой задачи. Использование метода Свернуть к таблице значений, полученной напрямую из запроса — это антипаттерн с точки зрения производительности 1С.
Если вам нужно получить сгруппированные данные, гораздо правильнее и эффективнее выполнять эту операцию на стороне сервера баз данных (СУБД), используя конструкцию СГРУППИРОВАТЬ ПО внутри самого текста запроса.
Почему мы рекомендуем делать именно так:
Посмотрим на пример правильной группировки прямо в запросе:
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаДокументов.НомерЗамеса КАК НомерЗамеса,
| СУММА(ТаблицаДокументов.Количество) КАК Количество
|ИЗ
| РегистрНакопления.ВыпускПродукции КАК ТаблицаДокументов
|СГРУППИРОВАТЬ ПО
| ТаблицаДокументов.НомерЗамеса";
В этом случае вы сразу получаете готовую, свернутую таблицу значений. Метод Свернуть() в коде стоит применять только тогда, когда таблица значений была собрана программно (например, в цикле или путем слияния разных структур данных, не связанных с СУБД) или когда исходные сырые данные нужно было сначала показать пользователю в форме, а лишь затем агрегировать для дальнейшей логики.