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

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

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

Метод 1: Прямой перебор строк табличной части

Самый интуитивно понятный и простой способ обнулить столбец табличной части — это перебрать каждую строку табличной части в цикле и установить нужное значение для соответствующей колонки. Этот метод особенно хорош для небольших табличных частей, где производительность не является критичным фактором.

Как это работает:

  1. Мы получаем доступ к табличной части документа, например, через объект ДокументОбъект.Товары.
  2. Используем цикл Для Каждого ... Из ... Цикл для итерации по всем строкам табличной части.
  3. Внутри цикла мы обращаемся к нужной колонке каждой строки и присваиваем ей значение 0 (или другое необходимое значение, например, пустую строку "" для строковых полей или Неопределено для ссылочных).

Пример кода:

Предположим, у нас есть табличная часть Товары и в ней колонка Количество, которую нам нужно обнулить.


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

Преимущества:

Недостатки:

Как мы видим из обсуждения, на вопрос "нужно ли только полным перебором строк это делать?" один из пользователей справедливо отметил, что "одной командной нельзя" в прямом смысле, подразумевая, что платформа 1С не предоставляет встроенной "SQL-подобной" команды для массового обновления столбца табличной части без итераций или вспомогательных объектов.

Метод 2: Выгрузка и загрузка в ТаблицуЗначений с использованием ЗаполнитьЗначения()

Этот метод является одним из наиболее производительных для работы с большими объемами данных в табличных частях. Он основан на использовании объекта ТаблицаЗначений, который предоставляет оптимизированные методы для массовой обработки данных.

Как это работает:

  1. Выгрузка данных: Мы выгружаем все данные из табличной части документа в новый объект ТаблицаЗначений. Метод Выгрузить() табличной части позволяет это сделать.
  2. Массовое заполнение значений: Используем метод ЗаполнитьЗначения() объекта ТаблицаЗначений. Этот метод позволяет одной командой установить одно и то же значение для всех строк указанной колонки.
  3. Загрузка данных обратно: Модифицированная ТаблицаЗначений загружается обратно в табличную часть документа с помощью метода Загрузить().

Пример кода:

Продолжаем использовать табличную часть Товары и колонку Количество:


ТабЗнач = ДокументОбъект.Товары.Выгрузить(); // Выгружаем всю табличную часть в ТаблицуЗначений
ТабЗнач.ЗаполнитьЗначения(0, "Количество"); // Обнуляем столбец "Количество" в ТаблицеЗначений
ДокументОбъект.Товары.Загрузить(ТабЗнач); // Загружаем модифицированную ТаблицуЗначений обратно в табличную часть

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

Преимущества:

Недостатки:

Метод 3: Использование ЗагрузитьКолонку() с массивом пустых значений

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

Как это работает:

  1. Создание массива значений: Мы создаем новый массив, размер которого равен количеству строк в табличной части.
  2. Заполнение массива: Все элементы этого массива заполняются значением, которое мы хотим присвоить колонке (в нашем случае — 0).
  3. Загрузка массива в колонку: С помощью метода ЗагрузитьКолонку() табличной части мы загружаем подготовленный массив непосредственно в нужную колонку.

Пример кода:

Для нашей колонки Количество:


// Создаем новый массив. По умолчанию элементы массива для числовых типов будут 0,
// но для явного указания и универсальности лучше заполнить их вручную.
МассивПустыхЗначений = Новый Массив(ДокументОбъект.Товары.Количество()); 

// Заполняем массив нулями
Для Индекс = 0 По МассивПустыхЗначений.ВВерхнейГранице() Цикл
    МассивПустыхЗначений[Индекс] = 0;
КонецЦикла;

// Загружаем массив в колонку "Количество"
ДокументОбъект.Товары.ЗагрузитьКолонку(МассивПустыхЗначений, "Количество");

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


МассивПустыхЗначений = Новый Массив(ДокументОбъект.Товары.Количество()); 
ДокументОбъект.Товары.ЗагрузитьКолонку(МассивПустыхЗначений, "Количество");

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

Преимущества:

Недостатки:

Метод 4: Копирование только нужных колонок при выгрузке/загрузке

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

Как это работает:

  1. Выборочная выгрузка: Мы выгружаем табличную часть, но указываем в параметрах метода Выгрузить() только те колонки, которые нам необходимо сохранить. Все остальные колонки будут проигнорированы.
  2. Полная очистка: Мы полностью очищаем исходную табличную часть документа методом Очистить().
  3. Обратная загрузка: Загружаем выборочно выгруженные данные обратно в табличную часть. Колонки, которые не были включены в выгрузку, будут созданы заново с их значениями по умолчанию (обычно 0 для чисел, пустая строка для строк, Неопределено для ссылок).

Пример кода:

Предположим, нам нужно сохранить только Номенклатуру и Цену, а все остальные колонки, включая Количество, обнулить или очистить.


// Выгружаем только нужные колонки: Номенклатура и Цена
ТЗ = ДокументОбъект.Товары.Выгрузить(,"Номенклатура,Цена"); 

// Очищаем всю табличную часть документа
ДокументОбъект.Товары.Очистить(); 

// Загружаем только сохраненные колонки. Остальные будут пустыми/нулевыми.
ДокументОбъект.Товары.Загрузить(ТЗ); 

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


// Предположим, у нас есть колонки Колонка1, Количество, Колонка3. 
// Мы хотим обнулить Количество.
// Выгружаем все колонки, кроме "Количество".
ДокументОбъект.Товары.Загрузить(ДокументОбъект.Товары.Выгрузить(,"Колонка1,Колонка3, ...")); 
// Важно перечислить все колонки, которые должны остаться, кроме той, что очищается.

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

Преимущества:

Недостатки:

Метод 5: Масштабируемость и универсальность для нескольких табличных частей

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

Как это работает:

  1. Подготовка массива значений: Мы создаем массив нулей (или других "пустых" значений) максимальной длины, которая может потребоваться для любой из целевых табличных частей. Для этого мы можем взять количество строк из самой большой табличной части.
  2. Заполнение массива: Заполняем этот массив необходимыми значениями (например, нулями).
  3. Загрузка массива в колонки: Используем метод ЗагрузитьКолонку() для каждой из целевых табличных частей, загружая подготовленный массив в соответствующую колонку.

Пример кода:

Предположим, у нас есть табличные части Товары, Материалы, Тара, и в каждой из них есть колонка Количество, которую нужно обнулить.


// Создаем ТаблицуЗначений из одной колонки "Количество" из первой табличной части
// Это позволяет получить массив нулей нужной длины и типа
ТЗ = ДокументОбъект.Товары.Выгрузить(,"Количество"); 
ТЗ.ЗаполнитьЗначения(0, "Количество"); // Заполняем эту колонку нулями

// Выгружаем колонку "Количество" из ТЗ в массив
МассивКоличестваНулей = ТЗ.ВыгрузитьКолонку("Количество"); 

// Теперь используем этот массив для обнуления колонок в разных табличных частях
ДокументОбъект.Товары.ЗагрузитьКолонку(МассивКоличестваНулей, "Количество");
ДокументОбъект.Материалы.ЗагрузитьКолонку(МассивКоличестваНулей, "Количество");
ДокументОбъект.Тара.ЗагрузитьКолонку(МассивКоличестваНулей, "Количество");

// Этот же массив можно использовать для обнуления любой числовой колонки 
// в любой другой табличной части, при условии, что количество строк 
// в целевой ТЧ меньше или равно количеству элементов в массиве.
// Если ЛюбаяТЧ.Количество() <= МассивКоличестваНулей.Количество() Тогда
//    ЛюбаяТЧ.ЗагрузитьКолонку(МассивКоличестваНулей, "ЛюбаяКолонкаТипЧисло");
// КонецЕсли;

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

Преимущества:

Недостатки:

Подводим итоги и выбираем оптимальный подход

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

  1. Размер табличной части:
    • Для небольших табличных частей (до нескольких сотен строк) прямой перебор строк (Метод 1) является самым простым и понятным решением. Разница в производительности с другими методами будет незначительной.
    • Для больших табличных частей (тысячи строк и более) мы рекомендуем использовать методы с Выгрузить()/Загрузить() (Метод 2) или ЗагрузитьКолонку() (Метод 3). Они значительно превосходят перебор по скорости выполнения.
  2. Количество обнуляемых колонок:
    • Если нужно обнулить только одну колонку, метод с ЗагрузитьКолонку() и массивом (Метод 3) будет наиболее оптимальным по производительности и потреблению памяти.
    • Если нужно обнулить несколько колонок, но при этом сохранить другие, можно использовать метод Выгрузить()/Загрузить() с ЗаполнитьЗначения() для каждой колонки (Метод 2).
    • Если нужно очистить большинство колонок, сохранив лишь несколько, метод выборочной выгрузки/загрузки (Метод 4) может быть удобен.
  3. Универсальность и масштабируемость:
    • Если задача требует обнуления одноименных колонок в нескольких табличных частях одного или разных документов, подход с формированием массива нулей и последующей загрузкой его в колонки (Метод 5) является наиболее масштабируемым и эффективным.

Мы настоятельно рекомендуем всегда тестировать выбранный метод на реальных данных и объемах, чтобы убедиться в его производительности и корректности работы в вашей конкретной конфигурации 1С. В большинстве случаев для типовых задач оптимальным будет использование метода 2 или 3, которые обеспечивают хороший баланс между простотой реализации и производительностью.

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

← На главную