本文参考以下文档:
https://blog.csdn.net/qq_36617521/article/details/71215528
https://blogs.sap.com/2013/07/10/read-comm-port-using-abap-wo-third-party-
software/
https://blogs.sap.com/2014/10/02/how-to-registeractivate-activex-component-
mscomm32ocx-on-windows-7/
https://zhidao.baidu.com/question/270542924.html
SAP连接地磅系统,基本原理是使用OLE技术,通过本地系统的MSCOM32.OCX文件,访问COM端口上的设备。地磅相关设备会通过COM端口,将近期的缓存数据,全部通过端口传给计算机。我们需要截取最新的一段数据进行读取。
我们需要注意,设备给我们的数据,是一个近期的缓存,因为车辆货物上称后,有一段时间重量是无法固定下来的。静置片刻后,数字稳定,我们才能读取这个数字。数据波动期间,如果我们监听COM端口,会得到大量数字不停跳动的数据。这些数据是设备近期n次读取到并输出的结果。我们需要的是一次返回最后的那条最新数据。
要想设备通过电脑连接,并让SAP可以读取到数据,我们需要做如下的工作。
第一步:安装MSCOM32.OCX
首先检查直连地磅的计算机,在下面位置有没有这个文件:
32位操作系统检查C:\Windows\System32
64位操作系统检查C:\Windows\SysWOW64
如果没有这个文件,需要百度这个文件并下载,复制到对应的文件夹中
使用管理员模式运行命令提示符。。
根据具体的操作系统,32位操作系统输入 cd C:\Windows\System32 ,64位操作系统输入 cd
C:\Windows\SysWOW64 。
输入regsvr32 MSCOMM32.OCX,回车注册文件。
如果电脑上已经安装并正常使用地磅相关的读取软件,并且系统目录中有MSCOMM32.OCX这个文件,上面的步骤可以跳过。
第二步:注册表注册
WIN+R打开运行,输入regedit,确定,打开注册表编辑器。
定位HKEY_CLASSES_ROOT\Licenses\。如果没有Licenses项,就在HKEY_CLASSES_ROOT下新建一个Licenses项。
检查下面是否存在4250E830-6AC2-11cf-8ADB-00AA00C00905这个项,如果没有就创建,然后修改它的默认值为kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun。
创建完成后,重启电脑。
第三步,配置SAP
打开事务代码SOLE,如下配置:
第四步,代码书写
我们封装一个函数,用来读取或写入参数,具体代码可以见参考程序,我这里着重解释下这里的参数。
这个有个settings参数,是在打开端口读取数据中有使用。
前面的9600,是地磅产品的传输速度,串口通信中通常使用的是异步串口通信,既没有时钟线,所以两个设备要通信,必须要保持一致的波特率。
“N”表示的是无校验位,由于串口通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、
0 校验(space)、1 校验(mark)以及无校验(noparity)。
从说明书我判断是无校验位,测试证明没有猜错
“8”表示的是数据位数为 8 位。
这个说明书是2款产品的通用说明书,数据位数在看到设备机器之前,光凭借说明书是无法判断的
“1”表示的是 1 位停止位,串口通讯的一个数据包从起始信号开始,直到停止信号结束。数据包的起始信号由一个逻辑 0 的数据位表示,而数据包的停止信号可由
0.5、 1、 1.5 或 2 个逻辑 1 的数据位表示,只要双方约定一致即可。
这些参数可以在设备的产品说明书中查询到。
精简版只读DEMO附上。如果身边有设备可以连接COM端口
*&---------------------------------------------------------------------**& Report ZTEST2*&*&---------------------------------------------------------------------**&*&*&---------------------------------------------------------------------*
REPORT ztest2.TYPE-POOLS sabc.TYPE-POOLS ole2 .
PARAMETERS p_com TYPE i DEFAULT 1.PARAMETERS p_set TYPE string DEFAULT '9600,N,8,1'.
START-OF-SELECTION.
DATA balance TYPE string.DATA pos TYPE i.DATA e_output TYPE string.
DATA: o_obj TYPE ole2_object.CLEAR: pos,balance,e_output.
*初始化CALL FUNCTION 'AUTHORITY_CHECK_OLE'EXPORTINGprogram = sy-repidactivity = sabc_act_callapplication = 'MSCOMMLIB.MSCOMM.1'EXCEPTIONSno_authority = 1activity_unknown = 2OTHERS = 3.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.ENDIF.
CREATE OBJECT o_obj 'MSCOMMLib.MSComm.1'.IF sy-subrc <> 0.MESSAGE '创建组件失败' TYPE 'E'.ENDIF.*打开端口SET PROPERTY OF o_obj 'CommPort' = p_com.SET PROPERTY OF o_obj 'Settings' = p_set.SET PROPERTY OF o_obj 'InputLen' = 0.SET PROPERTY OF o_obj 'PortOpen' = 1.
*读取数据DATA: wa_buffer TYPE i,inde TYPE i.DO 70 TIMES.inde = inde + 1.GET PROPERTY OF o_obj 'InBufferCount' = wa_buffer.IF wa_buffer > 0.GET PROPERTY OF o_obj 'Input' = e_output.IF inde < 20."不读取前20条历史记录ELSE.CONCATENATE balance e_output INTO balance.ENDIF.ELSE.EXIT.ENDIF.ENDDO.CLEAR:wa_buffer,inde.*关闭端口SET PROPERTY OF o_obj 'PortOpen' = 0.FREE OBJECT o_obj.CLEAR o_obj.COMMIT WORK.
*数据处理SEARCH balance FOR '+'.IF sy-subrc = 0.pos = sy-fdpos.SHIFT balance BY ( pos + 1 ) PLACES.ENDIF.
SEARCH balance FOR 'g'.IF sy-subrc = 0.pos = sy-fdpos.balance = balance+0(pos).CONDENSE balance NO-GAPS.e_output = balance+2(6)."我这里的地磅确定可以直接读取中间的部分作为结果,再稳妥点就是考虑加入balance+1(1)的正负号判断ENDIF.* COMMIT WORK.