При разработке мобильных приложений на платформе «1С:Предприятие» начинающие разработчики часто сталкиваются с ситуацией, когда стандартный код перебора элементов справочника вида Справочники.Номенклатура.Выбрать() вызывает ошибку при выполнении в процедуре с директивой &НаКлиенте. Возникает закономерный вопрос: если база данных находится локально на мобильном устройстве и физического сервера 1С нет, почему этот метод не работает на клиенте и как правильно получить данные?
Разберем детально архитектурные особенности мобильной платформы 1С и рассмотрим правильные способы выборки элементов справочника.
Проанализируем, как устроена работа с данными на мобильных устройствах. В мобильной платформе «1С:Предприятие» полностью сохраняется концепция клиент-серверного разделения кода, аналогичная работе настольной файловой или клиент-серверной базы:
&НаКлиенте) отвечает исключительно за пользовательский интерфейс, отображение форм, обработку событий ввода и взаимодействие с аппаратной частью мобильного устройства. На клиенте недоступна прямая работа с таблицами базы данных, менеджерами объектов (Справочники, Документы, РегистрыСведений), а также объектами Запрос.&НаСервере) в мобильном приложении — это встроенное ядро платформы, которое работает с локальной базой данных прямо на смартфоне или планшете. Серверный вызов не означает обращение к удаленному компьютеру по сети, а представляет собой переключение контекста выполнения кода для прямого взаимодействия с локальной СУБД устройства.Таким образом, для выполнения любых операций чтения или записи данных нам необходимо вызывать серверный контекст.
Рассмотрим наиболее производительный и надежный способ получения данных на мобильном устройстве. Для оптимизации расхода оперативной памяти и ресурсов процессора мобильного устройства рекомендуется использовать не метод Выбрать(), а объект Запрос в процедуре или функции с директивой &НаСервереБезКонтекста.
Посмотрим на практический пример реализации:
&НаКлиенте
Процедура ОбработатьЭлементыСправочника(Команда)
// Получаем массив структур с данными из локальной базы данных
ДанныеСправочника = ПолучитьСписокЭлементовНаСервере();
// Перебираем полученные данные на клиенте
Для Каждого СтрокаДанных Из ДанныеСправочника Цикл
Сообщить("Элемент: " + СтрокаДанных.Наименование + ", Код: " + СтрокаДанных.Код);
КонецЦикла;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьСписокЭлементовНаСервере()
Результат = Новый Массив;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Стр = Новый Структура("Ссылка, Код, Наименование");
ЗаполнитьЗначенияСвойств(Стр, Выборка);
Результат.Добавить(Стр);
КонецЦикла;
Возврат Результат;
КонецФункции
Обратим внимание на то, что сложные серверные типы (такие как ВыборкаИзРезультатаЗапроса или ТаблицаЗначений) нельзя напрямую передавать на клиент. Поэтому мы выгружаем результат в сериализуемые типы: Массив и Структура.
Если логика требует применения стандартного метода Выбрать() менеджера справочника, мы также должны разместить эту операцию на сервере.
Разберем пример с использованием метода Выбрать():
&НаКлиенте
Процедура ЗапуститьПереборСправочника(Команда)
ВыполнитьПереборНаСервере();
КонецПроцедуры
&НаСервере
Процедура ВыполнитьПереборНаСервере()
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
// Обрабатываем данные непосредственно в серверном контексте
Если Не Выборка.ЭтоГруппа Тогда
// Выполняем требуемую логику обработки
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Рассмотрим правильную организацию архитектуры кода. Если логику работы со справочниками требуется вызывать из различных форм или фоновых заданий мобильного приложения, ее следует размещать в общем модуле:
РаботаСоСправочникамиСервер).Экспорт.Посмотрим на пример вызова из клиентской процедуры формы:
&НаКлиенте
Процедура КнопкаОбновитьНажатие(Команда)
СписокТоваров = РаботаСоСправочникамиСервер.ПолучитьМассивНоменклатуры();
// Обработка данных на клиенте
КонецПроцедуры
При разработке мобильных решений важно учитывать ограниченные ресурсы смартфонов и планшетов:
&НаСервереБезКонтекста: Обычный вызов &НаСервере передает все данные формы на локальный сервер и обратно. Вызовы без контекста работают быстрее и экономят память.ДинамическийСписок, и платформа самостоятельно оптимизирует порционную загрузку данных из локальной базы.