ДиалогОтбораВерсийИсторииДанных

Типы · DataHistoryVersionsFilterDialog

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

Примеры платформы

Окно = Новый ДиалогОтбораВерсийИсторииДанных(Параметры.Данные);
Окно.Отбор = Отбор;
Окно.Показать(Новый ОписаниеОповещения("ВыполнитьПослеЗакрытияОтбора",
                                        ЭтотОбъект));
Полное описание, параметры и ограничения

ДиалогОтбораВерсийИсторииДанных (DataHistoryVersionsFilterDialog)

ДиалогОтбораВерсийИсторииДанных (DataHistoryVersionsFilterDialog)

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

Свойства:
Данные (Data)
Отбор (Filter)

Методы:
ОткрытьАсинх (DoAsync)
Показать (Show)

Конструкторы:
По умолчанию

Описание:

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

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

Тонкий клиент, веб-клиент, толстый клиент.

Пример:

Окно = Новый ДиалогОтбораВерсийИсторииДанных(Параметры.Данные);
Окно.Отбор = Отбор;
Окно.Показать(Новый ОписаниеОповещения("ВыполнитьПослеЗакрытияОтбора",
ЭтотОбъект));

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

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

Описание изменено в версии 8.3.22.

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

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

Выбрать условия отбора версий: полный асинхронный и callback-вариант

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

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

Полный модуль собственной обычной формы толстого клиента файловой ИБ; полный общий модуль создает реальные2версии и ограничивает чтение своимUUID. 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 отклоняет даже частично созданный собственный объект.

  10. В отдельной своей обычной форме оставьте UUIDОпыта и ПодтвержденСвойОпыт; свяжите кнопку СоздатьДве с СоздатьДве(Кнопка), еще две кнопки с обработчиками ОтобратьАсинх и ОтобратьСОповещением. Весь код формы вставляйте целиком на уровень модуля, включая Перем и экспортный callback.

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

  12. Сначала только один раз СоздатьДве. После создания не повторяйте кнопку; используйте оба способа диалога поочередно. Во время открытого окна не меняйтеUUIDОпыта и не изменяйте данные в другом сеансе.

Перем Занят85;
Перем Диалог85;
Перем Паспорт85;

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

Асинх Процедура ОтобратьАсинх(Кнопка)
    Если Занят85 = Истина Тогда
        Возврат;
    КонецЕсли;
    Занят85 = Истина;
    Попытка
        ПодготовитьСвойДиалог85();
        Результат = Ждать Диалог85.ОткрытьАсинх();
        ОбработатьСвойОтбор85(Результат, Паспорт85);
    Исключение
        Сообщить("Собственный отбор не подтвержден; данные и история не менялись");
    КонецПопытки;
    ОсвободитьСвойДиалог85();
КонецПроцедуры

Процедура ОтобратьСОповещением(Кнопка)
    Если Занят85 = Истина Тогда
        Возврат;
    КонецЕсли;
    Занят85 = Истина;
    Попытка
        ПодготовитьСвойДиалог85();
        Оповещение = Новый ОписаниеОповещения("ПослеСвоегоОтбора85", ЭтаФорма, Паспорт85);
        Диалог85.Показать(Оповещение);
    Исключение
        ОсвободитьСвойДиалог85();
        Сообщить("Диалог не открыт; неизвестный результат не применяется");
    КонецПопытки;
КонецПроцедуры

Процедура ПослеСвоегоОтбора85(Результат, ДополнительныеПараметры) Экспорт
    Попытка
        ОбработатьСвойОтбор85(Результат, ДополнительныеПараметры);
    Исключение
        Сообщить("Own-результат не принят; никакие версии не менялись");
    КонецПопытки;
    ОсвободитьСвойДиалог85();
КонецПроцедуры

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

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

Процедура ОсвободитьСвойДиалог85()
    Диалог85 = Неопределено;
    Паспорт85 = Неопределено;
    Занят85 = Ложь;
КонецПроцедуры
Полный общий модуль УчебнаяИстория85: own-версии и паспорт диалогов

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

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

Функция Выполнить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 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

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

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

Только свой справочник/своя файловая ИБ, native ограничение информации: толстый клиент.

Только свой справочник/своя файловая ИБ, native ограничение информации: толстый клиент.

Процедура ОбработкаПослеЗаписиВерсийИсторииДанных(ИнформацияОЗаписиВерсий)
    Попытка
        Количество = ИнформацияОЗаписиВерсий.Количество();
        Если Количество = 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 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

  1. СоздатьДве получает настоящую ссылку из фабрики/записи; паспорт диалога повторно проверяет единственный UUID-объект и хотябы2версии.

  2. Одновременное повторное открытие блокируется Занят85. Ссылка на диалог и паспорт хранятся до callback/Ждать, освобождаются после завершения, ошибки или отмены.

  3. Отбор — Структура, где обязательны собственные Данные. Диалог создается по реальной ссылке после создания двух версий, а не по неизвестному параметру формы.

  4. ОткрытьАсинх возвращает Обещание, его результат получается через Ждать. OK дает Структуру, отмена — Неопределено. Показать использует ОписаниеОповещения с двумя параметрами callback: Результат и ДополнительныеПараметры.

  5. Свойство Отбор перед открытием задает условия, после OK отражает выбранные. Данные подтверждают границу своего объекта. Результат пользовательского отбора дополнительно привязывается к собственным метаданным и ссылке перед ВыбратьВерсии.

  6. ПосчитатьСвоиОтобранныеВерсии85 проверяет собственный контекст и устанавливает точные Данные/Метаданные своего справочника. ВыбратьВерсии ограничен4строками, каждая проверяется по ссылке; возвращается только количество, никаких чужих значений.

  7. Эти две кнопки читают/отбирают историю, не записывают комментарии, не удаляют версии и не восстанавливают объект. Число0 после ограничивающего фильтра — допустимый реальный результат.

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

  1. OK: ожидаемая Структура/Массив обрабатывается; число собственных отобранных версий0..3, ссылка остается своей.

  2. Отмена: Результат=Неопределено, вывод об отмене, подсчет не вызывается, Занят85 сноваЛожь.

  3. Другой UUID, тип результата или иной автор отклоняются; после ошибки повторное открытие не заблокировано.

  4. Ни один диалог при авторстве не открывался, никакие реальные данные/пользователи/история не менялись.

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

Освоены два корректных способа асинхронного выбора по реально подготовленной собственной истории с разными результатамиOK/Отмена и защищенной границей данных.

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

  1. Обещание не готовый результат: не проверяйте типОбещание как будто этоСтруктура/Массив.

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

  3. Native допускает тонкий/веб-клиент для диалогов, но полный собственный workflow подготовлен для толстого обычного клиента из-за контекста основного модуля и информации события. Другой контекст здесь не проверялся.

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

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

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

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

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