При интеграции 1С со сторонними системами часто возникает задача экспорта отчетов или печатных форм в текстовый формат с разделителями (CSV). Разберем особенности платформы 1С:Предприятие 8.3, выясним, почему нельзя просто указать тип файла CSV в стандартном методе сохранения, и рассмотрим надежные способы решения этой задачи.
Проанализируем возможности системного перечисления ТипФайлаТабличногоДокумента. В платформе 1С:Предприятие метод ТабличныйДокумент.Записать() поддерживает выгрузку во множество форматов: XLSX, PDF, DOCX, HTML, MXL, а также текстовые форматы TXT и ANSITXT. Однако формата CSV в этом списке нет, и метод не позволяет задать произвольный разделитель колонок или правила экранирования спецсимволов.
Посмотрим на практические варианты реализации выгрузки данных в формат CSV.
Рассмотрим самый быстрый способ, предложенный на практике: сохранить табличный документ как текстовый файл с разделителями-табуляциями, после чего программно заменить символы табуляции на нужный разделитель (например, точку с запятой).
Разберем по шагам, как реализовать этот подход:
ТабличныйДокумент во временный файл с типом ТипФайлаТабличногоДокумента.TXT.ТекстовыйДокумент или строковую переменную.Символы.Таб) на требуемый разделитель (запятую или точку с запятой)..csv.Посмотрим на пример программного кода:
// 1. Сохраняем табличный документ в текстовый формат
ВременныйФайл = ПолучитьИмяВременногоФайла("txt");
ТабДок.Записать(ВременныйФайл, ТипФайлаТабличногоДокумента.TXT);
// 2. Считываем содержимое и заменяем табуляцию на точку с запятой
ТекстДок = Новый ТекстовыйДокумент;
ТекстДок.Прочитать(ВременныйФайл, КодировкаТекста.UTF8);
Текст = ТекстДок.ПолучитьТекст();
ТекстCSV = СтрЗаменить(Текст, Символы.Таб, ";");
// 3. Сохраняем итоговый CSV-файл
ТекстДокCSV = Новый ТекстовыйДокумент;
ТекстДокCSV.УстановитьТекст(ТекстCSV);
ТекстДокCSV.Записать(ПутьКФайлуCSV, КодировкаТекста.UTF8);
УдалитьФайлы(ВременныйФайл);
Важное замечание: данный способ подходит только для простых плоских таблиц. Если в ячейках исходного документа уже присутствуют символы переноса строк или разделители, файл может сформироваться некорректно.
Если печатная форма уже сгенерирована (например, через СКД или внешний отчет) и нам требуется строгое соблюдение стандарта CSV с экранированием строк, наиболее надежным решением будет построчный обход области ячеек.
Разберем алгоритм решения:
ТабличныйДокумент.ВысотаТаблицы и ТабличныйДокумент.ШиринаТаблицы.ЗаписьТекста с указанием требуемой кодировки.Текст каждой ячейки.Посмотрим на пример реализации обхода:
ЗаписьCSV = Новый ЗаписьТекста(ПутьКФайлуCSV, КодировкаТекста.UTF8);
Высота = ТабДок.ВысотаТаблицы;
Ширина = ТабДок.ШиринаТаблицы;
Разделитель = ";";
Для НомерСтроки = 1 По Высота Цикл
МассивКолонок = Новый Массив;
Для НомерКолонки = 1 По Ширина Цикл
ЗначениеЯчейки = ТабДок.Область(НомерСтроки, НомерКолонки).Текст;
// Экранирование кавычек
ЗначениеЯчейки = СтрЗаменить(ЗначениеЯчейки, """", """""");
// Оборачивание в кавычки при наличии спецсимволов
Если СтрНайти(ЗначениеЯчейки, Разделитель) > 0
Или СтрНайти(ЗначениеЯчейки, """") > 0
Или СтрНайти(ЗначениеЯчейки, Символы.ПС) > 0 Тогда
ЗначениеЯчейки = """" + ЗначениеЯчейки + """";
КонецЕсли;
МассивКолонок.Добавить(ЗначениеЯчейки);
КонецЦикла;
СтрокаCSV = СтрСоединить(МассивКолонок, Разделитель);
ЗаписьCSV.ЗаписатьСтроку(СтрокаCSV);
КонецЦикла;
ЗаписьCSV.Закрыть();
Проанализируем наиболее производительный и архитектурно правильный подход. Если вам требуется выгрузить результат запроса или ТаблицуЗначений, формировать промежуточный ТабличныйДокумент не требуется.
Прямой обход выборки данных через объект ЗаписьТекста работает значительно быстрее, не расходует память на построение графических элементов отчета и позволяет гибко управлять разделителями колонок и кодировкой итогового файла.