В практике автоматизации складского и производственного учета часто возникает задача получения данных с весоизмерительного оборудования, которое подключено к другому компьютеру. Если локально весы работают через стандартную библиотеку Controller.ScAuto, то при попытке достучаться до них по сети возникают сложности. В этой статье мы подробно разберем, как решить задачу удаленного считывания веса, проанализируем различные архитектурные подходы — от классического DCOM до создания современного HTTP-шлюза.
Стандартный подход 1С для работы с COM-объектами предполагает использование конструкции Новый COMОбъект("ИмяОбъекта"). Для удаленной работы существует расширенный синтаксис Новый COMОбъект("ИмяОбъекта", "ИмяУдаленногоКомпьютера"). Однако на практике этот метод крайне нестабилен по следующим причинам:
dcomcnfg на обеих машинах.ScAuto.dll должна быть корректно зарегистрирована в реестре обеих операционных систем.Рассмотрим более надежные и современные способы решения этой задачи.
Это один из самых эффективных методов. Мы создаем маленькую программу-посредника (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 Тогда
Вес = Ответ.ПолучитьТелоКакСтроку();
Сообщить("Текущий вес: " + Вес);
Иначе
Сообщить("Ошибка сервиса: " + Ответ.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Не удалось связаться с ПК весов");
КонецПопытки;
КонецПроцедуры
Если на компьютере с весами уже установлена 1С (даже в файловом варианте), можно обойтись без сторонних языков программирования. Мы можем опубликовать небольшой HTTP-сервис прямо из 1С.
Разберем последовательность действий:
ScalesData)./weight и метод GET.
Функция weightGET(Запрос)
Попытка
Терминал = Новый COMОбъект("Controller.ScAuto");
Вес = Терминал.GetWeight(1, 1);
Ответ = Новый HTTPСервисОтвет(200);
Ответ.УстановитьТелоИзСтроки(Строка(Вес));
Возврат Ответ;
Исключение
Возврат Новый HTTPСервисОтвет(500);
КонецПопытки;
КонецФункции
Этот способ хорош тем, что вся логика остается внутри экосистемы 1С. Однако он требует наличия лицензии 1С на клиентском ПК и настроенного веб-сервера (Apache или IIS).
Проанализируем ситуацию, когда мы хотим использовать оригинальную библиотеку ScAuto.dll прямо на рабочем месте программиста, но весы подключены к другому ПК. Для этого существуют программы-трансляторы (например, HW VSP или TCP2COM).
Алгоритм настройки выглядит так:
COM1 и транслирует их в сеть по TCP-протоколу.COM3 (виртуальный), который ведет себя так, будто весы подключены в соседнее гнездо.Терминал.GetWeight(1, 1), где параметры указывают на ваш виртуальный порт.При работе с весовым оборудованием важно учитывать несколько технических нюансов, которые помогут избежать зависания системы:
Обработка таймаутов: Весы могут не ответить вовремя, если они заняты самодиагностикой или передачей данных. Всегда ограничивайте время ожидания ответа в HTTPСоединение параметром Таймаут (например, 5-10 секунд).
Многопоточность: Если к одним весам обращаются сразу несколько пользователей, библиотека Controller.ScAuto может выдать ошибку блокировки порта. В случае с HTTP-шлюзом на Go или 1С, рекомендуется реализовать простую очередь запросов или кеширование значения веса на 500 миллисекунд.
Безопасность: Если вы используете решение с самописным exe файлом, обязательно настройте Windows Firewall так, чтобы порт (например, 8080) был доступен только для конкретных IP-адресов вашей подсети. Это предотвратит несанкционированный доступ к оборудованию.
Выбор конкретного метода зависит от ваших навыков. Если вы знакомы с веб-технологиями, создание HTTP-шлюза на Go обеспечит наилучшую производительность и независимость от настроек DCOM. Если же вы хотите оставаться в рамках 1С, используйте HTTP-сервисы платформы или виртуализацию портов. Для интеграции популярного весового оборудования без написания кода с нуля можно применить готовое решение для работы с весами Штрих-Принт напрямую через драйвер.