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