Отказ от работы с временными файлами при работе с двоичными данными или Потоки как простая замена ADODB.Stream и временным файлам

Публикация № 672498

Разработка - Практика программирования

В платформе начиная с версии 3.8.9 (как я понял по документации) появился расширенный функционал средств работы с двоичными данными. Если раньше простой и очевидный способ преобразования данных строился на использовании временных файлов, то теперь благодаря новым средствам можно уйти от их использования.

Вместо дисклеймера: Это первая моя статья, поэтому прошу отнестись с пониманием. Цель - попытка показать возможности нового функционала на примере двух конкретных задач.

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

Итак задачи:

  1. Собственная десериализация объектов из механизма версионирования объектов УПП.  Задача - обойтись без временного файла.
  2. Получение данных из SQL базы с varbinary типом данных. Задача - уйти от использования COM объекта ADODB.Stream и временного файла.

Начнем по порядку.

1. Собственная десериализация объектов из механизма версионирования объектов.

Здесь нет абсолютно никаких проблем. Объекты сериализуются стандартными механизмами и помещаются в регистр с ресурсом типа ХранилищеЗначений. И все хорошо за исключением последующей десериализации объектов. Для основы был взят механизм из отчета "История изменения объектов". Опускаем ненужное и идем к самой функции, которая из ресурса с типом ХранилищеЗначений получает строку для десерализации. Всю функцию приводить не буду, нам нужны строки преобразования двоичных данных в строковый тип:

ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
ВерсияОбъекта.Записать(ИмяВременногоФайла);
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ИмяВременногоФайла, КодировкаТекста.UTF8);
СтрокаXML = ТекстовыйДокумент.ПолучитьТекст();
УдалитьФайлы(ИмяВременногоФайла);

И как мы видим - используется механизм временных файлов. ВерсияОбъекта в данном случае имеет тип ДвоичныеДанные, получаемые из ресурса регистра с типом ХранилищеЗначения.

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

Собственно нас интересует объект "ЧтениеДанных", а точнее конструктор на основе двоичных данных. У этого объекта широйкий набор свойств и методов. И по СП видно, что нам пригодятся чтение данных в строковые типы - а именно два метода ЧтениеСтроки и ЧтениеСимволов. Первый дает возможность читать построчно, но это цикл и нам сейчас ни к чему. Второй читает количество символов, по умолчанию равное всему потоку. Его мы и будем использовать.

В качестве ремарки - оба метода имеют возможность указания вида кодировки в качестве параметра чтения, однако мы укажем кодировку в конструкторе объекта вторым параметром.

Почитав внимательно мы преобразуем код и получаем всего три строки:

Читатор = новый ЧтениеДанных(ВерсияОбъекта,КодировкаТекста.UTF8);
СтрокаXML = Читатор.ПрочитатьСимволы();
Читатор.Закрыть(); //не забываем чистить за собой

И в общем то все. Никаких временных файлов, на выходе строка для разбора десериализатором.

В голову приходит логичная мысль - для собственных целей мы получаем объект десереализацией по нашему новому алгоритму без временных файлов, но это не частая операция. А как выглядят дела с механизмом версионирования в принципе? Как происходит запись в регистр? Точнее нас интересует как происходит помещение данных в ХранилищеЗначения. Идем в общий модуль УПП реализующий версионирование и ищем то что нам нужно:

ИмяВременногоФайла = ПолучитьИмяВременногоФайла();

ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяВременногоФайла); 
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписатьXML(ЗаписьXML, Источник, НазначениеТипаXML.Явное);
ЗаписьXML.Закрыть();
		
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременногоФайла);
ХранилищеДанных = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));

Бинго! В регистр уходит ХранилищеДанных, но используются временные файлы для формирования ДовичныхДанных. И это понятно конфигурация УПП должна иметь и обратную совместимость. Но у нас уже в руках новые технологии и мы хотим их использовать. В базе с 3000 активными пользователями каждую минуту формируются огромное количество объектов подлежащих версионированию, а значит здесь уже мы имеем возможность практического применения потоков для ускорения и удаления "слабого звена".

Абсолютно справедливо механизм работает и в обратную сторону при помощи объекта ЗаписьДанных. Однако если при чтении  мы уже имеем двоичные данные, которые по сути являются потоком данных и нам нет необходимости его формировать, то при записи нам потребуется поток который мы затем и выгрузим как двоичные данные, а запись в этот поток осуществляется объектом ЗаписьДанных:

ЗаписьXML = новый ЗаписьXML();
ЗаписьXML.УстановитьСтроку();
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписатьXML(ЗаписьXML, Источник, НазначениеТипаXML.Явное);
СтрокаXML = ЗаписьXML.Закрыть();

Поток = новый ПотокВПамяти();
Запись = новый ЗаписьДанных(Поток,КодировкаТекста.UTF8);
Запись.ЗаписатьСимволы(СтрокаXML);
Запись.Закрыть(); //не забываем чистить за собой	
ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные(); 

ХранилищеДанных = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));

И опять никаких временных файлов. На что стоит обратить внимание - кодировка как и в первом случае может указываться в конструкторе объекта ЗаписьДанных, так и в его методах при непосредственной записи. Кроме того кодировка может указываться и в сериализации, но это уже другая история. Мы снова используем метод записи символов, но можем так же использовать и построчную "порционную" запись.

Код вышел чуть длиннее, но у нас нет временных файлов, все происходит в памяти. Вот так бесхитростно мы оптимизировали версионирование объектов в УПП.

Все выше перечисленное - очевидное использование Потоков. Теперь же сладкое - неочевидное использование потоков, а именно конкретная задача по чтению данных из SQL.

2. Получение данных из SQL базы с varbinary типом данных.

Возникла задача - создать обработку, которая будет обращаться к внешней базе данных на MS SQL и хранить в ней макеты текущих версий разрабатываемых внешних обработок. Такой некий совсем простой аналог GIT. Это обработки начального заполнения данных из разных источников, а необходимость хранения во внешнем источнике так как в процессе разработки параллельно тестируется около 20 баз и потребовался единый источник обработок заполнения. Возможно подход и неправильный, но речь сейчас не об этом.

В ходе работы с ADODB возникла проблема получения двоичных данных из varbinary типа SQL. Все кто работал и сталкивался понимают о чем идет речь - при получении значения из базы через ADODB.Recordset нам вываливается значение типа COMSafeArray с целочисленными элементами.

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

Начинаем копать и думать. Первая мысль - преобразовать каждый элемент в 16-тиричный формат и попытаться сформировать двоичные данные по символьным значениям. Но через 30 секунд отметаем идею - она тупиковая так как налицо избыточность используемых объемов памяти, и "детскость" в подходе. Вывод - смотрим в сторону потоков в 1С. Мы понимаем что наш COMSafeArray  это и есть поток данных, но в "особом" виде. Курим СП выискивая возможность формирования потока в 1С на основе нашего. Основной объект который мы смотрим ПотокВПамяти. Понятно что нам надо формировать его, однако не очевиден способ.

Вертим объект Поток со всех сторон и не находим методов нас удовлетворяющих. Однако находим зацепку - поток данных можно сформировать конструктором на основе буфера. Курим объект БуферДвоичныхДан

ных в СП и выясняем что БуферДвоичныхДанных согласно СП это:

Описание:
Коллекция байтов фиксированного размера с возможностью произвольного доступа и изменения по месту.

Дак это то что надо! Это и есть словесное описание того результата, что мы получаем из SQL. Смотрим методы и находим то, что нужно:

БуферДвоичныхДанных (BinaryDataBuffer)
Установить (Set)

Синтаксис:

Установить(<Позиция>, <Значение>)

Параметры:

<Позиция> (обязательный)

Тип: Число.
Позиция, на которую требуется поместить новое значение.

<Значение> (обязательный)

Тип: Число.
Значение, которое требуется установить в заданную позицию буфера.
Если значение больше 255 или меньше 0, будет выдана ошибка о неверном значении параметра.

Описание:

Устанавливает значение элемента на заданной позиции (нумерация начинается с 0).

Почему именно тут мы танцуем джигу? Потому что мы изначально работаем с набором байтов  в виде массива чисел от 0 до 255, и тут без каких либо преобразований нам предлагают установку этих байтов в виде этих же самых чисел от 0 до 255. На что обращаем внимание - конструктор буфера подразумевает заранее известную длину, а методом придется писать однозначно в цикле. Остальное - дело техники, поток сформировать по буферу и выгрузить в двоичные данные мы уже пробовали.

Вот код с использованием ADODB.Stream:

Функция ПолучитьФайлАДО_Stream(Value)
	Файл = Неопределено;
	Stream = Новый COMОбъект("ADODB.Stream");
	Stream.Type = 1;
	Stream.Open();
	Stream.Write(Value);
	ИмяФайла = ПолучитьИмяВременногоФайла();
	Stream.SaveToFile(ИмяФайла);
	Stream.Close();
	Файл = Новый ДвоичныеДанные(ИмяФайла);
	УдалитьФайлы(ИмяФайла);
	Возврат Файл;
КонецФункции

Пример вызова:

Файл = ПолучитьФайлАДО_Stream(АДОНаборДанных.Fields(2).Value);

Итак, код функции получения файла без использования ADODB.Stream и временных файлов.

Функция ПолучитьФайлАДО(Массив)
	Длинна = Массив.Количество();
	Буфер = новый БуферДвоичныхДанных(Длинна);
	Для индекс = 0 по Длинна - 1 Цикл
		Буфер.Установить(индекс,Массив[индекс]);	
	КонецЦикла;
	
	Поток = новый ПотокВПамяти(Буфер);
	ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
	
	Возврат ДвоичныеДанные;	

КонецФункции // ПолучитьФайлАДО()

И вызов этой функции при чтении данных (выдержка из кода моей функции):

	Пока не АДОНаборДанных.eof() Цикл
		Строка = ТЧОбработки.Добавить();
		Строка.ИмяОбработки = АДОНаборДанных.Fields(1).Value;
				
		Если ТипЗнч(АДОНаборДанных.Fields(2).Value) = Тип("COMSafeArray") Тогда
			Строка.Макет = ПолучитьФайлАДО(АДОНаборДанных.Fields(2).Value.Выгрузить());
			Строка.Запустить = "Запустить";
		КонецЕсли;
		
		АДОНаборДанных.MoveNext();
	КонецЦикла;

В качестве пояснения - проверка на тип COMSafeArray нужна для исключения NULL. Ну и с помощью Выгрузить() делаем сразу преобразование в обычный массив. Зачем? Просто так захотелось. Можно работать и без выгрузки прямиком с COMSafeArray.

Итого - мы получили двоичные данные без временных файлов и дополнительной внешней компоненты.

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

В качестве вывода - об использовании временных файлов в 1С можно забыть.

Upd: Исправил орфографические ошибки. Спасибо всем, кто обратил внимание.

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. VmvLer 12.09.17 14:55 Сейчас в теме
При таком способе ухода от временных файлов мы минимизируем операции с диском, но увеличиваем нагрузку на память, так нет? Если под временными файлами быстрый диск, то может память поберечь для других задач.

Я хочу спросить хрен редки не слаще ли, т.е. тесты на общую производительность есть?
2. vardeg 179 12.09.17 15:09 Сейчас в теме
Полноценные тесты не стояла задача делать.
Вот умозаключения по этому поводу не подкрепленные практическими тестами:
Выигрыш в производительности вполне может быть и малым, но насчет слаще редька или нет - готов поспорить. Каждый объект и так у нас существует в памяти. Если для преобразования строки в ДД и обратно мы в добавок к ним задействуем еще и временные файлы - то выделенной памяти явно не станет меньше. В любом случае для записи в файл и чтения из него платформа должна будет сформировать временные структуры в памяти - мы это делаем сами потоками. По логике - то же самое.
А вот при работе с ADODB.Stream - выигрыш очевиден. У нас нет необходимости при прочих равных (я имею ввиду и так наличие временных структур в памяти) иметь еще один COM объект и обращаться к его методам. Все делается штатными средствами.
Чего искренне не хватает и что хотелось бы - формирование БуфераДвоичныхДанных на основе массива. Если это будет реализовано на уровне платформы - то итоговый выигрыш в производительности так же будет очевиден - пока же я не уверен, что цикл формирования буфера не съест весь профит.
GreenDragon; mevgenym; +2 Ответить
3. vitkhv 12.09.17 15:30 Сейчас в теме
Исправьте плиз:
Получение данных из SQL базы с varbinaty varbinary типом данных.
4. PerlAmutor 124 12.09.17 17:13 Сейчас в теме
Исправьте плиз:
Итак, код функции получения фала файла без использования ADODB.Stream и временных файлов.

работаем с наобором набором байтов

десереализация десериализация

мощного инустремнты инструмента работы
5. PerlAmutor 124 13.09.17 08:37 Сейчас в теме
Upd: Исправил орфографические ошибки. Спасибо всем, кто обратил внимание.

Тогда вот еще =)
десерализации десериализации

десереализации десериализации

десереализацией десериализацией

интерисует интересует

десятиричном десятеричном

инструмента работы с двоичными данным данными


P.S.: я не Grammar Nazi =)
14. Altair777 640 13.09.17 12:43 Сейчас в теме
(5) Ну, и это поправьте
Точнее нас интерисует как происходит

А еще не хватает несколько десятков запятых. Попробуйте воспользоваться MS Word
6. RailMen 806 13.09.17 08:37 Сейчас в теме
Отличная статья, задрали временные файлы.
ValentinGushchin; +1 Ответить
7. Silenser 532 13.09.17 10:45 Сейчас в теме
8. Tangram 154 13.09.17 10:58 Сейчас в теме
Интересно, буду использовать. Ну и в заголовке поправь версию платформы пжлста (3.8.9).
GreenDragon; +1 Ответить
9. ivanov660 2386 13.09.17 11:12 Сейчас в теме
"+" за акцент внимания на новых фитчах от 1С.
10. kiruha 386 13.09.17 11:25 Сейчас в теме
Иногда файлы xml имеют размеры > 1 Гб
Этот Поток будет скидывать данные во временный файл в случае нехватки памяти
или рухнет 1С ?
11. vardeg 179 13.09.17 12:11 Сейчас в теме
(10) Если честно - Вы меня немного озадачили и заставили задуматься.
Хотелось бы посмотреть на работу с такими xml файлами через механизм временных файлов, ну или вообще на работу с ними.
Хотелось бы посмотреть на попытку создать конструктором ДовчиныеДанные на основе такого файла. Ну или простую десериализацию такого файла.
Однако мысли на этот счет следующие - мы имеем набор инструментов, и сами определяем в какой ситуации каким набором инструментов.
Поэтому в качестве ответа:
В отличии от коснтруктора ДвоичныхДанных на основе файла мы с потоками можем работать порционно - делать последовательные записи и чтения Потока, для этого существует полный набор методов объекта ЧтениеДанных, включая приятный метод ПрочитатьСтроку, который в потоке ДД определяет по указанному нами разделителю строку. Аналогично в обратную сторону.Если мы знаем, что XML будет таких размеров, а у нас возникает необходимость получить его из двоичных данных, то я бы создал механизм поточного чтения и обработки порций информации. Тем более что десериализация XML так же поддерживает механизм последовательного чтения - у объекта ЧтениеXML есть соответствующие методы.
Теоретически используя подход чтения и обработки таких файлов "по кускам", а правильнее поточного (масло масленое конечно, но все же) мы можем обойти ограничения по памяти, которое вывалит нам ошибку при попытке работы в объектной модели.
Если честно - Ваш вопрос очень интересный и в нем я вижу потенциал для нового исследования и статьии с практическими примерами работы с большими массивами данных. Если Вас не затруднит сформулировать задачу из абстрактной в более или менее предметную - было бы интересно попытаться ее решить.
16. kiruha 386 13.09.17 13:14 Сейчас в теме
(11)
Если Вас не затруднит сформулировать задачу из абстрактной в более или менее предметную - было бы интересно попытаться ее решить.

В более предметной - читаются или пишутся файлы обмена со сторонними системами xml - очень большого размера .
Обсуждений много и на инфостарте и на мисте , например http://www.forum.mista.ru/topic.php?id=489798 https://infostart.ru/public/15464/
17. vardeg 179 13.09.17 13:23 Сейчас в теме
(16) я в принципе Вас понял. Я смоделирую ситуацию и попробую создать инструментарий для таких загрузок из сторонних систем.
12. PerlAmutor 124 13.09.17 12:32 Сейчас в теме
Жалко что 1С умеет работать со своими коллекциями (Массив, Структура, ТаблицаЗначений и т.д.) только на уровне оперативной памяти.
Вы можете сериализовать ТаблицуЗначений в файл и потом загрузить обратно. А представьте что будет, если сериализовать ТаблицуЗначений в файл на сервере где >100Гб ОЗУ, а потом попробовать загрузить этот файл уже на клиенте (толстый клиент, обычное приложение) ?
Такие операции как построение индекса, сортировка или свертывание ТЗ хотелось бы иметь возможность проводить на диске.
Чтобы можно было делать отборы по ТЗ находящейся на диске, подгружать порционно в окно пользователя (pagination), а не держать сотни мегабайт в ОЗУ, где все данные и не нужны.
Иногда хочется иметь выбор между скоростью (забить всю оперативку) и стабильностью (медленно но с гарантией, что всё будет обработано и в критичный момент не свалится)
13. CyberCerber 756 13.09.17 12:34 Сейчас в теме
По поводу оптимизации могу сказать, что операцию, описанную во второй части статьи, пришлось проделать пару месяцев назад в одном проекте, т.к. объект ADODB.Stream время от времени отваливался на сервере. Код, в принципе, почти полностью совпадает с вашим.
Только в итоге остановился на варианте, что сначала в попытке выполняется по ADODB.Stream, а только в исключении встроенный ЗакрытьИПолучитьДвоичныеДанные, т.к. на данных объемом в несколько мегабайт тормоза у встроенного заметные. Наверное, дело в побайтовой записи в цикле.
15. vardeg 179 13.09.17 12:47 Сейчас в теме
(13) Собственно подтверждение домыслов из моего ответа (2) . Как уже говорил - вполне логично разработчикам платформы предусмотреть метод формирования буфера двоичных данных по массиву. Если это будет реализовано, то это даст ощутимый прирост скорости.
18. Arxxximed 9 13.09.17 13:50 Сейчас в теме
По первому пункту вроде добавлен
 	ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(ПараметрСтрока,КодировкаТекста.ANSI);
 	ПараметрСтрока = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные,КодировкаТекста.ANSI);



Как то все намного изящнее... Но это в 8.3.10 я вижу. Не знаю как в 8.3.9
binex; vardeg; +2 Ответить
19. vardeg 179 13.09.17 14:34 Сейчас в теме
(18) да, в 8.3.10 функционал еще более расширен. так как с самой платформой еще не работал - упустил из виду эти функцию. спасибо - изучим.
20. palsergeich 13.09.17 14:34 Сейчас в теме
Вместо
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяВременногоФайла); 
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписатьXML(ЗаписьXML, Источник, НазначениеТипаXML.Явное);
ЗаписьXML.Закрыть(); 

и обратного есть же шикарные методы - XMLСтрока и XMLЗначение ...
Функция ПолучитьФайлАДО_Stream(Value)
	Файл = Неопределено;
	Stream = Новый COMОбъект("ADODB.Stream");
	Stream.Type = 1;
	Stream.Open();
	Stream.Write(Value);
	ИмяФайла = ПолучитьИмяВременногоФайла();
	Stream.SaveToFile(ИмяФайла);
	Stream.Close();
	Файл = Новый ДвоичныеДанные(ИмяФайла);
	УдалитьФайлы(ИмяФайла);
	Возврат Файл;
КонецФункции
Показать

Нет никаких гарантий, что завтра сервер переедет на тот же linux и придется все участки с COM лопатить. Что мешает сделать сразу универсально с помошью хранимых процедур....
22. vardeg 179 13.09.17 15:41 Сейчас в теме
(20)
1 - речь в статье не возможностях сериализатора. Уверен там есть изящные и удобные методы работы. Речь идет о преобразовании данных при работе с ДД.
2 - как раз таки от COM и предлагается в статье уйти на примере получения двоичных данных. Касательно хранимых процедур - не всегда есть возможность создать хранимые процедуры на целевом источнике данных. Понятно, что есть варианты различные решения и этой проблемы - но повторюсь - речь в статье о том как новый механизм на основе новых объектов Поток позволяет штатными средствами работать с двоичными данными и заниматься их преобразованием. А именно применять новые возможности в задачах решаемых ранее шаблонным типом на основе временных файлов.
21. binex 271 13.09.17 15:00 Сейчас в теме
Спасибо за разбор! Сегодня уже применил. Недавно ковырял в этом направлении, да забросил.
23. LexSeIch 208 14.09.17 06:23 Сейчас в теме
Спасибо за интересную статью. Добавил себе в копилку.
24. vlengin 18.09.17 12:27 Сейчас в теме
За информацию по новым объектам - спасибо!
Ну а от ADODB.Stream (и "промежуточного" файла) легко избавиться другим способом: конвертировать Binary-Base64 (Base64-Binary) средствами MS SQL, ну а на стороне 1С использовать Base64Значение(Base64Строка), т.е. "обмен данными" с MS SQL через строку Base64
25. Silenser 532 20.09.17 11:34 Сейчас в теме
Попробовал прямой метод считывания побайтово данных из потока и запихивания в COMSafeArray. С производительностью, как и ожидалось, беда. На файлах 2-10 Кб - все проходит незаметно, а вот на файлах в несколько мегабайт все печально.
Прикрепленные файлы:
26. Silenser 532 20.09.17 13:23 Сейчас в теме
Какой-то глюк, вот вариант с временными файлами
Прикрепленные файлы:
27. Crush 25.10.17 14:43 Сейчас в теме
Спасибо!
Хорошее применение потокам.
Вот бы еще gzip через них распаковывать:)
28. Crush 25.10.17 16:36 Сейчас в теме
Побайтовая запись только подвела. Неадекватно долго перебирается массив. Пробовал и с массивом и с COMsafeArray. Запись попробовал и в буфер и в ЗаписьДанных.
В общем, как выше было сказано, ждём когда в платформе реализуют конструктор двоичных данных на основании массива байт.
29. Crush 27.10.17 11:04 Сейчас в теме
Еее!!! Справился с тормознутым побитовыми операциями.


Для решения моей задачи нужно было ComSafeArray конвертить в ДвоичныеДанные. И вот чё получилось:

Функция ПолучитьДвоичныеДанныеИзCOMSafeArray(COMSafeArray)
	дом				= Новый COMОбъект("Msxml2.DOMDocument");
	элДом			= дом.createElement("tmp");
	элДом.datatype	= "bin.base64";
	элДом.nodeTypedvalue = COMSafeArray;
	дд		= ПолучитьДвоичныеДанныеИзBase64Строки(элДом.Text);
	Возврат дд; 
КонецФункции


Кстати, может кто-то знает, WinHttp.WinHttpRequest.5.1 в ResponseBody отдаёт массив, а сам WinHttp умеет в base64 сразу конвертировать тело ответа? Собственно под эту задачу и искал решение
fvr2000; EMelihoff; +2 Ответить
30. PLAstic 270 27.11.17 15:45 Сейчас в теме
В анонсе, вероятно, подразумевалась платформа 8.3.9.
31. endym 199 30.11.17 13:06 Сейчас в теме
Автор, исправь шапку "В платформе начиная с версии 3.8.9" ;)
Оставьте свое сообщение

См. также

Serverless (Faas) в 1С. Создание и вызов Yandex Cloud Functions Промо

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

"Я не могу просто взять и скопировать код с гитхаба", "у нас 1С микросервисами окружена", "возможностей мало" - частые фразы 1С разработчиков. которым не хватает возможностей платформы в современном мире. Faas, конечно, история не новая, но нас сдерживало 152ФЗ и задержки по пингам. Для того, чтобы действительно использовать в 1С код, к примеру, на Python, надо было приложить усилия. Теперь всё намного проще - берём и используем.

28.12.2020    4477    comol    22    

Базовые вещи БСП, которые облегчат жизнь программисту 1С

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Россия Бесплатно (free)

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

30.08.2020    11075    quazare    33    

Форма выбора (подбор) в управляемых формах

Практика программирования v8 v8::УФ 1cv8.cf Россия Бесплатно (free)

Разбор небольших примеров того, как правильно открывать форму выбора (подбора) в управляемых формах, не прибегая к модальным окнам.

08.05.2020    36378    user5300    16    

Программная работа с настройками СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Нюансы программной работы с настройками системы компоновки данных в отчетах и динамических списках. Обзор всех видов настроек компоновки. Что в каких случаях правильно применять. В качестве примера рассмотрена работа с отборами и группировками.

27.01.2020    39556    ids79    26    

Использование программных перечислений, ч.1: строковые константы Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Часто ли у вас возникает необходимость в коде выполнять сравнение на строку?

10.12.2016    38482    unichkin    74    

[СКД] Программное создание схемы компоновки данных

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Сделаем отчет на СКД полностью программно, без использования макета "схема компоновки данных".

15.01.2020    30731    John_d    22    

Последовательности событий при проведении документа 1С. Шпаргалка + про формы + про расширения

Практика программирования v8 Россия Бесплатно (free)

Собрал информацию о событиях/подписках/расширениях в одном месте.

30.12.2019    23400    kuzyara    38    

30 задач. Странных и не очень

Практика программирования v8 Бесплатно (free)

30 задач на знание языка программирования 1С и некоторого поведения платформы. Маленьких. Странных и не очень.

02.12.2019    18918    YPermitin    60    

Вспомогательные инструкции в коде 1С Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Помогаем редактору кода 1С помогать нам писать и анализировать код.

15.10.2018    32099    tormozit    104    

Как передать IP адрес, который вызвал HTTP запрос в 1C (для веб-сервера Apache)

Практика программирования v8 Бесплатно (free)

Столкнулся с задачей получения IP адреса, который вызывает http сервис 1С. Итак, решение:

22.11.2019    9884    Sibars    19    

Полезные процедуры и функции для программиста

Практика программирования Универсальные функции v8 1cv8.cf Россия Бесплатно (free)

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

07.10.2019    33276    HostHost    41    

Таблица значений. Нюансы

Практика программирования v8 Бесплатно (free)

Обзор некоторых аспектов использования общеизвестного инструмента 1С.

01.10.2019    40423    Yashazz    50    

Оформление и рефакторинг сложных логических выражений Промо

Практика программирования v8 Россия Бесплатно (free)

В сложных логических выражениях нередко самому автору спустя какое-то время тяжело разобраться, не говоря уже о других программистах. Предлагаемая методика позволяет повысить наглядность таких выражений путем оформления в виде И-ИЛИ дерева и одновременно выполнять их рефакторинг.

20.09.2012    79353    tormozit    131    

О программе Postman для тестирования API и для чего она нужна 1С-нику

Практика программирования Программное обеспечение (software) v8 Бесплатно (free)

Для чего нужна программа Postman для тестирования API и какая от него польза для 1С-программиста.

24.09.2019    14687    budidich    28    

[Шпаргалка] Программное создание элементов формы

Практика программирования Работа с интерфейсом v8 1cv8.cf Бесплатно (free)

Программное создание практически всех популярных элементов формы.

06.09.2019    67916    rpgshnik    68    

Агрегатные функции СКД, о которых мало кто знает

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Пользуетесь ли Вы всеми возможными агрегатными функциями, которые предоставляет система компоновки данных? Если Вы используете только: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, то эта статья для Вас.

05.09.2019    58563    ids79    55    

Запись значения в поле ввода/формы со срабатыванием события ПриИзменении Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Иногда возникает необходимость после записи значения в какое либо поле ввода/формы вызвать для него обработчик события ПриИзменении, а о вызове самого события приходится только мечтать. В этой статье приводится программный способ вызова этого события.

11.07.2007    50112    tormozit    48    

Регистры бухгалтерии. Общая информация

Практика программирования Математика и алгоритмы v8 v8::БУ БУ Бесплатно (free)

Общая информация о внутреннем устройстве регистров бухгалтерии.

05.09.2019    33381    YPermitin    24    

Три костыля. Сказ про фокусы в коде

Практика программирования v8 Бесплатно (free)

Три интересных (или странных) костыля в коде, которые могут помочь в повседневных и не очень задачах.

03.09.2019    27096    YPermitin    80    

Отслеживание выполнения фонового задания

Практика программирования Универсальные функции Разработка v8 1cv8.cf Бесплатно (free)

Запуск фонового задания из модуля внешней обработки. Отслеживание выполнения задания в виде прогресса, расположенного на форме.

17.08.2019    35641    ids79    16    

Как сделать из &НаКлиентеНаСервереБезКонтекста почти &НаКлиентеНаСервере Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Как сделать метод формы, доступный на клиенте и на сервере одновременно, и сохранить при этом удобство разработки

10.09.2017    46815    tormozit    74    

Функции СКД: ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Подробное описание и использование внутренних функций системы компоновки данных: Вычислить, ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений.

08.08.2019    107753    ids79    63    

Фоновое выполнение кода в 1С - это просто

Практика программирования v8 1cv8.cf Бесплатно (free)

Как легко запускать выполнение в фоне, не прибегая к долгому описанию фоновых процедур.

02.08.2019    44254    avalakh    26    

Разбираемся с параметрами редактирования СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Связь по типу, Параметры выбора, Связи параметров выбора

31.07.2019    29409    json    15    

Выгрузка документа по условию Промо

Практика программирования Разработка v8 Бесплатно (free)

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий... А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

25.04.2019    16437    m-rv    2    

СКД - наборы данных и связи между ними, создание собственной иерархии, вложенные отчеты

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Набор данных объект. Использование в схеме компоновки нескольких наборов данных. Различные варианты связи наборов: объединение, соединение. Использование иерархии в отчетах на СКД. Создание собственной иерархии, иерархия детальных записей. Использование вложенных схем в отчетах на СКД.

26.07.2019    76562    ids79    14    

СКД - использование расширений языка запросов, секция ХАРАКТЕРИСТИКИ

Инструментарий разработчика Практика программирования v8 v8::СКД Бесплатно (free)

Автоматическое и не автоматическое заполнение полей компоновки данных. Использование расширений языка запросов для СКД «{…}», секция ВЫБРАТЬ, секция ГДЕ, параметры виртуальных таблиц. Автоматизированное использование дополнительных данных в запросе: секция ХАРАКТЕРИСТИКИ.

17.07.2019    40048    ids79    27    

Регистры сведений. За кулисами

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

Небольшие заметки по внутреннему устройству регистров сведений.

09.07.2019    28445    YPermitin    14    

Как прикрутить ГУИД к регистру сведений Промо

Практика программирования Перенос данных из 1C8 в 1C8 Разработка v8 Бесплатно (free)

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

16.04.2019    20979    m-rv    17    

"Меньше копипаста!", или как Вася универсальную процедуру писал

Практика программирования Разработка v8 v8::СКД 1cv8.cf Бесплатно (free)

Программист Вася разбирает подход создания универсальных методов на примере программного вывода СКД.

04.07.2019    20418    SeiOkami    50    

Работа с настройками системы компоновки данных

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

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

02.07.2019    59709    ids79    17    

Создание отчетов с помощью СКД - основные понятия и элементы

Практика программирования Математика и алгоритмы v8 v8::СКД Бесплатно (free)

Основные принципы работы СКД. Понятия схемы компоновки и макета компоновки. Описание основных элементов схемы компоновки: наборы данных, поля, вычисляемые поля, ресурсы, параметры.

25.06.2019    60675    ids79    26    

Как сделать запрос на изменение данных Промо

Практика программирования v8 v8::Запросы 1cv8.cf Бесплатно (free)

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    32359    m-rv    21    

Многопоточное ускорение однопользовательских нагрузок в 1С + Microsoft SQL Server 2017

Практика программирования Производительность и оптимизация (HighLoad) v8 v8::Запросы Бесплатно (free)

Взаимодействие с Microsoft SQL Server нередко вызывает трудности у 1С-ников, а потому интересны любые моменты, связанные с его использованием. О своем опыте работы с новым SQL Server 2017 участникам конференции Infostart-2018 рассказал директор ООО «Аналитика софт» Дмитрий Дудин.

11.06.2019    27070    dmurk    146    

Регистры накопления. Виртуальные таблицы. Часть №2: "Остатки" и "Остатки и обороты"

Практика программирования v8 1cv8.cf Бесплатно (free)

Описание работы платформы 1С:Предприятие 8.2 с виртуальными таблицами регистров накопления "Остатки" и "Остатки и обороты". Анализ SQL-запрос при работе с виртуальными таблицами

22.05.2019    31960    YPermitin    7    

Регистры накопления. Структура хранения в базе данных

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

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

16.05.2019    49920    YPermitin    30    

Метод формирования движений в типовых регистрах нетиповыми регистраторами Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

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

05.12.2017    28865    itriot11    34    

О расширениях замолвите слово...

Практика программирования Разработка v8 Бесплатно (free)

О чём стоит задуматься при принятии решения о создании расширения конфигурации…

07.04.2019    37950    ellavs    126    

Git-репозитории для 1С-кода (опыт использования при небольших проектах)

Практика программирования v8 Бесплатно (free)

Инструкции по взаимодействию с Git-репозиторием, которые писались для тех наших программистов, которые вообще никогда не работали с Git (руководства в духе "Как получить код из git-репозитория?", "Как отправить код в git-репозиторий")...

28.03.2019    28660    ellavs    90    

Трюки с внешними источниками данных

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

Некоторые трюки для преодоления ограничений внешних источников данных.

14.03.2019    34589    YPermitin    53    

Использование классов .Net в 1С для новичков Промо

Практика программирования Разработка внешних компонент Универсальные функции v7.7 v8 Бесплатно (free)

Руководство для новичков. Написав статью http://infostart.ru/public/238584/, я понял, что многие не понимают того, что написано. Поэтому в этой статье постараюсь более подробно остановиться на азах и без кода на вражеском языке (C#)

27.01.2016    78449    Serginio    113    

Ошибки при работе с хранилищем конфигурации и способы их решения

Практика программирования v8 Бесплатно (free)

В статье собраны наиболее распространенные ошибки при работе с хранилищем конфигурации и способы их обхода и решения.

01.03.2019    48826    Смешной 1С    31    

Разработка и сценарное тестирование с Vanessa-ADD. Отчетность Allure. Автоматизация запуска сценариев

Практика программирования Vanessa Automation v8 Россия Бесплатно (free)

Формируем отчетность о результатах выполнения сценариев. Автоматизируем запуск.

26.02.2019    24225    Vladimir Litvinenko    28    

Автоматические и управляемые блокировки применительно к типовым конфигурациям 1С Промо

Математика и алгоритмы Практика программирования v8 v8::blocking 1cv8.cf Бесплатно (free)

Основные принципы работы с режимами автоматических и управляемых блокировок в 1С Предприятие 8. Теория и применение в типовых конфигурациях: БП, УТ, ЕРП

10.11.2018    37475    ids79    40    

Возможности типовых шаблонов ограничения доступа на уровне записей (RLS)

Практика программирования БСП (Библиотека стандартных подсистем) Роли и права v8 v8::Права Бесплатно (free)

Краткий обзор применения типовых шаблонов ограничения доступа на уровне записей в конфигурациях, созданных на базе БСП: #ПоЗначениям, #ПоНаборамЗначений, #ПоЗначениямРасширенный, #ПоЗначениямИНаборамРасширенный

03.02.2019    46585    ids79    11    

Тестер: частые вопросы Промо

Практика программирования v8 Бесплатно (free)

Ошибкам бой - тесты норма жизни!

25.07.2018    30169    grumagargler    31    

EnterpriseData – часть 2. Процесс выгрузки данных

Практика программирования Обмен через XML v8 v8::УФ Россия Бесплатно (free)

Основные этапы выгрузки данных через ED, обработчики событий выгрузки, правила обработки данных, правила конвертации объектов, конвертация свойств первого и второго этапов, процедуры БСП, используемые при выгрузке данных, структура «КомпонентыОбмена».

26.12.2018    29058    ids79    31