VBA中将字符串赋值给自定义类型字节数组报错,求助网络连接继电器模块
问题解决:VBA中网络连接继电器模块的代码修正
你的核心问题出在两个地方:
- VBA不支持VB.NET的
System.String.Copy方法,这是.NET框架专属API DAPI_OPENMODULEEX_STRUCT的address是Byte数组类型,不能直接赋值字符串,必须把IP地址字符串转换成ASCII字节数组填充进去
完整修正代码:
' 64位Office声明,32位版本去掉PtrSafe Public Declare PtrSafe Function DapiOpenModuleEx Lib "DELIB64" (ByVal moduleID As Long, _ ByVal nr As Long, ByRef exbuffer As DAPI_OPENMODULEEX_STRUCT, ByVal open_options As Long) As LongPtr ' 本地定义结构体,无需引用外部库类型 Public Type DAPI_OPENMODULEEX_STRUCT address(255) As Byte timeout As Long portno As Long encryption_type As Long encryption_password(31) As Byte End Type ' 辅助函数:将字符串转为ASCII字节数组并填充到目标数组 Private Sub StringToByteArray(ByVal inputStr As String, ByRef targetArray() As Byte) Dim i As Integer Dim strBytes() As Byte ' VBA字符串默认是Unicode,转ASCII字节数组 strBytes = StrConv(inputStr, vbFromUnicode) ' 清空目标数组原有内容 For i = LBound(targetArray) To UBound(targetArray) targetArray(i) = 0 Next i ' 填充转换后的字节 For i = 0 To UBound(strBytes) If i > UBound(targetArray) Then Exit For targetArray(i) = strBytes(i) Next i End Sub ' 连接网络继电器模块的主逻辑 Sub OpenEthRelayModule() Dim handle As LongPtr ' 64位Office用LongPtr,32位用Long Dim MyModuleID As Long MyModuleID = 42 Dim open_buffer As DAPI_OPENMODULEEX_STRUCT Dim ipAddress As String ipAddress = "192.168.1.1" ' 将IP字符串填充到address字节数组 StringToByteArray ipAddress, open_buffer.address open_buffer.portno = 0 ' 使用默认端口,有指定端口则修改此处 open_buffer.timeout = 5000 ' 自定义超时时间(毫秒) open_buffer.encryption_type = 0 ' 无加密,需加密则按厂商要求设置 ' 调用打开模块函数 handle = DapiOpenModuleEx(MyModuleID, 0, open_buffer, 0) ' 根据厂商文档判断返回值是否成功,示例以非0为成功 If handle <> 0 Then MsgBox "模块连接成功,句柄:" & handle Else MsgBox "模块连接失败" End If End Sub
关键修改点说明:
- 结构体定义:直接在VBA代码内定义
DAPI_OPENMODULEEX_STRUCT,避免外部类型引用的兼容性问题 - 字符串转字节数组:用VBA原生的
StrConv将Unicode字符串转为ASCII字节数组,再填充到address数组,同时清空多余位置为0,符合C风格字符串要求 - 函数声明适配:64位Office必须添加
PtrSafe,返回值用LongPtr保证跨版本兼容性;32位版本可去掉PtrSafe,返回值改用Long - 移除.NET专属代码:彻底删除
System.String.Copy相关语句,改用VBA原生方法处理字符串
内容的提问来源于stack exchange,提问作者Mark De Meyere
相关产品推荐
相关产品推荐

