6

Как скопировать структуру в 1с 8?

Существует несколько способов скопировать содержимое одной структуры в другую.

Самое простое решение, к которому прибегают начинающие программисты — это копирование всех свойств структуры с использованием цикла Для каждого:

НоваяСтруктура = Новый Структура;

Для каждого Элемент Из Структура Цикл
	НоваяСтруктура.Вставить(Элемент.Ключ, Элемент.Значение);
КонецЦикла;

Но он годится только для простых структур, которые не содержат вложенных структур и коллекций. Попробуйте ради интереса самостоятельно написать код для копирования следующей структуры:

Структура = Новый Структура;
Структура.Вставить("Код", 100);
Структура.Вставить("Наименование", "Стул деревянный");
Структура.Вставить("Остатки", Новый Структура);
Структура.Остатки.Вставить("Основной", 10);
Структура.Остатки.Вставить("Дополнительный", 3);

Согласитесь, накладно каждый раз продумывать и писать код для копирования)

Более универсальным будет использование встроенных функций ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр(). К тому же, можно уложиться в одну строку:

НоваяСтруктура = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Структура));

Этот же способ можно использовать для копирования других коллекций (правда, в рамках одной информационной базы).

Читайте также:

  1. Программная работа со структурой

Поделиться страницей в соц.сетях

6 комментариев к записи “Как скопировать структуру в 1с 8?

  1. Есть решение гораздо проще и элегантнее — Копировать через преобразование в «Новый ФиксированнаяСтруктура()».

    // Оригинал
    Оригинал_Стр = Новый Структура;
    Оригинал_Стр.Вставить( «Ключ1», «Значение1» );
    Оригинал_Стр.Вставить( «Ключ2», «Значение2» );
    Оригинал_Стр.Вставить( «Ключ3», «Значение3» );
    ……
    // ЛайфХак
    Оригинал_Стр = Новый ФиксированнаяСтруктура( Оригинал_Стр );

    // Копирование
    Копия_1 = Новый Структура( Оригинал_Стр );
    Копия_2 = Новый Структура( Оригинал_Стр );
    ….

    1. Как вариант — возможно! Элегантный!? — под вопросом!
      Еще есть куда оптимизироваться)) Тот же конструктор ФиксированнаяСтруктура(Ключи, Значения)

  2. Оба решения, к сожалению не корректны. Надо именно проверять вложенные коллекции и копировать их. Нормального способа рекурсивно скопировать все содержимое коллекции нет
    Копирование через ФиксированнаяСтруктура — точно так же, как первый вариант автора, скопирует лишь ссылки на вложенные коллекции и любая попытка поменять, например, вложенный массив в копии приведет к его изменению в источнике.
    ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр() — фирма 1С не рекомендует использовать эти функции: https://its.1c.ru/db/metod8dev/content/2612/hdoc

    1. Дельное замечание, но по поводу функций ЗначениеВСтрокуВнутр() и ЗначениеИзСтрокиВнутр() дословно там сказано так:

      Использовать их в большинстве случаев не рекомендуется

      Т.е. это вовсе не означает, что пользоваться ими нельзя: не рекомендуется использовать их для хранения значений в базе на длительном отрезке времени, т.к. при архивации\разархивации базы изменятся идентификаторы метаданных и ссылки при восстановлении скорее всего слетят. Но для копирования сложной структуры — лучше варианта не найти…

  3. Как насчет варианта?

    Функция КопироватьСтруктуру(Знач Структура)
    Возврат Структура;
    КонецФункции

    1. Хорошая попытка, Сергей))
      Если бы все было так просто, все бы пользовались этим методом. Но как всегда, дьявол кроется в мелочах: передача по значению хорошо работает на примитивных типах: число, строка, дата и т.п. Но если передать в таком параметре ссылку, то копия ссылки будет ссылаться на тот же объект в памяти. Попробуйте для примера запустить следующий код:

      Функция СкопироватьОбъект(Знач Значение)
          
          Возврат Значение;    
          
      КонецФункции//СкопироватьОбъект()
      
      стр1 = Новый Структура("Тест", 1);
      стр2 = СкопироватьОбъект(стр1);
      стр2.Тест = 2;
      Сообщить(стрШаблон("%1 = %2", стр1.Тест, стр2.Тест));
      

      Подробнее написано здесь

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *