При разработке и кастомизации отчетов в среде 1С программисты часто сталкиваются с необходимостью выгрузки готовых данных во внешние форматы для последующего анализа или интеграции с другими системами. Формат CSV (Comma-Separated Values) пользуется огромной популярностью благодаря своей простоте и универсальности. Однако при попытке выгрузить данные напрямую из экранной формы отчета разработчики нередко совершают фундаментальные архитектурные ошибки.
В этой статье мы подробно проанализируем, почему возникает популярная ошибка «Метод объекта не обнаружен (Выгрузить)» при работе с формой отчета, разберем базовый ручной способ обхода этой проблемы, а также изучим три надежных программных метода автоматизации выгрузки «Оборотки» в формат CSV.
---
Рассмотрим исходный код, который часто пытаются использовать начинающие разработчики:
Процедура КоманднаяПанельФормыCSV(Кнопка)
ТЗЭкспорт = ЭлементыФормы.ДокументРезультат.Выгрузить(); // Ошибка здесь!
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
// ... настройка диалога ...
Если Диалог.Выбрать() Тогда
Текст = Новый ТекстовыйДокумент;
Пока ЭлементыФормы.ДокументРезультат.Следующий Цикл // И здесь ошибка!
Текст.ДобавитьСтроку();
КонецЦикла;
Текст.Записать(Диалог.ПолноеИмяФайла);
КонецЕсли;
КонецПроцедуры
При выполнении этого кода система генерирует исключение: {ВнешнийОтчет.ОборотноСальдоваяВедомостьТиповой.Форма.ФормаОсновная.Форма(434)}: Метод объекта не обнаружен (Выгрузить).
Давайте разберем по шагам, почему этот код принципиально недееспособен:
ЭлементыФормы.ДокументРезультат (или просто Результат в управляемых формах) представляет собой объект типа ТабличныйДокумент. Этот объект предназначен исключительно для визуализации данных (вывода печатных форм, отчетов, графиков). У него нет и не может быть метода Выгрузить(). Данный метод присутствует у коллекций данных, таких как ТаблицаЗначений или ТабличнаяЧасть.Следующий() принадлежит объектам типа ВыборкаИзРезультатаЗапроса. Пытаться вызвать его у элемента отображения формы — грубая синтаксическая ошибка.Записать() поддерживает множество форматов (XLS, XLSX, PDF, HTML, TXT), но среди них отсутствует прямой экспорт в CSV.Ниже мы подробно разберем четыре практических способа решения этой задачи: от простого ручного до продвинутых программных алгоритмов.
---
Если задача разовая и автоматизация процесса не требуется, самым быстрым решением будет использование штатных механизмов платформы и табличного редактора Excel.
Выполним следующие действия:
Лист Excel (*.xlsx) или Документ HTML (*.html) и сохраним его на диск.CSV (разделители - запятые) (*.csv).Этот способ прост, но абсолютно не подходит, если выгрузку требуется выполнять регулярно или в автоматическом режиме по расписанию.
---
Рассмотрим элегантный программный способ, который не требует наличия установленного Excel на компьютере пользователя и отлично работает как в файловом, так и в клиент-серверном режиме (включая Linux-серверы).
Суть метода заключается в следующем: платформа 1С умеет сохранять ТабличныйДокумент в обычном текстовом формате (ТипФайлаТабличногоДокумента.TXT). При этом ячейки таблицы разделяются стандартным символом табуляции (Символы.Таб). Нам достаточно записать временный текстовый файл, прочитать его в память, заменить знаки табуляции на разделитель CSV (обычно это точка с запятой ";") и сохранить файл обратно с нужным расширением.
Разберем готовый листинг кода:
Процедура ВыгрузитьТабДокВCSV(ТабДок, ПутьКФайлуCSV)
// Шаг 1. Получаем имя для временного файла на диске
ВременныйФайл = ПолучитьИмяВременногоФайла("txt");
// Шаг 2. Записываем табличный документ во временный текстовый файл.
// Платформа автоматически разделит колонки символом табуляции.
ТабДок.Записать(ВременныйФайл, ТипФайлаТабличногоДокумента.TXT);
// Шаг 3. Читаем созданный текстовый файл в память
ТекстовыйФайл = Новый ТекстовыйДокумент;
// Обязательно указываем кодировку UTF-8 для корректного сохранения кириллицы
ТекстовыйФайл.Прочитать(ВременныйФайл, КодировкаТекста.UTF8);
ТекстДанных = ТекстовыйФайл.ПолучитьТекст();
// Шаг 4. Производим замену табов на точку с запятой
ТекстДанных = СтрЗаменить(ТекстДанных, Символы.Таб, ";");
// Шаг 5. Записываем итоговое содержимое в целевой файл CSV
ТекстовыйФайл.УстановитьТекст(ТекстДанных);
ТекстовыйФайл.Записать(ПутьКФайлуCSV, КодировкаТекста.UTF8);
// Шаг 6. Удаляем временный файл с диска
Попытка
УдалитьФайлы(ВременныйФайл);
Исключение
// Игнорируем ошибку удаления, если файл занят системой
КонецПопытки;
Предупреждение("Выгрузка успешно завершена!");
КонецПроцедуры
Преимущества метода: Высокая скорость работы, кроссплатформенность, независимость от стороннего софта.
Важное ограничение: Если внутри ячеек вашей оборотки (например, в наименованиях субконто или контрагентов) изначально содержатся знаки табуляции или точки с запятой, структура колонок итогового CSV-файла может "поплыть". Для простых отчетов этот метод идеален.
---
Часто конечным потребителям данных (внешним базам данных, BI-системам, веб-сайтам) не требуются визуальные элементы оформления Оборотно-сальдовой ведомости — им не нужны шапка отчета, пустые строки, группировочные промежуточные итоги и подписи бухгалтера. Им нужны чистые, структурированные табличные данные.
Поскольку типовая оборотка в современных конфигурациях строится на базе Системы компоновки данных (СКД), мы можем перехватить вывод отчета и направить результат не на экран в ТабличныйДокумент, а напрямую в коллекцию ТаблицаЗначений. После этого мы программно сформируем CSV-строки в соответствии с международным стандартом RFC 4180.
Рассмотрим этот алгоритм детально:
Функция ПолучитьДанныеОСВВТаблице(КомпоновщикНастроек, СхемаКомпоновки)
// Создаем процессор компоновки данных
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
// Инициализируем макет компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, КомпоновщикНастроек.ПолучитьНастройки());
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
// Выводим результат не в ТабличныйДокумент, а в ТаблицуЗначений
ТаблицаРезультата = Новый ТаблицаЗначений;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультата);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Возврат ТаблицаРезультата;
КонецФункции
Процедура СохранитьТЗвCSV(ТаблицаДанных, ПутьКФайлу)
Разделитель = ";";
ФайлCSV = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8);
// Шаг 1. Формируем строку заголовков колонок
СтрокаШапки = "";
Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл
СтрокаШапки = СтрокаШапки + ?(СтрокаШапки = "", "", Разделитель) + Колонка.Имя;
КонецЦикла;
ФайлCSV.ЗаписатьСтроку(СтрокаШапки);
// Шаг 2. Перебираем строки таблицы и выгружаем данные
Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
ТекущаяСтрока = "";
Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл
ЗначениеЭлемента = Строка(СтрокаТЗ[Колонка.Имя]);
// Защита структуры CSV по стандарту RFC 4180:
// 1. Если в значении есть кавычки, удваиваем их.
ЗначениеЭлемента = СтрЗаменить(ЗначениеЭлемента, """", """""");
// 2. Если внутри значения есть разделитель или переносы строк,
// оборачиваем все значение в двойные кавычки.
Если Найти(ЗначениеЭлемента, Разделитель) > 0 Или Найти(ЗначениеЭлемента, Символы.ПС) > 0 Тогда
ЗначениеЭлемента = """" + ЗначениеЭлемента + """";
КонецЕсли;
ТекущаяСтрока = ТекущаяСтрока + ?(ТекущаяСтрока = "", "", Разделитель) + ЗначениеЭлемента;
КонецЦикла;
ФайлCSV.ЗаписатьСтроку(ТекущаяСтрока);
КонецЦикла;
ФайлCSV.Закрыть();
Предупреждение("Файл успешно сохранен!");
КонецПроцедуры
Преимущества метода: Получение идеальной структуры данных без лишнего «мусора» оформления. Исключена порча структуры файла благодаря строгому соблюдению правил экранирования спецсимволов.
---
Если решение разрабатывается строго под Windows-инфраструктуру и на рабочих местах пользователей гарантированно установлен пакет MS Office, можно автоматизировать классический ручной сценарий с помощью технологии COM-соединения.
Проанализируем пример кода:
Процедура КонвертироватьЧерезExcel(ТабДок, ИтоговыйПутьCSV)
// Шаг 1. Сохраняем табличный документ во временный файл формата XLSX
ВременныйXLSX = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ВременныйXLSX, ТипФайлаТабличногоДокумента.XLSX);
// Шаг 2. Инициализируем COM-объект Excel
Попытка
ExcelПриложение = Новый COMОбъект("Excel.Application");
// Отключаем отображение предупреждений Excel на экране
ExcelПриложение.DisplayAlerts = Ложь;
Исключение
Сообщить("Ошибка инициализации Excel. Проверьте, установлен ли MS Office!", СтатусСообщения.Важное);
Возврат;
КонецПопытки;
// Шаг 3. Открываем временную книгу и пересохраняем её в CSV
Попытка
Книга = ExcelПриложение.Workbooks.Open(ВременныйXLSX);
// Значение константы xlCSV (разделители - запятые/точки с запятой в русской локали) равно 6
Книга.SaveAs(ИтоговыйПутьCSV, 6);
Книга.Close();
ExcelПриложение.Quit();
// Удаляем временный файл XLSX
УдалитьФайлы(ВременныйXLSX);
Сообщить("Файл успешно сконвертирован через Excel COM!");
Исключение
// В случае сбоя обязательно корректно закрываем процесс Excel в памяти
ExcelПриложение.Quit();
Сообщить("Произошла ошибка в процессе конвертации: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
КонецПроцедуры
Преимущества метода: Excel самостоятельно берет на себя все заботы по экранированию сложных символов, длинных строк и сохраняет структуру колонок в первозданном виде.
Недостатки метода: Низкая скорость работы, привязка к операционной системе Windows и обязательное требование коммерческой лицензии MS Office на рабочей станции или сервере.
---
Завершая наш разбор, обратим внимание на важный нюанс работы с кодировками файлов. При программной записи текстовых файлов в 1С с использованием параметра КодировкаТекста.UTF8, платформа создает файл с сигнатурой BOM (Byte Order Mark).
Это крайне важная особенность для интеграции с внешними программами:
ЗаписьТекста с явным указанием кодировки без сигнатуры.Выбирайте подходящий метод выгрузки в зависимости от архитектурных ограничений вашей системы, и ваши отчеты всегда будут выгружаться быстро и без ошибок!