Как преобразовать строку с разделителями в таблицу значений с динамическим числом колонок

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработчика 1С часто возникает задача преобразования текстовой информации в табличный вид. Особенную сложность представляет ситуация, когда количество значений в строке заранее неизвестно, и нам необходимо динамически формировать структуру Таблицы Значений. В этой статье мы разберем несколько эффективных способов решения данной задачи, проанализируем нюансы именования колонок и рассмотрим современные подходы с использованием БСП.

Метод 1: Классический алгоритм с использованием массива и цикла

Рассмотрим наиболее гибкий и понятный способ, который работает на любой версии платформы, начиная с 8.3.6. Основная идея заключается в предварительном разбиении строки в массив и последующем создании колонок с программно сгенерированными именами.

Выясним причину, по которой нельзя просто добавить данные в таблицу: ТаблицаЗначений требует жесткого определения структуры перед добавлением строк. Если мы не знаем количество элементов в строке "Значение1-Значение2-...", нам нужно сначала посчитать их.

Проанализируем следующий пример кода:


// Исходная строка с разделителями
СтрокаДанных = "Значение1-Значение2-Значение3-ЗначениеN";

// Разделяем строку в массив по разделителю "-"
МассивЭлементов = СтрРазделить(СтрокаДанных, "-");

// Создаем объект ТаблицаЗначений
ТЗ = Новый ТаблицаЗначений;

// Шаг 1: Динамическое создание колонок
Для Итератор = 1 По МассивЭлементов.Количество() Цикл
    // Формируем уникальное имя колонки, так как имя не может начинаться с цифры
    ИмяКолонки = "Колонка" + Итератор;
    ТЗ.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов("Строка"), "Значение " + Итератор);
КонецЦикла;

// Шаг 2: Добавление строки и заполнение данными
НоваяСтрока = ТЗ.Добавить();
Для Индекс = 0 По МассивЭлементов.Количество() - 1 Цикл
    ИмяКолонки = "Колонка" + (Индекс + 1);
    НоваяСтрока[ИмяКолонки] = МассивЭлементов[Индекс];
КонецЦикла;

В данном примере мы использовали функцию СтрРазделить, которая является стандартным инструментом платформы. Обратите внимание, что при создании колонок мы добавили префикс "Колонка", так как 1С не позволяет использовать чисто числовые идентификаторы для имен полей.

Метод 2: Использование функций Библиотеки Стандартных Подсистем (БСП)

Если ваша конфигурация построена на базе БСП (например, 1С:Управление торговлей 11 или 1С:ERP), мы можем значительно упростить себе задачу, используя готовые универсальные методы. Это позволяет избежать написания "велосипедов" и делает код более надежным.

Разберем вариант с использованием программного интерфейса БСП:


СтрокаЭлементов = "Значение1-Значение2-Значение3";
МассивЭлементов = СтрРазделить(СтрокаЭлементов, "-");

// Превращаем массив в структуру, чтобы БСП могла распознать поля
СтруктураЭлементов = Новый Структура;
Для К = 1 По МассивЭлементов.Количество() Цикл
    СтруктураЭлементов.Вставить("Поле" + К, МассивЭлементов[К-1]);
КонецЦикла;

МассивСтруктур = Новый Массив;
МассивСтруктур.Добавить(СтруктураЭлементов);

// Используем метод БСП для создания ТЗ из массива структур
ТЗ = ОбщегоНазначения.РазгрузитьТаблицу(МассивСтруктур);

Также существует метод ОбщегоНазначенияКлиентСервер.ДополнитьТаблицуИзМассива, который позволяет быстро наполнять уже существующую таблицу, если её структура совпадает с данными массива.

Метод 3: Решение для устаревших версий платформы (до 8.3.6)

Если вам приходится работать в условиях, где функция СтрРазделить еще не доступна (старые релизы 8.2 или 8.3), мы можем применить "классический" метод преобразования разделителей в символы переноса строки. Посмотрим на этот алгоритм:


СтрокаДанных = "Значение1-Значение2-Значение3";
// Заменяем разделитель на символ переноса строки
ПодготовленнаяСтрока = СтрЗаменить(СтрокаДанных, "-", Символы.ПС);

ТЗ = Новый ТаблицаЗначений;
КолВоСтрок = СтрЧислоСтрок(ПодготовленнаяСтрока);

// Создаем колонки
Для Номер = 1 По КолВоСтрок Цикл
    ТЗ.Колонки.Добавить("К" + Номер);
КонецЦикла;

НоваяСтрока = ТЗ.Добавить();
// Заполняем данными, извлекая их по номерам строк
Для Номер = 1 По КолВоСтрок Цикл
    НоваяСтрока["К" + Номер] = СтрПолучитьСтроку(ПодготовленнаяСтрока, Номер);
КонецЦикла;

Этот метод считается менее производительным на очень больших объемах данных из-за работы функции СтрПолучитьСтроку, но он абсолютно универсален для старых систем.

Важные технические рекомендации

При реализации подобных алгоритмов всегда следует учитывать несколько критических моментов, которые могут привести к ошибкам в работе программы:

  1. Правила именования колонок: Имя колонки должно быть правильным идентификатором. Оно не может содержать пробелов, начинаться с цифры или содержать специальные символы. Если вы планируете называть колонки именами самих значений, обязательно используйте функцию очистки строки от недопустимых символов.
  2. Типизация данных: По умолчанию колонка создается с типом Произвольный. Для оптимизации памяти и корректной сортировки рекомендуется явно указывать ОписаниеТипов при вызове метода Добавить() коллекции колонок.
  3. Обработка пустых значений: Если в вашей строке могут идти два разделителя подряд (например, "Значение1--Значение3"), функция СтрРазделить создаст пустой элемент. Используйте третий параметр функции Ложь, если хотите игнорировать пустые фрагменты текста.
  4. Лимиты: Помните, что ТаблицаЗначений хранится в оперативной памяти. При обработке строк длиной в миллионы символов с тысячами разделителей вы можете столкнуться с нехваткой памяти на стороне сервера или клиента.

Проанализировав эти методы, мы видим, что наиболее современным и эффективным является использование функции СтрРазделить в сочетании с типизацией колонок. Это обеспечивает высокую скорость работы и чистоту программного кода.

← На главную