Excel-串口配合工具分享

Excel 作为数据统计的神奇,能非常方便的筛选和生成各种数据
串口作为嵌入式的常见接口,是个板子都会用到

将二者结合起来使用,

  • 方便直观的生成数据
  • 在Excel中点击即可通过串口发送
  • 在Excel中点击即可从串口读回数据

-0- 目录

-1- 缘由

Excel 作为数据统计的神奇,能非常方便的筛选和生成各种数据
串口作为嵌入式的常见接口,是个板子都会用到

将二者结合起来使用,

  • 方便直观的生成数据
  • 在Excel中点击即可通过串口发送
  • 在Excel中点击即可从串口读回数据

-2- 实现路径

在实现上,我绕过了用vba底层实现串口读写,采用更熟悉的编程语言生成串口读写 exe,
在通过 Excel vba 调用 cmd 运行 底层 exe。

这样的实现,相当于可以调用任一语言平台打包的 exe,在 exe 中封装底层,为实现更丰富的功能留下可能。

-3- 实现细节

-3.1- Excel文件的区别

  • 选择 Excel 后缀为 xlsm 支持宏的文件格式
  • alt + F11 打开 vba 编程面板

-3.2- 底层exe实现

  • 这里实现一个最简单串口发送数据
  • 我自己选择的实现平台是 C# net4.0 32bit
    • net4.0 默认支持win7 (目前没有布置win7环境来测试)
    • 我对 c# 相对要熟悉一些
  • 这里加了些编程内容
    • 对串口配置以xml文件的形式保存,在每次点击的时候读入配置,这样的实现只在excel点击时候占用串口
    • 封装了查找当前目录的实现
    • 封装了串口配置的序列化和反序列化
    • 对串口open失败的可能做了处理,但没有打印失败信息,为从串口读值留下打印信息

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Program
{
private static MySerialPort _serialPort;
private static ServiceConfigModel _serviceConfigModel;
static void Main(string[] sss)
{
byte[] result = CommonTool.HexStringToByteArray(sss[0]);
if (result == null)
{
return;
}
string path = CommonTool.GetDirectory() + @"\ConsoleAppConfig.xml";
_serviceConfigModel = new ServiceConfigModel();
_serviceConfigModel = SerializeTool<ServiceConfigModel>.ReadXML(path);
_serialPort = new MySerialPort();
_serialPort.ConfigService(_serviceConfigModel.PortName, _serviceConfigModel.ConfigDates);

try
{
_serialPort.Open();
_serialPort.Write(result, 0, result.Length);
_serialPort.Close();
}
catch
{
_serialPort = null; // 其实这个没必要,当总要放点啥在这才安心
}
}
}

代码就是一个很简单的控制台程序

-3.3- Excel的命令行调用

这个实现是对比了几种实现,搜了好一通才找到了,目前这种实现基本满意,唯一的不好的地方是 cmd 窗口会弹一下,目前把它当成有没有成功调用的提醒

在 excel vba 中添加一个模块,注意是添加一个模块
键入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Public Sub SendStringNoRead(abc As String)
Dim strProgramName As String
strProgramName = Application.ActiveWorkbook.Path & "\ConsoleApp.exe " & abc
ShellRun (strProgramName)
End Sub

'网上搜到的实现
Public Function ShellRun(sCmd As String) As String

'Run a shell command, returning the output as a string

Dim oShell As Object
Set oShell = CreateObject("WScript.Shell")

'run command
Dim oExec As Object
Dim oOutput As Object
Set oExec = oShell.Exec(sCmd)
Set oOutput = oExec.StdOut

'handle the results as they are written to and read from the StdOut object
Dim s As String
Dim sLine As String
While Not oOutput.AtEndOfStream
sLine = oOutput.ReadLine
If sLine <> "" Then s = s & sLine & vbCrLf
Wend

ShellRun = s

End Function

SendStringNoRead这个函数的功能是

  • 接收单击单元格的值-就是输入参数
  • 给出 exe 的路径 并把 命令行参数拼上去
  • 调用函数 ShellRun 实现exe执行

-3.4- Excel单击发送的实现

  • 在对应的 Sheet对象上双击
  • 选择 Worksheet 中的 SelectionChange

键入下面的代码

1
2
3
4
5
6
7
8
9
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 11 Then
If Target.Count = 1 Then
If Target.Value <> "" Then
SendStringNoRead (Target.Value)
End If
End If
End If
End Sub

要解释一下,这几个if

  • Target.Column = 11 选择的 第11列
  • Target.Count = 1 筛出单个格子点击的情况
  • Target.Value <> “” 单个格子的内容不为空

tip:这里有个地方,命令行是以空格分割参数的,我不想再往字符串上加双引号,所以Excel生成的命令不能有空格(这个可以在 Excel 中观察到)

-4- 往后的方向

  • 加入可配置的读串口
  • 加入 modbus 协议
  • 等等,待更新

-5- 测试指南

建议先通过虚拟串口,用命令行中测试 exe 能否使用

假设有两个直连的串口 COM2 <—-> COM1

在命令行中

1
2
3
//xml中配置 COM2
>ConsoleApp.exe A55A0582036B0001
>_

在另一个串口调试器中连接 COM1

1
[10:28:27.789]收←◆A5 5A 05 82 03 6B 00 01 

测试文件下载 – 文件是在实际的文件中简化的,所有不用奇怪 Excel 的空格
另外有异常报告可以留言

test.zip