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