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

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

При разработке внешних обработок на обычных формах часто возникает задача отображения данных, структура которых заранее неизвестна. Например, это может быть загрузка данных из произвольного Excel или CSV файла, где количество и состав колонок определяются содержимым самого файла. В процессе реализации программисты часто сталкиваются с ошибками при попытке очистить таблицу и заполнить её заново.

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

Разбор типичной ошибки при работе с колонками

Проанализируем ситуацию: разработчик пытается программно создать структуру таблицы. При первом нажатии кнопки на форме всё работает корректно, но при повторном вызове процедуры система выдает ошибку: «Ошибка при вызове метода контекста (Добавить): Недопустимое значение параметра (параметр номер '1')». Это происходит на этапе добавления колонки в ЭлементыФормы.ТаблицаЗагрузки.Колонки.

Выясним причину этой проблемы. Когда мы вручную добавляем колонку в визуальный элемент ТабличноеПоле, 1С жестко связывает имя колонки с её внутренним идентификатором в коллекции элементов формы. Даже если вы вызываете Очистить() для самой таблицы значений, визуальный элемент управления на форме может сохранять «память» о старых колонках или конфликтовать с новыми данными при попытке их пересоздания с теми же именами.

Правильный алгоритм: метод СоздатьКолонки()

Основной секрет стабильной работы динамических таблиц на обычных формах заключается в том, что нам не нужно вручную добавлять колонки в ЭлементыФормы. Вместо этого следует использовать автоматизацию, предусмотренную платформой.

Разберем по шагам правильную последовательность действий:

  1. Очистка структуры: Сначала мы полностью очищаем колонки и строки у объекта-источника данных (переменной типа ТаблицаЗначений).
  2. Формирование структуры: Добавляем нужные колонки только в программный объект ТаблицаЗначений, определяя их имена и типы данных.
  3. Связь с интерфейсом: Вызываем метод СоздатьКолонки() у элемента формы. Этот метод автоматически анализирует структуру привязанной таблицы значений и перестраивает визуальное отображение «с нуля», удаляя всё старое и создавая новое.

Программная реализация динамической загрузки

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


Процедура ЗагрузитьДанныеНажатие(Элемент)
    
    // 1. Проверка выбора файла
    Если Не ЗначениеЗаполнено(ФайлЗагрузки) Тогда
        Предупреждение("Выберите файл для загрузки!");
        Возврат;
    КонецЕсли;

    // 2. Полная очистка структуры данных
    // Сначала удаляем данные и колонки из программного объекта
    ТаблицаЗагрузки.Очистить();
    ТаблицаЗагрузки.Колонки.Очистить();
    
    // Теперь синхронизируем визуальный элемент с пустой таблицей
    // Это удалит все старые колонки из интерфейса
    ЭлементыФормы.ТаблицаЗагрузки.СоздатьКолонки();

    // 3. Подготовка типов данных
    КвалификаторСтроки = Новый КвалификаторыСтроки(250);
    ОписаниеТипаСтрока = Новый ОписаниеТипов("Строка", , КвалификаторСтроки);

    // 4. Чтение файла и создание структуры
    ЗагружаемыйФайл = Новый ТекстовыйДокумент;
    ЗагружаемыйФайл.Прочитать(ФайлЗагрузки);
    
    Если ЗагружаемыйФайл.КоличествоСтрок() = 0 Тогда
        Возврат;
    КонецЕсли;

    // Читаем первую строку (шапку) для создания колонок
    СтрокаШапки = ЗагружаемыйФайл.ПолучитьСтроку(1);
    МассивИменКолонок = РазложитьСтрокуВМассивПодстрок(СтрокаШапки, ";"); // Используем ваш разделитель

    Для Каждого ИмяКолонки Из МассивИменКолонок Цикл
        // Очищаем имя от пробелов и спецсимволов для корректного идентификатора
        ИмяБезОшибок = СтрЗаменить(ИмяКолонки, " ", "");
        
        // Добавляем колонку ТОЛЬКО в таблицу значений (объект данных)
        ТаблицаЗагрузки.Колонки.Добавить(ИмяБезОшибок, ОписаниеТипаСтрока, ИмяКолонки, 15);
    КонецЦикла;

    // 5. КЛЮЧЕВОЙ МОМЕНТ: Обновляем колонки на форме одной командой
    ЭлементыФормы.ТаблицаЗагрузки.СоздатьКолонки();

    // 6. Заполнение данными
    Для НомерСтроки = 2 по ЗагружаемыйФайл.КоличествоСтрок() Цикл
        ТекСтрокаФайла = ЗагружаемыйФайл.ПолучитьСтроку(НомерСтроки);
        Если ПустаяСтрока(ТекСтрокаФайла) Тогда
            Продолжить;
        КонецЕсли;
        
        ДанныеСтроки = РазложитьСтрокуВМассивПодстрок(ТекСтрокаФайла, ";");
        НоваяСтрокаТЗ = ТаблицаЗагрузки.Добавить();
        
        // Заполняем колонки по индексу
        Для Индекс = 0 По ТаблицаЗагрузки.Колонки.Количество() - 1 Цикл
            Если Индекс < ДанныеСтроки.Количество() Тогда
                НоваяСтрокаТЗ[Индекс] = ДанныеСтроки[Индекс];
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;

КонецПроцедуры

Важные замечания по работе с типами данных

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

Посмотрим на пример создания числовой колонки с квалификаторами:


КЧ = Новый КвалификаторыЧисла(15, 2);
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
ОписаниеТипаЧисло = Новый ОписаниеТипов(МассивТипов, , , КЧ);

ТаблицаЗагрузки.Колонки.Добавить("Сумма", ОписаниеТипаЧисло, "Сумма документа");

Почему не стоит удалять колонки формы вручную?

Многие начинающие разработчики пытаются использовать цикл ЭлементыФормы.ТаблицаЗагрузки.Колонки.Удалить(). Проанализируем, почему это плохая практика:

Итоги и рекомендации

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

Если вам требуется дополнительно настроить внешний вид созданных колонок (например, установить ширину или запретить редактирование), делайте это сразу после вызова метода СоздатьКолонки(), обращаясь к коллекции ЭлементыФормы.ТаблицаЗагрузки.Колонки. На этот момент структура уже будет соответствовать вашей таблице, и вы сможете безопасно обращаться к колонкам по их именам.

← На главную