Региональные установки: понятные статусы оплаты и проверяемое восстановление

Учебные задачи

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

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

Тонкий управляемый клиент своей новой File ИБ 8.5.1.1343; все региональные и монопольные API выполняются в одном серверном вызове собственной формы.

Подготовка

  1. Создайте вручную в отдельной новой одноразовой Windows VM пустую файловую базу C:\1c-labs\OwnRegionalSettings85_587cd6c6-8790-46df-838a-a55058f8a1d\IB на платформе 8.5.1.1343. Не используйте рабочую базу или копию чужой конфигурации. Сейчас база не создавалась, 1С не запускалась.

  2. В свойствах новой конфигурации задайте Имя = УчебныйРегион85, Версия = 587cd6c6-8790-46df-838a-a55058f8a1d, ОсновнойРежимЗапуска = УправляемоеПриложение, РежимСовместимости = НеИспользовать; встроенный язык русский. Создайте только одну общую управляемую форму УчебныйРегион85 и одну роль УчебнаяПолная85. Не добавляйте справочники, документы, регистры, общие реквизиты, фоновые задания, подписки, расширения, HTTP/Web-сервисы или другие обработчики.

  3. В своей единственной роли вручную задайте полные права только для этой пустой лаборатории, включая Администрирование, АктивныеПользователи и установку монопольного режима. Через Администрирование → Пользователи создайте своего единственного пользователя УченикРегиона85 с этой ролью. Это консервативная учебная подготовка, а не доказанный минимальный набор прав для рабочего решения.

  4. Общие → Общие формы → УчебныйРегион85: реквизиты Согласие85 и Остановка85 типа Булево; Протокол85 типа Строка неограниченной длины. Согласие85 выведите флажком «Разрешаю изменить региональные установки своей новой базы». Остановка85 скройте от редактирования; Протокол85 выведите многострочным полем только просмотра. Не требуйте начальных значений редактора: на фактически новой форме Остановка85 = Ложь проверяется кодом, согласие задается пользователем. Сброса остановки программно нет.

  5. В свойствах своей формы вручную установите СохранениеДанныхВНастройках = НеИспользовать и АвтоматическоеСохранениеДанныхВНастройках = НеИспользовать как значения соответствующих перечислений, не Булево. Создайте команду ПроверитьРегион85 с действием ПроверитьРегион85 и настоящую кнопку этой команды. В модуль формы вставьте основной код целиком; параметр Команда не удаляйте. Других событий формы связывать не нужно.

  6. Конфигурация → Открыть модуль управляемого приложения: вставьте отдельный полный блок «УправляемоеПриложение» ниже. После проверки конфигурации обновите только свою новую базу. Закройте ее Конфигуратор и все остальные сеансы, затем запустите тонкий клиент под УченикРегиона85. Штатный ПриНачалеРаботыСистемы только открывает свою форму; региональные установки не читает и не меняет.

  7. Подготовьте запись запуска своей базы ровно File="C:\1c-labs\OwnRegionalSettings85_587cd6c6-8790-46df-838a-a55058f8a1d\IB";. Другой вид строки даст отказ, а не автоматическое исправление. Путь, имя и версия не доказывают владение: одноразовый стенд действительно должен быть создан вами. В native справке setter нет явного запрета File ИБ, но работоспособность этой подготовки запуском не подтверждена.

  8. До согласия прочитайте это предупреждение: меняются сохраненные установки всей собственной базы, setter может попытаться включить монопольный доступ. Нужен единственный сеанс без исходного монопольного режима. После ошибки установки или режим могут остаться измененными; автоматического восстановления и повторной попытки нет. Не выполняйте опыт в базе с реальными данными.

  9. Включите Согласие85 и один раз нажмите ПроверитьРегион85. Клиент удерживает фактическое исходное Булево согласие, снимает флажок и устанавливает остановку до обращения к серверу. Сервер проверяет этот исходный параметр вместе с уже остановленной собственной формой. Непроверенное значение или неверное состояние не допускается к региональным операциям. Это протокол одной своей кнопки, не средство защиты от поддельных RPC.

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

&НаСервере
Процедура ПроверитьСтенд85(Знач ИсходноеСогласие)
    Если ТипЗнч(ИсходноеСогласие) <> Тип("Булево") Или Не ИсходноеСогласие
        Или ТипЗнч(Согласие85) <> Тип("Булево") Или Согласие85
        Или ТипЗнч(Остановка85) <> Тип("Булево") Или Не Остановка85
        Или ТипЗнч(Протокол85) <> Тип("Строка") Тогда
        ВызватьИсключение "Нужно настоящее согласие, уже потребленное клиентской командой";
    КонецЕсли;
    Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1c-labs\OwnRegionalSettings85_587cd6c6-8790-46df-838a-a55058f8a1d\IB"";" Или Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Или Метаданные.ОсновнойРежимЗапуска <> РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Или ИмяФормы <> "ОбщаяФорма.УчебныйРегион85" Тогда
        ВызватьИсключение "Откройте только свою новую одноразовую лабораторию и ее форму";
    КонецЕсли;
    Если Метаданные.ОбщиеФормы.Количество() <> 1 Или Метаданные.ОбщиеФормы.Найти("УчебныйРегион85") = Неопределено
        Или Метаданные.Роли.Количество() <> 1 Или Метаданные.Роли.Найти("УчебнаяПолная85") = Неопределено
        Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0
        Или Метаданные.ПодпискиНаСобытия.Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() <> 0 Тогда
        ВызватьИсключение "Нужна одна своя форма и роль, без разделителей, заданий, подписок и расширений";
    КонецЕсли;
    Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Если ТипЗнч(Пользователь) <> Тип("ПользовательИнформационнойБазы")
        Или ТипЗнч(Пользователи) <> Тип("Массив") Или Пользователи.Количество() <> 1
        Или Пользователь.Имя <> "УченикРегиона85" Тогда
        ВызватьИсключение "Нужен единственный собственный пользователь учебной базы";
    КонецЕсли;
КонецПроцедуры

&НаСервере
Функция Снимок85(Настройки)
    Если ТипЗнч(Настройки) <> Тип("РегиональныеНастройкиИнформационнойБазы") Тогда
        ВызватьИсключение "Нужен настоящий объект, полученный из региональных установок базы";
    КонецЕсли;
    Снимок = Новый Структура("ИспользоватьНастройкиТекущегоСеанса,КодЛокализации,ПервыйДеньНедели,ПредставлениеБулевоИстина,ПредставлениеБулевоЛожь,ПредставлениеОтрицательныхЧисел,РазделительГруппЦифрЧисел,РазделительДробнойЧастиЧисел,ФорматГруппировкиЦифрЧисел,ФорматПредставленияВремени,ФорматПредставленияДаты",
        Настройки.ИспользоватьНастройкиТекущегоСеанса, Настройки.КодЛокализации, Настройки.ПервыйДеньНедели,
        Настройки.ПредставлениеБулевоИстина, Настройки.ПредставлениеБулевоЛожь, Настройки.ПредставлениеОтрицательныхЧисел,
        Настройки.РазделительГруппЦифрЧисел, Настройки.РазделительДробнойЧастиЧисел, Настройки.ФорматГруппировкиЦифрЧисел,
        Настройки.ФорматПредставленияВремени, Настройки.ФорматПредставленияДаты);
    Для Каждого Поле Из Снимок Цикл
        Если Поле.Ключ = "ИспользоватьНастройкиТекущегоСеанса" Тогда
            НужныйТип = Тип("Булево");
        ИначеЕсли Поле.Ключ = "ПервыйДеньНедели" Или Поле.Ключ = "ПредставлениеОтрицательныхЧисел" Тогда
            НужныйТип = Тип("Число");
        Иначе
            НужныйТип = Тип("Строка");
        КонецЕсли;
        Если ТипЗнч(Поле.Значение) <> НужныйТип Тогда
            ВызватьИсключение "Неверный тип поля региональных установок: " + Поле.Ключ;
        КонецЕсли;
    КонецЦикла;
    Возврат Новый ФиксированнаяСтруктура(Снимок);
КонецФункции

&НаСервере
Процедура Сравнить85(Ожидаемый, Фактический)
    Если ТипЗнч(Ожидаемый) <> Тип("ФиксированнаяСтруктура") Или ТипЗнч(Фактический) <> Тип("ФиксированнаяСтруктура")
        Или Ожидаемый.Количество() <> 11 Или Фактический.Количество() <> 11 Тогда
        ВызватьИсключение "Нужны два полных снимка из 11 полей";
    КонецЕсли;
    Для Каждого Поле Из Ожидаемый Цикл
        Если Не Фактический.Свойство(Поле.Ключ, Значение)
            Или ТипЗнч(Поле.Значение) <> ТипЗнч(Значение) Или Поле.Значение <> Значение Тогда
            ВызватьИсключение "Не совпало поле полного снимка: " + Поле.Ключ;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

&НаСервере
Функция ПроверитьРегионНаСервере85(Знач ИсходноеСогласие)
    ПроверитьСтенд85(ИсходноеСогласие);
    Соединения = ПолучитьСоединенияИнформационнойБазы();
    Если ТипЗнч(Соединения) <> Тип("Массив") Или Соединения.Количество() <> 1 Тогда
        ВызватьИсключение "Закройте Конфигуратор и все другие сеансы своей новой базы";
    КонецЕсли;
    РежимДо = МонопольныйРежим();
    Если ТипЗнч(РежимДо) <> Тип("Булево") Или РежимДо Или ПолучитьПараметрыМонопольногоРежима() <> Неопределено Тогда
        ВызватьИсключение "Стенд уже монопольный: региональные установки не менялись";
    КонецЕсли;
    Настройки = ПолучитьРегиональныеНастройкиИнформационнойБазы();
    Исходный = Снимок85(Настройки);
    КоличествоА = 2;
    ЦенаА = 250;
    ОплатаА = 0;
    КоличествоБ = 3;
    ЦенаБ = 250;
    ОплатаБ = 750;
    СуммаА = КоличествоА * ЦенаА;
    СуммаБ = КоличествоБ * ЦенаБ;
    ОплаченА = ОплатаА >= СуммаА;
    ОплаченБ = ОплатаБ >= СуммаБ;
    ДоА = Настройки.Представление(ОплаченА);
    ДоБ = Настройки.Представление(ОплаченБ);
    Если ТипЗнч(ДоА) <> Тип("Строка") Или ТипЗнч(ДоБ) <> Тип("Строка") Тогда
        ВызватьИсключение "Не получены исходные строки статусов двух счетов";
    КонецЕсли;
    План = Новый Структура(Исходный);
    План.ИспользоватьНастройкиТекущегоСеанса = Ложь;
    Если Не Исходный.ИспользоватьНастройкиТекущегоСеанса И Исходный.ПредставлениеБулевоИстина = "Оплачено"
        И Исходный.ПредставлениеБулевоЛожь = "Ожидает оплаты" Тогда
        План.ПредставлениеБулевоИстина = "Платеж получен";
        План.ПредставлениеБулевоЛожь = "Платеж еще не получен";
    Иначе
        План.ПредставлениеБулевоИстина = "Оплачено";
        План.ПредставлениеБулевоЛожь = "Ожидает оплаты";
    КонецЕсли;
    Настройки.ИспользоватьНастройкиТекущегоСеанса = План.ИспользоватьНастройкиТекущегоСеанса;
    Настройки.ПредставлениеБулевоИстина = План.ПредставлениеБулевоИстина;
    Настройки.ПредставлениеБулевоЛожь = План.ПредставлениеБулевоЛожь;
    Ожидаемый = Новый ФиксированнаяСтруктура(План);
    Сравнить85(Ожидаемый, Снимок85(Настройки));
    УстановитьРегиональныеНастройкиИнформационнойБазы(Настройки);
    Свежие = ПолучитьРегиональныеНастройкиИнформационнойБазы();
    Сравнить85(Ожидаемый, Снимок85(Свежие));
    ПослеА = Свежие.Представление(ОплаченА);
    ПослеБ = Свежие.Представление(ОплаченБ);
    Если ТипЗнч(ПослеА) <> Тип("Строка") Или ТипЗнч(ПослеБ) <> Тип("Строка")
        Или ПослеА <> План.ПредставлениеБулевоЛожь Или ПослеБ <> План.ПредставлениеБулевоИстина Тогда
        ВызватьИсключение "Сохраненные установки не дали фактические подписи счетов";
    КонецЕсли;
    Свежие.ИспользоватьНастройкиТекущегоСеанса = Исходный.ИспользоватьНастройкиТекущегоСеанса;
    Свежие.ПредставлениеБулевоИстина = Исходный.ПредставлениеБулевоИстина;
    Свежие.ПредставлениеБулевоЛожь = Исходный.ПредставлениеБулевоЛожь;
    Сравнить85(Исходный, Снимок85(Свежие));
    УстановитьРегиональныеНастройкиИнформационнойБазы(Свежие);
    Восстановленные = ПолучитьРегиональныеНастройкиИнформационнойБазы();
    Сравнить85(Исходный, Снимок85(Восстановленные));
    ВозвратА = Восстановленные.Представление(ОплаченА);
    ВозвратБ = Восстановленные.Представление(ОплаченБ);
    Если ТипЗнч(ВозвратА) <> Тип("Строка") Или ТипЗнч(ВозвратБ) <> Тип("Строка") Или ВозвратА <> ДоА Или ВозвратБ <> ДоБ Тогда
        ВызватьИсключение "Исходные фактические строки статусов не восстановлены";
    КонецЕсли;
    РежимПосле = МонопольныйРежим();
    Если ТипЗнч(РежимПосле) <> Тип("Булево") Тогда
        ВызватьИсключение "Не получен фактический признак монопольного режима";
    КонецЕсли;
    Если РежимПосле Тогда
        УстановитьМонопольныйРежим(Ложь);
    КонецЕсли;
    РежимИтог = МонопольныйРежим();
    Если ТипЗнч(РежимИтог) <> Тип("Булево") Или РежимИтог Или ПолучитьПараметрыМонопольногоРежима() <> Неопределено Тогда
        ВызватьИсключение "Фактическое снятие монопольного режима не подтверждено";
    КонецЕсли;
    СоединенияИтог = ПолучитьСоединенияИнформационнойБазы();
    Если ТипЗнч(СоединенияИтог) <> Тип("Массив") Или СоединенияИтог.Количество() <> 1 Тогда
        ВызватьИсключение "После опыта число собственных сеансов не равно одному";
    КонецЕсли;
    Возврат "Счет А: " + Строка(КоличествоА) + " × " + Строка(ЦенаА) + " = " + Строка(СуммаА) + "; оплата " + Строка(ОплатаА)
        + "; до: " + ДоА + "; учебный статус: " + ПослеА + "; восстановлен: " + ВозвратА
        + Символы.ПС + "Счет Б: " + Строка(КоличествоБ) + " × " + Строка(ЦенаБ) + " = " + Строка(СуммаБ) + "; оплата " + Строка(ОплатаБ)
        + "; до: " + ДоБ + "; учебный статус: " + ПослеБ + "; восстановлен: " + ВозвратБ
        + Символы.ПС + "Все 11 региональных установок восстановлены; монопольный режим фактически выключен.";
КонецФункции

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

Конфигурация → Открыть модуль управляемого приложения

Тонкий управляемый клиент

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

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

  1. Кнопка сначала проверяет фактическое согласие и собственную команду. Еще до серверного вызова расходует согласие и останавливает форму; передается удержанное исходное согласие, не константа.

  2. Сервер проверяет полученное согласие, остановленную форму, свои маркеры, отсутствие разделителей/заданий/подписок/расширений, единственного пользователя и сеанс. Исходная монополия запрещена: ее не снимают ради продолжения.

  3. Настоящий getter дает объект установок. Неизменяемый снимок сохраняет все 11 имен, типов и значений до любого изменения. Суммы двух счетов вычисляются в памяти: 2 × 250 = 500 и 3 × 250 = 750; сравнение оплаты с суммой дает Ложь и Истина.

  4. План копируется из полного снимка; изменяются только флаг использования настроек сеанса и две подписи Булево. Обычно это «Ожидает оплаты» и «Оплачено». Если исходная тройка уже такая, берутся «Платеж еще не получен» и «Платеж получен», чтобы изменение было настоящим.

  5. Setter вызывается как процедура. Новый getter подтверждает весь сохраненный профиль, а Представление на этом свежем объекте форматирует именно вычисленные статусы двух счетов. Видимый вывод использует эти полученные строки, не заранее напечатанные подписи.

  6. На нормальном пути три измененных поля возвращаются из неизменяемого снимка. Setter и новый getter подтверждают полное восстановление 11 установок, затем Представление возвращает исходные строки статусов. Остальные восемь полей не меняются.

  7. После нормального восстановления читается фактическая монополия. Если она осталась включена, снимается только в собственной базе без разделителей; если выключена, setter режима не вызывается. Повторное чтение подтверждает Ложь, отсутствие параметров монополии и один сеанс.

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

  1. До кнопки нет вызовов региональных/монопольных API. Без фактического согласия, с Остановка85 = Истина или с чужой командой отказ наступает до серверного вызова.

  2. В будущем нормальном протоколе счет А имеет количество 2, цену 250, сумму 500, оплату 0 и фактическую подпись Ложь; счет Б — 3, 250, 750, оплату 750 и фактическую подпись Истина. Учебные подписи соответствуют выбранному отличающемуся профилю.

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

  4. Успешный вывод появляется только после полного совпадения всех 11 исходных полей по имени, типу и значению, восстановленных строк статусов и фактического отсутствия монополии. Ошибка или отказ не являются успешным результатом.

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

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

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

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

  1. УстановитьРегиональныеНастройкиИнформационнойБазы сохраняет установки базы, требует Администрирование и монопольный доступ; при его отсутствии пытается установить его. Возвращаемое значение не документировано. Любая ошибка вызывает исключение.

  2. РегиональныеНастройкиИнформационнойБазы не имеет конструктора. Объект берется только настоящим getter. Независимость объектов разных getter не обещана, поэтому сохранение исходного объекта не заменяет неизменяемый снимок примитивов.

  3. ПредставлениеБулевоЛожь, КодЛокализации и ФорматПредставленияВремени в установленной справке доступны серверу и внешнему соединению, но не толстому клиенту. Все 11 полей читаются на сервере, объект установок клиенту не передается.

  4. Native setter не обещает, что монопольный режим обязательно останется включенным или сам выключится. Код читает фактическое состояние. Для освобождения своего неподеленного контекста УстановитьМонопольныйРежим(Ложь) вызывается лишь на нормальном пути и лишь при фактическом Истина.

  5. Не меняются локализация, правила сортировки, числа, даты, время, первый день недели, язык интерфейса или установки сеанса. Остальные восемь свойств сохраняются даже с пустыми строками или специальными значениями: свои новые значения им не назначают.

  6. ПолучитьСоединенияИнформационнойБазы требует АктивныеПользователи. Полные учебные права не означают минимальные права рабочего решения. Нет гарантии успеха в File ИБ, автоматического отката, конкурентной защиты или восстановления после ошибки.

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

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

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

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

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