Введение
Мобильная платформа 1С работает только с одной конфигурацией. Под каждую конфигурацию создается свой мобильный клиент.
Если посмотреть объекты в конфигурации, то в основном это справочники, документы и регистры.
А это уже процентов 80% тех данных, которым нужно обмениваться с любым клиентом.
Но ведь справочники и документы это стандартные объекты, у них есть стандартные реквизиты и стандартное поведение. И поведение справочников и документов не меняется при переходе например от УТ к БП. Например документ можно провести, а справочник поставить пометку на удаление.
В этой статье мы попробуем описать решение, в котором мы стандартную логику вынесем в общие модули, которые не будут меняться при переходе от одной конфигурации к другой. И напишем добавленную логику, которая будет зависеть от конкретной конфигурации 1С.
Инфраструктура
Договоримся, что мобильное приложение работать через HTTP сервисы. Для этого 1С должна быть опубликована на веб-сервере. Обмен будет происходит через обычные запросы с использование JSON.
Также в 1С будет создан ПланОбмена, в котором будет хранится регистрация изменений объектов
В мобильном приложении сохранен логин и пароль для авторизации к 1С и выполнения запросов.
План обмена
У нас может быть одна база 1С и несколько мобильных устройств на каждом из которых стоит мобильный клиент. Значит, нужно знать какие изменения были для каждого устройства. Для этого при первом обмене мобильного клиента в 1С создается экземпляр плана обмена с ID устройством. Это поможет идентифицировать план обмена для каждого устройства и знать, какие данные изменились для каждого устройства.
HTTP сервис 1С
В нашем HTTP сервисе будет несколько эндпоинтов:
- ЗарегистрироватьОбъекты
- ВыгрузитьРегистрациюОбъектов
- ВыгрузитьОбъекты
- УдалитьРегистрациюОбъектов
- ЗагрузитьОбъекты
- ВыгрузитьОбновленныеДанные
1 ЗарегистрироватьОбъекты
Этот метод нужен для регистрации какого либо типа объекта в плане обмена при первой синхронизации данных. В мобильном клиенте еще не было синхронизаций например справочника Номенклатуры. Значит нужно сходить в 1С и зарегистрировать все объекты Номенклатуры чтобы потом их загрузить.
Возвращаем успешный ответ или ошибку.
2 ВыгрузитьРегистрациюОбъектов
В этом методе мы выгражаем зарегистрированные объекты какого либо типа данных из шага 1. Почему мы выгружаем не сами данные а их регистрацию ? Потому что данных может быть очень много и это нужно разбить на запросы.
Возвращаем массив данных или ошибку.
3 ВыгрузитьОбъекты
В этом методе зная регистрацию объекта мы идем в 1С и получаем данные этого объекта.
Возвращаем JSON данные или ошибку.
4 УдалитьРегистрациюОбъектов
При успешном шаге 3 мы в 1С удаляем регистрацию изменений тех объектов которые успешно загрузили
Возвращаем успешный ответ или ошибку.
5 ЗагрузитьОбъекты
В этом методе мы загружаем из мобильного клиента например документ Заказ покупателя.
Возвращаем успешный ответ или ошибку.
6 ВыгрузитьОбновленныеДанные
После шага 5 мы в 1С уже что то загрузили и объект после загрузки в 1С мог получить дополнительные свойства. Например документ получает номер из базы 1С.
Так вот в этом методе мы возвращаем новые данные которых не было на шаге 3. Мы не выполняем заново шаг 3 на мобильном клиенте чтобы сэкономить на траффике и скорости обмена.
Возвращаем JSON данные или ошибку.
Маппинг данных
Давайте подумаем, как мы можем разделить данные на те, которые не меняются от разных конфигураций и те, которые будут меняться в зависимости от конфигурации.
Например регистрация объекта. Справочник и документ идентифицируются в базе по ссылке. У ссылки есть уникальный идентификатор. Уникальный идентификатор не меняется в зависимости от конфигурации.
А вот тип данных меняется. В УТ есть справочник Номенклатура, а в базе ЗУП справочник Сотрудники. Это разные типы данных. Значит 1С должна уметь понимать какой тип данных. С другой стороны справочник имеет стандартные реквизиты: код, наименование, пометка удаления. Стандартные реквизиты не меняются.
Архитектурная идея
Представим, что мы выполняем запрос 3 ВыгрузитьОбъекты. Давайте распишем по шагам.
- 1 Мобильный клиент отправляет запрос, в котором передает, что он хочет получить данные справочника номенклатуры и передает ссылку на номенклатуру.
type: catalogNomenclature
uuid: UUID
- 2 1С получила запрос с type: catalogNomenclature. 1С нужно понять какой это тип данных. Для этого в 1С сделаем общий модуль "МобильноеПриложение_МаппингДанныхПовтИспЧастный" в котором будет функция которая зная type: catalogNomenclature может вернуть тип данных 1С.
Зная тип данных 1С можно получить менеджер этого тип данных. В нашем примере мы получим "СправочникМенеджер.Номенклатура".
Зная менеджер справочника мы в менеджере напишем формирование данных для объекта с конкретным UUID.
- 3 1С формирует данные и возвращает их в ответе на запрос
Из этих 3 шагов у нас для разных конфигураций 1С будет только отличаться будет только маппинг типа данных в менеджер объекта.
Например база УТ
type: catalogNomenclature - "СправочникМенеджер.Номенклатура"
База ЗУП
type: catalogEmployee - "СправочникМенеджер.Сотрудники"
Но ведь это логично. Разные базы, разные объекты, для каждой базы свой маппинг.
Также для каждой базы свой "СправочникМенеджер". Но внутри модуля "СправочникМенеджер" и будет формирование данных этого типа. Мы все равно при установки расширения в новую базу будет выгружать другие объекты, значит другие менеджеры справочников, значит этот код завязан на конкретную конфигурацию.
Структура модулей расширения

Давайте посмотрим на структуру модулей. Красным цветом я выделил те модули которые будут менятся при установке расширения на новую конфигурацию 1С.
А весь остальной код будет неизменным.
Давайте посмотрим модуль МобильноеПриложение_МаппингДанныхПовтИспЧастный.
Функция ПолучитьСоотвествиеМенеджеры() Экспорт
Соответствие = Новый Соответствие;
//Справочники
Соответствие.Вставить("catalogNomenclature", Справочники.Номенклатура);
//Документы
Соответствие.Вставить("documentOrder", Документы.ЗаказКлиента);
Возврат Соответствие;
КонецФункции
Тут как пример мы формируем соответствие типов данных для мобильного клиента и менеджера объекта в 1С.
Следующий интересный модуль будет МобильноеПриложение_ФормированиеДанных.
Функция ПодготовитьДанныеОбъекта(Регистрация)
ТипОбъекта = МобильноеПриложение_ЧтениеДанных.ПолучитьСвойство(Регистрация, МобильноеПриложение_МаппингДанныхПовтИспОбщий.ПолучитьКлючТип());
Менеджер = МобильноеПриложение_МаппингДанныхПовтИспОбщий.ПолучитьМенеджерОбъекта(ТипОбъекта);
Если Менеджер = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Данные = Менеджер.ПодготовитьДанныеРегистрация(Регистрация);
Возврат Данные;
КонецФункции
Самое интересное тут то, что зная тип объекта мы получаем менеджер объекта. Но мы тут ссылаемся на МобильноеПриложение_МаппингДанныхПовтИспОбщий.
Давайте и его посмотрим МобильноеПриложение_МаппингДанныхПовтИспОбщий
Функция ПолучитьМенеджерОбъекта(ТипОбъектаПриложения) Экспорт
СоотвествиеМенеджеров = МобильноеПриложение_МаппингДанныхПовтИспЧастный.ПолучитьСоотвествиеМенеджеры();
МенеджерОбъекта = СоотвествиеМенеджеров.Получить(ТипОбъектаПриложения);
Если МенеджерОбъекта = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Возврат МенеджерОбъекта;
КонецФункции
Такие образом зная тип объекта, мы можем получить его менеджер.
Далее давайте посмотрим на формирование данных в менеджере. Метод ПодготовитьДанныеРегистрация.
Функция ПодготовитьДанныеРегистрация(Регистрация) Экспорт
УИСтрока = МобильноеПриложение_ЧтениеДанных.ПолучитьСвойство(Регистрация, МобильноеПриложение_МаппингДанныхПовтИспОбщий.ПолучитьКлючИдентификацияОбъекта());
УникальныйИдентификатор = Новый УникальныйИдентификатор(УИСтрока);
Данные = ПодготовитьДанныеУИ(УникальныйИдентификатор);
Возврат Данные;
КонецФункции
Функция ПодготовитьДанныеУИ(УникальныйИдентификатор) Экспорт
СправочникСсылка = ПолучитьСсылку(УникальныйИдентификатор);
Данные = ПодготовитьДанныеСсылка(СправочникСсылка);
Возврат Данные;
КонецФункции
Функция ПодготовитьДанныеСсылка(СправочникСсылка) Экспорт
СтруктураДанных = МобильноеПриложение_ФормированиеДанных.ПодготовитьСтруктуруСправочника(СправочникСсылка);
Если СправочникСсылка.ЭтоГруппа Тогда
Возврат СтруктураДанных;
КонецЕсли;
СтруктураДанных.Вставить(МобильноеПриложение_МаппингДанныхПовтИспОбщий.ПолучитьКлючАртикул(), СправочникСсылка.Артикул);
СтруктураДанных.Вставить(МобильноеПриложение_МаппингДанныхПовтИспЧастный.ПолучитьКлючЕдиницаИзмерения(), Справочники.УпаковкиЕдиницыИзмерения.ПодготовитьДанныеСсылка(СправочникСсылка.ЕдиницаИзмерения));
СтруктураДанных.Вставить(МобильноеПриложение_МаппингДанныхПовтИспЧастный.ПолучитьКлючВидНоменклатуры(), Справочники.ВидыНоменклатуры.ПодготовитьДанныеСсылка(СправочникСсылка.ВидНоменклатуры));
СтруктураДанных.Вставить(МобильноеПриложение_МаппингДанныхПовтИспЧастный.ПолучитьКлючСтавкаНДС(), Справочники.СтавкиНДС.ПодготовитьДанныеСсылка(СправочникСсылка.СтавкаНДС));
ДанныеКартинки = Неопределено;
Если ЗначениеЗаполнено(СправочникСсылка.ФайлКартинки) Тогда
ДанныеКартинки = МобильноеПриложение_ФормированиеДанных.ПодготовитьОбщуюСтруктуруСправочника(СправочникСсылка.ФайлКартинки)
КонецЕсли;
СтруктураДанных.Вставить(МобильноеПриложение_МаппингДанныхПовтИспЧастный.ПолучитьКлючКартинка(), ДанныеКартинки);
Возврат СтруктураДанных;
КонецФункции
В суть в методе ПодготовитьДанныеСсылка. Именно тут и происходит формирование данных.
Помните, в самом начале я говорил, что у справочников есть стандартные реквизиты.
СтруктураДанных = МобильноеПриложение_ФормированиеДанных.ПодготовитьСтруктуруСправочника(СправочникСсылка);
Эта строчка и формирует общие данные для справочников. То есть при переходе в новую базу мы просто возьмем формирование этих данных и вставим сюда.
А вот дальше идет формирование бизнес данных конкретного справочника. Проще говоря, мы формируем структуру реквизитов для мобильного клиента.
Теперь давайте посмотрим на модуль МобильноеПриложение_ПланОбменаЧастный.
Процедура ЗарегистрироватьОбъекты(ПланОбмена, ИмяОбъекта) Экспорт
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| &ВыгружатьНоменклатуру";
Запрос.УстановитьПараметр("ПланОбмена", ПланОбмена);
Запрос.УстановитьПараметр("ВыгружатьНоменклатуру", ИмяОбъекта = "Номенклатура");
Массив = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
МобильноеПриложение_ПланОбменаОбщий.ДобавитьРегистрациюМассивДанных(ПланОбмена, Массив);
КонецПроцедуры
Функция ПолучитьРегистрациюОбъектов(ПланОбмена, ИмяОбъекта) Экспорт
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| НоменклатураИзменения.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура.Изменения КАК НоменклатураИзменения
|ГДЕ
| НоменклатураИзменения.Узел = &ПланОбмена
| И &ВыгружатьНоменклатуру";
Запрос.УстановитьПараметр("ПланОбмена", ПланОбмена);
Запрос.УстановитьПараметр("ВыгружатьНоменклатуру", ИмяОбъекта = "Номенклатура");
Массив = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
Возврат Массив
КонецФункции
Поскольку это частный модуль, он зависит от конкретных объектов конфигурации.
1 ЗарегистрироватьОбъекты. Это метод из шага 1. Тут мы зная тип данных который смаппили регистрируем объекты на плане обмена.
2 ПолучитьРегистрациюОбъектов. Это метод из шага 2. Тут мы зная тип данных выгружаем регистрацию например ссылки справочника в виде UUID.
Краткие выводы
Такое решение позволит нам гибко маппить типы данных для разных конфигураций 1С.
Формирование данных происходит в менеджере объекта.
Нет смысла выносить формирование данных в общие модули. Поскольку формирование данных объекта очень тесно связано с самим объектов и его типом данных. Лучше внутри менеджера использовать общий инфраструктурный код который поможет сформировать данные этого объекта.
При масштабировании у нас будет меняться
- 2 общих модуля
МобильноеПриложение_МаппингДанныхПовтИспЧастный.
МобильноеПриложение_ПланОбменаЧастный.
- Менеджеры объектов
СправочникМенеджерНоменклатура
СправочникМенеджерСклады
и т.д.
Но у нас будет много инфраструктурного кода который будет помогать нам формировать данные, формировать JSON, формировать ключи для структур и прочий полезный код.
Проблемы которые ждут это решение
Поскольку это расширение нужно четко вести версионирование кода.
Каждая версия мобильного клиента должна работать с конкретной версией расширения. Иначе клиент сделает запрос, на который 1С не сможет ответить.
Также будет проблема версионирования самой конфигурации. Представим что мы дали это расширение для работы с УТ 2 клиентам у которых разная версия самой базы УТ.
У первого клиента в справочнике номенклатуры есть новый реквизит. А у второго клиенте еще нет. Это проблема.
Финальные мысли
В этой статье мы коснулись разработки решения для обмена с мобильными клиентами. Мы не затронули работу самих мобильных клиентов. А это тоже очень важная и большая часть. Ведь раз мы хотим масштабировать решение 1С мы также должны масштабировать решение и самого мобильного клиента. То есть мобильные клиент не должен каждый раз писаться с нуля. А должен использовать различные библиотеки например для выполнения запросов. Также мобильный клиент должен как то хранить данные. А также понимать что на мобильном клиенте изменилось чтобы эти изменения выгрузить обратно.
Мобильные приложения
Но не все так плохо. На самом деле уже вышла первая версия приложения. В приложении можно просматривать справочники, создать заказ и выгрузить заказ в 1С.
Приложение уже доступно в AppStore
iOS Приложение Управление торговлей в AppStore
| Номенклатура | Создание заказа |
![]() |
![]() |
Мобильное приложение Управление деньгами
Этого приложения пока нету в AppStore, но я этим приложением пользуюсь уже больше 3 лет. Приложение ведет учет личных финансов и выгружает данные в базу 1С Деньги.
Знаю что разработку конфигурации 1С уже остановили. Но это не мешает вести учет в этой базе. Добавлю скриншотов.
Вопросы к сообществу
Напишите в комментариях насколько интересно такое решение ? Стоит ли его развивать дальше как альтернативу мобильной платформы 1С ? Задавайте свои вопросы по этому решению.
Вступайте в нашу телеграмм-группу Инфостарт