В процессе разработки часто возникает задача выгрузки данных из табличной части (ТЧ) документа, например, в формат XML или JSON. Типичная ошибка начинающего разработчика заключается в попытке получить имя колонки напрямую из значения ячейки при обходе строки. Рассмотрим, почему прямой обход строки не дает имен и как правильно организовать получение метаданных колонок.
Разберем ситуацию, когда мы пишем код: Для Каждого ТекущаяЯчейка Из СтрокаТЧ Цикл. В этом случае переменная ТекущаяЯчейка на каждой итерации будет содержать значение (число, строку, ссылку на справочник), которое хранится в данной ячейке. У примитивных типов данных или ссылок нет свойства Имя, которое соответствовало бы названию колонки в конфигураторе. Программа просто «не знает», из какой колонки пришло это значение, так как коллекция строки представляет собой лишь набор данных.
Чтобы получить имя реквизита, нам необходимо обращаться не к значениям в строке, а к структуре табличной части. Выясним, какими способами это можно сделать.
Этот метод наиболее точен, если вам нужно получить именно те имена реквизитов, которые заданы в конфигураторе. Мы будем обходить коллекцию реквизитов конкретной табличной части документа. Проанализируем пример кода для документа «Начисление оценочных обязательств по отпускам»:
// 1. Получаем коллекцию метаданных реквизитов конкретной ТЧ
МетаданныеТЧ = Метаданные.Документы.НачислениеОценочныхОбязательствПоОтпускам.ТабличныеЧасти.ОценочныеОбязательства;
РеквизитыКоллекция = МетаданныеТЧ.Реквизиты;
// 2. Внешний цикл по строкам табличной части документа
Для Каждого СтрокаТЧ Из Объект.ОценочныеОбязательства Цикл
// 3. Вложенный цикл по метаданным реквизитов
Для Каждого РеквизитМетаданные Из РеквизитыКоллекция Цикл
ИмяРеквизита = РеквизитМетаданные.Имя;
ЗначениеЯчейки = СтрокаТЧ[ИмяРеквизита]; // Доступ к данным по имени
// Теперь мы можем использовать ИмяРеквизита, например, для записи в XML
ЗаписьXML.ЗаписатьАтрибут(ИмяРеквизита, Строка(ЗначениеЯчейки));
КонецЦикла;
КонецЦикла;
Важный момент: Обратите внимание, что получение коллекции метаданных РеквизитыКоллекция следует выносить за пределы цикла по строкам. Это значительно повышает производительность, так как обращение к дереву метаданных — операция ресурсоемкая.
Если код должен быть универсальным (работать для разных документов без жесткого прописывания путей метаданных), лучше всего использовать выгрузку табличной части в объект ТаблицаЗначений. У таблицы значений есть коллекция Колонки, которая хранит идентификаторы (имена).
Рассмотрим по шагам этот алгоритм:
Выгрузить().Колонки этой таблицы, чтобы заранее знать все имена.
// Выгружаем ТЧ в таблицу значений
ТаблицаДанных = Объект.ОценочныеОбязательства.Выгрузить();
// Перебираем строки таблицы
Для Каждого СтрокаДанных Из ТаблицаДанных Цикл
// Перебираем колонки таблицы
Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл
ИмяКолонки = Колонка.Имя;
Значение = СтрокаДанных[ИмяКолонки];
// Пример вывода:
Сообщить("Колонка: " + ИмяКолонки + ", Значение: " + Значение);
КонецЦикла;
КонецЦикла;
Этот метод удобен тем, что в таблицу значений при выгрузке попадают не только дополнительные реквизиты, но и стандартные, такие как НомерСтроки, если это необходимо для вашей логики.
Проанализируем ситуацию: если вы используете Метаданные...Реквизиты, вы получите только те поля, которые добавил разработчик. Однако в табличной части всегда есть системные поля. Если ваша задача — выгрузить абсолютно все данные, включая технические, лучше использовать метод с ТаблицейЗначений или дополнительно обращаться к коллекции СтандартныеРеквизиты в метаданных ТЧ.
Когда мы получаем ИмяРеквизита и Значение, часто требуется корректно преобразовать данные в строковый формат. Простое использование функции Строка() может быть недостаточно для дат и ссылок. Рекомендуем использовать следующие подходы:
Формат(Значение, "ДФ=yyyy-MM-ddTHH:mm:ss"), чтобы формат соответствовал международным стандартам XML.УникальныйИдентификатор(), либо Код/Наименование, в зависимости от требований принимающей системы.Таким образом, мы выяснили, что для получения имени реквизита необходимо идти «от структуры к данным», а не пытаться извлечь имя из самого значения. Использование метаданных или колонок таблицы значений — наиболее надежные и эффективные способы решения данной задачи.