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

Программист 1С v8.3 (Обычные формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

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

Проанализируем реальный случай, с которым столкнулся разработчик. При попытке свернуть таблицу значений с четырьмя позициями программа переставала отвечать. Проблема оказалась не в объеме данных и не в сложной логике, а в деталях, на которые часто не обращают внимания.

Выясняем причину: коварные опечатки в параметрах

Основной причиной "зависания" метода Свернуть() часто являются банальные опечатки в именах колонок, которые передаются в его параметры. Метод принимает два основных параметра:

  1. Строку с именами колонок, по которым нужно сгруппировать данные (ключевые поля).
  2. Строку с именами колонок, значения в которых нужно просуммировать.

Рассмотрим проблемный код, который приводил к зависанию:


ПараметрыПроведения.ТаблицаУслуги.Свернуть("ВидКорСубконто1,
                                             |ВидКорСубконто2,
                                             |ВидКорСубконто3,
                                             |ИмяСписка,
                                             |КорСубконто1,
                                             |КорСубконто2,
                                             |КорСубконто3,
                                             |КоррСчет,
                                             |ПодразделениеЗатрат,
                                             |Содаржание,
                                             |СпособУчетаНДС,
                                             |Ссылка,
                                             |СтавкаНДС,
                                             |Субконто1,
                                             |Субконто2,
                                             |Субконто3,
                                             |СубконтоНУ1,
                                             |СубконтоНУ2,
                                             |СубконтоНУ3,
                                             |СчетЗатрат,
                                             |СчетЗатратНУ,
                                             |СчетУчетаНДС",
                                             "СуммаБУ,
                                             |СуммаВзаиморасчетов,
                                             |СуммаНДСВзаиморасчетов,
                                             |СуммаНДСПодтвержденнаяРуб,
                                             |СуммаНДСРуб,
                                             |СуммаНУ,
                                             |СуммаПодтвержденнаяРуб,
                                             |СуммаРуб");

На первый взгляд, все выглядит корректно. Однако при внимательном изучении можно найти две ошибки в именах колонок для группировки:

Важный момент: ожидаемым поведением платформы в такой ситуации была бы выдача ошибки, например, "Поле не найдено". Но в некоторых версиях и контекстах выполнения 1С вместо этого входит в бесконечный цикл или просто зависает, что сильно усложняет диагностику. Именно это неочевидное поведение и является главной ловушкой.

Пошаговое решение проблемы

Если вы столкнулись с подобным зависанием, не стоит паниковать. Выполним проверку по шагам:

  1. Внимательная вычитка параметров. Первое, что нужно сделать — это самым тщательным образом, буквально по буквам, проверить каждое имя колонки в строках, передаваемых в метод Свернуть().
  2. Использование отладчика. Это самый надежный способ. Поставьте точку останова на строке перед вызовом метода Свернуть(). Когда выполнение остановится, откройте вашу таблицу значений (в нашем примере это ПараметрыПроведения.ТаблицаУслуги) в окне "Табло" или через "Вычислить выражение...". Вы увидите точную структуру таблицы с правильными именами всех колонок.
  3. Сравнение "эталона" с кодом. Теперь, имея перед глазами реальные имена колонок в отладчике, сравните их с теми, что написаны в вашем коде. Так вы быстро найдете любые расхождения.
  4. Исключите ручной ввод. Чтобы избежать подобных ошибок в будущем, возьмите за правило не печатать имена колонок вручную. Лучше скопируйте их напрямую из конфигуратора (из определения табличной части или реквизитов) или прямо из табло отладчика.

Альтернативный и более надежный подход: использование запросов

Хотя метод Свернуть() прост и удобен для небольших задач, для агрегации данных в 1С существует более мощный, надежный и часто более производительный инструмент — запросы.

Рассмотрим его преимущества в контексте нашей проблемы:

Посмотрим, как могла бы выглядеть наша задача, решенная с помощью запроса.


// Создаем запрос
Запрос = Новый Запрос;

// Устанавливаем в качестве источника данных нашу таблицу значений
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.УстановитьПараметр("ТаблицаУслуги", ПараметрыПроведения.ТаблицаУслуги);

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

Да, кода получается больше, но он гораздо надежнее и прозрачнее. Любая ошибка в имени поля будет сразу обнаружена, что сэкономит вам массу времени на отладку.

Итог: если метод Свернуть() вызывает необъяснимое зависание, в первую очередь ищите опечатки в его параметрах. А для серьезных задач и обработки больших объемов данных настоятельно рекомендуем использовать запросы как более стабильный и контролируемый инструмент.

← На главную