Перейти к содержимому

Сериализация данных с помощью файловых потоков 1С

Сериализация данных с помощью потоков 1С

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

1. Создаем базу данных.

Создаем пустую базу данных, где в качестве источника данных будет использоваться выгрузка базы данных из заметки «Анализ данных и прогнозирование в 1С — Общая статистика», в которой имеется регистр сведений «Данные продаж», содержащий данные для выгрузки и последующей загрузки. Для этого необходимо скачать файл dt и загрузить его через меню «Администрирование» — «Загрузить информационную базу…». В регистре сведений оставим измерения «Дата покупки», «Время покупки», «Идентификатор счет-фактуры», ресурсы «Цена», «Количество» и «Сумма».

2. Добавим общую форму.

Для реализации механизма выгрузки/загрузки (сериализация данных) будет использоваться общая форма, добавленная в рабочую область начальной страницы.

Создание общей формы
Создание общей формы

3. Добавим реализацию выгрузки.

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

&НаКлиенте
Асинх Процедура Выгрузить(Команда)
	
	// Получаем адрес данных во временном хранилище.
	АдресДанных = ВыгрузитьНаСервере();
	Если АдресДанных = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если НЕ ЭтоАдресВременногоХранилища(АдресДанных) Тогда
		ВызватьИсключение "Выгрузка данных вернула не верный результат, ожидается адрес во временном хранилище.";
	КонецЕсли;

	ПолучитьФайлССервераАсинх(АдресДанных, "ВыгрузкаДанных.txt", Новый ПараметрыДиалогаПолученияФайлов);
	
КонецПроцедуры

Пояснение: получаем адрес данных во временном хранилище и сохраняем на клиенте в файл.

Потоковая запись во временный файл происходит на стороне сервера, для этого в функцию выгрузки добавляем следующий код:

&НаСервереБезКонтекста
Функция ВыгрузитьНаСервере()

	// Основной запрос получения данных.
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	Т.ДатаПокупки КАК ДатаПокупки,
		|	Т.ВремяПокупки КАК ВремяПокупки,
		|	Т.ИдентификаторСчетФактуры КАК ИдентификаторСчетФактуры,
		|	Т.Цена КАК Цена,
		|	Т.Количество КАК Количество,
		|	Т.Сумма КАК Сумма
		|ИЗ
		|	РегистрСведений.ДанныеПродаж КАК Т";
	
	РезультатЗапроса = Запрос.Выполнить();  
	Если РезультатЗапроса.Пустой() Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	// Создание файлового потока на основании временного файла.
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
	ПотокФайловый = Новый ФайловыйПоток(ИмяВременногоФайла, РежимОткрытияФайла.Создать);
	
	// Объект, с помощью которого производится запись в поток.
	ЗаписьТекстаВФайл = Новый ЗаписьТекста(ПотокФайловый);
	
	// Шаблон в каком виде будут выгружаться строки данных.
	Шаблон = "%1~%2~%3~%4~%5~%6";
	
	Выборка = РезультатЗапроса.Выбрать();
	Пока Выборка.Следующий() Цикл
		
		// Формирование строки данных.
		СтрокаДанных = СтрШаблон(Шаблон, 
			XMLСтрока(Выборка.ДатаПокупки), 
			XMLСтрока(Выборка.ВремяПокупки),
			Выборка.ИдентификаторСчетФактуры,
			XMLСтрока(Выборка.Цена),
			XMLСтрока(Выборка.Количество),
			XMLСтрока(Выборка.Сумма));
			
		// Запись строки в поток.	
		ЗаписьТекстаВФайл.ЗаписатьСтроку(СтрокаДанных);
		
	КонецЦикла;
	
	// Обязательное закрытие потока и объекта записи.
	ЗаписьТекстаВФайл.Закрыть();  
	ПотокФайловый.Закрыть();

	// Двоичные данные файла помещаются во временной хранилище.
	ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяВременногоФайла);
	АдресДанных = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла);
	
	УдалитьФайлы(ИмяВременногоФайла);
	
	Возврат АдресДанных;              
	
КонецФункции

Пояснение: запросом получаем необходимые данные для выгрузки, формируем объекты, благодаря которым происходит сериализация данных с помощью файловых потоков 1С.

Результат выгрузки:

Сериализация данных с помощью потоков 1С - Результат выгрузки
Сериализация данных с помощью потоков 1С — Результат выгрузки

4. Добавим реализацию загрузки.

В общей форме добавляем команду «Загрузить» и создаем обработчик команды на клиенте и процедуру на сервере без контекста. В клиентском коде обработчика команды «Загрузить», добавляем следующий код:

&НаКлиенте
Асинх Процедура Загрузить(Команда)
	
	// Помещаем файл, из локальной файловой системы во временное хранилище.
	ОписаниеПомещенногоФайла = Ждать ПоместитьФайлнаСерверАсинх ( , , , , УникальныйИдентификатор);
	Если ОписаниеПомещенногофайла = Неопределено ИЛИ ОписаниеПомещенногофайла.ПомещениефайлаОтменено Тогда
		Возврат;
	КонецЕсли;
	
	// Получаем адрес данных во временном хранилище.
	АдресДанных = ОписаниеПомещенногофайла.Адрес;
	Если АдресДанных = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если НЕ ЭтоАдресВременногоХранилища(АдресДанных) Тогда
		ВызватьИсключение "Помещение файла на сервер вернуло не верный результат, ожидается адрес во временном хранилище.";
	КонецЕсли;

	// Переход на сторону сервера.
	ЗагрузитьНаСервере(АдресДанных);
	
КонецПроцедуры

Пояснение: передача файла на сторону сервера через временно хранилище.

Потоковое чтение происходит на стороне сервера, для возможности загрузки данных в регистр сведений, для этого в процедуру загрузки добавляем следующий код:

&НаСервереБезКонтекста
Процедура ЗагрузитьНаСервере(АдресДанных)   
	
	// Получаем двоичные данные из временного хранилища.
	ДанныеФайла = ПолучитьИзВременногоХранилища(АдресДанных);
	
	// Создание объекта для потока чтения.
	ПотокЧтения = ДанныеФайла.ОткрытьПотокДляЧтения();
	
	// Объект, с помощью которого производится чтение из потока.
	ЧтениеТекстаИзФайла = Новый ЧтениеТекста(ПотокЧтения);
	
	// Набор записей для последующей записи в регистр.
	НаборЗаписей = РегистрыСведений.ДанныеПродаж.СоздатьНаборЗаписей();
	
	Пока Истина Цикл
		
		ПрочитаннаяСтрока = ЧтениеТекстаИзФайла.ПрочитатьСтроку();
		Если ПрочитаннаяСтрока = Неопределено Тогда
			Прервать;
		КонецЕсли;
		
		// Из строки данных получаем непосредственно данные.
		ДанныеСтроки = СтрРазделить(ПрочитаннаяСтрока, "~", Ложь);
		
		Запись = НаборЗаписей.Добавить();
		Запись.ДатаПокупки = XMLЗначение(Тип("Дата"), ДанныеСтроки[0]);
		Запись.ВремяПокупки = XMLЗначение(Тип("Дата"), ДанныеСтроки[1]);
		Запись.ИдентификаторСчетФактуры = ДанныеСтроки[2];
		Запись.Цена = XMLЗначение(Тип("Число"), ДанныеСтроки[3]);
		Запись.Количество = XMLЗначение(Тип("Число"), ДанныеСтроки[4]);
		Запись.Сумма = XMLЗначение(Тип("Число"), ДанныеСтроки[5]);

		// Запись порциями по 100 строк.
		Если НаборЗаписей.Количество() >= 100 Тогда
			
			НаборЗаписей.Записать(РежимЗамещения.Обновление); 
			НаборЗаписей.Очистить();
			
		КонецЕсли;
	
	КонецЦикла;   
	
	// Если есть остаток, который необходимо записать.
	Если НаборЗаписей.Количество() Тогда
		НаборЗаписей.Записать(РежимЗамещения.Обновление); 
	КонецЕсли;
	
	// Обязательное закрытие потока и объекта чтения.
	ЧтениеТекстаИзФайла.Закрыть();
	ПотокЧтения.Закрыть();
	
	УдалитьИзВременногоХранилища(АдресДанных);
	
КонецПроцедуры

Пояснение: формируются объекты для потокового чтения, в бесконечном цикле построчно читаются данные и загружаются в регистр сведений.

Итого:

Представленный вариант сериализации данных с помощью файловых потоков 1С, можно использовать для различных ситуаций, выгрузка и загрузка данных из регистра носит чисто информативный контекст и служит только для учебных целей по работе с файловыми потоками в 1С.

💾 Выгрузка базы данных: Сериализация данных с помощью потоков 1С — Выгрузка базы данных.

Дополнительная информация:

Метки:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *