Как перебрать элементы справочника в мобильном приложении 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке мобильных приложений на платформе «1С:Предприятие» начинающие разработчики часто сталкиваются с ситуацией, когда стандартный код перебора элементов справочника вида Справочники.Номенклатура.Выбрать() вызывает ошибку при выполнении в процедуре с директивой &НаКлиенте. Возникает закономерный вопрос: если база данных находится локально на мобильном устройстве и физического сервера 1С нет, почему этот метод не работает на клиенте и как правильно получить данные?

Разберем детально архитектурные особенности мобильной платформы 1С и рассмотрим правильные способы выборки элементов справочника.

Архитектурная причина: разделение на Клиент и Сервер в мобильной платформе

Проанализируем, как устроена работа с данными на мобильных устройствах. В мобильной платформе «1С:Предприятие» полностью сохраняется концепция клиент-серверного разделения кода, аналогичная работе настольной файловой или клиент-серверной базы:

  1. Клиентский контекст (&НаКлиенте) отвечает исключительно за пользовательский интерфейс, отображение форм, обработку событий ввода и взаимодействие с аппаратной частью мобильного устройства. На клиенте недоступна прямая работа с таблицами базы данных, менеджерами объектов (Справочники, Документы, РегистрыСведений), а также объектами Запрос.
  2. Серверный контекст (&НаСервере) в мобильном приложении — это встроенное ядро платформы, которое работает с локальной базой данных прямо на смартфоне или планшете. Серверный вызов не означает обращение к удаленному компьютеру по сети, а представляет собой переключение контекста выполнения кода для прямого взаимодействия с локальной СУБД устройства.

Таким образом, для выполнения любых операций чтения или записи данных нам необходимо вызывать серверный контекст.

Способ 1. Использование запроса в серверном контексте (рекомендуемый подход)

Рассмотрим наиболее производительный и надежный способ получения данных на мобильном устройстве. Для оптимизации расхода оперативной памяти и ресурсов процессора мобильного устройства рекомендуется использовать не метод Выбрать(), а объект Запрос в процедуре или функции с директивой &НаСервереБезКонтекста.

Посмотрим на практический пример реализации:


&НаКлиенте
Процедура ОбработатьЭлементыСправочника(Команда)
    // Получаем массив структур с данными из локальной базы данных
    ДанныеСправочника = ПолучитьСписокЭлементовНаСервере();
    
    // Перебираем полученные данные на клиенте
    Для Каждого СтрокаДанных Из ДанныеСправочника Цикл
        Сообщить("Элемент: " + СтрокаДанных.Наименование + ", Код: " + СтрокаДанных.Код);
    КонецЦикла;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьСписокЭлементовНаСервере()
    Результат = Новый Массив;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Номенклатура.Ссылка КАК Ссылка,
        |	Номенклатура.Код КАК Код,
        |	Номенклатура.Наименование КАК Наименование
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	НЕ Номенклатура.ПометкаУдаления";
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        Стр = Новый Структура("Ссылка, Код, Наименование");
        ЗаполнитьЗначенияСвойств(Стр, Выборка);
        Результат.Добавить(Стр);
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

Обратим внимание на то, что сложные серверные типы (такие как ВыборкаИзРезультатаЗапроса или ТаблицаЗначений) нельзя напрямую передавать на клиент. Поэтому мы выгружаем результат в сериализуемые типы: Массив и Структура.

Способ 2. Использование объектной выборки через Справочники.ИмяСправочника.Выбрать()

Если логика требует применения стандартного метода Выбрать() менеджера справочника, мы также должны разместить эту операцию на сервере.

Разберем пример с использованием метода Выбрать():


&НаКлиенте
Процедура ЗапуститьПереборСправочника(Команда)
    ВыполнитьПереборНаСервере();
КонецПроцедуры

&НаСервере
Процедура ВыполнитьПереборНаСервере()
    Выборка = Справочники.Номенклатура.Выбрать();
    
    Пока Выборка.Следующий() Цикл
        // Обрабатываем данные непосредственно в серверном контексте
        Если Не Выборка.ЭтоГруппа Тогда
            // Выполняем требуемую логику обработки
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Способ 3. Вынос логики в общий серверный модуль

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

  1. Создадим общий модуль (например, РаботаСоСправочникамиСервер).
  2. В свойствах модуля установим флажки «Сервер» и «Вызов сервера».
  3. Поместим функцию выборки с ключевым словом Экспорт.

Посмотрим на пример вызова из клиентской процедуры формы:


&НаКлиенте
Процедура КнопкаОбновитьНажатие(Команда)
    СписокТоваров = РаботаСоСправочникамиСервер.ПолучитьМассивНоменклатуры();
    // Обработка данных на клиенте
КонецПроцедуры

Практические рекомендации по оптимизации

При разработке мобильных решений важно учитывать ограниченные ресурсы смартфонов и планшетов:

  1. Предпочитайте &НаСервереБезКонтекста: Обычный вызов &НаСервере передает все данные формы на локальный сервер и обратно. Вызовы без контекста работают быстрее и экономят память.
  2. Ограничивайте объем данных: Не выбирайте все поля справочника без необходимости. В запросе указывайте только те реквизиты, которые действительно нужны для дальнейшей работы.
  3. Используйте динамические списки для интерфейса: Если цель перебора — просто показать пользователю список элементов в форме, не перебирайте данные вручную. Добавьте в форму реквизит с типом ДинамическийСписок, и платформа самостоятельно оптимизирует порционную загрузку данных из локальной базы.
← На главную