Массив из встроенного языка 1С в файл: рабочие примеры кода для каждого формата

· 10 мин

Содержание

Чтобы выгрузить массив 1С в файл, пройдите по нему циклом и запишите каждый элемент объектом ЗаписьТекста (для CSV и TXT), ЗаписьJSON (для JSON) или ЗаписьXML вместе с СериализаторXDTO (для XML). Для Excel массив сначала раскладывают по ячейкам табличного документа и сохраняют методом Записать с типом XLSX.

Сам массив в 1С — это коллекция в памяти, у него нет метода «сохранить в файл». Формат выбирают под получателя: человеку нужен Excel или CSV, внешней системе — JSON или XML, другой базе 1С — внутренний формат. Все примеры ниже написаны для платформы 8.3 и проверяются в обычной внешней обработке.

Подготовка массива: что лежит внутри и куда его отдавать

Сначала посмотрите, из чего состоит массив. От этого зависит, сколько кода понадобится.

  • 🔹 Примитивы (строки, числа, даты, булево) — выгружаются любым способом в несколько строк.
  • 🔹 Структуры или соответствия — по сути строки таблицы с именованными полями. Хорошо ложатся в CSV с шапкой, в JSON и в таблицу значений.
  • 🔹 Ссылки на справочники и документы — напрямую в JSON не пишутся. Их переводят в строки (код, наименование, уникальный идентификатор) или сериализуют через XDTO.
  • 🔹 Вложенные массивы — двумерные данные. Каждый внутренний массив становится строкой файла.
ФорматКому нуженЧем писатьТипы 1С сохраняются
CSV / TXTExcel, загрузка в другие программыЗаписьТекстаНет, всё становится текстом
XLSXЧеловеку, бухгалтеруТабличныйДокументЧастично
JSONСайт, сервис, APIЗаписьJSONТолько примитивы
XMLОбмены, другая 1С, интеграцииСериализаторXDTO, ЗаписьXMLДа, при явном указании типов
Внутренний форматТолько другая база 1СЗначениеВФайлДа

Выгружайте на сервере (&НаСервере или &НаСервереБезКонтекста). Передача большого массива между клиентом и сервером сама по себе стоит времени: платформа сериализует его при каждом вызове.

Выгрузка массива в CSV и текстовый файл

Простейший случай — массив строк или чисел, по одному элементу в строке файла.

&НаСервереБезКонтекста
Процедура ВыгрузитьМассивВТекст(Массив, ИмяФайла)
	Запись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8);
	Попытка
		Для Каждого Элемент Из Массив Цикл
			Запись.ЗаписатьСтроку(ЗначениеДляCSV(Элемент));
		КонецЦикла;
		Запись.Закрыть();
	Исключение
		Запись.Закрыть();
		ВызватьИсключение;
	КонецПопытки;
КонецПроцедуры

Закрыть() стоит в обеих ветках не случайно. Если цикл упадёт на середине, незакрытый файл останется занят процессом 1С до конца сеанса.

Как превратить значение в ячейку CSV

Числа, даты и строки с разделителем нужно привести к виду, который поймёт Excel или парсер на другой стороне.

&НаСервереБезКонтекста
Функция ЗначениеДляCSV(Значение, Разделитель = ";")
	Если ТипЗнч(Значение) = Тип("Число") Тогда
		Возврат Формат(Значение, "ЧРД=.; ЧГ=0; ЧН=0");
	ИначеЕсли ТипЗнч(Значение) = Тип("Дата") Тогда
		Возврат Формат(Значение, "ДФ=yyyy-MM-dd");
	ИначеЕсли ТипЗнч(Значение) = Тип("Булево") Тогда
		Возврат ?(Значение, "1", "0");
	КонецЕсли;

	Текст = Строка(Значение);
	Если СтрНайти(Текст, Разделитель) > 0 Или СтрНайти(Текст, """") > 0
		Или СтрНайти(Текст, Символы.ПС) > 0 Тогда
		Текст = """" + СтрЗаменить(Текст, """", """""") + """";
	КонецЕсли;
	Возврат Текст;
КонецФункции

Что делает каждый параметр форматной строки:

  1. ЧРД=. — точка вместо запятой в дробной части. Нужна, если файл читает программа, а не русский Excel.
  2. ЧГ=0 — убирает разделитель групп разрядов. Без него 1234567 превратится в 1 234 567 с неразрывными пробелами, и число на той стороне станет строкой.
  3. ЧН=0 — ноль выводится как 0, а не пустой строкой.

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

Массив структур — в CSV с шапкой

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

&НаСервереБезКонтекста
Функция МассивСтруктурВCSV(Массив, Поля)
	// Поля — строка вида "Артикул,Наименование,Цена"
	ИменаПолей = СтрРазделить(Поля, ",", Ложь);
	Строки = Новый Массив;
	Строки.Добавить(СтрСоединить(ИменаПолей, ";"));

	Для Каждого Элемент Из Массив Цикл
		Ячейки = Новый Массив;
		Для Каждого Имя Из ИменаПолей Цикл
			Ячейки.Добавить(ЗначениеДляCSV(Элемент[СокрЛП(Имя)]));
		КонецЦикла;
		Строки.Добавить(СтрСоединить(Ячейки, ";"));
	КонецЦикла;

	Возврат СтрСоединить(Строки, Символы.ВК + Символы.ПС);
КонецФункции

Готовую строку пишут в файл одним вызовом ЗаписатьСтроку или кладут в ТекстовыйДокумент и сохраняют его методом Записать. Функции СтрСоединить и СтрРазделить появились в платформе 8.3.6. В более старых релизах строку собирают циклом.

СтрСоединить ждёт массив строк. Если в массиве лежат числа или ссылки, сначала прогоните каждый элемент через Строка() или функцию форматирования, как выше.

Кодировка: UTF-8 или Windows-1251

ЗаписьТекста с КодировкаТекста.UTF8 добавляет в начало файла метку BOM. По ней Excel понимает, что файл в UTF-8, и показывает кириллицу нормально. Если получатель — старая программа, которая ждёт Windows-1251, укажите КодировкаТекста.ANSI: на русской Windows это и есть 1251.

Массив через таблицу значений и выгрузка в Excel

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

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номер", Новый ОписаниеТипов("Число"));
ТЗ.Колонки.Добавить("Значение");

Для Индекс = 0 По Массив.ВГраница() Цикл
	НоваяСтрока = ТЗ.Добавить();
	НоваяСтрока.Номер = Индекс + 1;
	НоваяСтрока.Значение = Массив[Индекс];
КонецЦикла;

Обратное движение ещё проще. ТЗ.ВыгрузитьКолонку("Значение") возвращает массив значений колонки. Так же получают массив ссылок из запроса: Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка").

Метод ЗагрузитьКолонку(Массив, ИмяКолонки) заполняет колонку из массива, но строки таблицы к этому моменту уже должны существовать. Он подходит, чтобы дописать колонку в готовую таблицу, а не создать таблицу с нуля.

Сохранение в XLSX через табличный документ

ТабДок = Новый ТабличныйДокумент;
КоличествоКолонок = ТЗ.Колонки.Количество();

Для НомерКолонки = 1 По КоличествоКолонок Цикл
	ТабДок.Область(1, НомерКолонки, 1, НомерКолонки).Текст =
		ТЗ.Колонки[НомерКолонки - 1].Имя;
КонецЦикла;

НомерСтроки = 1;
Для Каждого СтрокаТЗ Из ТЗ Цикл
	НомерСтроки = НомерСтроки + 1;
	Для НомерКолонки = 1 По КоличествоКолонок Цикл
		ТабДок.Область(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки).Текст =
			Строка(СтрокаТЗ[НомерКолонки - 1]);
	КонецЦикла;
КонецЦикла;

ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);

Через свойство Текст всё попадает в Excel строками. Если с числами будут считать, задайте ячейке СодержитЗначение = Истина, нужный ТипЗначения и записывайте в Значение, а не в Текст.

Есть путь без кода. Выведите таблицу значений в реквизит формы, откройте форму и сохраните список штатной командой. В форме списка она обычно лежит в меню Ещё: «Вывести список …», затем сохранение табличного документа. Для разовой выгрузки этого хватает.

Выгрузка массива в JSON и XML

JSON: ЗаписьJSON и ЗаписатьJSON

Массив примитивов, структур и соответствий со строковыми ключами пишется в JSON одной функцией.

&НаСервереБезКонтекста
Процедура ВыгрузитьМассивВJSON(Массив, ИмяФайла)
	Параметры = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, Символы.Таб);
	Запись = Новый ЗаписьJSON;
	Запись.ОткрытьФайл(ИмяФайла, "UTF-8", Ложь, Параметры);
	ЗаписатьJSON(Запись, Массив);
	Запись.Закрыть();
КонецПроцедуры

Третий параметр ОткрытьФайл — нужна ли метка BOM. Для веб-сервисов ставьте Ложь: часть парсеров на BOM спотыкается. Нужна строка, а не файл — вместо ОткрытьФайл вызовите Запись.УстановитьСтроку(Параметры), и Запись.Закрыть() вернёт готовый текст JSON.

Ссылки, таблицы значений и объекты ЗаписатьJSON не принимает. Переложите каждый элемент в структуру с простыми полями:

Результат = Новый Массив;
Для Каждого Ссылка Из МассивСсылок Цикл
	Элемент = Новый Структура;
	Элемент.Вставить("id", Строка(Ссылка.УникальныйИдентификатор()));
	Элемент.Вставить("code", Ссылка.Код);
	Элемент.Вставить("name", Ссылка.Наименование);
	Результат.Добавить(Элемент);
КонецЦикла;

Обращение Ссылка.Код в цикле — это отдельное чтение из базы на каждый элемент. Для сотни элементов терпимо, для десятков тысяч берите поля одним запросом, об этом ниже.

Если тип 1С надо сохранить, чтобы прочитать JSON обратно в другой базе, есть СериализаторXDTO.ЗаписатьJSON. Он пишет значения вместе с описанием типа, но такой JSON понятен в первую очередь самой 1С.

XML: СериализаторXDTO

Для обмена между базами 1С массив сериализуют целиком, со всеми ссылками и типами:

Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла, "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
СериализаторXDTO.ЗаписатьXML(Запись, Массив, НазначениеТипаXML.Явное);
Запись.Закрыть();

Читают обратно так:

Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
Чтение.ПерейтиКСодержимому();
Массив = СериализаторXDTO.ПрочитатьXML(Чтение);
Чтение.Закрыть();

Ссылки восстановятся по уникальным идентификаторам. В базе-приёмнике объект с тем же идентификатором может отсутствовать — тогда получится битая ссылка, а не ошибка.

XML своей структуры

Внешней системе обычно нужна своя схема, а не формат 1С. Её пишут вручную:

Запись.ЗаписатьНачалоЭлемента("items");
Для Каждого Элемент Из Массив Цикл
	Запись.ЗаписатьНачалоЭлемента("item");
	Запись.ЗаписатьАтрибут("code", XMLСтрока(Элемент.Артикул));
	Запись.ЗаписатьТекст(XMLСтрока(Элемент.Наименование));
	Запись.ЗаписатьКонецЭлемента();
КонецЦикла;
Запись.ЗаписатьКонецЭлемента();

XMLСтрока переводит числа, даты и булево в формат XML : дата станет 2026-10-07T00:00:00, булево — true или false. Спецсимволы вроде & и < ЗаписьXML экранирует сама.

Внутренний формат для обмена 1С↔1С

ЗначениеВФайл(ИмяФайла, Массив) сохраняет массив во внутреннем формате платформы, ЗначениеИзФайла читает его обратно. Это самый короткий путь, если файл откроет только другая 1С. Метод работает на сервере и в толстом клиенте, в тонком клиенте его нет. Строковый вариант — ЗначениеВСтрокуВнутр, им удобно положить массив в реквизит типа «Строка неограниченной длины».

Куда попадает файл: сервер, клиент и права доступа

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

  • 🖥️ Файловая база — сервер и клиент совпадают, путь C:\Выгрузка\items.csv указывает на ваш диск.
  • 🌐 Клиент-серверная база — код &НаСервере пишет файл на сервер 1С. Путь C:\Выгрузка — это диск сервера.
  • 🔒 Учётная запись службы — на сервере файл создаёт пользователь, от которого запущена служба агента сервера 1С. По умолчанию это USR1CV8 в Windows и usr1cv8 в Linux. Ему нужны права на запись в каталог.
  • 📁 Сетевые диски — буквы, подключённые у пользователя (Z:), служба не видит. Используйте UNC-путь \\server\share\ и дайте учётной записи службы права на эту папку.

Как отдать файл пользователю

Надёжная схема для тонкого и веб-клиента: на сервере записать во временный файл, прочитать в двоичные данные, положить во временное хранилище и сохранить на клиенте.

&НаКлиенте
Процедура ВыгрузитьВФайл(Команда)
	Адрес = ПодготовитьФайлНаСервере(УникальныйИдентификатор);
	ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, Адрес, "items.csv");
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПодготовитьФайлНаСервере(ИдентификаторФормы)
	ИмяВременного = ПолучитьИмяВременногоФайла("csv");
	Массив = ПолучитьДанныеДляВыгрузки(); // ваша функция
	ВыгрузитьМассивВТекст(Массив, ИмяВременного);
	Данные = Новый ДвоичныеДанные(ИмяВременного);
	УдалитьФайлы(ИмяВременного);
	Возврат ПоместитьВоВременноеХранилище(Данные, ИдентификаторФормы);
КонецФункции

ФайловаяСистемаКлиент — модуль Библиотеки стандартных подсистем, он есть в типовых конфигурациях. В конфигурации без БСП используйте платформенные методы получения файла из временного хранилища.

Безопасный режим

Внешние обработки, подключённые через «Дополнительные отчёты и обработки», часто запускаются в безопасном режиме. В нём запись в произвольный каталог запрещена. Разрешения на работу с файловой системой выдаются профилями безопасности в консоли кластера или запросом разрешений из самой обработки. Если обработка работала у разработчика и падает у пользователя, начните проверку с этого.

Большие массивы: скорость и память

На тысяче элементов разницы между способами не заметно. На сотнях тысяч ошибки в коде превращаются в минуты ожидания и нехватку памяти рабочего процесса.

ПриёмПочему помогает
Не склеивать строку через Текст = Текст + … в циклеКаждое сложение создаёт новую строку, время растёт быстрее объёма. Собирайте массив строк и вызывайте СтрСоединить один раз или пишите построчно ЗаписатьСтроку
Писать из выборки запроса, минуя массивВыборка.Следующий() держит в памяти одну строку, массив — все сразу
Получать поля запросомСсылка.Наименование в цикле — отдельное обращение к базе на каждый элемент
JSON писать потоковоЗаписатьНачалоМассива, ЗаписатьНачалоОбъекта, ЗаписатьИмяСвойства, ЗаписатьЗначение не требуют собирать весь массив в памяти
Выгружать на сервереНет пересылки массива между клиентом и сервером
Долгую выгрузку — в фоновое заданиеФорма не зависает, в БСП для этого есть механизм длительных операций

Потоковая запись JSON прямо из запроса выглядит так:

Запись.ЗаписатьНачалоМассива();
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
	Запись.ЗаписатьНачалоОбъекта();
	Запись.ЗаписатьИмяСвойства("code");
	Запись.ЗаписатьЗначение(Выборка.Код);
	Запись.ЗаписатьИмяСвойства("name");
	Запись.ЗаписатьЗначение(Выборка.Наименование);
	Запись.ЗаписатьКонецОбъекта();
КонецЦикла;
Запись.ЗаписатьКонецМассива();

Для файлов в сотни мегабайт подумайте о разбиении: например, по 50 000 записей в файл с номером в имени. Такие куски легче передать, и сбой посередине не обнуляет всю работу.

Ошибки при выгрузке массива и как их обойти

  • 🔤 Кракозябры в Excel. Файл в UTF-8 без BOM или в другой кодировке. Пишите через ЗаписьТекста с КодировкаТекста.UTF8 либо в ANSI.
  • 📊 Всё в одной колонке. Русский Excel по умолчанию делит CSV по точке с запятой. Файл с запятыми открывайте через импорт данных с указанием разделителя или меняйте разделитель в коде.
  • 🔢 Числа стали текстом. В строку попал неразрывный пробел групп разрядов или запятая. Форматируйте числа с ЧГ=0.
  • 🚫 Ошибка в ЗаписатьJSON. В массиве оказалась ссылка, таблица значений или дата в нестандартном виде. Переложите элемент в структуру с примитивами.
  • 📂 «Файл не найден» или нет доступа. Файл записан на сервер, а ищут на клиенте, или у службы 1С нет прав на каталог.
  • 🔁 Пустой индекс в цикле. Для Индекс = 0 По Массив.Количество() Цикл выходит за границу на последнем шаге. Верхняя граница — Массив.ВГраница() или Количество() - 1.

Частые вопросы

Как быстро посмотреть содержимое массива при отладке?
Вычислите в табло отладчика СтрСоединить(Массив, Символы.ПС) для массива строк. Для массива структур удобнее ЗначениеВСтрокуВнутр(Массив) или запись в JSON строкой через УстановитьСтроку.
Как выгрузить двумерный массив?
Двумерный массив в 1С — массив массивов. Внешний цикл идёт по строкам, внутренний собирает ячейки в массив, который склеивается СтрСоединить с разделителем. В JSON такой массив пишется ЗаписатьJSON без доработок.
Как загрузить массив обратно из CSV?
Прочитайте файл через ЧтениеТекста или ТекстовыйДокумент, каждую строку разбейте СтрРазделить(Строка, ";"). Числа и даты придётся привести к типу самостоятельно: CSV хранит только текст. Поля в кавычках с разделителем внутри простой СтрРазделить разобьёт неверно, для них нужен разбор по символам.
Чем отличается выгрузка фиксированного массива?
Ничем. ФиксированныйМассив перебирается тем же Для Каждого и принимается ЗаписатьJSON. Изменить его нельзя, но для выгрузки это не нужно.
Можно ли выгрузить массив из веб-клиента прямо на диск?
Напрямую нет: у веб-клиента нет доступа к файловой системе. Файл готовят на сервере и отдают через временное хранилище, браузер сохраняет его как обычную загрузку.