Excel VBA InputBox读取QR码时丢失ASCII 29控制字符如何解决
系统自带的InputBox是面向普通可打印文本输入场景封装的标准对话框,默认会自动过滤ASCII码值小于32的非打印控制字符——你提到的ASCII 29(GS组分隔符)就在过滤列表里,从设计上它就不适合接收带控制字符的扫码枪原始数据,不存在简单的配置开关可以关掉这个过滤逻辑。
方案1:监听原始键盘输入(零额外成本,适配绝大多数场景)
市面绝大多数扫码枪默认工作在HID键盘模拟模式,本质是将扫码得到的内容逐字符模拟键盘按键输入。你不需要调用InputBox,只需要在界面上放一个保持输入焦点的文本框(甚至可以把文本框隐藏掉,不影响交互),直接监听控件的KeyPress事件逐字符拼接输入内容,所有非打印控制字符都会被完整捕获,不会被过滤。
- 实现要点:
- 提前确认扫码枪的结束符配置,绝大多数设备默认扫码完成后会自动输入回车(ASCII 13),你只要在
KeyPress事件里检测到回车字符,就代表一整段二维码内容接收完成,可以进入后续处理流程 - 字符拼接过程不要加任何过滤逻辑,接收完成后直接用ASCII 29作为分隔符拆分字符串即可得到所有单独参数,以VB语法为例,其他语言逻辑完全一致:
' rawScan为逐字符拼接得到的完整扫码原始内容 Dim paramList As String() = rawScan.Split(ChrW(29))
- 提前确认扫码枪的结束符配置,绝大多数设备默认扫码完成后会自动输入回车(ASCII 13),你只要在
方案2:切换扫码枪为Raw/串口通信模式(稳定性最高)
如果使用场景对扫码可靠性要求高,可以直接把扫码枪的工作模式从HID键盘模拟切换到串口(COM)通信或者HID Raw模式,直接通过系统API读取扫码枪返回的原始字节流。这种模式下数据完全不经过系统标准输入控件的处理链路,所有控制字符、特殊二进制内容都会100%保留,完全不存在字符被过滤的问题。
- 实现要点:
- 模式切换不需要改硬件,参考对应品牌扫码枪的说明书,扫描对应的配置码即可完成切换
- 如果用串口模式,通信参数要和扫码枪配置保持一致,绝大多数设备默认参数为
9600波特率、8数据位、无校验、1停止位
方案3:自定义输入弹窗替换系统InputBox
如果业务上必须用弹窗式的输入交互,不要调用系统自带的InputBox,自己做一个极简弹窗窗体,窗体内放置一个默认获取焦点的文本框,关闭文本框所有自动格式化、内容过滤的相关配置,同样通过KeyPress事件逐字符接收原始输入,检测到扫码结束符后自动返回拼接完成的完整字符串即可,交互体验和系统InputBox完全一致,同时支持保留所有控制字符。
不要尝试用全局Hook、修改系统控件参数的方式强行让系统InputBox保留控制字符,这类方案兼容性极差,不同Windows版本的InputBox底层过滤逻辑不一致,后续系统更新就可能失效,维护成本极高。
内容的提问来源于stack exchange,提问作者Thomas

