При программной работе с документами в 1С часто возникает задача: заполнить табличную часть (например, список товаров) данными, которые хранятся в массиве. Начинающие разработчики могут столкнуться с ошибкой "Поле объекта не обнаружено", пытаясь напрямую присвоить значения реквизитам табличной части, забывая о ключевом шаге — создании новой строки. Давайте разберем основные способы решения этой задачи, от самого базового до наиболее оптимального. При миграции данных между похожими базами вместо написания кода вручную применяется перенос данных между конфигурациями 1С с сопоставлением объектов по произвольным полям.
Это самый фундаментальный и универсальный метод. Его логика проста: мы перебираем каждый элемент исходного массива, для каждого элемента создаем новую пустую строку в табличной части документа и только после этого заполняем ее данными. Главное здесь — использование метода Добавить() у объекта табличной части.
Проанализируем ситуацию. Ошибка "Поле объекта не обнаружено" возникает, когда вы пытаетесь обратиться к реквизиту строки (например, Док.Товары.Номенклатура), но самой строки еще не существует. Метод Добавить() как раз и создает эту строку, возвращая на нее ссылку, с которой уже можно работать.
Посмотрим на пример. Допустим, у нас есть массив структур, где каждая структура описывает одну товарную позицию.
// Предположим, Док - это объект нужного нам документа
// МассивДанных - массив, содержащий структуры с данными для загрузки
// Пример массива структур
МассивДанных = Новый Массив;
МассивДанных.Добавить(Новый Структура("Номенклатура, Количество, Цена", Справочники.Номенклатура.НайтиПоКоду("001"), 2, 1500));
МассивДанных.Добавить(Новый Структура("Номенклатура, Количество, Цена", Справочники.Номенклатура.НайтиПоКоду("005"), 10, 500));
// Перед заполнением рекомендуется очистить табличную часть, если там могут быть старые данные
Док.Товары.Очистить();
// Теперь обходим массив в цикле
Для каждого ЭлементМассива Из МассивДанных Цикл
// 1. Добавляем новую пустую строку и получаем на нее ссылку
НоваяСтрока = Док.Товары.Добавить();
// 2. Заполняем реквизиты созданной строки
НоваяСтрока.Номенклатура = ЭлементМассива.Номенклатура;
НоваяСтрока.Количество = ЭлементМассива.Количество;
НоваяСтрока.Цена = ЭлементМассива.Цена;
// Сумма и другие вычисляемые реквизиты могут рассчитываться платформой автоматически
// или их можно рассчитать здесь же:
// НоваяСтрока.Сумма = ЭлементМассива.Количество * ЭлементМассива.Цена;
КонецЦикла;
Важный момент, на который обратили внимание в обсуждении, — типы данных. Если реквизит табличной части (например, "Номенклатура") имеет тип СправочникСсылка, то и присваивать ему нужно значение именно этого типа, а не просто строку с названием. В примере выше мы используем Справочники.Номенклатура.НайтиПоКоду() для получения нужной ссылки.
Этот способ дает полный контроль над процессом и позволяет выполнять сложные преобразования данных для каждой строки непосредственно в цикле. Для заполнения документов на основе заказов из электронной почты применяется создание счетов и договоров в 1С:Бухгалтерии 3.0, что сокращает время на обработку информации.
Когда данных много, построчное добавление в цикле может быть не самым производительным решением. Платформа 1С предлагает более эффективный механизм — загрузку данных из ТаблицыЗначений одной командой. Этот подход состоит из двух шагов.
ТаблицаЗначений. Важно, чтобы имена колонок в создаваемой ТЗ в точности совпадали с именами реквизитов табличной части документа.Загрузить() табличной части документа, передав ему нашу подготовленную ТЗ.Давайте посмотрим, как это выглядит в коде. Сначала напишем универсальную функцию для преобразования массива структур в ТЗ.
Функция МассивСтруктурВТаблицуЗначений(МассивСтруктур)
Если МассивСтруктур = Неопределено Или МассивСтруктур.Количество() = 0 Тогда
Возврат Новый ТаблицаЗначений;
КонецЕсли;
// Создаем новую Таблицу Значений
ТЗ = Новый ТаблицаЗначений;
// Создаем колонки в ТЗ на основе ключей первой структуры в массиве
Для каждого КлючИЗначение Из МассивСтруктур[0] Цикл
ТЗ.Колонки.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
// Заполняем строки ТЗ данными из массива
Для каждого ЭлементМассива Из МассивСтруктур Цикл
НоваяСтрокаТЗ = ТЗ.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрокаТЗ, ЭлементМассива);
КонецЦикла;
Возврат ТЗ;
КонецФункции
Теперь используем эту функцию для нашей задачи.
// Исходный массив структур (тот же, что и в первом примере)
МассивДанных = Новый Массив;
МассивДанных.Добавить(Новый Структура("Номенклатура, Количество, Цена", Справочники.Номенклатура.НайтиПоКоду("001"), 2, 1500));
МассивДанных.Добавить(Новый Структура("Номенклатура, Количество, Цена", Справочники.Номенклатура.НайтиПоКоду("005"), 10, 500));
// Шаг 1: Преобразуем массив в Таблицу Значений
ТаблицаДляЗагрузки = МассивСтруктурВТаблицуЗначений(МассивДанных);
// Шаг 2: Очищаем табличную часть документа и загружаем в нее ТЗ
Док.Товары.Очистить();
Док.Товары.Загрузить(ТаблицаДляЗагрузки);
Этот метод предпочтительнее для больших объемов данных, так как он оптимизирован на уровне платформы и выполняется значительно быстрее, чем добавление строк в цикле. Код также становится более читаемым и структурированным. При обработке больших массивов данных из внешних файлов маркетплейсов в 1С:Бухгалтерии 3.0 применяется загрузка отчётов о продажах из Excel для переноса сведений в документы.
В современных типовых конфигурациях, использующих Библиотеку стандартных подсистем (БСП) или имеющих собственные библиотеки общего кода, часто уже есть готовые функции для подобных преобразований. Это самый правильный подход, так как он позволяет не "изобретать велосипед" и использовать уже протестированный и поддерживаемый код.
Как было подсказано в обсуждении, в конфигурации "Управление торговлей" для этой цели существует удобная функция.
Пример для "Управление торговлей":
// Вызываем готовую функцию из общего модуля
ТаблицаДляЗагрузки = ОбщегоНазначенияУТ.МассивВТаблицуЗначений(МассивДанных);
// И загружаем результат
Док.Товары.Очистить();
Док.Товары.Загрузить(ТаблицаДляЗагрузки);
Преимущества этого подхода:
Поэтому, прежде чем писать свою функцию преобразования, всегда проверяйте общие модули вашей конфигурации (например, с названиями ОбщегоНазначения, РаботаСМассивами, РаботаСоЗначениями и т.п.) на предмет наличия подходящих инструментов.