Почему результат запроса 1С отображается как строка таблицы значений и как исправить ошибку метода Свернуть?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке в 1С начинающие (а иногда и опытные) программисты часто сталкиваются с неочевидным поведением платформы. Выгружая результат выполнения запроса, вместо ожидаемой таблицы значений в отладчике можно внезапно увидеть тип СтрокаТаблицыЗначений. А при попытке свернуть полученную таблицу система выдает ошибку: Ошибка при вызове метода контекста (Свернуть) по причине: Неверное имя колонки. Давайте разберем эти ситуации по шагам, выясним причину такого поведения и проанализируем оптимальные способы решения проблем.

Особенности работы отладчика 1С: Таблица значений или Строка таблицы значений?

Рассмотрим первую проблему. Вы выполнили запрос, выгрузили его результат в переменную, открыли отладчик и видите, что тип значения отображается как СтрокаТаблицыЗначений, хотя вы ожидали получить саму таблицу значений.

Чаще всего эта проблема кроется не в коде, а в особенностях работы самого отладчика 1С. Проанализируем ситуацию:

  1. Когда мы вычисляем выражение (например, нажимая Shift+F9), отладчик показывает общий тип коллекции — ТаблицаЗначений.
  2. Если кликнуть по этой коллекции (или нажать F2), открывается список строк таблицы. Шапка окна при этом все еще будет называться «ТаблицаЗначений».
  3. Если пойти дальше и «провалиться» в конкретную строку (например, строку с индексом 0), отладчик переключится на детальный просмотр. Именно здесь тип меняется на СтрокаТаблицыЗначений, и мы видим значения колонок исключительно для этой конкретной строки.

Таким образом, если вы видите строку вместо таблицы, скорее всего, вы случайно открыли первую строку (индекс 0) в окне вычисления выражений. Сама таблица никуда не делась и сформирована корректно, просто вы просматриваете ее элементы на более глубоком уровне вложенности.

Выгрузка временных таблиц и пакетные запросы

Посмотрим на другую возможную причину странного поведения результатов запроса. Часто разработчики используют конструкцию ПОМЕСТИТЬ В для создания временных таблиц. Разберем подробнее, как это влияет на выгрузку.

Если выполнить запрос, который только помещает данные во временную таблицу, и применить метод Выполнить().Выгрузить(), вы не получите таблицу с вашими данными. В результате выгрузится таблица значений с одной-единственной колонкой Количество. В ней будет указано число записей, которые были обработаны и помещены во временную таблицу.

Чтобы получить сами данные из временной таблицы в виде полноценной таблицы значений, запрос необходимо сделать пакетным (разделяя запросы символом ;). Рассмотрим пример правильной конструкции:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    ВТ_Исходная.Колонка1 КАК Колонка1
    |ПОМЕСТИТЬ ВременнаяТаблица
    |ИЗ
    |    &ТаблицаДанных КАК ВТ_Исходная
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    Таб.Колонка1 КАК Колонка1
    |ИЗ
    |    ВременнаяТаблица КАК Таб";

Запрос.УстановитьПараметр("ТаблицаДанных", ИсходныеДанные);
Таб_Результат = Запрос.Выполнить().Выгрузить();

При таком подходе первый запрос в пакете сформирует временную таблицу, а второй запрос выберет из нее данные. Итоговый метод Выгрузить() вернет результат последнего запроса в пакете, то есть нужную нам таблицу значений.

Ошибка метода Свернуть: Неверное имя колонки

Теперь проанализируем вторую проблему. Допустим, мы успешно выгрузили данные в таблицу значений (назовем ее Промежуточная) и пытаемся свернуть её по колонке НомерЗамеса с помощью кода:

Промежуточная.Свернуть("НомерЗамеса");

Платформа выдает ошибку: Неверное имя колонки. Разберем основные причины, почему это происходит:

  1. Банальная опечатка. Как обсуждалось на форуме, чаще всего имя колонки просто написано с ошибкой. Рекомендуется скопировать точное имя колонки прямо из текста запроса и вставить его в метод Свернуть.
  2. Использование псевдонимов. Если в секции выбора запроса вы написали ВЫБРАТЬ Документ.НомерЗамеса КАК НомерПартии, то в итоговой таблице колонки НомерЗамеса не существует. Система назвала её НомерПартии.
  3. Отсутствие поля в выборке. Убедитесь, что поле действительно указано в секции ВЫБРАТЬ. Если оно есть в базе данных, но вы забыли включить его в результат выборки, таблица значений его не будет содержать.
  4. Скрытые символы. При копировании текста (особенно с форумов или из мессенджеров) в имя переменной или строки может попасть неразрывный пробел или символ другой раскладки (например, русская «С» вместо английской «C»).

Оптимизация: СГРУППИРОВАТЬ ПО в запросе или Свернуть в коде?

Давайте обсудим архитектурный аспект этой задачи. Использование метода Свернуть к таблице значений, полученной напрямую из запроса — это антипаттерн с точки зрения производительности 1С.

Если вам нужно получить сгруппированные данные, гораздо правильнее и эффективнее выполнять эту операцию на стороне сервера баз данных (СУБД), используя конструкцию СГРУППИРОВАТЬ ПО внутри самого текста запроса.

Почему мы рекомендуем делать именно так:

  1. Скорость выполнения. SQL-сервер оптимизирован для математических операций, агрегации и группировки огромных массивов данных. Он сделает это в десятки раз быстрее, чем сервер 1С будет перебирать строки в оперативной памяти.
  2. Экономия оперативной памяти и трафика. Сворачивая данные в запросе, вы передаете на сервер 1С уже сжатый, сгруппированный результат. Если вы выгружаете 100 000 строк детальных записей, чтобы свернуть их в 1 000 строк с помощью кода, вы неоправданно загружаете сеть и память сервера приложений.

Посмотрим на пример правильной группировки прямо в запросе:


Запрос.Текст = 
    "ВЫБРАТЬ
    |    ТаблицаДокументов.НомерЗамеса КАК НомерЗамеса,
    |    СУММА(ТаблицаДокументов.Количество) КАК Количество
    |ИЗ
    |    РегистрНакопления.ВыпускПродукции КАК ТаблицаДокументов
    |СГРУППИРОВАТЬ ПО
    |    ТаблицаДокументов.НомерЗамеса";

В этом случае вы сразу получаете готовую, свернутую таблицу значений. Метод Свернуть() в коде стоит применять только тогда, когда таблица значений была собрана программно (например, в цикле или путем слияния разных структур данных, не связанных с СУБД) или когда исходные сырые данные нужно было сначала показать пользователю в форме, а лишь затем агрегировать для дальнейшей логики.

← На главную