Перевод механизмов обмена данными с формата XML на CSV — это распространенная задача, когда требуется обеспечить совместимость с банковскими системами или упростить чтение данных в редакторах таблиц вроде Microsoft Excel. В отличие от иерархического XML, формат CSV (Comma Separated Values) имеет плоскую структуру, где данные разделены определенным символом (обычно запятой или точкой с запятой). В этой статье мы подробно разберем, как изменить существующую обработку выгрузки, проанализируем примеры кода и обсудим важные технические нюансы, которые часто остаются за кадром на форумах.
Для того чтобы успешно сформировать CSV, нам необходимо придерживаться строгой последовательности действий. В отличие от XML, где мы открываем и закрываем узлы (теги), здесь мы работаем со строками текста. Рассмотрим основные этапы:
Рассмотрим ситуацию, когда нам нужно выгрузить зарплатную ведомость. Для реализации выгрузки в 1С удобнее всего использовать объект ТекстовыйДокумент. Проанализируем пример кода, который решает задачу формирования файла с информацией о лицевых счетах сотрудников.
Сначала подготовим запрос и определим шапку файла. Обратите внимание, что в качестве разделителя мы будем использовать точку с запятой ;, так как это стандарт для русской локализации Windows и Excel.
// Инициализация объекта для работы с текстом
ТД = Новый ТекстовыйДокумент;
// Формируем строку заголовков (шапку)
СтрокаШапки = "Дата;НомерДоговора;Организация;ИНН;Счет;БИК;Сотрудник;ЛицевойСчет;Сумма";
ТД.ДобавитьСтроку(СтрокаШапки);
Разделитель = ";";
// Предположим, РезультатЗапроса уже содержит данные о сотрудниках
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Сборка одной строки данных
// Важно: преобразуем все данные в строку явно
Стр = Строка(ДатаФормирования) + Разделитель
+ НомерДоговора + Разделитель
+ Выборка.ОрганизацияНаименование + Разделитель
+ Выборка.ИНН + Разделитель
+ Выборка.НомерЛицевогоСчета + Разделитель
+ Формат(Выборка.Сумма, "ЧЦ=15; ЧДЦ=2; ЧГ=0"); // Форматируем число без пробелов-разделителей
// Добавляем сформированную строку в текстовый документ
ТД.ДобавитьСтроку(Стр);
КонецЦикла;
// Выбор пути и запись
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.Фильтр = "Файлы CSV (*.csv)|*.csv";
Если Диалог.Выбрать() Тогда
ТД.Записать(Диалог.ПолноеИмяФайла, КодировкаТекста.ANSI);
КонецЕсли;
Часто начинающие разработчики сталкиваются с проблемой, когда в итоговом файле оказывается только заголовок и последняя строка данных. Проанализируем причину. Ошибка обычно кроется в том, что метод ДобавитьСтроку() вызывается вне тела цикла Пока...КонецЦикла или вместо добавления строки происходит перезапись переменной. Выясним причину: объект ТекстовыйДокумент накапливает строки только тогда, когда метод ДобавитьСтроку() вызывается на каждой итерации цикла. Проверьте, чтобы вызов метода ТД.ДобавитьСтроку(Стр) находился строго внутри цикла обхода выборки.
Простого соединения строк через разделитель недостаточно для создания надежного механизма обмена. Рассмотрим дополнительные факторы, которые могут повлиять на корректность выгрузки.
1. Обработка спецсимволов и кавычек
Если в наименовании организации попадется точка с запятой (наш разделитель), структура файла будет нарушена. Чтобы избежать этого, рекомендуется заключать текстовые поля в двойные кавычки. Если же внутри самого текста уже есть кавычка, ее нужно удваивать. Рассмотрим пример функции-помощника:
Функция ПодготовитьПолеCSV(Значение)
Текст = Строка(Значение);
// Если есть кавычки, удваиваем их
Текст = СтрЗаменить(Текст, """", """""");
// Оборачиваем в кавычки
Возврат """" + Текст + """";
КонецФункции
2. Форматирование чисел и дат
При выгрузке в CSV нельзя полагаться на стандартное преобразование Строка(). Например, 1С часто добавляет неразрывный пробел в числах (например, "1 250,00"), что воспринимается другими системами как ошибка. Всегда используйте функцию Формат() с параметром ЧГ=0 (исключение группировки разрядов). Для дат используйте формат, который ожидает принимающая сторона (например, "ДФ=yyyy-MM-dd").
3. Выбор объекта: ТекстовыйДокумент или ЗаписьТекста
Объект ТекстовыйДокумент хранит все данные в оперативной памяти. Если вы выгружаете десятки тысяч сотрудников, это может привести к замедлению системы. В таких случаях лучше использовать объект ЗаписьТекста. Он записывает данные напрямую в файл порциями, что значительно экономит ресурсы.
4. Кодировка и BOM
Для корректного открытия файла в Excel на платформе Windows обычно достаточно кодировки КодировкаТекста.ANSI. Однако для работы с веб-сервисами или кроссплатформенными системами лучше использовать UTF-8. При использовании UTF-8 важно помнить о BOM (Byte Order Mark) — специальной метке в начале файла, которая сообщает программам о кодировке. В 1С это настраивается при создании объекта ЗаписьТекста.
Если в вашей конфигурации данные уже выводятся в печатную форму, вы можете воспользоваться встроенным методом платформы. Проанализируем этот вариант: объект ТабличныйДокумент имеет метод Записать(), который поддерживает формат CSV. Рассмотрим пример:
ТабДок = Новый ТабличныйДокумент;
// ... (Заполнение Табличного документа данными) ...
ТабДок.Записать("C:\Export\data.csv", ТипФайлаТабличногоДокумента.CSV);
Этот метод удобен тем, что платформа 1С самостоятельно берет на себя заботу о кавычках, разделителях и корректном форматировании строк. Это самый быстрый способ «переделать» выгрузку, если визуальное представление данных в таблице вас устраивает.
Мы проанализировали процесс трансформации выгрузки из XML в CSV. Главное различие заключается в переходе от иерархии к строгой последовательности текстовых строк. Помните о необходимости очистки данных от переносов строк (символы ПС или ВК), которые могут разорвать запись в CSV-файле, и всегда уточняйте региональные настройки разделителей у стороны, принимающей ваш файл.