Как программно сохранить ТаблицуЗначений в файл Excel в 1С 8.x?

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

При работе с платформой 1С:Предприятие 8.x часто возникает необходимость экспортировать данные из внутренней структуры, такой как ТаблицаЗначений, в популярный формат Microsoft Excel. Эта задача может показаться сложной для новичков, но мы рассмотрим несколько эффективных и программных способов, позволяющих выполнить эту операцию. При необходимости сохранить данные форм без написания кода можно использовать готовое решение для выгрузки табличных частей в Excel.

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

Мы разберем основные подходы, начиная от прямого заполнения ТабличногоДокумента и использования макетов, заканчивая более высокоуровневыми инструментами вроде ПостроителяОтчета и альтернативными методами сохранения в формат CSV.

Метод 1: Прямое заполнение ТабличногоДокумента

Это один из наиболее прямолинейных способов. Он заключается в том, что мы создаем новый ТабличныйДокумент и затем построчно и поколоночно переносим в него данные из нашей ТаблицыЗначений.

  1. Создаем ТабличныйДокумент:

    Для начала нам понадобится экземпляр объекта ТабличныйДокумент.

    ТабДок = Новый ТабличныйДокумент;
  2. Создаем и заполняем ТаблицуЗначений (для примера):

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

    
    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("К1");
    Таблица.Колонки.Добавить("К2");
    Таблица.Колонки.Добавить("К3");
    
    Строка = Таблица.Добавить();
    Строка.К1 = 7;
    Строка.К2 = 8;
    Строка.К3 = 9;
    
    Строка = Таблица.Добавить();
    Строка.К1 = 4;
    Строка.К2 = 5;
    Строка.К3 = 6;
    
  3. Переносим данные из ТаблицыЗначений в ТабличныйДокумент:

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

    Важно: При работе с номерами строк и колонок в ТабличномДокументе, особенно при формировании имен областей, следует быть внимательными к спецсимволам, которые могут появляться при преобразовании чисел в строки. Например, функция Строка() может добавить непечатаемый символ в начало строки, что нарушит работу. Чтобы избежать этого, мы можем использовать СтрЗаменить(Строка(С), Символы.НПП, "").

    
    // Заголовки колонок
    // Мы можем вывести заголовки вручную, используя имена колонок из ТаблицыЗначений.
    Для ИндексКолонки = 0 По Таблица.Колонки.Количество() - 1 Цикл
        ТабДок.Область("R1C" + (ИндексКолонки + 1)).Текст = Таблица.Колонки[ИндексКолонки].Имя;
    КонецЦикла;
    // Если мы хотим, чтобы заголовки были напечатаны, нам нужно их "Вывести".
    // Для этого можно использовать отдельную область или просто задать текст.
    // При прямом заполнении, можно просто задавать текст, а потом "Вывести" весь ТабличныйДокумент.
    // Однако, для корректного вывода данных, лучше выводить построчно.
    // Пример с выводом одной "секции" для данных, как в сообщении 12:
    // Предположим, что мы создаем секцию динамически для каждой строки.
    
    Для Н = 0 По Таблица.Количество() - 1 Цикл
        // С - это номер строки в ТабличномДокументе, начинаем с 2, если первая строка - заголовки.
        С = Н + 2; 
        ТабДок.Область("R" + СтрЗаменить(Строка(С), Символы.НПП, "") + "C1").Текст = Таблица[Н].К1;
        ТабДок.Область("R" + СтрЗаменить(Строка(С), Символы.НПП, "") + "C2").Текст = Таблица[Н].К2;
        ТабДок.Область("R" + СтрЗаменить(Строка(С), Символы.НПП, "") + "C3").Текст = Таблица[Н].К3;
        // В данном случае, так как мы заполняем ячейки напрямую, нам не нужно выводить каждую секцию отдельно,
        // если мы хотим, чтобы все было на одном листе. Мы просто заполняем ТабличныйДокумент, а затем его записываем.
        // Если бы мы использовали метод ПолучитьОбласть("R1") как в примере 12, то это была бы ссылка на первую строку.
        // Пример 12 некорректно использует ПолучитьОбласть("R1") и Вывести(Секция) внутри цикла без создания новых секций.
        // Правильный подход при прямом заполнении - это просто задать текст в ячейки по координатам.
        // Или использовать метод Вывести для каждой строки или области.
    
        // Корректный подход с использованием метода Вывести для каждой строки (более гибкий для форматирования)
        // Создадим временную область для текущей строки
        ТекущаяСтрокаОбласть = ТабДок.Область("R" + СтрЗаменить(Строка(С), Символы.НПП, "") + "C1:R" + СтрЗаменить(Строка(С), Символы.НПП, "") + "C" + Таблица.Колонки.Количество());
        ТекущаяСтрокаОбласть.Область("R1C1").Текст = Таблица[Н].К1; // Относительные координаты внутри ТекущаяСтрокаОбласть
        ТекущаяСтрокаОбласть.Область("R1C2").Текст = Таблица[Н].К2;
        ТекущаяСтрокаОбласть.Область("R1C3").Текст = Таблица[Н].К3;
        ТабДок.Вывести(ТекущаяСтрокаОбласть);
    КонецЦикла;
    

    В случае, если заголовки тоже должны быть выведены, можно сделать так:

    
    // Создаем ТабличныйДокумент
    ТабДок = Новый ТабличныйДокумент;
    
    // Выводим заголовки
    Для ИндексКолонки = 0 По Таблица.Колонки.Количество() - 1 Цикл
        ТабДок.Область("R1C" + (ИндексКолонки + 1)).Текст = Таблица.Колонки[ИндексКолонки].Имя;
    КонецЦикла;
    // Если нужно, чтобы заголовки были оформлены как одна область,
    // можно создать временную область для заголовков и затем ее вывести.
    ОбластьЗаголовков = ТабДок.Область("R1C1:R1C" + Таблица.Колонки.Количество());
    ТабДок.Вывести(ОбластьЗаголовков); // Выводим строку заголовков
    
    // Переносим данные из ТаблицыЗначений
    Для Каждого Стр Из Таблица Цикл
        // Номер строки в ТабличномДокументе, начинаем со 2, так как 1-я строка занята заголовками
        НомерСтрокиТД = ТабДок.ВысотаТаблицы + 1; // Определяем следующую свободную строку
        
        Для ИндексКолонки = 0 По Таблица.Колонки.Количество() - 1 Цикл
            // Заполняем ячейку в текущей строке ТабличногоДокумента
            ТабДок.Область("R" + СтрЗаменить(Строка(НомерСтрокиТД), Символы.НПП, "") + "C" + (ИндексКолонки + 1)).Текст = Стр[ИндексКолонки];
        КонецЦикла;
        // Или, если мы хотим явно выводить каждую строку как отдельную область:
        // Создаем временную область для текущей строки ТабличногоДокумента
        ТекущаяОбластьДанных = ТабДок.Область("R" + СтрЗаменить(Строка(НомерСтрокиТД), Символы.НПП, "") + "C1:R" + СтрЗаменить(Строка(НомерСтрокиТД), Символы.НПП, "") + "C" + Таблица.Колонки.Количество());
        
        Для ИндексКолонки = 0 По Таблица.Колонки.Количество() - 1 Цикл
            ТекущаяОбластьДанных.Область("R1C" + (ИндексКолонки + 1)).Текст = Стр[ИндексКолонки];
        КонецЦикла;
        ТабДок.Вывести(ТекущаяОбластьДанных);
    КонецЦикла;
    

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

  4. Сохраняем ТабличныйДокумент в Excel:

    Используем метод Записать() объекта ТабличныйДокумент, указывая путь к файлу и тип файла. Для современных версий Excel используйте ТипФайлаТабличногоДокумента.XLSX, для старых — ТипФайлаТабличногоДокумента.XLS или XLS97.

    
    // Сохранение в формат XLSX (современный Excel)
    ТабДок.Записать("C:\МоиДокументы\Отчет.xlsx", ТипФайлаТабличногоДокумента.XLSX);
    
    // Сохранение в формат XLS (старый Excel)
    ТабДок.Записать("C:\МоиДокументы\Отчет.xls", ТипФайлаТабличногоДокумента.XLS);
    

    После выполнения этого кода ваш файл Excel будет создан по указанному пути.

Метод 2: Заполнение ТабличногоДокумента с использованием макета

Если вам требуется более сложное форматирование, заголовки, подвалы или группировки, то использование макетов является предпочтительным. Макетом мы можем заранее определить структуру и внешний вид нашего будущего отчета. Для этой задачи также подойдет инструмент выгрузки данных из 1С в шаблон Excel.

  1. Создаем макет:

    В конфигураторе создайте новый макет (например, "МакетДляExcel") и определите в нем области, которые будут использоваться для вывода заголовков и строк данных. Каждая область может содержать параметры, которые мы будем заполнять программно.

    Например, мы можем создать область "Заголовок" с параметрами, соответствующими именам колонок, и область "СтрокаДанных" с параметрами для значений ячеек.

    Допустим, в макете есть область с именем "СтрокаТаблицы" и внутри этой области определены параметры, например, "Параметр1", "Параметр2" и т.д., соответствующие колонкам нашей ТаблицыЗначений.

  2. Получаем макет и области:

    В коде мы получаем наш макет и нужные области из него.

    
    Макет = ПолучитьМакет("МакетДляExcel"); // Имя вашего макета
    ТабДок = Новый ТабличныйДокумент;
    
    // Получаем область для заголовков
    ОбластьЗаголовков = Макет.ПолучитьОбласть("Заголовок"); 
    
    // Получаем область для строк данных
    ОбластьДанных = Макет.ПолучитьОбласть("СтрокаТаблицы");
    
  3. Заполняем параметры и выводим области:

    Мы заполняем параметры в области заголовков и выводим их. Затем в цикле по ТаблицеЗначений заполняем параметры области данных для каждой строки и также выводим ее.

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

    Это примерный подход. Если ваш макет имеет более сложную структуру (например, секции для каждой колонки как в сообщении 23), то код будет немного отличаться:

    
    Процедура ВывестиТЗвТаблицу(ТЗ, Заголовок = "")
    
        ТЕхел = Новый ТабличныйДокумент;
        Макет = ПолучитьМакет("Ехел"); // Здесь "Ехел" - это имя макета
    
        // Выводим заголовки
        Для ИндексКолонки = 0 По ТЗ.Колонки.Количество() - 1 Цикл
            Область = Макет.ПолучитьОбласть("Секция_1|Секция_2"); // Предполагается, что в макете есть такая область
            Область.Параметры.Параметр = ТЗ.Колонки[ИндексКолонки].Имя; // Заполняем параметр именем колонки
            
            Если ИндексКолонки = 0 Тогда // Если это первая колонка, выводим область
                ТЕхел.Вывести(Область);
            Иначе // Иначе присоединяем к предыдущей области (для колонок одной строки)
                ТЕхел.Присоединить(Область);
            КонецЕсли;
        КонецЦикла;
    
        // Выводим данные
        Для Каждого Стр Из ТЗ Цикл
            Для ИндексКолонки = 0 По ТЗ.Колонки.Количество() - 1 Цикл
                Область = Макет.ПолучитьОбласть("Секция_1|Секция_2"); // Снова получаем область для данных
                Область.Параметры.Параметр = Стр[ИндексКолонки]; // Заполняем параметр значением ячейки
                
                Если ИндексКолонки = 0 Тогда // Первая колонка новой строки
                    ТЕхел.Вывести(Область);
                Иначе // Остальные колонки той же строки
                    ТЕхел.Присоединить(Область);
                КонецЕсли;
            КонецЦикла;
        КонецЦикла;
    
        // Показываем ТабличныйДокумент (необязательно, но полезно для отладки)
        ТЕхел.Показать(Заголовок);
    
        // Сохраняем в файл Excel
        ИмяФайла = ?(ПустаяСтрока(Заголовок), ПолучитьИмяВременногоФайла(), КаталогВременныхФайлов() + "\" + Заголовок + ".xls");
        ТЕхел.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLS);
    
    КонецПроцедуры
    
  4. Сохраняем ТабличныйДокумент в Excel:

    Как и в предыдущем методе, используем Записать():

    
    ТабДок.Записать("C:\МоиДокументы\ОтчетСМакетом.xlsx", ТипФайлаТабличногоДокумента.XLSX);
    

Метод 3: Использование ПостроителяОтчета

ПостроительОтчета – это мощный и удобный инструмент для формирования отчетов в 1С. Он позволяет быстро преобразовать ТаблицуЗначений в ТабличныйДокумент с минимальным количеством кода, автоматически формируя заголовки и данные.

  1. Создаем ТабличныйДокумент и ПостроительОтчета:
    
    ТабДок = Новый ТабличныйДокумент;
    Построитель = Новый ПостроительОтчета;
    
  2. Указываем источник данных:

    Мы передаем нашу ТаблицуЗначений в ПостроительОтчета через объект ОписаниеИсточникаДанных.

    
    // Предположим, у нас есть ТаблицаЗначений с именем ТестоваяТаблица
    // (пример создания см. выше в Методе 1)
    Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТестоваяТаблица);
    
  3. Настраиваем построитель и выводим результат:

    Мы можем отключить вывод стандартного заголовка отчета, если он не нужен, и затем вызвать метод Вывести(), передав ему наш ТабличныйДокумент. ПостроительОтчета сам заполнит его данными из ТаблицыЗначений.

    
    Построитель.ВыводитьЗаголовокОтчета = Ложь; // Если не нужен стандартный заголовок
    Построитель.Вывести(ТабДок);
    
  4. Сохраняем ТабличныйДокумент:

    Завершающий шаг аналогичен предыдущим методам.

    
    ИмяФайла = "C:\Users\AbisSoft\Desktop\test.xls"; // Укажите свой путь
    ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLS97); // Или ТипФайлаТабличногоДокумента.XLSX
    

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

Метод 4: Сохранение в формат CSV

Хотя CSV (Comma Separated Values) не является нативным форматом Excel, файлы CSV легко открываются в Excel и могут служить отличной альтернативой, особенно для экспорта больших объемов чистых данных, где форматирование не играет ключевой роли. Этот метод не использует ТабличныйДокумент.

  1. Создаем объект ЗаписьТекста:

    Для записи в текстовый файл мы используем объект ЗаписьТекста, указывая имя файла и кодировку. Кодировка ANSI часто подходит для русского языка в Excel, но UTF8 может быть более универсальной.

    
    Процедура ЗаписатьТаблицуЗначенийВcsv(тз, ИмяФайла, Разделитель=";")
    
        ФайлCSV = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.ANSI);
    
  2. Записываем заголовки колонок:

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

    
    Текст = "";
    Для Каждого Колонка Из тз.Колонки Цикл
        Текст = Текст + Колонка.Имя + Разделитель;
    КонецЦикла;
    ФайлCSV.ЗаписатьСтроку(Текст);
    
  3. Записываем данные строк:

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

    
    Для Каждого Стр Из тз Цикл
        Текст = "";
        Для Каждого Колонка Из тз.Колонки Цикл
            Значение = Стр[Колонка.Имя];
            // Особая обработка для чисел, чтобы избежать лишних разделителей или ошибок формата
            Если ТипЗнч(Значение) = Тип("Число") Тогда
                Значение = Формат(Значение,"ЧГ=0"); // Форматируем число без группировки разрядов
            КонецЕсли;
            Текст = Текст + Значение + Разделитель;
        КонецЦикла;
        ФайлCSV.ЗаписатьСтроку(Текст);
    КонецЦикла;
    
  4. Закрываем файл:

    После записи всех данных обязательно закрываем файл.

    
        ФайлCSV.Закрыть();
    
    КонецПроцедуры
    

Этот метод прост, не требует наличия Microsoft Excel на компьютере и хорошо подходит для обмена данными между различными системами.

Дополнительные рекомендации и особенности

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

Форматы файлов

При сохранении ТабличногоДокумента в Excel, вы сталкиваетесь с выбором формата файла. Платформа 1С поддерживает несколько типов:

  1. ТипФайлаТабличногоДокумента.XLSX: Это современный формат Excel, используемый с версии 2007 и выше. Мы рекомендуем использовать его для максимальной совместимости с актуальными версиями Excel и для поддержки большего количества строк и столбцов.
  2. ТипФайлаТабличногоДокумента.XLS: Это старый формат Excel (до версии 2007). Если вам нужна обратная совместимость со старыми системами, которые могут не открывать XLSX, используйте этот формат.
  3. ТипФайлаТабличногоДокумента.XLS97: Этот формат аналогичен XLS, но может быть полезен в специфических случаях, когда нужна совместимость с самыми ранними версиями Excel.

Форматирование ячеек и типов данных

При использовании ТабличногоДокумента для экспорта в Excel, иногда возникает проблема с сохранением исходного типа данных ячеек. Например, числа могут быть экспортированы как текст, или даты могут отображаться некорректно. Рассмотрим этот момент подробнее:

Прямое взаимодействие с Excel через COM-объект (OLE-автоматизация)

Мы можем напрямую управлять приложением Microsoft Excel через COM-объект. Этот метод предоставляет максимальный контроль над процессом сохранения, включая:

Алгоритм работы:

  1. Создаем COM-объект Excel:
    
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
    Исключение
        Сообщить("Не удалось запустить Excel. Возможно, он не установлен или отсутствует COM-обобъект.");
        Возврат;
    КонецПопытки;
    Excel.Visible = Ложь; // Или Истина, если нужно видеть Excel
    Книга = Excel.Workbooks.Add();
    Лист = Книга.Sheets(1);
    
  2. Записываем данные в ячейки:

    Проходим по ТаблицеЗначений и записываем данные напрямую в ячейки листа Excel.

    
    // Заголовки
    Для ИндексКолонки = 0 По Таблица.Колонки.Количество() - 1 Цикл
        Лист.Cells(1, ИндексКолонки + 1).Value = Таблица.Колонки[ИндексКолонки].Имя;
    КонецЦикла;
    
    // Данные
    Для ИндексСтроки = 0 По Таблица.Количество() - 1 Цикл
        Для ИндексКолонки = 0 По Таблица.Колонки.Количество() - 1 Цикл
            ЗначениеЯчейки = Таблица[ИндексСтроки][ИндексКолонки];
            Лист.Cells(ИндексСтроки + 2, ИндексКолонки + 1).Value = ЗначениеЯчейки;
            
            // Пример форматирования: установка формата даты
            Если ТипЗнч(ЗначениеЯчейки) = Тип("Дата") Тогда
                Лист.Cells(ИндексСтроки + 2, ИндексКолонки + 1).NumberFormat = "ДД.ММ.ГГГГ";
            КонецЕсли;
            // Пример форматирования: установка формата числа
            Если ТипЗнч(ЗначениеЯчейки) = Тип("Число") Тогда
                Лист.Cells(ИндексСтроки + 2, ИндексКолонки + 1).NumberFormat = "0.00"; // Два знака после запятой
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    
  3. Сохраняем и закрываем:
    
    Книга.SaveAs("C:\МоиДокументы\ОтчетOLE.xlsx");
    Книга.Close(Ложь); // Закрыть без сохранения изменений
    Excel.Quit(); // Завершить работу Excel
    

Недостатки COM-объекта:

Производительность

При работе с большими ТаблицамиЗначений (более нескольких тысяч строк) важно учитывать производительность выбранного метода:

Сохранение нескольких ТаблицЗначений на разных листах Excel

Если нам необходимо сохранить несколько ТаблицЗначений в один файл Excel, но на разных листах, мы можем комбинировать подходы:

  1. Сохраняем каждую ТаблицуЗначений во временный ТабличныйДокумент (используя Методы 1, 2 или 3).
  2. Затем, используя COM-объект Excel, мы открываем созданный первый файл Excel, добавляем новые листы и копируем на них данные из других временных ТабличныхДокументов (которые также предварительно можно сохранить во временные файлы .xls/.xlsx). Это позволит объединить несколько отчетов в одну книгу Excel с разными вкладками.

Заключение

Мы видим, что в 1С:Предприятии 8.x существует несколько мощных и гибких способов для программного сохранения ТаблицыЗначений в файл Excel. Выбор конкретного метода зависит от ваших требований к форматированию, объему данных, производительности и наличию Microsoft Excel на машине пользователя. Для быстрой и простой выгрузки больших объемов данных мы рекомендуем использовать ПостроительОтчета или сохранение в CSV. Если требуется сложное и детальное форматирование, то макеты ТабличногоДокумента или прямое взаимодействие через COM-объект Excel будут более подходящими, с учетом их особенностей.

Мы проанализировали каждый подход, предоставив рабочие примеры кода и объяснения, чтобы вы могли уверенно применять эти знания в своих проектах 1С.

← На главную