Сериализация больших таблиц значений в 1С8

25.09.12

Разработка - Универсальные функции

Рассмотрена специфика и предложена конкретная методика сериализации в файл больших таблиц значений
Введение в проблему

В моей задаче необходимо было сохранять таблицу значений в файл. Но при большой нагрузке на сервер приложений таблица не сериализировалась через ЗначениеВСтрокуВнутр.

Методика, предложенная в http://kb.mista.ru/2/doku.php?id=1c:v8:howto:serializacija_tablicyznachenij_v_xml, не работает в 1с81 (8.1.15.14), видимо,  в более ранних версиях платформы это не возможно.

Если упаковать таблицу значений в хранилище значений, то методика работает:
ХЗ = Новый ХранилищеЗначений(ТЗ);

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

Решение

Решение нужно было написать быстро, и скорость чтения таблиц не должна была бы сильно пострадать. Скорость записи была не принципиальна.

Решено было таблицу пробовать выгружать обычным методом, а если ЗначениеВСтрокуВнутр выдаст ошибку, выгружать построчно.

Соответственно, при восстановлении таблицы проверялся формат файла, и в зависимости от формата использовалась та или иная распаковка.


 

Код по упаковке в модуле САП:

 

Функция ТЗВТекст(ТЗ) Экспорт

       Попытка

             Т = Новый ТекстовыйДокумент();

             Т.УстановитьТекст(ЗначениеВСтрокуВнутр(ТЗ));

             Возврат Т;

       Исключение

             Возврат ТЗВТекстЧерезСтроки(ТЗ);

       КонецПопытки;

КонецФункции

 

Функция ТЗИзТекста(ТекстовыйДокумент) Экспорт

      

       Если ТекстовыйДокумент.ПолучитьСтроку(1) = "LINE_FORMAT" Тогда

             Возврат ТЗИзТекстаЧерезСтроки(ТекстовыйДокумент);

       КонецЕсли;

      

       Возврат ЗначениеИЗСтрокиВнутр(ТекстовыйДокумент.ПолучитьТекст());

КонецФункции

 

Функция ТЗВТекстЧерезСтроки(ТЗ) Экспорт

       Т = Новый ТекстовыйДокумент();

       МассивКолонок = Новый Массив();

       ВсегоКолонок = ТЗ.Колонки.Количество()-1;

       Для Инд = 0 По ВсегоКолонок Цикл

             МассивКолонок.Добавить(0);

       КонецЦикла;

      

       Т.ДобавитьСтроку("LINE_FORMAT");

      

       ТЗ2 = ТЗ.СкопироватьКолонки();

      

       РезСтрока = ЗначениеВСтрокуВнутр(ТЗ2);

       РезСтрока = ЭкранироватьСимволы(РезСтрока);

       Т.ДобавитьСтроку(РезСтрока);

 

      

       Для Каждого Строка ИЗ ТЗ Цикл

             Для Инд = 0 По ВсегоКолонок Цикл

                    МассивКолонок[Инд] = Строка[Инд];

             КонецЦикла;

             РезСтрока = ЗначениеВСтрокуВнутр(МассивКолонок);

             РезСтрока = ЭкранироватьСимволы(РезСтрока);

             Т.ДобавитьСтроку(РезСтрока);

       КонецЦикла;

       Возврат Т;

КонецФункции

 

Функция ТЗИзТекстаЧерезСтроки(ТекстовыйДокумент) Экспорт

       ИсхСтрока = РазЭкранироватьСимволы(ТекстовыйДокумент.ПолучитьСтроку(2));

       ТЗ = ЗначениеИзСтрокиВнутр(ИсхСтрока);

       ВсегоКолонок = ТЗ.Колонки.Количество()-1;

       Для Инд = 3 По ТекстовыйДокумент.КоличествоСтрок() Цикл

             ИсхСтрока = РазЭкранироватьСимволы(ТекстовыйДокумент.ПолучитьСтроку(Инд));

             Массив = ЗначениеИзСтрокиВнутр(ИсхСтрока);

             НСтр = ТЗ.Добавить();

             Для КолИнд = 0 По ВсегоКолонок Цикл

                    НСтр[КолИнд] = Массив[КолИнд];

             КонецЦикла;

       КонецЦикла;

      

       Возврат ТЗ;

      

КонецФункции

 

Функция ЭкранироватьСимволы(Строка)

       Р = СтрЗаменить(Строка, "\", "\\");

       Р = СтрЗаменить(Р, Символы.ПС, "\n");

       Р = СтрЗаменить(Р, Символы.ВК, "\r");

       Р = СтрЗаменить(Р, Символы.Таб, "\t");

      

       Возврат Р;

КонецФункции

 

Функция РазЭкранироватьСимволы(Строка)

       Р = СтрЗаменить(Строка, "\\", "\");

       Р = СтрЗаменить(Р, "\n", Символы.ПС);

       Р = СтрЗаменить(Р, "\r", Символы.ВК);

       Р = СтрЗаменить(Р, "\t", Символы.Таб);

       Возврат Р;

КонецФункции

 

Пример использования кода:

Функция СохранитьРасчет(ИмяФайла, Таблица) Экспорт

       Попытка

             Значение = ЗначениеВСтрокуВнутр(Таблица);

             Т = Новый ТекстовыйДокумент();

             Т.УстановитьТекст(Значение);

             Т.Записать(ИмяФайла, "UTF-8");

            

             Возврат ИмяФайла;

       Исключение

             ОписаниеОшибки = ОписаниеОшибки();

             Сообщить("Не смогли преобразовать таблицу для сохранения в файл: " + ИмяФайла +  "  " + ОписаниеОшибки + ". Будем записывать в другом формате.", СтатусСообщения.Важное);

            

             Т = САП.ТЗВТекст(Таблица);

             Т.Записать(ИмяФайла, "UTF-8");

       КонецПопытки;

      

КонецФункции

 

 

Функция ВосстановитьРасчет(ИмяФайла) Экспорт

       Попытка

             Т = Новый ТекстовыйДокумент();

             Т.Прочитать(ИмяФайла, "UTF-8");

             Значение = САП.ТЗИзТекста(Т);

       Исключение

             Возврат Неопределено;

       КонецПопытки;

       Возврат Значение;

      

КонецФункции

Пример тестирования функции:

 

ТЗ = новый ТаблицаЗначений;

  ТЗ.Колонки.Добавить("Кол1");

  ТЗ.Колонки.Добавить("Кол2");

 

  Стр = ТЗ.Добавить();

  Стр.Кол1 = 1;

  Стр.Кол2 = "1";

 

  Стр = ТЗ.Добавить();

  Стр.Кол1 = 2;

  Стр.Кол2 = "2";

 

 

 

  ТД = САП.ТЗВТекстЧерезСтроки(ТЗ);

  Сообщить(ТД.ПолучитьТекст());

  ТЗ = САП.ТЗИзТекстаЧерезСтроки(ТД);

  ТЗ.ВыбратьСтроку();


 

Вступайте в нашу телеграмм-группу Инфостарт

См. также

Загрузка и выгрузка в Excel Универсальные функции Программист 1С:Предприятие 8 Россия Бесплатно (free)

Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).

30.10.2025    2909    Abysswalker    7    

43

Универсальные функции Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

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

14.05.2025    5773    DeerCven    15    

57

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    47228    dimanich70    83    

167

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    7058    6    John_d    13    

59

Универсальные функции Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    58652    atdonya    31    

69

Универсальные функции Программист 1С:Предприятие 8 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    8795    ke.92@mail.ru    17    

68
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. khaoos 239 26.09.12 05:16 Сейчас в теме
А какова разница по скорости упаковки/распаковки обычного метода и построчного на больших таблицах? Если не очень существенная, то я бы не давал шанса обычному методу вывалить ошибку о нехватке памяти (если эта ошибка конечно не быстро вываливается). Или все же имеет смысл разделять использование методов в зависимости от ситуации?
2. ander_ 26.09.12 07:40 Сейчас в теме
(1) khaoos, осмелюсь предположить, что разница в скорости будет в несколько раз.
3. fixin 4323 26.09.12 08:01 Сейчас в теме
(2) не замерял, но думаю, что стандартный метод работает гораздо быстрее
4. orefkov 1158 26.09.12 09:22 Сейчас в теме
Имхо, чем выгружать построчно, да еще перебирая все колонки в цикле, можно используя метод Скопировать ТаблицыЗначений, выдергивать по 1000 строк в другую ТЗ, и сохранять ее.
artbear; fixin; +2 Ответить
5. fixin 4323 26.09.12 11:28 Сейчас в теме
(4) да, согласен, будет работать быстрее, но мне нужно было сделать затычку для защиты от переполнения памяти. Переделывать уже не буду.
Для отправки сообщения требуется регистрация/авторизация