КоллекцияИнформацииОЗаписиВерсииИсторииДанных

Типы · WriteDataHistoryVersionInformationCollection

Представляет коллекцию версий истории данных.

Полное описание, параметры и ограничения

КоллекцияИнформацииОЗаписиВерсииИсторииДанных (WriteDataHistoryVersionInformationCollection)

КоллекцияИнформацииОЗаписиВерсииИсторииДанных (WriteDataHistoryVersionInformationCollection)

Доступен, начиная с версии 8.3.15.

Элементы коллекции:
ИнформацияОЗаписиВерсииИсторииДанных
Для объекта доступен обход коллекции посредством оператора Для каждого … Из … Цикл. При обходе выбираются элементы.
Возможно обращение к элементам посредством оператора [...]. В качестве аргумента передается индекс элемента коллекции (нумерация с 0).

Методы:
Индекс (IndexOf)
Количество (Count)
Получить (Get)

Описание:

Представляет коллекцию версий истории данных.

Доступность:

Сервер, толстый клиент, внешнее соединение.

Использование в версии:

Доступен, начиная с версии 8.3.15.

Методическая информация

Практические примеры

Прочитать реальную платформенную коллекцию после записи только своего объекта

Платформа сама передает КоллекцияИнформацииОЗаписиВерсииИсторииДанных: Count/Get/Index,12readonly-полей настоящих версий, защитное чтение данных/различий и адресная работа очереди без повторной записи объекта.

Где и как запускать

Полный модуль менеджера собственного справочника УчебныеТовары, отдельная файловая ИБ/толстый обычный клиент. Настоящее платформенное событие, runtime0; данные не записываются обработчиком.

Подготовка

  1. Только НОВАЯ отдельная файловая учебная ИБ8.5.1.1343, конфигурация УчебнаяИсторияВерсий85, совместимостьНеИспользовать, основной режим запуска ОбычноеПриложение. Запускайте толстый клиент обычного приложения, не серверную рабочую ИБ. Native8.5 ограничивает ИнформацияОЗаписиВерсииИсторииДанных и ее свойства толстым клиентом; обработчик на кластерном сервере этим уроком не обещается.

  2. Единственный справочник УчебныеТовары: неиерархический, без владельцев и табличных частей, НаименованиеСтрока50, КодСтрока9; реквизиты МаркерUUID(Строка36) и Количество(Число9,0,неотрицательное). Других справочников, документов, регистров, разделителей, планов обмена, подписок, фоновых заданий и расширений нет. Изначально0элементов.

  3. В Конфигураторе для справочника и полей МаркерUUID, Количество, Наименование включите использование истории данных. Общий модуль УчебнаяИстория85: Клиент(обычное приложение)=Истина, Сервер=Ложь, Глобальный=Ложь, Привилегированный=Ложь. Полностью вставьте основной модуль, не внутрь другой процедуры.

  4. Заранее создайте своего настоящего учебного пользователя с административными правами для этого пустого стенда и именем/полным именем без секретов. Войдите им; импорт берет его фактический UUID и имена через ПользователиИнформационнойБазы, а не вымышляет автора.

  5. Создайте собственную обработку с обычной формой. Строковые реквизиты Операция и UUIDОпыта, булевый ПодтвержденСвойОпыт; кнопку Выполнить свяжите с обработчиком Выполнить(Кнопка). Вставьте полный дополнительный модуль формы. UUIDОпыта один раз получите выражением Строка(Новый УникальныйИдентификатор), сохраните в своем журнале опыта.

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

  7. Никакие изменения схемы/F7/объекты/настройки/версии/диалоги здесь не создавались и не запускались. Это полный авторский план самостоятельного будущего запуска только в своем стенде; runtimeVerifiedScenarios=0.

  8. Порядок отдельных операций: СоздатьДвеВерсии85, Прочитать85, Комментарий85. Для очереди по выбору СнятьПервуюИзОчереди85, затем ОбработатьОчередь85. Для миграционного снимка ИмпортироватьСнимок85, затем только явно УдалитьТолькоИмпорт85. Нельзя удалять все версии/метаданные или пропускать данные в API удаления.

  9. Только один оператор/сеанс изменяет опыт. После исключения нет автоматического повторения/отката/очистки: сначала прочитайте реальные оставшиеся записи. Повторное СоздатьДвеВерсии85 отклоняет даже частично созданный собственный объект.

Процедура ОбработкаПослеЗаписиВерсийИсторииДанных(ИнформацияОЗаписиВерсий)
    Попытка
        Количество = ИнформацияОЗаписиВерсий.Количество();
        Если Количество = 0 Тогда
            Сообщить("Own-пакет истории пуст; ничего не записывается");
            Возврат;
        КонецЕсли;
        Для Индекс = 0 По Количество - 1 Цикл
            Информация = ИнформацияОЗаписиВерсий.Получить(Индекс);
            Если ИнформацияОЗаписиВерсий.Индекс(Информация) <> Индекс Тогда
                Сообщить("Own-индекс пакета не подтвержден");
                Возврат;
            КонецЕсли;
            Если ТипЗнч(Информация.Данные) <> Тип("СправочникСсылка.УчебныеТовары") Тогда
                Продолжить;
            КонецЕсли;
            Объект = Информация.Данные.ПолучитьОбъект();
            UUIDОпыта = Объект.МаркерUUID;
            ПроверитьСвойПакет85(UUIDОпыта, Информация.Данные);
            ДанныеВерсии = Информация.ДанныеВерсии;
            Различия = Информация.РазличияВерсий;
            Если ДанныеВерсии = Неопределено Тогда
                Сообщить("Own-пакет содержит удаление: данные версии отсутствуют; поле количества не читается");
                Продолжить;
            КонецЕсли;
            Если Не ДанныеВерсии.Свойство("МаркерUUID") Или ДанныеВерсии.МаркерUUID <> UUIDОпыта Тогда
                Сообщить("Чужой исторический маркер: содержимое не выводится");
                Продолжить;
            КонецЕсли;
            Сообщить(СтрШаблон("Own-пакет: индекс=%1/%2; версия=%3; дата=%4; вид=%5; количество=%6",
                Индекс, Количество, Информация.НомерВерсии, Информация.Дата, Информация.ВидИзмененияДанных, ДанныеВерсии.Количество));
            Сообщить(СтрШаблон("Автор: UUID=%1; имя=%2; полное=%3; комментарий=%4; транзакция задана=%5; узел задан=%6; различия заданы=%7",
                Информация.Пользователь, Информация.ИмяПользователя, Информация.ПолноеИмяПользователя, Информация.Комментарий,
                Не ПустаяСтрока(Информация.Транзакция), ЗначениеЗаполнено(Информация.Узел), Различия <> Неопределено));
        КонецЦикла;
    Исключение
        Сообщить("Собственный пакет не подтвержден; исключение перехвачено, запись объекта или повторная постановка не выполнялись");
    КонецПопытки;
КонецПроцедуры

Процедура ПроверитьСвойПакет85(UUIDОпыта, Ссылка)
    ПроверитьСвойПустойСтенд();
    Если ТипЗнч(UUIDОпыта) <> Тип("Строка") Тогда
        ВызватьИсключение "Маркер собственного объекта должен быть строкой";
    КонецЕсли;
    UUID = Новый УникальныйИдентификатор(UUIDОпыта);
    Если UUIDОпыта <> Строка(UUID) Или UUIDОпыта = "00000000-0000-0000-0000-000000000000" Тогда
        ВызватьИсключение "В собственном пакете нужен канонический ненулевой UUID";
    КонецЕсли;
    Выборка = Справочники.УчебныеТовары.Выбрать();
    Найден = Ложь;
    Пока Выборка.Следующий() Цикл
        Если Найден Или Выборка.Ссылка <> Ссылка Или Выборка.МаркерUUID <> UUIDОпыта Или Выборка.ПометкаУдаления Тогда
            ВызватьИсключение "Пакет не относится к собственному единственному элементу";
        КонецЕсли;
        Найден = Истина;
    КонецЦикла;
    Если Не Найден Тогда
        ВызватьИсключение "Собственный исторический объект отсутствует";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 1 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.Справочники[0].Имя <> "УчебныеТовары"
        Или Метаданные.Справочники.УчебныеТовары.Реквизиты.Количество() <> 2
        Или Метаданные.Справочники.УчебныеТовары.ТабличныеЧасти.Количество() <> 0
        Или Метаданные.Справочники.УчебныеТовары.Реквизиты.Найти("МаркерUUID") = Неопределено
        Или Метаданные.Справочники.УчебныеТовары.Реквизиты.Найти("Количество") = Неопределено Тогда
        ВызватьИсключение "Нужен только свой единственный учебный справочник с двумя точными реквизитами";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры
Полный клиентский общий модуль: реальные версии и адресное управление очередью

Клиент(обычное приложение), серверЛожь; полный основной модуль из подготовки.

Клиент(обычное приложение), серверЛожь; полный основной модуль из подготовки.

Функция Выполнить85(Операция, UUIDОпыта, Подтверждение) Экспорт
    ПроверитьОпыт85(UUIDОпыта, Подтверждение);
    Если СтрРазделить("СоздатьДвеВерсии85,Прочитать85,Комментарий85,ИмпортироватьСнимок85,СнятьПервуюИзОчереди85,ОбработатьОчередь85,УдалитьТолькоИмпорт85", ",").Найти(Операция) = Неопределено Тогда
        ВызватьИсключение "Неизвестная отдельная учебная операция истории";
    КонецЕсли;
    Ссылка = НайтиСвойЕдинственныйОбъект85(UUIDОпыта, Истина);
    Если Операция = "СоздатьДвеВерсии85" Тогда
        Если Ссылка <> Неопределено Тогда
            ВызватьИсключение "Нельзя перезаписывать уже начатый собственный опыт";
        КонецЕсли;
        Настройки = Новый НастройкиИсторииДанных;
        Настройки.Использование = Истина;
        Поля = Новый Соответствие;
        Поля.Вставить("МаркерUUID", Истина);
        Поля.Вставить("Количество", Истина);
        Поля.Вставить("Наименование", Истина);
        Настройки.ИспользованиеПолей = Поля;
        ИсторияДанных.УстановитьНастройки(Метаданные.Справочники.УчебныеТовары, Настройки);
        ПрочитанныеНастройки = ИсторияДанных.ПолучитьНастройки(Метаданные.Справочники.УчебныеТовары);
        Если ПрочитанныеНастройки = Неопределено Или Не ПрочитанныеНастройки.Использование
            Или ПрочитанныеНастройки.ИспользованиеПолей.Получить("МаркерUUID") <> Истина
            Или ПрочитанныеНастройки.ИспользованиеПолей.Получить("Количество") <> Истина
            Или ПрочитанныеНастройки.ИспользованиеПолей.Получить("Наименование") <> Истина Тогда
            ВызватьИсключение "Применение own-профиля не подтверждено; остановитесь без записи данных";
        КонецЕсли;
        Свой = Справочники.УчебныеТовары.СоздатьЭлемент();
        Свой.МаркерUUID = UUIDОпыта;
        Свой.Наименование = "Уч85 " + UUIDОпыта;
        Свой.Количество = 1;
        Свой.ЗаписьИсторииДанных.КомментарийВерсии = "own-history85-first:" + UUIDОпыта;
        Свой.ЗаписьИсторииДанных.ВыполнятьОбработкуПослеЗаписиВерсии = Истина;
        Свой.ЗаписьИсторииДанных.ОбновлятьИсториюСразуПослеЗаписи = Ложь;
        Свой.Записать();
        Ссылка = Свой.Ссылка;
        Если ТранзакцияАктивна() Тогда
            ВызватьИсключение "Обновление истории не вызывается внутри транзакции";
        КонецЕсли;
        ИсторияДанных.ОбновитьИсторию(Ссылка, Ложь, Ложь);
        ПроверитьКоличествоВерсий85(ПолучитьСвоиВерсии85(Ссылка, UUIDОпыта), 1);
        Свой = Ссылка.ПолучитьОбъект();
        Свой.Количество = 3;
        Свой.ЗаписьИсторииДанных.КомментарийВерсии = "own-history85-second:" + UUIDОпыта;
        Свой.ЗаписьИсторииДанных.ВыполнятьОбработкуПослеЗаписиВерсии = Истина;
        Свой.ЗаписьИсторииДанных.ОбновлятьИсториюСразуПослеЗаписи = Ложь;
        Свой.Записать();
        ИсторияДанных.ОбновитьИсторию(Ссылка, Ложь, Ложь);
        Версии = ПолучитьСвоиВерсии85(Ссылка, UUIDОпыта);
        ПроверитьКоличествоВерсий85(Версии, 2);
        Возврат СтрШаблон("Own-объектUUID=%1; фактические номера=%2,%3; количество1→3; очередь пока не обрабатывалась",
            Строка(Ссылка.УникальныйИдентификатор()), Версии[0].НомерВерсии, Версии[1].НомерВерсии);
    КонецЕсли;
    Если Ссылка = Неопределено Тогда
        ВызватьИсключение "Сначала создайте обе реальные own-версии";
    КонецЕсли;
    Версии = ПолучитьСвоиВерсии85(Ссылка, UUIDОпыта);
    Если Версии.Количество() < 2 Тогда
        ВызватьИсключение "Обе исходные собственные версии должны существовать";
    КонецЕсли;
    Первая = Версии[0].НомерВерсии;
    Вторая = Версии[1].НомерВерсии;
    Если Операция = "Прочитать85" Тогда
        Снимок1 = ИсторияДанных.ПолучитьДанныеВерсии(Ссылка, Первая);
        Снимок2 = ИсторияДанных.ПолучитьДанныеВерсии(Ссылка, Вторая);
        Если Снимок1.Количество <> 1 Или Снимок2.Количество <> 3 Тогда
            ВызватьИсключение "Исторический собственный переход1→3 не подтвержден";
        КонецЕсли;
        МетаданныеВерсии = ИсторияДанных.ПолучитьМетаданные(Ссылка, Вторая);
        Если ТипЗнч(МетаданныеВерсии) <> Тип("Структура") Или Не МетаданныеВерсии.Свойство("Поля")
            Или Не МетаданныеВерсии.Поля.Свойство("Количество") Тогда
            ВызватьИсключение "Фактические метаданные версии не содержат ожидаемое own-поле";
        КонецЕсли;
        Различия = ИсторияДанных.ПолучитьРазличияВерсий(Ссылка, Вторая, Первая);
        Если Различия = Неопределено Или Не Различия.Свойство("Количество") Тогда
            ВызватьИсключение "Own-различия количества не найдены";
        КонецЕсли;
        Изменение = Различия.Количество;
        Если Изменение.ЗначениеДоИзменения <> 1 Или Изменение.ЗначениеПослеИзменения <> 3 Тогда
            ВызватьИсключение "Native before/after перепутаны или история изменилась";
        КонецЕсли;
        Черновик = ИсторияДанных.СформироватьПоВерсии(Ссылка, Первая);
        Если Черновик.МаркерUUID <> UUIDОпыта Или Черновик.Количество <> 1
            Или Ссылка.ПолучитьОбъект().Количество <> 3 Тогда
            ВызватьИсключение "Не подтвержден отдельный незаписанный own-черновик первой версии";
        КонецЕсли;
        Возврат "Снимки1→3 и различия подтверждены. Черновик содержит1, текущий объект3: восстановление в базу не выполнялось";
    ИначеЕсли Операция = "Комментарий85" Тогда
        ИсторияДанных.ЗаписатьКомментарий(Ссылка, Вторая, "own-history85-checked:" + UUIDОпыта);
        После = ПолучитьСвоиВерсии85(Ссылка, UUIDОпыта);
        Если После[1].НомерВерсии <> Вторая Или После[1].Комментарий <> "own-history85-checked:" + UUIDОпыта Тогда
            ВызватьИсключение "Комментарий собственной фактической версии не подтвержден";
        КонецЕсли;
        Возврат "Изменен только комментарий своей второй версии; данные и номер не менялись";
    ИначеЕсли Операция = "ИмпортироватьСнимок85" Тогда
        ПроверитьКоличествоВерсий85(Версии, 2);
        Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
        Если Пользователь = Неопределено Тогда
            ВызватьИсключение "Заранее войдите своим реальным учебным пользователем";
        КонецЕсли;
        ЧерновикИмпорта = Ссылка.ПолучитьОбъект();
        ЧерновикИмпорта.Количество = 7;
        ИсторияДанных.ЗаписатьВерсию(ЧерновикИмпорта, ТекущаяДата(), Пользователь.УникальныйИдентификатор,
            Пользователь.Имя, Пользователь.ПолноеИмя, ВидИзмененияДанных.Изменение,
            "own-history85-import:" + UUIDОпыта, "", Неопределено);
        После = ПолучитьСвоиВерсии85(Ссылка, UUIDОпыта);
        ПроверитьКоличествоВерсий85(После, 3);
        Если После[2].Комментарий <> "own-history85-import:" + UUIDОпыта
            Или ИсторияДанных.ПолучитьДанныеВерсии(Ссылка, После[2].НомерВерсии).Количество <> 7
            Или Ссылка.ПолучитьОбъект().Количество <> 3 Тогда
            ВызватьИсключение "Не подтвержден импорт только снимка, без записи текущего объекта";
        КонецЕсли;
        Возврат "Создан собственный исторический импорт количества7; текущий объект остался3. НомерИмпорта=" + Строка(После[2].НомерВерсии);
    ИначеЕсли Операция = "СнятьПервуюИзОчереди85" Тогда
        ИсторияДанных.УдалитьИзОбработкиПослеЗаписиВерсий(Ссылка, Первая);
        После = ПолучитьСвоиВерсии85(Ссылка, UUIDОпыта);
        Если После[0].НомерВерсии <> Первая Тогда
            ВызватьИсключение "Снятие из обработки не должно удалять собственную историческую версию";
        КонецЕсли;
        Возврат "Из обработки снята только первая own-версия; сама версия истории сохранена. Записей очереди API не перечисляет";
    ИначеЕсли Операция = "ОбработатьОчередь85" Тогда
        ИсторияДанных.ВыполнитьОбработкуПослеЗаписиВерсий(Ссылка);
        Возврат "Обработка запрошена только по своему объекту. Проверьте вывод собственного обработчика; отсутствие вывода не доказывает существование очереди";
    КонецЕсли;
    ПроверитьКоличествоВерсий85(Версии, 3);
    Импорт = Версии[2];
    Если Импорт.Комментарий <> "own-history85-import:" + UUIDОпыта
        Или ИсторияДанных.ПолучитьДанныеВерсии(Ссылка, Импорт.НомерВерсии).Количество <> 7 Тогда
        ВызватьИсключение "Удалять разрешено только свою подтвержденную импортную версию";
    КонецЕсли;
    ИсторияДанных.УдалитьВерсии(Ссылка, Импорт.НомерВерсии, Импорт.НомерВерсии);
    После = ПолучитьСвоиВерсии85(Ссылка, UUIDОпыта);
    ПроверитьКоличествоВерсий85(После, 2);
    Если После[0].НомерВерсии <> Первая Или После[1].НомерВерсии <> Вторая
        Или Ссылка.ПолучитьОбъект().Количество <> 3 Тогда
        ВызватьИсключение "Удаление только собственного импортного снимка не подтверждено";
    КонецЕсли;
    Возврат "Удалена только одна own-импортная версия по точному замкнутому интервалу; обе исходные и текущий объект3 сохранены";
КонецФункции

Процедура ПроверитьОпыт85(UUIDОпыта, Подтверждение)
    ПроверитьСвойПустойСтенд();
    Если ТипЗнч(Подтверждение) <> Тип("Булево") Или Не Подтверждение Тогда
        ВызватьИсключение "Добровольно подтвердите только собственную новую файловую учебную ИБ";
    КонецЕсли;
    Если ТипЗнч(UUIDОпыта) <> Тип("Строка") Тогда
        ВызватьИсключение "UUIDОпыта должен быть строкой";
    КонецЕсли;
    UUID = Новый УникальныйИдентификатор(UUIDОпыта);
    Если UUIDОпыта <> Строка(UUID) Или UUIDОпыта = "00000000-0000-0000-0000-000000000000" Тогда
        ВызватьИсключение "Нужен канонический собственный ненулевой UUID опыта";
    КонецЕсли;
КонецПроцедуры

Функция НайтиСвойЕдинственныйОбъект85(UUIDОпыта, РазрешеноОтсутствие = Ложь)
    Выборка = Справочники.УчебныеТовары.Выбрать();
    Свой = Неопределено;
    Пока Выборка.Следующий() Цикл
        Если Свой <> Неопределено Или Выборка.МаркерUUID <> UUIDОпыта Или Выборка.ПометкаУдаления Тогда
            ВызватьИсключение "Разрешен только один собственный UUID-элемент, без чужих данных";
        КонецЕсли;
        Свой = Выборка.Ссылка;
    КонецЦикла;
    Если Свой = Неопределено И Не РазрешеноОтсутствие Тогда
        ВызватьИсключение "Сначала создайте реальный собственный элемент командой СоздатьДвеВерсии85";
    КонецЕсли;
    Возврат Свой;
КонецФункции

Функция ПолучитьСвоиВерсии85(Ссылка, UUIDОпыта)
    Если НайтиСвойЕдинственныйОбъект85(UUIDОпыта) <> Ссылка Тогда
        ВызватьИсключение "Подменена ссылка на собственный единственный элемент";
    КонецЕсли;
    Отбор = Новый Структура("Данные", Ссылка);
    Версии = ИсторияДанных.ВыбратьВерсии(Отбор,
        "Данные,НомерВерсии,Дата,Пользователь,ИмяПользователя,ПолноеИмяПользователя,ВидИзмененияДанных,Комментарий,Транзакция,Узел",
        "НомерВерсии Возр", 4);
    Если ТипЗнч(Версии) <> Тип("ТаблицаЗначений") Или Версии.Количество() > 3 Тогда
        ВызватьИсключение "Свой новый опыт допускает не более трех подтвержденных версий";
    КонецЕсли;
    Для Каждого Версия Из Версии Цикл
        Если Версия.Данные <> Ссылка Или Версия.НомерВерсии <= 0 Тогда
            ВызватьИсключение "Получена чужая ссылка или недопустимый номер версии";
        КонецЕсли;
        Снимок = ИсторияДанных.ПолучитьДанныеВерсии(Ссылка, Версия.НомерВерсии);
        Если ТипЗнч(Снимок) <> Тип("Структура") Или Не Снимок.Свойство("МаркерUUID")
            Или Снимок.МаркерUUID <> UUIDОпыта Тогда
            ВызватьИсключение "Исторические данные не принадлежат нашему реальному UUID-объекту";
        КонецЕсли;
    КонецЦикла;
    Возврат Версии;
КонецФункции

Процедура ПроверитьКоличествоВерсий85(Версии, Ожидание)
    Если Версии.Количество() <> Ожидание Тогда
        ВызватьИсключение "Фактическое число own-версий отличается; повторять запись автоматически нельзя";
    КонецЕсли;
КонецПроцедуры

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 1 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.Справочники[0].Имя <> "УчебныеТовары"
        Или Метаданные.Справочники.УчебныеТовары.Реквизиты.Количество() <> 2
        Или Метаданные.Справочники.УчебныеТовары.ТабличныеЧасти.Количество() <> 0
        Или Метаданные.Справочники.УчебныеТовары.Реквизиты.Найти("МаркерUUID") = Неопределено
        Или Метаданные.Справочники.УчебныеТовары.Реквизиты.Найти("Количество") = Неопределено Тогда
        ВызватьИсключение "Нужен только свой единственный учебный справочник с двумя точными реквизитами";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры
Полный модуль обычной управляющей формы

КнопкаВыполнить, реквизитыОперация/UUIDОпыта/ПодтвержденСвойОпыт.

КнопкаВыполнить, реквизитыОперация/UUIDОпыта/ПодтвержденСвойОпыт.

Процедура Выполнить(Кнопка)
    Попытка
        Ответ = УчебнаяИстория85.Выполнить85(Операция, UUIDОпыта, ПодтвержденСвойОпыт);
    Исключение
        Сообщить("Own-операция не подтверждена. Не повторяйте запись автоматически; сначала прочитайте фактическое состояние собственного опыта");
        Возврат;
    КонецПопытки;
    Сообщить(Ответ);
КонецПроцедуры

Разбор по шагам

  1. Полный основной модуль создает2реальные версии с явноВыполнятьОбработкуПослеЗаписиВерсии=Истина. Событие менеджера не вызывается вручную и не принимает произвольный ИсходныйОбъект.

  2. ОбновитьИсторию(свояСсылка,Ложь,Ложь) создает версии без обработки. Затем ОбработатьОчередь85 вызывает ВыполнитьОбработкуПослеЗаписиВерсий только по своему объекту, не по всем метаданным/областям.

  3. Необязательная отдельная команда СнятьПервуюИзОчереди85 исключает только реальный номер первой своей версии из обработки, но не удаляет саму версию. Публичного перечислителя очереди здесь нет, поэтому наличие/число очереди не выдумывается.

  4. Платформенная коллекция передается оригинальным параметром события. Количество дает размер; Получить использует индекс с0; Индекс возвращает позицию именно того же объекта. Пакет может быть пустым/частичным и не более1000по native.

  5. Каждый элемент проверяется по типу ссылки, единственному реальному объекту и историческомуМаркерUUID. Только после этой границы читаются собственные данные/авторские сведения; чужие значения не печатаются.

  6. ДанныеВерсии/РазличияВерсий readonlyФиксированнаяСтруктура либоНеопределено; при удалении данных поля могут отсутствовать. СвойствоДанные дает настоящую ссылку; НомерВерсиинеИндексКоллекции.

  7. Дата/ВидИзмененияДанных/Комментарий/ПользовательUUID/Имя/ПолноеИмя показываются только для своего объекта. Транзакция выводится какпризнакнепустоты, Узел какпризнакналичия; случайные транзакции/узлы не создаются.

  8. Обработчик ничего не записывает, не вызывает обновление истории и не ставит версию снова. Исключение перехватывается: native предупреждает, что неперехваченное исключение прекращает обработку остальных версий очереди.

Как проверить результат

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

  2. После СнятьПервуюИзОчереди85 первая историческая версия остается; сама очередь не считается перечисленной. Последующий callback может содержать только оставшуюся часть.

  3. Readonly-поля Информация не присваиваются. В обработчике нет Записать/ОбновитьИсторию/ЗаписатьВерсию и рекурсивного накопления версий.

  4. При ДанныеВерсии=Неопределено количество не читается. После перехваченной ошибки нет автоматического повтора или массовой очистки.

Ожидаемый результат

Прочитан и разобран настоящий собственный пакет платформы без вымышленных коллекций/версий, измененияreadonly-полей или повторной записи данных.

На что обратить внимание

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

  2. Настройки могут кэшироваться; повторное чтение не следует выдавать за независимую runtime-гарантию применения в другом сеансе. Проверки здесь статические.

  3. ПолучитьДанныеВерсии не содержит независимые разделители; в собственной схеме разделителей нет. Нельзя переносить структуру в рабочую ИБ с разделением без отдельного проектирования.

  4. Импорт истории и запись текущего объекта различаются. ЗаписатьВерсию не вызывает запись текущих данных; вымышленный UUID автора или произвольная строка транзакции недопустимы.

  5. После частичной ошибки нельзя повторять создание/импорт автоматически; номер версии не является глобальным идентификатором между объектами.

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

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.