При программировании собственной консоли запросов, особенно для экранов смартфонов, и поддержки платформы 1С 8.0 столкнулся со следующими неприятными особенностями старых мобильных платформ:
Этот баг был выявлен на версии платформы:
Для системных перечислений нет классического метода Менеджер.ИмяПеречисления.Значение как для обычных перечислений - там сразу идет ИмяПеречисления.Значение.
Обход ограничений на системные перечисления в зависимости от способов можно разделить на 2 категории:
- Обход ветвления на сервере или обычных формах. Самый простой способ.
- Обход ветвления на клиенте. Требует дополнительного кода и хранения значений.
ПРИМЕЧАНИЕ: Статья написана в справочных целях как памятка, и также для того, чтобы закрыть этот не слишком приятный момент в документации.
ОБХОД ОГРАНИЧЕНИЙ НА СЕРВЕРЕ ИЛИ ОБЫЧНЫЕ ФОРМЫ
По итогу разбора полетов (учитывая многострадальный IOS), получилась следующая таблица основных способов вызова системных перечислений для сервера и обычных:
| Способ | Достоинства | Недостатки |
|
1. Использование внутреннего формата 1С (функции времен 1с 7.7). |
Универсально для всех компьютерных платформ | Не поддерживается в мобильном приложении |
| 2. Получение значения при помощи конструкции ОписаниеТипов. | Работает везде, включая мобильное приложение. | Допускает возврат только значения по умолчанию. |
| 3. Использование оператора Вычислить или Выполнить | Работает как на компьютерных платформах, так и на мобильных приложениях. | IOS не поддерживает операторы Вычислить или Выполнить |
| 4. Использование функции ПредопределенноеЗначение | Работает везде, включая мобильное приложение на платформе 8.3. | Требует платформы 1с 8.3.4 и выше. (для несистемных перечислений - появилась в 1с 8.2.9). Нельзя использовать для системных перечислений на клиенте. |
Примеры исходного кода первых двух способов:
//Для первого способа:
ЗначениеИзСтрокиВнутр(Значение));
//Для второго способа:
//ОбходРезультатаЗапроса - генерация прямой выборки для древней
// 1С мобильной платформы.
Попытка
Массив = новый Массив;
Массив.Добавить(Тип("ОбходРезультатаЗапроса"));
ОписаниеТипов1 = новый ОписаниеТипов(Массив);
Значение = ОписаниеТипов1.ПривестиЗначение(Неопределено);
исключение
Значение = Неопределено;
КонецПопытки;
Сообщить(Значение);
Последние 2 способа удобно объединить в следующую универсальную конструкцию:
//Вызов осуществляется на стороне Сервера для Управляемых форм.
Попытка
#Если МобильноеПриложениеСервер ИЛИ МобильныйАвтономныйСервер Тогда
Значение_тест = ПредопределенноеЗначение(НаименованиеПараметра); // Для смартфонов!!!
#иначе
Значение_тест = Вычислить(НаименованиеПараметра); //Для компьютерных платформ!!!
#КонецЕсли
Исключение
Значение_тест = Неопределено;
КонецПопытки;
Пример результата вызова подхода 4 на экране смартфона (8.3.5.96):
Проверить код - обертка над кнопкой Выполнить (android).
Таким образом, обход на сервере сложностей не представляет.
ОБХОД ОГРАНИЧЕНИЯ ПО СИСТЕМНЫМ ПЕРЕЧИСЛЕНИЯМ НА КЛИЕНТЕ В УФ
Для управляемых форм имеются 2 способа:
- Выполнить/Вычислить. Пример кода аналогичен ситуации на сервере.
- Переопределение значений через переменные формы.
В этом разделе рассмотрен будет именно 2-й способ. Пример реализации этого способа для работы с диалогом выбора файлов.
&НаКлиенте
перем ВыборФайлаОткрытие, ВыборФайлаСохранение; //Переменные кэша
&НаКлиенте
Процедура ПриОткрытии(Отказ)
//Вставить содержимое обработчика
// Определяем связанный тип или же исповедуем по версии
Попытка
Стр=Тип("ДиалогВыбораФайла");
Исключение
Стр = Неопределено;
КонецПопытки;
//Ставим заглушку на обращение к перечислениям
Если Стр = Неопределено Тогда
РежимДиалогаВыбораФайла = Неопределено;
КонецЕсли;
//
Если РежимДиалогаВыбораФайла = Неопределено Тогда
// Установка произвольного нужного значения, когда нет типа!!!
ВыборФайлаОткрытие = Неопределено;
ВыборФайлаСохранение = Неопределено;
иначе
//Кэшируем системные перечисления
ВыборФайлаОткрытие = РежимДиалогаВыбораФайла.Открытие;
ВыборФайлаСохранение = РежимДиалогаВыбораФайла.Сохранение;
КонецЕсли;
КонецПроцедуры
Теперь приведу пример обработки комнды:
&НаКлиенте
Процедура Тест(Команда)
Если ВыборФайлаОткрытие = НЕОПРЕДЕЛЕНО Тогда
Сообщить("Не поддерживается - нужен другой способ реализации диалога");
иначе
// Все ок - открываем файл
МассивАргументов = новый Массив;
МассивАргументов.Добавить(ВыборФайлаОткрытие);
Диалог = новый("ДиалогВыбораФайла",МассивАргументов);
// В реальных системах использовать метод Показать() или другой асинхронный метод
Если Диалог.Выбрать()=Ложь Тогда
Сообщить("Не выбран файл");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Изюминка в следующем: на клиенте есть возможность сохранять многие значения в переменные и они не очищаются при серверных вызовах. Более того, благодаря этому можно сохранить значения, которые нельзя передать на сервер, как в этом примере кода.
Вступайте в нашу телеграмм-группу Инфостарт