1с версияданных что это
Начиная с версии технологической платформы 8.3.9 средства для работы с двоичными данными претерпели существенные изменения. В этой статье я постараюсь рассказать как о старых, так и о новых инструментах для работы с двоичными данными. При написании статьи использовалась версия технологической платформы 8.3.12
Общая информация
Если раньше, до версии технологической платформы 8.3.9, мы располагали только объектом ДвоичныеДанные, то к настоящему времени у нас имеется целый набор объектов, которые серьезно расширяют наши возможности по манипуляциям с двоичными данными. Рассмотрим все эти объекты чуточку подробнее.
Двоичные данные
Экземпляры объекта ДвоичныеДанные содержат двоичные данные, которые считываются из файла. При это объект ДвоичныеДанные является достаточно многофункциональным — мы можем:
- читать двоичные данные из файла и записывать их в файл;
- передавать их между клиентом и сервером при помощи временного хранилища;
- передавать и получать их по сети;
- хранить их базе данных в реквизитах вида ХранилищеЗначения;
- превратить двоичные данные в объект вида Картинка (при определенных условиях конечно);
- хранить двоичные данные в макетах;
- шифровать и расшифровывать, подписывать и проверять подписи;
Наверняка я что-то пропустил, но главное должно быть понятно — несмотря на значительное развитие средств работы с двоичными данными, объект ДвоичныеДанные остается ключевым.
Потоки
Это группа объектов назначение которых заключается в работе с потоками данных.
Поток — этот объект представляет собой поток данных из которого можно читать и/или записывать в него данные. Данный объект не имеет конструктора, а получить экземпляр объекта можно при помощи различных методов других объектов.
ФайловыйПоток — специализированный вариант объекта Поток, предназначенный для работы с данными находящимися в файлах на диске.
ПотокВПамяти — специализированный вариант объекта Поток, предназначенный для работы с данными находящимися в оперативной памяти.
МенеджерФайловыхПотоков — этот объект предоставляет типовые методы для работы с файлами (открытие и создание). Создать экземпляр этого объекта нельзя — имеется объект глобального контекста ФайловыеПотоки который и предоставляет доступ к методам менеджера.
Чтение и запись
ЧтениеДанных — этот объект предназначен для чтения различных типов данных из различных источников (потоки, файлы, двоичные данные).
РезультатЧтенияДанных — этот объект содержит описание результата чтения данных из потока. Объект не имеет конструктора, получить экземпляр объекта можно при помощи методов других объектов.
БуферДвоичныхДанных — этот объект представляет собой коллекцию байтов фиксированного размера, имеется возможность произвольного доступа и изменения по месту.
ЗаписьДанных — этот объект предназначен для записи различных типов данных в приемник.
Практическая часть
Итак, у нас достаточно много различных объектов, которые, в свою очередь, имеют много разных свойств и методов. Разобраться во всем этом более подробно помогут практические примеры, к ним и перейдем.
Многие объекты — ДвоичныеДанные, Поток, ФайловыйПоток, ПотокВПамяти, ЧтениеДанных, ЗаписьДанных, РезультатЧтенияДанных имеют пары синхронных и асинхронных методов, например: Записать — НачатьЗапись, Закрыть — НачатьЗакрытие. Асинхронные методы нужны для обеспечения возможности одинаковой работы и в тонком клиенте, и в веб-клиенте.
Подробнее про синхронные и асинхронные методы можно прочесть в этой статье.
Двоичные данные
Ниже приведены примеры основных операций с объектом ДвоичныеДанные.
Добрый день.
При интеграции двух баз хочу использовать свойство объекта ВерсияДанных не только для валидации объектов, но и сравнения версий (Источник.ВерсияДанных > Приемник.ВерсияДанныхИзИсточника ).
В приемнике версия данных хранится в отдельном поле.
Из описания: _Version - версия записи (изменяется после каждого обновления данной записи)
Base64Значение(Выборка.ВерсияДанных) - возвращает шестнадцатеричное представление: 00 00 00 00 00 00 46 7C,
Переводим в десятичную и можно сравнивать.
Кто-то пользовался? Или есть "подводные" камни?
(1) Base64Значение(Выборка.ВерсияДанных) - возвращает шестнадцатеричное представление.
Кажется, что вы ошибаетесь в предположении действия Base64Значение.
Base64Значение (Base64Value)
Синтаксис:
Тип: Строка.
Строка, закодированная по алгоритму base64.
Возвращаемое значение:
То есть "00 00 00 00 00 00 46 7C" это представление двоичных данных.
(1) Версия данных устанавливается на уровне базы данных - для SQL это timestamp - т.е. в момент создания или обновления (при записи документа каждый раз) туда записывается инкрементальное поле в пределах БД в двоичном формате.
Поэтому для 2х баз они всегда будут разными - и по ним сравнивать нельзя
Заводить дополнительный реквизит для каждого документа в принципе можно, но зачем это делать - ведь регистрация в узле плана обмена взводится при каждой записи документа, и при каждой записи версия будет меняться.
В профилере можно увидеть что при записи документа это поле никогда не записывается.
(3) Заводить дополнительный реквизит - да.(У меня регистр сведений соответствий)
Я использую многопоточную загрузку данных. И уже есть проблемы, что более позднее изменение объекта загружается раньше, чем ранняя версия этого объекта.
Поэтому и хочу сравнивать.
Загружать, если: Источник.ВерсияДанных > Приемник.ВерсияДанныхИзИсточника
У меня она оказалась не нужна, хотя прикидки делал.
Написал функцию преобразования ВерсииДанных в число, может кому-то пригодится.
Передаем ссылочный тип данных:
ВерсияДанных (DataVersion)
Тип: Строка.
а не проще ли сравнивать сразу строки?
вот попробовал в Табло - работает.
или СтрокаHEX = Base64Значение(ВерсияСтрокой) - тут уже базой будет 0123456789ABCDEF - т.е в порядке увеличения;
и сравнивать без преобразования с помощью СравнениеДанных (все равно по строковому представлению сравнивается)
Так ещё проще и побыстрее будет.
ВерсияСтрокой = Ссылка.ВерсияДанных
СтрокаHEX = "0x"+СтрЗаменить(Base64Значение(ВерсияСтрокой), " ", "") ;
Народ, просветите, что есть поле ВерсияДанных в 8.2?
Теоретически понятно, но как с ним работать? Ято оно из себя представляет? Как его расшифровать?
Например, в подписке на события ПриЗаписи объекта, можно по нему понять новый объект или уже был записан?
Это верися объекта, используется для реализации оптимистичной блокировки.
На уровне данных информация была всегда, просто в 8.2 к ней открыли доступ прикладному разработчику.
(3) я описал задачу в корне темы.
Что оно из себя представляет? Как его расшифровать?
Например, в подписке на события ПриЗаписи объекта, можно по нему понять новый объект или уже был записан?
(0) при каждой записи обновляется версия.
удобно использовать для синхронизации и понимания что объекты изменены без использованиять какихнить там планов обмена
При этом при создании может быть явно записан и несколько раз. Т.е. пользователь создал элемент нажал ОК и версияДанных будет равна к пример 3 (3 раза записан был)
2(8) Поставь эксперимент. Создать по 100 объектов 10 разных типов данных. Запиши каждый по 10 раз. Обменяйся с другой базой 3-мя разными способами. Расскажи как меняется при этом версия данных. Пожни славу и PROFIT.
Свойство "ВерсияОбъекта", содержащееся в данных формы, представляющих объектные типы (СправочникОбъект и т.п.) переименовано в "ВерсияДанных" и имеет тип Строка. В данной строке содержится Base64-представление версии объекта.
из описания к 8_2_8_195
еще раз.
ВерсияДанных используется для оптимистической блокировки и никаких других функций на нее не возлагается.
(18) не согласен. ВерсияДанных используется для определения изменен объект в базе данных или нет. А где эта проверка используется дело десятое.
(19) Т.е. хранишь версию с момента последней синхронизации - версия изменилась - объект нужно выгружать и обновить версию
(19) с чего бы?
если мне надо малой кровью например из одной базы в другую односторонне перегонять только измененные платежки например не, невзлетит?
(22) нет. это поле заполняется движком субд. у одного и того же объекта, в разных базах, будут всегда разные версии.
создал документ в базе, у него версия например 0x0000000000000CA6. перегнал его в другую базу, там у него версия 0x0000000000000C7B стала. в источнике документ перезаписали, версия стала 0x0000000000000CB1. как тут синхронизировать.
версия используется что бы проверять менялся ли объект в субд по отношению к этому же объекту в оперативной памяти.
я во второй базе сделаю поле "версия_первой_базы" и буду с этим полем сравнивать версию документа.
при изменении обновлять документ и номер версии
(29) хотя реально мало знать факт перезаписи, хорошо бы точно определять, были ли значимые изменения или просто "записать" нажали, фактически ничего не изменив :)
у меня есть адская самописка на УТ.
у меня есть 10 отдельных баз БП из которых эта самая УТ дергает разнесенные платежки.
БП все на поддержке.
УТ11 переписана наглухо (к примеру: в ней есть регистры бухгалтерии и план счетов с типовыми бухгалтерскими отчетами по плану счетов который не бухгалтерский)
как думаешь - для 15 баз планы обмена рисовать и поддерживать много легче чем написать обработку которая будет тупо реквизит сверять и если он различается перезаписывать объект.
(31) а если базу перепровели - все документы перезаписались, а фактически нет изменений :)
Буквально неделю назад была такая задача от клиента: "хочу видеть список-отчет об измененных документах в прошлых периодах, но если комментарий у документа поменяли или просто перепровели, то его не включать в отчет" :)
(35) на эту "жертву" можно пойти.
темболее что например в моем случае ограничение по периоду синхронизации задано.
то есть перепроведи всю базу - все равно ВСЕ платежки не лезут.
кстати чо там с планами обмена.. если я перепроведу всю базу, в РБД все объеты перейдут заново?
(36) тоже заново. Поэтому пришлось свой "слепок данных" делать и с ним сверять, ХЗ может лисапед получился :)
(37) А что какая то принципиальная разница между планом и на версии? Никакой. Или в палын попадают только "измененые"? Или групповое перепроведение не влияет на план обменов?
Данная статья является анонсом новой функциональности.
Не рекомендуется использовать содержание данной статьи для освоения новой функциональности.
Полное описание новой функциональности будет приведено в документации к соответствующей версии.
Полный список изменений в новой версии приводится в файле v8Update.htm.
Реализовано в версии 8.3.20.1549
Когда мы пишем запросы и создаем отчёты, нередко бывает нужно не просто показать данные в том виде, в котором они лежат в БД, а произвести над ними какие-то операции. Например, посчитать разницу между двумя датами или округлить число до нужной разрядности. Хорошо, если нужная функция есть в языке запросов (или в языке СКД) - тогда мы можем сделать с данными то, что хотим, на уровне запроса / СКД, а потом просто отобразить результат. Если же нужная функция в языке запросов не реализована – приходится делать постобработку запроса в языке 1С, проходясь в цикле по результатам запроса и выполняя нужные операции. Что приводит к разрастанию кода конфигурации и может снизить производительность.
К нам довольно часто обращаются разработчики с пожеланиями о добавлении дополнительных функций в язык запросов и язык СКД. Мы внимательно проанализировали пожелания и выделили список наиболее востребованных функций, которые планируем реализовать в версии 8.3.20.
Язык запросов
В язык запросов добавляются функции:
Строка(String) – преобразует значение в примитивного типа в строку с учетом национальных установок.
Тригонометрические функции Sin, Cos, Tan, ASin, ACos, ATan (все вычисления производятся в радианах)
Exp - вычисляет результат возведения основания натурального логарифма (числа e) в степень
Log - вычисляет натуральный логарифм числа.
Log10 - вычисляет десятичный логарифм числа.
Pow - вычисляет возведение в степень.
Sqrt – вычисляет квадратный корень.
Окр(Round) - округляет исходное число до нужной разрядности
Цел(Int) - вычисляет целую часть переданного числа, полностью отсекая дробную часть.
ДлинаСтроки(StringLength) – вычисляет длину строки.
СокрЛ(TrimL) – отбрасывает незначащие пробелы слева.
СокрП(TrimR) – отбрасывает незначащие пробелы справа.
СокрЛП(TrimAll) – отбрасывает незначащие пробелы слева и справа.
Лев(Left) – получает первые слева символы строки.
Прав(Right) – получает первые справа символы строки.
СтрНайти(StrFind) – находит первую позицию подстроки в строке (без учета регистра).
ВРег(Upper) – преобразует все символы строки в верхний регистр.
НРег(Lower) – преобразует все символы строки в нижний регистр.
СтрЗаменить(StrReplace) – заменяет все вхождения подстроки на другую подстроку (без учета регистра).
РазмерХранимыхДанных(StoredDataSize) – возвращает размер данных в байтах, которые занимают данные параметра.
Система компоновки данных
В язык выражений системы компоновки данных добавлены новые функции:
СокрЛ(TrimL) – отбросить незначащие пробелы слева.
СокрП(TrimR) – отбросить незначащие пробелы справа.
СокрЛП(TrimAll) – отбросить незначащие пробелы слева и справа.
Лев(Left) – получить первые слева символы строки.
Прав(Right) – получить первые справа символы строки.
СтрНайти(StrFind) – найти подстроку в строке (без учета регистра).
ВРег(Upper) – преобразует все символы строки в верхний регистр.
НРег(Lower) – преобразует все символы строки в нижний регистр.
СтрЗаменить(StrReplace) – заменяет все вхождения подстроки на другую подстроку (без учета регистра).
НСтр(NStr) – получает строку на языке пользователя (аналогично тому, как работает метод НСтр глобального контекста). Параметры:
ИсходнаяСтрока – строка, содержащая строки на разных языках (например, "ru = 'Добрый вечер!'; en = 'Good Evening!'").
КодЯзыка (необязательный) – строка с кодом языка, на котором нужно получать строку. Если не указан - строка получается на языке текущего пользователя.
В технологической платформе 8.3.11 был введен специальный механизм — «История данных». Этот механизм видится достаточно полезным, так как предоставляет ту функциональность, которую не редко приходится реализовывать вручную. В этой статье я попробую рассказать о том, что это за механизм, для чего он нужен и как с ним работать.
Общая информация
Начнем с общей теоретической информации о том, что такое история данных и как она устроена.
Описание и возможности
История данных — это механизм позволяющий хранить в базе данных упорядоченные по времени версии объектов конфигурации. Под версией понимаются данные, которые были в объекте на момент редактирования и состояние метаданных на момент редактирования. Хранить историю можно как для всего объекта целиком, так и для отдельных реквизитов — имеется возможность тонкой настройки работы механизма для каждого реквизита, в том числе табличные части.
Включать и выключать историю можно как из конфигуратора, так и средствами встроенного языка, все это дает возможность управлять историей для каждого пользователя отдельно.
Само по себе хранение истории достаточно бесполезная функция, поэтому с историей данных можно выполнять следующие операции:
- записывать версию данных;
- получать данные определенной версии;
- удалять данные определенной версии;
- получать разницу между двумя версиями одного объекта;
- прочие полезные возможности.
На момент написания статьи (8.3.13) история данных поддерживается для следующих объектов:
- общие реквизиты;
- константы;
- справочники;
- документы;
- бизнес-процессы;
- задачи;
- регистры сведений;
- планы обмена;
- планы счетов;
- планы видов характеристик;
- планы видов расчетов;
- расширения конфигурации.
Работа с историей данных регулируется правами доступа и отражается в журнале регистрации.
Устройство механизма
История данных хранится в специальных таблицах информационной базы. Кроме самих данных в этих таблицах хранятся метаданные прежних версий объектов. Версии метаданных создаются в момент изменения этих самых метаданных у объекта и никак не связаны с изменением данных объекта.
Также следует помнить, что на данный момент система не отличает включение версионирования для реквизита от создания реквизита и отключение версионирования реквизита от удаления реквизита.
Создание версии объекта состоит из двух этапов. Сначала, автоматически или с помощью специального метода, фиксируется факт изменения объекта и информация об этом изменении попадает в очередь. Перенос данных из очереди в таблицы базы выполняется методом ОбновитьИсторию(), этот метод можно выполнять асинхронно, например регламентным заданием. Идущие подряд изменения одного объекта не «склеиваются» и фиксируются отдельно, вне зависимости от периодичности обновления истории данных.
Настройка версирования объектов осуществляется либо из конфигуратора либо при помощи встроенного языка. Конфигуратор логично использовать в тех случаях, когда история данных потребуется во всех режимах работы приложения или на нее завязана какая-то прикладная логика. Использование встроенного языка потребуется для реализации более гибкой системы, например когда пользователя потребуется самому выбирать для каких объектов хранить историю данных.
Для управления историей данных объектов в конфигураторе реализовано свойство «История данных», оно присутствует как у основных объектов (у справочников, например) так и у подчиненных — реквизиты, табличные части с их реквизитами, ресурсы регистров сведений.
Свойство «История данных»
По умолчанию свойство «История данных» установлено в значение «Использовать» у:
- стандартных реквизитов;
- реквизитов объектов;
- реквизитов табличных частей;
- измерений регистров сведений (без возможности отключения);
- ресурсов регистров сведений.
Использование механизма
Для обращения к истории данных используется свойство глобального контекста ИсторияДанных, методы этого этого свойства будут рассмотрены ниже.
Управление использованием истории данных
Ниже приведены примеры того, как, средствами встроенного языка, можно управлять использованием истории данных. Отмечу, что значения свойства ИсторияДанных (полученные «через точку») берутся из конфигуратора и могут не соответствовать действительности, для получения актуальной информации нужно пользоваться методом ПолучитьНастройки().
Читайте также: