Как правильно преобразовать ТабличныйДокумент в ТаблицуЗначений в 1С

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

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

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

Рассмотрим ситуацию, когда начинающий разработчик пытается обойти ячейки табличного документа в цикле, используя строковую адресацию типа "R1C1". На этом этапе часто возникают досадные ошибки, которые трудно отловить с первого взгляда. Разберем их, чтобы не повторять в будущем:

  1. Смешение раскладок: Одна из самых коварных проблем — использование русской буквы "С" вместо английской "C" в строке адреса области. Визуально они идентичны, но для платформы 1С это разные символы, и метод Область() просто не поймет, что вы от него хотите.
  2. Опечатки в методах: Например, написание Облать() вместо Область(). Всегда внимательно проверяйте синтаксис или используйте контекстную подсказку (Ctrl + Space).
  3. Использование зарезервированных слов: Крайне не рекомендуется называть переменные именами встроенных типов или функций, например Строка = Новый Структура;. Это может привести к конфликтам при обращении к глобальным методам преобразования типов.

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


// Неоптимальный вариант с возможными ошибками раскладки
x = 2; // Начинаем со второй строки, так как первая — заголовок
Пока Таблица.Область("R" + Строка(x) + "C1").Текст <> "" Цикл
    НоваяСтрока = ТаблицаЗначений.Добавить();
    НоваяСтрока.Номенклатура = Таблица.Область("R" + Строка(x) + "C1").Текст;
    НоваяСтрока.Количество = Число(Таблица.Область("R" + Строка(x) + "C3").Текст);
    x = x + 1;
КонецЦикла;

Способ 1: Обход ячеек с использованием числовых индексов

Чтобы навсегда забыть о проблемах с раскладкой "R" и "C", мы рекомендуем использовать альтернативный синтаксис метода Область(), где вместо строки передаются числовые координаты ячейки: Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки). Это делает код более читаемым и защищенным от опечаток.

Давайте посмотрим на пример правильного обхода таблицы с использованием свойств ВысотаТаблицы для определения границ цикла:


Процедура ЗаполнитьТЧНаСервере(ТабДок, ТаблицаЗначений)
    
    // Определяем границы таблицы
    ВсегоСтрок = ТабДок.ВысотаТаблицы;
    
    // Начинаем со второй строки, предполагая наличие шапки
    Для НомерСтроки = 2 По ВсегоСтрок Цикл
        
        // Получаем текст из первой колонки (Номенклатура)
        ТекстНоменклатуры = ТабДок.Область(НомерСтроки, 1, НомерСтроки, 1).Текст;
        
        // Если ячейка пустая, пропускаем строку
        Если ПустаяСтрока(ТекстНоменклатуры) Тогда
            Продолжить;
        КонецЕсли;
        
        НоваяСтрока = ТаблицаЗначений.Добавить();
        НоваяСтрока.Номенклатура = СокрЛП(ТекстНоменклатуры);
        
        // Обрабатываем числовые показатели
        ТекстКоличества = ТабДок.Область(НомерСтроки, 3, НомерСтроки, 3).Текст;
        // Очищаем строку от неразрывных пробелов перед преобразованием в число
        ЧистоеКоличество = СтрЗаменить(ТекстКоличества, Символы.НПП, "");
        НоваяСтрока.Количество = Число(ЧистоеКоличество);
        
        ТекстЦены = ТабДок.Область(НомерСтроки, 4, НомерСтроки, 4).Текст;
        ЧистаяЦена = СтрЗаменить(ТекстЦены, Символы.НПП, "");
        НоваяСтрока.Цена = Число(ЧистаяЦена);
        
    КонецЦикла;
    
КонецПроцедуры

Способ 2: Использование Построителя Отчета (быстрый метод)

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

Рассмотрим этот метод подробнее:


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

Обратите внимание на ограничения этого метода:

Важные нюансы при работе с данными

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

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

Выясним, какой метод лучше выбрать. Для простых задач с небольшим объемом данных и сложной структурой (где нужно проверять условия в каждой строке) идеально подходит Способ 1 (цикл). Для массовой загрузки "чистых" табличных данных без сложной логики проверки лучше использовать Способ 2 (Построитель).

← На главную