Как считать данные весов удаленно через COM-объект в 1С

Программист 1С v8.3 (Управляемые формы) Промышленность, строительство и АПК
← На главную

В практике автоматизации складского и производственного учета часто возникает задача получения данных с весоизмерительного оборудования, которое подключено к другому компьютеру. Если локально весы работают через стандартную библиотеку Controller.ScAuto, то при попытке достучаться до них по сети возникают сложности. В этой статье мы подробно разберем, как решить задачу удаленного считывания веса, проанализируем различные архитектурные подходы — от классического DCOM до создания современного HTTP-шлюза.

Проблема прямого обращения через COM по сети

Стандартный подход 1С для работы с COM-объектами предполагает использование конструкции Новый COMОбъект("ИмяОбъекта"). Для удаленной работы существует расширенный синтаксис Новый COMОбъект("ИмяОбъекта", "ИмяУдаленногоКомпьютера"). Однако на практике этот метод крайне нестабилен по следующим причинам:

  1. Сложность настройки DCOM: Требуется глубокая настройка прав доступа в dcomcnfg на обеих машинах.
  2. Безопасность: Системные администраторы часто блокируют порты, необходимые для работы RPC и DCOM, из-за их уязвимости.
  3. Версионность: Программное обеспечение весов (например, Controller Free) может быть не предназначено для сетевых вызовов в своей базовой версии.
  4. Зависимости: Библиотека ScAuto.dll должна быть корректно зарегистрирована в реестре обеих операционных систем.

Рассмотрим более надежные и современные способы решения этой задачи.

Способ 1. Создание легковесного HTTP-сервиса на Golang

Это один из самых эффективных методов. Мы создаем маленькую программу-посредника (exe-файл), которая запускается на компьютере с физически подключенными весами. Она будет «слушать» определенный порт и при обращении через обычный браузер или 1С возвращать текущий вес. Рассмотрим процесс создания такой «обертки» на языке Go.

Для начала нам потребуется установить среду Go и загрузить библиотеку для работы с OLE. Выполним в консоли следующие команды:


go get github.com/go-ole/go-ole
go get github.com/go-ole/go-ole/oleutil

После этого создадим файл main.go со следующим кодом, который инициализирует COM-объект весов и отдает результат по HTTP:


package main

import (
    "fmt"
    "net/http"
    "github.com/go-ole/go-ole"
    "github.com/go-ole/go-ole/oleutil"
)

func getWeightHandler(w http.ResponseWriter, r *http.Request) {
    // Инициализируем COM для текущего потока
    ole.CoInitialize(0)
    defer ole.CoUninitialize()

    // Создаем объект контроллера весов
    unknown, err := oleutil.CreateObject("Controller.ScAuto")
    if err != nil {
        http.Error(w, "Ошибка создания COM-объекта: "+err.Error(), 500)
        return
    }
    
    terminal, _ := unknown.QueryInterface(ole.IID_IDispatch)
    defer terminal.Release()

    // Вызываем метод GetWeight(1, 1), как в документации Тензо-М
    result, err := oleutil.CallMethod(terminal, "GetWeight", 1, 1)
    if err != nil {
        http.Error(w, "Ошибка получения веса: "+err.Error(), 500)
        return
    }

    weightStr := result.ToString()
    fmt.Println("Считанный вес:", weightStr)
    
    // Отправляем результат клиенту
    w.Write([]byte(weightStr))
}

func main() {
    http.HandleFunc("/getweight", getWeightHandler)
    fmt.Println("Сервис запущен на порту 8080...")
    http.ListenAndServe(":8080", nil)
}

Разберем, что происходит в коде. Мы импортируем пакеты для работы с сетью и OLE. Функция getWeightHandler выполняет ту же логику, что и ваш код на 1С, но локально на ПК с весами. Теперь достаточно скомпилировать этот код в exe файл командой go build main.go и запустить его.

Теперь в 1С на удаленном компьютере нам не нужен COM-объект. Мы используем HTTPСоединение:


&НаКлиенте
Процедура ПолучитьВесУдаленно(Команда)
    Соединение = Новый HTTPСоединение("ИмяКомпаСВесами", 8080);
    Запрос = Новый HTTPЗапрос("/getweight");
    
    Попытка
        Ответ = Соединение.Получить(Запрос);
        Если Ответ.КодСостояния = 200 Тогда
            Вес = Ответ.ПолучитьТелоКакСтроку();
            Сообщить("Текущий вес: " + Вес);
        Иначе
            Сообщить("Ошибка сервиса: " + Ответ.КодСостояния);
        КонецЕсли;
    Исключение
        Сообщить("Не удалось связаться с ПК весов");
    КонецПопытки;
КонецПроцедуры

Способ 2. Использование HTTP-сервиса внутри 1С

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

Разберем последовательность действий:

  1. Создадим в конфигурации новый объект HTTP-сервис (например, с именем ScalesData).
  2. Добавим шаблон URL /weight и метод GET.
  3. В обработчике метода пропишем локальное обращение к COM-объекту:

Функция weightGET(Запрос)
    Попытка
        Терминал = Новый COMОбъект("Controller.ScAuto");
        Вес = Терминал.GetWeight(1, 1);
        
        Ответ = Новый HTTPСервисОтвет(200);
        Ответ.УстановитьТелоИзСтроки(Строка(Вес));
        Возврат Ответ;
    Исключение
        Возврат Новый HTTPСервисОтвет(500);
    КонецПопытки;
КонецФункции

Этот способ хорош тем, что вся логика остается внутри экосистемы 1С. Однако он требует наличия лицензии 1С на клиентском ПК и настроенного веб-сервера (Apache или IIS).

Способ 3. Виртуальный COM-порт через Ethernet

Проанализируем ситуацию, когда мы хотим использовать оригинальную библиотеку ScAuto.dll прямо на рабочем месте программиста, но весы подключены к другому ПК. Для этого существуют программы-трансляторы (например, HW VSP или TCP2COM).

Алгоритм настройки выглядит так:

  1. На ПК с весами запускается «сервер порта», который перехватывает данные с физического COM1 и транслирует их в сеть по TCP-протоколу.
  2. На рабочем ПК устанавливается драйвер виртуального COM-порта, который подключается к IP-адресу первого ПК.
  3. В системе появляется новый COM3 (виртуальный), который ведет себя так, будто весы подключены в соседнее гнездо.
  4. В 1С вы продолжаете использовать локальный вызов: Терминал.GetWeight(1, 1), где параметры указывают на ваш виртуальный порт.

Рекомендации по стабильности и безопасности

При работе с весовым оборудованием важно учитывать несколько технических нюансов, которые помогут избежать зависания системы:

Обработка таймаутов: Весы могут не ответить вовремя, если они заняты самодиагностикой или передачей данных. Всегда ограничивайте время ожидания ответа в HTTPСоединение параметром Таймаут (например, 5-10 секунд).

Многопоточность: Если к одним весам обращаются сразу несколько пользователей, библиотека Controller.ScAuto может выдать ошибку блокировки порта. В случае с HTTP-шлюзом на Go или 1С, рекомендуется реализовать простую очередь запросов или кеширование значения веса на 500 миллисекунд.

Безопасность: Если вы используете решение с самописным exe файлом, обязательно настройте Windows Firewall так, чтобы порт (например, 8080) был доступен только для конкретных IP-адресов вашей подсети. Это предотвратит несанкционированный доступ к оборудованию.

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

← На главную