Как организовать обмен данными между 1С и мобильным приложением для проведения инвентаризации?

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

При разработке мобильных решений для 1С, особенно предназначенных для инвентаризации, ревизий или переучета, одной из самых сложных задач становится выбор надежного и удобного транспорта для обмена данными. Проблема усложняется, когда необходимо обеспечить работу на разных платформах (Android и iOS), где действуют разные правила доступа к файловой системе. В данной статье мы проанализируем ситуацию, разберем архитектурные подходы и рассмотрим готовое решение на базе промежуточного HTTP-сервера.

Почему стоит отказаться от передачи файлов в пользу HTTP

На начальном этапе многие разработчики рассматривают вариант прямого обмена файлами (через USB-кабель, FTP или облачные диски). Однако, проанализировав современные мобильные ОС, мы увидим серьезные ограничения. Например, в iOS платформа 1С может работать только с каталогом приложения, а передача файлов через iTunes крайне неудобна для конечного пользователя. Android более лоялен, но и там наблюдается тенденция к ужесточению прав доступа.

Рассмотрим основные заветы архитектуры: прежде чем выбирать транспорт, необходимо отделить бизнес-логику от способа передачи данных. Функции формирования данных должны быть универсальными, а транспортный слой — заменяемым. Проанализируем ситуацию: оптимальным решением является использование HTTP-запросов. Это позволяет упаковывать данные в формат JSON или XML и передавать их непосредственно в тело запроса. Такой подход работает одинаково стабильно как на мобильных устройствах, так и на стороне 1С.

Архитектура «Шлюза»: Промежуточный сервер между 1С и мобильным устройством

Зачастую базы 1С в магазинах или «ларьках» не опубликованы на веб-серверах и не имеют статического IP-адреса. В таких условиях прямое подключение мобильного приложения к 1С невозможно. Выясним причину: отсутствие публичного адреса у бэк-офиса требует наличия посредника в интернете. Рассмотрим схему работы через «шлюз»:

  1. Внешняя обработка 1С собирает данные о номенклатуре, штрихкодах и остатках, сериализует их в JSON и отправляет POST-запросом на промежуточный сервер.
  2. Промежуточный сервер сохраняет эти данные, присваивая им уникальный идентификатор обмена.
  3. Мобильное приложение по запросу пользователя (или по Push-уведомлению) обращается к серверу по этому же идентификатору и забирает данные методом GET.
  4. После проведения инвентаризации мобильное устройство отправляет результат обратно на сервер, откуда 1С забирает его для загрузки в документы.

Реализация промежуточного сервера на Golang

Для создания быстрого и легкого шлюза отлично подходит язык Golang. Проанализируем пример кода, который реализует генерацию уникальных ID и хранение JSON-файлов для обмена. Этот сервер будет принимать данные от 1С и отдавать их мобильному приложению.


package main
import (
    "encoding/json"
    "fmt"
    "github.com/gorilla/mux"
    "log"
    "net/http"
    "io/ioutil"
    "os"
    "path/filepath"
    "github.com/sethvargo/go-password/password"
)

type ID struct {
    ID string `json:"id"`
}

// Генерация уникального идентификатора для пары 1С-Мобилка
func getNewID(w http.ResponseWriter, r *http.Request) {
    var id ID
    res, _ := password.Generate(10, 5, 0, true, true)
    id.ID = res
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(id)
}

// Сохранение данных (выгрузка из 1С или из мобильного приложения)
func setFile(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    id := params["id"]
    fileType := params["file"]
    
    bData, _ := ioutil.ReadAll(r.Body)
    filename := id + "_" + fileType + ".json"
    ioutil.WriteFile(filename, bData, 0644)
    fmt.Println("Файл сохранен:", filename)
}

// Получение данных
func getFile(w http.ResponseWriter, r *http.Request) {
    params := mux.Vars(r)
    id := params["id"]
    fileType := params["file"]
    filename := id + "_" + fileType + ".json"
    
    data, _ := ioutil.ReadFile(filename)
    w.Header().Set("Content-Type", "application/json")
    w.Write(data)
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/getnewid", getNewID).Methods("GET")
    r.HandleFunc("/users/{id}/files/{file}", setFile).Methods("POST")
    r.HandleFunc("/users/{id}/files/{file}", getFile).Methods("GET")
    log.Fatal(http.ListenAndServe(":1717", r))
}

Этот сервис позволяет 1С отправить файл номенклатуры командой POST /users/ID_ОБМЕНА/files/goods, а мобильному приложению получить его командой GET по тому же адресу.

Реализация выгрузки данных на стороне 1С

Теперь разберем, как подготовить данные в 1С и отправить их на наш сервер. Нам потребуется собрать информацию о товарах (наименование, код, штрихкод) и преобразовать её в строку JSON. Посмотрим на пример кода внешней обработки для конфигурации «Розница 2» или «Управление торговлей»:


&НаСервере
Функция СформироватьДанныеНоменклатурыВJSON()
    
    ЗаписьJSON = Новый ЗаписьJSON();
    ЗаписьJSON.УстановитьСтроку();
    
    // Запрос к базе данных для получения номенклатуры и штрихкодов
    ТекстЗапроса = "ВЫБРАТЬ
                   |    Номенклатура.Наименование КАК Наименование,
                   |    Штрихкоды.Штрихкод КАК Штрихкод,
                   |    Номенклатура.Код КАК Код
                   |ИЗ
                   |    Справочник.Номенклатура КАК Номенклатура
                   |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Штрихкоды КАК Штрихкоды
                   |        ПО Штрихкоды.Владелец = Номенклатура.Ссылка";
    
    Запрос = Новый Запрос(ТекстЗапроса);
    ТаблицаДанных = Запрос.Выполнить().Выгрузить();
    
    МассивОбъектов = Новый Массив();
    Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
        СтруктураТовара = Новый Структура();
        СтруктураТовара.Вставить("Код", СокрЛП(СтрокаТЗ.Код));
        СтруктураТовара.Вставить("Наименование", СокрЛП(СтрокаТЗ.Наименование));
        СтруктураТовара.Вставить("ШК", СокрЛП(СтрокаТЗ.Штрихкод));
        МассивОбъектов.Добавить(СтруктураТовара);
    КонецЦикла;
    
    ЗаписатьJSON(ЗаписьJSON, МассивОбъектов);
    Возврат ЗаписьJSON.Закрыть();
    
КонецФункции

&НаСервере
Процедура ОтправитьДанныеНаСервер()
    
    СтрокаJSON = СформироватьДанныеНоменклатурыВJSON();
    ИдентификаторОбмена = "433zboc6d6"; // Полученный ранее ID
    
    АдресРесурса = "/users/" + ИдентификаторОбмена + "/files/goods";
    
    // Настройка соединения с промежуточным сервером
    HTTPСоединение = Новый HTTPСоединение("ваш-сервер.ru", 1717);
    HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
    HTTPЗапрос.Заголовки.Вставить("Content-type", "application/json");
    HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
    
    Попытка
        Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
        Если Ответ.КодСостояния = 200 Тогда
            Сообщить("Данные успешно выгружены!");
        Иначе
            Сообщить("Ошибка сервера: " + Ответ.КодСостояния);
        КонецЕсли;
    Исключение
        Сообщить("Не удалось установить соединение с сервером.");
    КонецПопытки;
    
КонецПроцедуры

Современные дополнения и рекомендации по улучшению обмена

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

  1. Использование QR-кодов для настройки: Чтобы пользователю не пришлось вручную вводить длинные ID на смартфоне, сформируйте в 1С QR-код, содержащий адрес сервера и ID. Мобильное приложение при первом запуске сканирует код и автоматически настраивает обмен.
  2. Delta-синхронизация: Если справочник товаров содержит более 50 000 позиций, полная выгрузка будет занимать много времени. Рекомендуется использовать ПланыОбмена в 1С, чтобы передавать только измененные или новые товары.
  3. Безопасность данных: Поскольку данные передаются через публичный интернет, обязательно используйте протокол HTTPS. Также стоит добавить простую авторизацию через заголовки запроса (например, API-Key), чтобы посторонние лица не могли получить доступ к вашим файлам по случайно угаданному ID.
  4. Формат Protobuf: Для очень больших объемов данных вместо JSON можно использовать бинарный формат Protocol Buffers. Это значительно сократит объем трафика и ускорит парсинг данных на мобильном устройстве, что критично для бюджетных ТСД (терминалов сбора данных).
  5. Offline-first подход: Мобильное приложение должно сохранять полученные данные в локальную базу (например, SQLite или встроенную базу мобильной платформы 1С). Это позволит кладовщику работать в зонах с плохим приемом Wi-Fi, а синхронизация произойдет автоматически при появлении связи.

Таким образом, мы выяснили, что создание собственного легкого HTTP-шлюза является наиболее универсальным способом организации обмена. Он избавляет от необходимости глубокого вмешательства в типовые конфигурации 1С и обходит ограничения мобильных операционных систем по работе с файлами.

← На главную