При переходе на платформу 1С:Предприятие 7.7 или при поддержке исторических конфигураций разработчики нередко сталкиваются с неочевидным поведением встроенного языка. В частности, это касается обращения к табличной части (многострочной части) документа: расчет сумм по числовым графам и удаление конкретных строк имеют характерные синтаксические отличия от работы с универсальным объектом ТаблицаЗначений.
Разберем две типичные ситуации: почему метод подсчета итогов выдает ошибку о неверном имени реквизита и как правильно спозиционироваться и удалить определенную строку табличной части.
Рассмотрим распространенную ошибку. Разработчик пытается получить сумму по колонке табличной части следующим образом:
ОбщаяРазница = Итог(Разница);
В ответ платформа выдает ошибку: «Неверное имя реквизита». Причина заключается в фундаментальных правилах встроенного языка: идентификатор, написанный без кавычек, компилятор платформы воспринимает как локальную переменную или реквизит текущего контекста (шапки документа), а не как название реквизита табличной части.
В отличие от некоторых методов работы с объектом ТаблицаЗначений, метод Итог() для табличной части документа принимает строго строковый литерал — строковое имя числового реквизита в кавычках. Передать порядковый номер колонки или переменную с незаполненным значением сюда нельзя. Правильный синтаксис вызова выглядит так:
ОбщаяРазница = Итог("Разница");
Выясним причину, по которой метод Итог() иногда возвращает ноль даже при заполненных данных в строках. Поведение метода напрямую зависит от настроек реквизита в конфигураторе:
Итог("ИмяРеквизита") срабатывает мгновенно и сразу возвращает корректное числовое значение.ВыбратьСтроки():
// Принудительно рассчитываем итоги по числовым графам
Док.ВыбратьСтроки();
// Цикл перебора строк делать не требуется
ВсегоПоРеквизиту = Док.Итог("Разница");
Обратите внимание: выполнять ручной обход через ПолучитьСтроку() для суммирования не нужно — сам по себе вызов метода ВыбратьСтроки() дает платформе команду проинициализировать итоги по всем числовым реквизитам многострочной части.
Если же требуется рассчитать итоги без изменения курсора строк документа, можно выгрузить данные в объект ТаблицаЗначений с помощью метода ВыгрузитьТабличнуюЧасть() и уже в ней вызвать ТЗ.Итог("Разница").
Вторая частая проблема возникает при попытке передать номер строки прямо в метод удаления, например:
// Приведет к ошибке: "Слишком много фактических параметров"
УдалитьСтроку(КоличествоСтрок());
Проанализируем причину ошибки. Разработчики часто путают контекст табличной части документа и объект ТаблицаЗначений. В объекте ТаблицаЗначений действительно существует перегрузка ТЗ.УдалитьСтроку(НомерСтроки). Однако в табличной части документа метод УдалитьСтроку() не принимает никаких параметров — он всегда удаляет исключительно текущую позиционированную строку.
Разберем по шагам, как удалить конкретную строку (например, последнюю) в табличной части документа:
КоличествоСтрок().ПолучитьСтрокуПоНомеру().УдалитьСтроку() без параметров.Посмотрим на готовый пример кода:
Если КоличествоСтрок() > 0 Тогда
ПолучитьСтрокуПоНомеру(КоличествоСтрок());
УдалитьСтроку();
КонецЕсли;
Если перед вами стоит задача удалить не одну строку, а несколько строк, удовлетворяющих определенному условию, важно помнить о сдвиге индексов. Прямой перебор строк от первой к последней приведет к пропуску элементов, так как после удаления текущей строки следующая за ней смещается на ее позицию.
Поскольку в цикле Для ... По встроенного языка 1С 7.7 нет шага с отрицательным приращением, безопасный проход по табличной части документа реализуется обратным счетчиком с конца в начало:
ВсегоСтрок = КоличествоСтрок();
Для Ном = 1 По ВсегоСтрок Цикл
// Вычисляем индекс строки с конца таблицы
ИндексСКонца = ВсегоСтрок - Ном + 1;
ПолучитьСтрокуПоНомеру(ИндексСКонца);
Если Разница = 0 Тогда
УдалитьСтроку();
КонецЕсли;
КонецЦикла;
Важное замечание: если удаление строк выполняется в форме документа программно, платформа может вызывать предопределенную процедуру ПриУдаленииСтроки(). Если в ней установлен оператор СтатусВозврата(0), удаление будет прервано. Кроме того, при изменении табличной части уже проведенного документа не забывайте о необходимости последующей записи и перепроведения документа для актуализации движений по регистрам.