Читаем COM-порт в 1C с помощью Delphi .Net
Привет всем обитателям сего сайта =) давнеько я уже ничего не писал, вот наконец выдалось свободное время.
В настоящее время широкое изобилее языков программирования и сред разработки просто пугает, и прогер решает чем пользоваться чтоб выполнить ту или иную задачу.
но бывает что возникают ситуёвины когда функциональности языка нехватает для решения задачи, ну не начинать же всё заново в другой среде О_о?
была у мня как то роботёнка: нужно было написать сервис который бы читал память внешнего устройства (подключеного черз COM), и писал данные в БД Access (всё прошло на ура).
Через пол года заказчик обратился ко мне с просьбой переделать сервис так чтобы писал он полученные данные не в Access а в таблицы 1С.
Тут то я и грузанулся как в 1С читать Com порт О_о (сервис я писал на Delphi)? Первое что пришло в голову сделать DLL в которой бы были функции для работы с девайсом, но потом появилась идея лучше На помощь пришла технологи .NET, а именно Web-сервисы созданные на платформа Net.
всё ремя пользовался Delphi 7, но тут никуда не денишся пришлось иди в ногу со временем, вощем установил я себе Borland Developer Studio 2006 (BDS) и в перёд.
Код до его модернизации выглядел приблизительно так:
Код:
type
TRec = record //объекты этого типа нам необходимо будет передават потом в 1С
DT: TDateTime; //время события
ch1: integer; //два свойства события...
ch2: integer;
end;
function GetData(Sector: integer): TRec;
var
FBuf: array [0..7] of byte;
FHandle: DWord;
FCount: cardinal;
FOverlapped: TOverlapped;
....
procedure WriteGetData(SectorNo: word);//отправка команды устройству
begin
FBuf[0] := $01; // команда для чиения данных
FBuf[1] := SectorNo;// в каестве параметра передаём номер сектора
Windows.WriteFile(FHandle, Fbuf, 2, FCount, @FOverlapped); // отправляем команду на ком порт
end;
finction ReadGetData: TRec; //чтение результата с устройства в масив FBuf
var
y, m, d, h, m, s: word;
begin
Windows.ReadFile(FHandle, Fbuf, 8, FCount, @FOverlapped); //читаем ответ устройства
y := Fbuf[0];
m := Fbuf[1];
d := Fbuf[2];
h := Fbuf[3];
m := Fbuf[4];
s := Fbuf[5];
result.DT := EncodeDateTime(y, m, d, h, m, s, 0); //возвращаем результат в удобном, красивом виде
result.ch1 := Fbuf[6];
result.ch2 := Fbuf[7];
end;
function GetData(Sector: integer): TRec; //функция которой будет пользоваться 1С
begin
WriteGetData(Sector);
result := ReadGetData;
end;
теперь нам предстоит модернизировать всё это дело под веб сервис с помощью .net
Код:
//в uses добавились модули net
uses {.NET MODULS}
System.Collections,
System.ComponentModel,
System.Data,
System.Diagnostics,
System.Web,
System.Web.Services,
Borland.Vcl.SysUtils,
Borland.Vcl.Variants,
//типы и переменные остаються теми же
type
TRec = record //объекты этого типа нам необходимо будет передават потом в 1С
DT: TDateTime; //время события
ch1: integer; //два свойства события...
ch2: integer;
end;
[WebMethod] //объявляем этот метов вебом... т.е. чтобы он был доступен
function GetData(Sector: integer): TRec;
{ВСЁ ОСТАЛЬНОЕ ТАК ЖЕ... ЬЕЗ КАКИХ ЛИБО ИЗМЕНЕНИЙ}
теперь запускаем веб сервис, и уже можно обращяться к нему ... открываеи браузер пищем свой локальный адрес 127.0.0.1
и вуаля... что мы видим, а видим мы тот самый метод... и даже можеи его вызывать, мало того, так ещё и ответ в XML-ке получаем.
вот так вот мы и примирили RS-232 и HTTP. но как вы помните задача первонапчальная стояла совсем другая...
вот код 1С для обращения к веб сервису
Код:
Определения = Новый WSОпределения(АдресВебСервиса);
ВебПрокси = Новый WSПрокси(Определения, Определения.Сервисы[0].URIПространстваИмен,Определения.Сервисы [0].Имя,Определения.Сервисы[0].ТочкиПодключения[0].Имя);
Результат = ВебПрокси.GetData(Номер сектора);
//обращаемся к методу веб сервиса
//и получаем результат типа TRec т.к. типы которые используются веб сервисом
//импортируються в 1С автоматически.
Итог
в итоге мы получаем следующую картину: 1С общаеться с внешним устройством (подключеным к ком порту) через веб сервис, это даёт возможность работать с данным устройством всем рабочим станциям в сети (но при этом в коде после обращения к девайсу нужно закрывать ком порт)