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