Почему таблица значений остается пустой при использовании ЗагрузитьКолонку и как это исправить

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

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

Разбор основной ошибки: почему метод не добавляет строки

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

Метод ЗагрузитьКолонку не является методом заполнения таблицы «с нуля». Его основная задача — замена значений в уже существующих строках. Если в вашей таблице значений 0 строк, то методу просто некуда записывать данные из массива. Он не создает новые записи автоматически. Чтобы метод сработал, количество строк в таблице значений должно быть как минимум равно количеству элементов в загружаемом массиве.

Рассмотрим, как работает индексация в этом случае. Платформа сопоставляет элементы массива и строки таблицы по их индексу: значение из Массив[0] попадает в ТЗ[0], Массив[1] в ТЗ[1] и так далее. Если строк в таблице меньше, чем элементов в массиве, лишние данные из массива будут просто проигнорированы.

Различие между массивом значений и массивом строк

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

Важно понимать: метод ЗагрузитьКолонку ожидает на вход массив простых значений (чисел, строк, дат или ссылок). Если мы передадим ему результат выполнения НайтиСтроки, система попытается записать объекты строк в ячейки таблицы. Это приведет к тому, что в колонке «МассаТовара» вместо чисел окажутся ссылки на объекты строк другой таблицы, что сделает невозможным дальнейшие арифметические операции или использование метода Свернуть.

Решение №1: Использование методов Скопировать и Выгрузить

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

Если ДанныеЗапроса — это полноценная ТаблицаЗначений на стороне сервера, используем метод Скопировать. Посмотрим на пример кода:


ПараметрыОтбора = Новый Структура("ДатаДокумента", ДатаДокумента);
// Копируем только нужные строки и только нужную колонку
ТаблицаМассы = ДанныеЗапроса.Скопировать(ПараметрыОтбора, "МассаТовара");

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


ПараметрыОтбора = Новый Структура("ДатаДокумента", ДатаДокумента);
ТаблицаМассы = ДанныеФормыКоллекция.Выгрузить(ПараметрыОтбора, "МассаТовара");

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

Решение №2: Правильное использование ЗагрузитьКолонку через цикл

Бывают случаи, когда нам необходимо использовать именно ЗагрузитьКолонку (например, если массив значений формируется сложной логикой, а не просто берется из другой таблицы). В этом случае мы должны подготовить «приемник».

Разберем по шагам правильный алгоритм:

  1. Создаем объект ТаблицаЗначений.
  2. Добавляем необходимые колонки с указанием типов данных.
  3. Добавляем в таблицу столько пустых строк, сколько элементов в нашем массиве.
  4. Вызываем ЗагрузитьКолонку.

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


// Предположим, у нас есть МассивЗначенийМассы, заполненный числами
ТаблицаМассы = Новый ТаблицаЗначений;
ТаблицаМассы.Колонки.Добавить("МассаТовара", Новый ОписаниеТипов("Число"));

// Добавляем пустые строки
Для Счетчик = 1 По МассивЗначенийМассы.Количество() Цикл
    ТаблицаМассы.Добавить();
КонецЦикла;

// Теперь загрузка сработает корректно
ТаблицаМассы.ЗагрузитьКолонку(МассивЗначенийМассы, "МассаТовара");

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

Решение №3: Заполнение через ЗаполнитьЗначениеСвойств

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


ИскомыеСтроки = ДанныеЗапроса.НайтиСтроки(ПараметрыОтбора);
ТаблицаМассы = Новый ТаблицаЗначений;
ТаблицаМассы.Колонки.Добавить("МассаТовара", Новый ОписаниеТипов("Число"));

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

Этот метод удобен тем, что если в будущем в ТаблицаМассы добавятся другие колонки, которые присутствуют в ДанныеЗапроса, они будут заполняться автоматически без изменения логики цикла.

Производительность и оптимизация

Проанализируем вопрос производительности. При работе с большими объемами данных (десятки и сотни тысяч строк) следует придерживаться следующих правил:

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

Нюансы метода Свернуть

В исходном примере упоминался метод Свернуть. Помните, что ТаблицаМассы.Свернуть("", "МассаТовара") удалит все колонки, кроме «МассаТовара», и просуммирует значения в ней. Если вы хотите сгруппировать данные по какому-то признаку (например, по товару), этот признак обязательно должен быть указан в первом параметре метода, иначе колонка с товаром будет безвозвратно удалена из структуры таблицы.

Подводя итог, можно сказать, что выбор метода зависит от структуры ваших данных. Для копирования подмножества строк идеально подходят Скопировать и Выгрузить, а для работы с подготовленными массивами простых значений — связка добавления пустых строк и ЗагрузитьКолонку.

← На главную