Как обнулить числовые значения в нескольких колонках табличной части в 1С?

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

В процессе разработки в среде 1С:Предприятие часто возникает задача массового изменения данных в табличных частях документов или обработок. Типичный сценарий: необходимо найти определенные строки по условию (например, по конкретному товару или статусу) и обнулить в них значения сразу нескольких числовых колонок. Если таких колонок две-три, задача решается быстро, но что делать, если их десятки (например, 37, как у автора вопроса)?

В этой статье мы разберем несколько подходов к решению данной задачи: от самого простого «в лоб» до максимально оптимизированных методов, которые будут быстро работать даже на больших объемах данных.

Способ 1. Простой перебор строк («В лоб»)

Рассмотрим самый очевидный вариант. Если нам нужно проверить условие в каждой строке и обнулить значения в конкретных колонках, мы можем использовать цикл Для Каждого. Этот метод хорош своей наглядностью и простотой отладки.

Проанализируем пример кода:


Для Каждого СтрокаТЧ Из Объект.Товары Цикл
    Если СтрокаТЧ.Номенклатура = ВыбраннаяНоменклатура Тогда
        СтрокаТЧ.Количество = 0;
        СтрокаТЧ.Сумма = 0;
        СтрокаТЧ.СуммаНДС = 0;
    КонецЕсли;
КонецЦикла;

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

Способ 2. Использование метода НайтиСтроки

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

Разберем алгоритм действий:

  1. Создаем структуру отбора, где ключ — имя колонки, а значение — искомый критерий.
  2. Получаем массив строк, соответствующих отбору.
  3. В цикле обходим только найденные строки.

Отбор = Новый Структура("Склад", СкладДляОбнуления);
НайденныеСтроки = Объект.Товары.НайтиСтроки(Отбор);

Для Каждого СтрокаТЧ Из НайденныеСтроки Цикл
    СтрокаТЧ.Количество = 0;
    // И так далее для всех нужных колонок...
КонецЦикла;

Это значительно эффективнее прямого перебора, так как платформа использует внутренние механизмы поиска.

Способ 3. Автоматическое обнуление всех числовых колонок

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

Посмотрим на пример реализации:


Для Каждого СтрокаТЧ Из Объект.Товары Цикл
    Если СтрокаТЧ.Статус = Перечисления.Статусы.Неактивен Тогда
        // Перебираем все колонки таблицы
        Для Каждого Колонка Из Объект.Товары.Выгрузить().Колонки Цикл
            // Проверяем, является ли тип данных в колонке числовым
            Если Колонка.ТипЗначения.СодержитТип(Тип("Число")) Тогда
                СтрокаТЧ[Колонка.Имя] = 0;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецЦикла;

Важное замечание по оптимизации: проверка типа колонки ТипЗначения.СодержитТип внутри цикла по строкам — это ресурсозатратная операция. Если у вас 1000 строк и 37 колонок, проверка выполнится 37 000 раз. Проанализируем, как сделать это лучше: правильнее будет один раз составить список имен числовых колонок (в массив), а затем в основном цикле обращаться только к ним.

Способ 4. Использование структуры-маски и ЗаполнитьЗначенияСвойств

Это, пожалуй, самый элегантный и быстрый способ для случая с большим количеством колонок. Мы можем использовать метод ЗаполнитьЗначенияСвойств(), который работает на уровне платформы очень эффективно.

Рассмотрим пошагово, как это реализовать:

  1. Создаем структуру, в которой ключи — это имена наших 37 колонок, а значения — нули.
  2. Используем НайтиСтроки для получения нужного подмножества данных.
  3. Применяем ЗаполнитьЗначенияСвойств к каждой строке.

// 1. Готовим структуру-маску (можно заполнить программно в цикле по метаданным)
СтруктураОбнуления = Новый Структура;
СтруктураОбнуления.Вставить("Количество", 0);
СтруктураОбнуления.Вставить("Сумма", 0);
СтруктураОбнуления.Вставить("Вес", 0);
// ... и так далее для всех 37 полей

// 2. Получаем нужные строки
НайденныеСтроки = Объект.Товары.НайтиСтроки(Новый Структура("Обнулить", Истина));

// 3. Быстрое заполнение
Для Каждого ТекущаяСтрока Из НайденныеСтроки Цикл
    ЗаполнитьЗначенияСвойств(ТекущаяСтрока, СтруктураОбнуления);
КонецЦикла;

Этот метод избавляет от написания 37 строк присваивания и работает быстрее, чем обращение к каждой колонке через квадратные скобки СтрокаТЧ[ИмяКолонки].

Дополнительные советы по производительности

Разберем еще несколько нюансов, которые помогут сделать ваш код профессиональнее:

  1. Выполнение на сервере: Всегда старайтесь выполнять подобные массовые операции на стороне сервера. Если вы будете изменять данные в цикле прямо в модуле формы (на клиенте), каждое изменение может вызывать пересчеты интерфейса, что приведет к визуальным «тормозам». Передайте таблицу на сервер, обработайте и верните результат.
  2. Работа с Таблицей Значений (ТЗ): Если данных очень много, иногда быстрее выгрузить табличную часть в объект ТаблицаЗначений методом Выгрузить(), обработать её там и загрузить обратно Загрузить(). В ТЗ поиск и замена происходят быстрее, но помните, что метод Загрузить полностью перезаписывает строки, что может повлиять на связи (например, если у строк есть уникальные идентификаторы).
  3. Метод ЗаполнитьЗначения(): У объекта ТаблицаЗначений есть метод ЗаполнитьЗначения(0, "ИмяКолонки"). Он работает мгновенно, но заполняет все строки в колонке. Если вам нужно обнулить только определенные строки, этот метод не подойдет в чистом виде, но его можно использовать, если предварительно скопировать нужные строки в отдельную временную ТЗ.
  4. Пересчет итогов: После программного изменения значений в колонках (особенно если это Сумма или Количество), не забудьте проверить, нужно ли вызывать процедуры пересчета итогов документа. В типовых конфигурациях это часто делается вызовом процедур типа РассчитатьИтоги() или через обработчики событий при изменении.

Резюме: Для обнуления большого количества колонок в 1С оптимальным является сочетание метода НайтиСтроки() для фильтрации и ЗаполнитьЗначенияСвойств() с заранее подготовленной структурой-маской для записи нулей. Это обеспечивает баланс между скоростью разработки, читаемостью кода и производительностью системы.

← На главную