Разработчики, переходящие в среду 1С:Предприятие из других языков программирования (например, Visual Basic или VBA), часто ищут привычные инструменты для управления памятью и коллекциями. Одним из таких инструментов является инструкция ReDim Preserve, которая позволяет динамически изменять размерность существующего массива, сохраняя при этом все накопленные в нем данные. В этой статье мы подробно разберем, как устроены массивы в 1С, как правильно управлять их размером и какие альтернативные объекты платформы можно использовать для решения подобных задач.
Начнем с главного отличия платформ: в 1С все стандартные массивы по умолчанию являются динамическими. Нам не требуется заранее жестко объявлять размерность массива для последующей работы с ним (как это делается в классическом статическом VB). Платформа 1С берет на себя управление выделением оперативной памяти под новые элементы.
Если нам необходимо добавить новый элемент в конец массива, мы не переопределяем его размер заново, а просто используем встроенный метод Добавить(). Посмотрим на простой пример создания и наполнения одномерного массива:
// Создаем пустой массив с нулевым количеством элементов
ДинамическийМассив = Новый Массив;
// Последовательно наполняем его данными
ДинамическийМассив.Добавить("Значение 1");
ДинамическийМассив.Добавить("Значение 2");
ДинамическийМассив.Добавить("Значение 3");
Каждый вызов метода Добавить() автоматически увеличивает размер коллекции на единицу, сохраняя все ранее записанные значения. Таким образом, классический аналог связки переопределения размерности в VBA здесь попросту не нужен.
Иногда алгоритм требует, чтобы массив изначально имел определенное количество ячеек (например, 12 элементов для месяцев года), к которым мы будем обращаться напрямую по их индексам. В 1С это реализуется при помощи передачи параметров в конструктор Новый Массив. Проанализируем пример инициализации:
// Создаем массив, сразу содержащий 12 элементов
МассивМесяцев = Новый Массив(12);
// Теперь мы можем обращаться к элементам по индексу
МассивМесяцев[0] = "Январь";
МассивМесяцев[11] = "Декабрь";
Важное ограничение платформы: В 1С индексы элементов массива всегда начинаются строго с 0. Задать произвольный диапазон индексов (например, от 1 до 12, как это позволяет конструкция 1 To 12 в VBA) невозможно. Первый элемент всегда будет иметь индекс 0, а последний — индекс Количество() - 1.
У объекта Массив в 1С нет прямого метода, позволяющего одной строкой кода изменить текущую длину до конкретного значения (например, уменьшить массив с 10 элементов до 5 или увеличить до 15). Тем не менее мы можем легко реализовать это поведение самостоятельно.
Если нам нужно гарантированно расширить существующий массив до определенного размера, сохранив старые значения, а новые ячейки заполнить пустыми значениями (Неопределено), мы можем использовать простой цикл:
// Исходный массив из 3 элементов
МойМассив = Новый Массив;
МойМассив.Добавить("А");
МойМассив.Добавить("Б");
МойМассив.Добавить("В");
ТребуемыйРазмер = 7; // Хотим расширить массив до 7 элементов
// Добавляем новые пустые элементы, пока не достигнем нужного размера
Пока МойМассив.Количество() < ТребуемыйРазмер Цикл
МойМассив.Добавить(Неопределено);
КонецЦикла;
Для уменьшения размерности массива без потери данных в оставшейся части нам необходимо удалять лишние элементы. При этом крайне важно соблюдать правило: удаление элементов должно производиться строго с конца массива (начиная с самых старших индексов).
Если начать удалять элементы с начала или середины коллекции, индексы оставшихся элементов динамически сдвинутся влево, что приведет к ошибкам позиционирования или выходу за границы в процессе работы цикла. Для безопасного обрезания мы задействуем метод ВГраница(), возвращающий максимальный индекс в массиве:
// Исходный массив из 5 элементов
МойМассив = Новый Массив;
МойМассив.Добавить("Элемент 1");
МойМассив.Добавить("Элемент 2");
МойМассив.Добавить("Элемент 3");
МойМассив.Добавить("Элемент 4");
МойМассив.Добавить("Элемент 5");
ТребуемыйРазмер = 3; // Хотим оставить только первые 3 элемента
// Удаляем элементы с конца, пока размер не уменьшится до требуемого
Пока МойМассив.Количество() > ТребуемыйРазмер Цикл
ИндексКонца = МойМассив.ВГраница();
МойМассив.Удалить(ИндексКонца);
КонецЦикла;
Если логика вашей программы завязана на работу со сложными или разреженными ключами, стандартный массив может оказаться не лучшим выбором. Платформа предлагает более специализированные коллекции.
Свернуть() или мгновенно выгружать значения отдельных колонок обратно в массив с помощью метода ВыгрузитьКолонку().Резюмируя, можно сказать, что явного аналога ReDim Preserve в 1С нет, поскольку философия работы с динамической памятью здесь иная. Благодаря встроенным динамическим свойствам массивов и простым циклам обрезания/добавления, любые манипуляции с размерностью коллекций реализуются прозрачно и надежно.