При разработке на платформе 1С:Предприятие 8 часто возникает задача преобразования данных из таблицы значений или другого набора данных в структуру. Однако новички часто сталкиваются с тем, что структура ведет себя не так, как ожидается. В этой статье мы подробно разберем, как правильно работать со структурами в циклах, какие существуют ограничения и какие альтернативные подходы считаются правильными с точки зрения архитектуры кода.
Представим ситуацию: у нас есть таблица значений ТЗКатегорийПайщиков с одной колонкой ИмяКатегории. Нам нужно перенести эти данные в структуру. Рассмотрим типичную ошибку начинающего разработчика:
СтруктураКатегорийПайщиков = Новый Структура;
Для каждого Категория Из ТЗКатегорийПайщиков Цикл
СтруктураКатегорийПайщиков.Вставить("ИмяКатегории", Категория.ИмяКатегории);
КонецЦикла;
Проанализируем этот код. На каждой итерации цикла метод Вставить() обращается к ключу "ИмяКатегории". Так как ключи в структуре должны быть уникальными, каждое новое значение просто перезаписывает предыдущее. В итоге в структуре останется только одна запись — из последней строки таблицы значений.
Если нам принципиально нужно хранить данные именно в одной структуре, мы должны обеспечить уникальность ключей. Один из способов — добавление счетчика к имени ключа. Рассмотрим пример:
СтруктураКатегорийПайщиков = Новый Структура;
Счетчик = 1;
Для каждого СтрокаТЗ Из ТЗКатегорийПайщиков Цикл
Ключ = "Строка" + Строка(Счетчик);
СтруктураКатегорийПайщиков.Вставить(Ключ, СтрокаТЗ.ИмяКатегории);
Счетчик = Счетчик + 1;
КонецЦикла;
В данном случае мы создаем ключи вида Строка1, Строка2 и так далее. Это рабочее решение, но у него есть технические ограничения, о которых важно помнить.
Важное ограничение: Ключ структуры в 1С обязан соответствовать правилам именования переменных. Это значит:
Если вы попытаетесь использовать в качестве ключа произвольный текст из справочника (например, "Хлебобулочные изделия"), программа выдаст ошибку, так как пробел недопустим в имени ключа.
Проанализируем ситуацию: если нам нужно хранить список однотипных объектов, то Структура — не самый подходящий инструмент. Гораздо правильнее использовать Массив, элементами которого будут структуры. Такой подход универсален, легко читается и идеально подходит для последующей сериализации в JSON.
Рассмотрим реализацию этого метода:
МассивКатегорий = Новый Массив;
Для каждого Категория Из ТЗКатегорийПайщиков Цикл
НоваяЗапись = Новый Структура;
НоваяЗапись.Вставить("ИмяКатегории", Категория.ИмяКатегории);
// Здесь можно добавить другие свойства строки
МассивКатегорий.Добавить(НоваяЗапись);
КонецЦикла;
В этом примере на каждой итерации создается новый экземпляр структуры, который затем помещается в массив. Это позволяет избежать конфликта ключей и сохранить структуру данных таблицы.
Если вам все же нужно хранить данные в формате "Ключ — Значение", но ключи непредсказуемы (содержат пробелы, цифры или являются ссылками на объекты), используйте объект Соответствие.
Выясним преимущества Соответствия:
СправочникСсылка.Пример заполнения соответствия в цикле:
МоеСоответствие = Новый Соответствие;
Для каждого Строка Из ТЗ Цикл
МоеСоответствие.Вставить(Строка.Наименование, Строка.Значение);
КонецЦикла;
В современных конфигурациях (таких как УТ 11, БП 3.0, ЗУП 3.1) разработчики уже написали вспомогательные функции, которые делают всю рутину за нас. Если в вашей базе есть БСП, мы крайне рекомендуем использовать программный интерфейс общего назначения.
Посмотрим на пример превращения всей таблицы значений в массив структур одной строкой:
МассивРезультат = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТЗКатегорийПайщиков);
Метод ТаблицаЗначенийВМассив самостоятельно обойдет все строки и колонки, создав массив структур, где ключами будут имена колонок вашей таблицы. Это максимально быстрый и надежный способ.
Если внутри цикла вам нужно быстро переложить данные из строки таблицы значений в структуру с точно такими же именами полей, воспользуйтесь методом ЗаполнитьЗначенияСвойств(). Это работает быстрее, чем ручной вызов метода Вставить() для каждого поля.
Проанализируем пример:
Для каждого СтрокаТЗ Из ТЗКатегорийПайщиков Цикл
ДанныеСтроки = Новый Структура("ИмяКатегории, Код, Описание"); // Инициализируем ключи
ЗаполнитьЗначенияСвойств(ДанныеСтроки, СтрокаТЗ);
МассивДанных.Добавить(ДанныеСтроки);
КонецЦикла;
Этот метод автоматически сопоставит имена колонок таблицы и ключи структуры, заполнив их значениями. Сходный принцип сопоставления объектов реализован и в решении для переноса данных между похожими конфигурациями 1С, которое поддерживает поиск по произвольным полям.
Мы рассмотрели несколько способов заполнения коллекций данных в цикле. Подведем итоги нашего анализа:
"Ключ1", "Ключ2") можно, но это неудобно для последующей обработки.Выбор конкретного метода зависит от вашей конечной цели: будет ли это передача данных на веб-сервер в формате JSON, промежуточное хранение параметров или вывод в отчет. Помните о правилах именования ключей структуры, и ваш код будет работать стабильно! Для контроля отсутствия ошибок в учете после подобных доработок полезно автоматически сравнить бухгалтерские проводки между базами.