ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Microsoft Barcode控件实战:Access/VB6/.NET条码打印与避坑

Microsoft Barcode控件实战:Access/VB6/.NET条码打印与避坑 干这行十几年我给企业做过不少进销存、MES、资产管理这类系统几乎每次都会碰到同一个需求要打条码。早期我图省事直接用条码字体结果被扫描枪识别率坑得够呛。后来换成了 Microsoft Barcode 控件一次性把标签打印、单据编号、扫码校验全捋顺了。如果你现在也在 Access、VB6 或者老一点的 .NET 项目里折腾条码这篇内容应该能帮你少走不少弯路。这个控件不是啥新东西它是微软提供的 ActiveX/COM 组件最常见的就是 Microsoft BarCode Control 9.0 和 15.0 两个版本文件名叫 MSBCODE9.OCX。把它拖到窗体或报表上设置好编码内容和码制它就能直接画出可打印的条码不用装字体不用调字形校验位也是自动处理。对内部管理系统这种场景来说属于性价比极高的方案。下面我把控件的设计思路、核心属性、三种主流环境的集成步骤还有我踩过的坑一次性讲透。1. 这个控件到底解决什么问题1.1 它和条码字体有什么区别很多新手一上来就搜“条码字体”觉得给文本框套个 3 of 9 Barcode 字体就完事了。确实这种方式在屏幕上看着像条码但实际打印后问题一大堆字体缩放导致条空比例失真、扫描枪不识别、不同电脑没装字体直接显示成一堆乱码、EAN-13 这类码制还要自己算校验位。做开发最怕的就是这种“看着能用生产环境掉链子”的方案。Microsoft Barcode 控件不一样它的本质是 ActiveX 组件直接在容器里绘制条码图形。你给它一个值它按照对应码制的编码规则把字符翻译成条和空并且自动处理校验位、静区、条空比例这些问题。我最早用它的场景是在 Access 进销存里给单据打条码仓库那边拿扫描枪一扫单据号直接进系统又快又稳。1.2 典型业务场景根据我接触过的项目这几个场景最常用到这个控件工厂出入库单据给单号生成条码贴在单据角落仓库扫描调单。固定资产标签资产编号用 Code 128 打出来贴设备上盘点时一扫就知道是哪台。商品价签和样品标签零售或者质检场景生成 EAN-13 或者 UPC 码。图书、档案、试剂管理用 Code 39 或者 Codabar存量大、结构简单。这些场景的共同点是数据量不大几千条到几万条但对稳定性要求高而且大多跑在内部网络或离线环境里。用服务器生成图片再打印的方案在这个体量下反而折腾。ActiveX 控件直接在客户端生成零服务器压力。1.3 老控件为什么还值得学有人可能会问现在都 Web 时代了还在搞 ActiveX 是不是过时了现实情况是大量企业内部系统还在用 Access 数据库 VBA或者 VB6 写的遗留工具在产线上跑了十几年。这类系统不会轻易重写而往里面加条码能力最靠谱的就是继续用 COM 组件。我这两年接的几个维护项目全是在老系统上新增条码标签打印用的就是这个控件。所以它一点不过时反而因为文档少、坑多谁先踩平了谁就吃香。2. 核心属性与码制选型2.1 属性页里那些选项到底什么意思把这个控件放到窗体上之后右键属性会看到一个“自定义”按钮点开就是它的属性页。这里面的每一项都有讲究我逐个说下Style码制选择这是最重要的一项。不同版本里数字对应的码制不完全一样所以最好在属性页的下拉列表里选不要凭记忆填数字。Value要编码的字符串。在 Access 里如果绑定了“控件来源”这里的 Value 就会被忽略以字段值为准。ShowText是否在条码下方显示人可读的字符。一般打标签我都会打开方便人眼核对。Direction方向0 是水平1 是垂直。垂直条码对手持扫描枪不友好默认水平就好。LineWeight条码中最细线条的宽度单位是英寸常见默认值是 0.01 左右。这个值直接决定打印清晰度太小了扫描枪容易罢工。LineLength条码区域的长度约束。这个值如果设置得小于条码实际宽度条码可能会被截断。2.2 码制选择对照表码制选错是很多新手的第一个坑。我整理了一张表你按场景对着选就行码制支持的字符典型场景备注Code 128全部 ASCII 字符、混合字符物流、单据、资产编号自带校验密度高我个人最推荐Code 39大写字母、数字、部分符号企业内部编码、库存不需要校验位长度不限简单可靠EAN-1313 位数字零售商品条码校验位控件自动算传 12 位即可EAN-88 位数字小包装商品空间有限时很管用UPC-A / UPC-E数字北美零售场景国内用得少Interleaved 2 of 5偶数位数字仓储、配送箱号要求长度固定密度高但容错性一般Codabar数字和少量符号血库、图书、快递老场景还在用我一直跟别人说凡是拿不准的闭眼选 Code 128。它的字符覆盖范围广密度比 Code 39 高而且校验位自动算打印出来占地方小扫描识别也快。2.3 条码尺寸怎么估算很多时候标签就这么大条码打多大得提前算清楚。我在实际项目里总结了一个简单粗暴的估算方法以 Code 39 为例Code 39 每个字符占 9 个模块宽度5 条 4 空字符之间还要加一个模块宽度的间隔。所以编码 N 个字符时整个条码的模块数大约是(N 2) * 12这里加 2 是因为起始符和终止符都是星号。然后总宽度等于模块数乘以 LineWeight。举个例子编码ABC123一共 6 个字符模块数就是(6 2) * 12 96。如果 LineWeight 设为 0.01 英寸条码本体大约 0.96 英寸宽。左右两侧还要预留静区也就是条码前后至少 10 倍模块宽度的空白约 0.1 英寸。这样算下来大概需要 1.16 英寸也就是不到 3 厘米。如果你的标签只有 2 厘米宽那就得把 LineWeight 降一点或者改用 Code 128。这里有个经验之谈LineWeight 不要低于 0.008 英寸。我用 200dpi 热敏打印机测试过低于这个值最小模块的宽度连一个打印点都覆盖不住打出来就是一团黑糊糊扫描枪基本瞎了。3. 从注册到集成三种主流环境的实操步骤3.1 先把 OCX 注册好这个控件说到底是一个 COM 组件系统里没有注册信息程序就创建不了它。常见文件就是 MSBCODE9.OCX一般在C:\Windows\SysWOW64\32 位或者C:\Windows\System32\64 位目录下。注册方法很简单管理员权限打开命令行执行regsvr32 C:\Windows\SysWOW64\MSBCODE9.OCX如果提示成功那就可以去项目里引用了。如果提示“模块已加载但找不到入口点”多半是位数不匹配你用了 64 位的 regsvr32 去注册 32 位的 OCX或者反过来。这个坑我见过好多次。另外提醒一句如果你装的是 64 位 Office有些版本的 Microsoft BarCode Control 可能会找不到或者属性页打不开。我的经验是在 Access 里用这个控件用 32 位 Office 最省心兼容性最好。3.2 在 Access 窗体/报表中使用Access 是这个控件最常用的容器。操作路径是打开窗体或者报表的设计视图找到“插入”或“ActiveX 控件”在弹出的列表里选择 Microsoft BarCode Control 15.0然后在画布上拖出合适大小。最经典的用法是直接绑定字段。在报表里选中条码控件属性表里找到“控件来源”填上表里的编号字段。这样打印多条记录时每条记录都会自动生成自己的条码一行代码都不用写。如果是未绑定的情况比如在窗体上做一个动态条码可以在 VBA 里这样写Private Sub Form_Load() With Me.Barcode0.Object .Style 2 Code 128 .Value PO-2025-001 .ShowText True .LineWeight 0.012 End With End Sub有个细节要注意Drive美其名曰“Object”。在 Access 里通过控件名.Object才能拿到 COM 组件的接口直接写Me.Barcode0.Style会报错。这个我一开始也迷糊过。3.3 在 VB6 / VBA 中编程使用在 VB6 里先通过“部件”对话框勾选 Microsoft Barcode Control 9.0然后工具箱里就能看到它了。拖到窗体上之后代码写起来很直接Private Sub Form_Load() Barcode1.Style 2 Barcode1.Value ASSET-2025-0087 Barcode1.ShowText True Barcode1.Direction 0 Barcode1.LineWeight 0.01 Barcode1.LineLength 2 End Sub这里的 LineLength 是条码区域的上限长度如果你知道值比较短可以适当调小如果值可能会很长就留大一些否则条码会显示不全。我一般设成 2 英寸覆盖绝大多数场景。3.4 在 .NET WinForms 中引入 COM 控件.NET 项目里用这个控件稍微绕一点。打开工具箱在空白处右键选择“选择项”切到“COM 组件”选项卡勾选 Microsoft Barcode Control 9.0。确定之后工具箱里会多出一个AxBarcode控件拖到窗体上就能用了。C# 里的设置和 VB6 大同小异private void Form1_Load(object sender, EventArgs e) { axBarcode1.Style 2; axBarcode1.Value 20250228-001; axBarcode1.ShowText true; axBarcode1.LineWeight 0.01; }注意一点这个 OCX 通常按 32 位注册所以在 VS 里要把项目平台目标改成 x86否则在 64 位系统上运行时会报“ActiveX 控件不能创建对象”的错。如果你的目标机器是 64 位 Windows发布时也别忘了带上Interop.Barcode和AxInterop.Barcode这两个 DLL并且目标机器上要注册好 OCX。发布这一环最容易漏。4. 打印与识别是真正出问题的地方4.1 DPI 与条宽设置屏幕上看不清楚的条码打印出来反而能扫屏幕上清晰的条码打印出来未必好用。这个反直觉的现象根子在打印分辨率和条空比例的匹配上。条码的每个模块宽度最好不小于打印设备的 2 个物理点1 个点是底线。200dpi 的打印机1 个点是 0.005 英寸所以你设置 LineWeight 为 0.01 英寸就是 2 个点这个值是安全的。如果打印机是 300dpi0.008 英寸也能勉强到 2.4 个点但不太建议把余量卡那么死。还有一点Access 报表在打印时可能会做缩放。如果你不小心设置了“打印到合适大小”或者报表宽度和纸张宽度不匹配条码会被整体缩放。缩放不是整数倍时计算机只能四舍五入地取整点条空比例就会变形。所以做标签报表一定要 1:1 设计纸张大小和报表宽度严格对应不要依赖缩放。4.2 扫描枪不识别怎么排查扫描枪不识别条码原因通常是这几条按概率从高到低排查码制没开很多扫描枪默认只开 EAN/UPC 和 Code 128Code 39 可能没启用或者启用了但关闭了校验位设置。用枪的说明书或者设置码打开对应码制。内容字符集不对比如 Code 39 不支持小写字母你把小写字母传进去有的版本会自动转大写有的版本直接画一个无效条码。最好在代码里先做校验。条码模糊或缺线拿手机微距拍一下条码看看边缘是否毛糙、白条里有没有黑点。这种情况一般是打印头的脏污或者碳粉/热敏纸质量差。激光打印机碳粉不足时特别容易出现白线。静区不够条码左右没有留空白扫描枪无法定位条码的起始和结束。我见过有人把条码贴到标签纸边缘怎么扫都失败。方向不对Direction 设为 1 的垂直条码手持枪默认角度识别不了。需要配置扫描枪支持大角度旋转。从实操来看10 条不识别里有 7 条是因为静区不够、条码太小或打印模糊3 条是码制没设置好。先把这几点检查完再怀疑控件。4.3 批量打印标签的实战建议做批量打印时最省事的是 Access 报表绑定字段的方式让报表引擎自己遍历记录生成条码。我做过三千多条资产的标签打印跑起来很轻松没有性能压力。如果要在程序里逐条生成并打印我建议事先把数据处理好再统一走循环。不要在循环里频繁创建和销毁控件实例那样内存和性能都吃不消。正确的做法是放一个可见的控件在窗体上循环里只改 Value 和触发打印这样效率高得多。还一个容易被忽略的细节批量打印之前先用带刻度的小标签纸打几份测试用尺子量一下条码实际宽度和设计宽度是否一致。打印机驱动里如果勾选了“缩放以适合”之类的选项打印结果会偏大或偏小。我的习惯是测试条码实物宽度误差在 0.5 毫米内才放量。5. 踩坑记录与问题速查表5.1 注册失败和 License 问题最常见的错误就是程序报“ActiveX 控件不能创建对象”但明明在开发环境里用得好好的。我遇到的情形主要有两种换了机器OCX 没注册。重新执行一次 regsvr32 就好了。目标机器是 64 位程序但 OCX 是 32 位。这个不是注册能解决的要么把程序编译成 x86要么找 64 位版本的控件。还有一个稍少见但很折腾的 License 问题开发环境一切正常编译发布到别的机器运行时报许可证无效。这是因为 COM 控件的设计时许可证没有随程序部署。在 VS 项目里注意检查有没有生成.lic文件如果有要一起作为内容文件发布出去。VB6 发布时则要确认安装包带上了控件的注册信息。这个问题在 Access 里基本碰不到在 .NET 里相对常见。5.2 换机器后报表显示红叉或空白Access 报表里有时会看到条码位置变成一个大红叉这个基本就是计算机上没有正确注册 OCX。重新注册一下就好regsvr32 MSBCODE9.OCX如果注册成功但还是空的就检查一下是不是 64 位 Office 不支持这个 32 位控件的一些绘制操作。从我的经验看64 位 Access 下这个控件的属性页经常打不开但运行时显示反而没问题。如果你的属性页打不开就直接在代码里设属性能绕过这个限制。5.3 常见问题速查表现象可能原因处理方式提示 ActiveX 控件不能创建对象OCX 未注册或位数不匹配regsvr32 注册确认程序位数与 OCX 一致报表中显示红叉OLE 对象引用失效重新注册 OCX属性页打不开64 位环境对 32 位控件支持不完整改用代码设置属性条码打印模糊、扫描不识别LineWeight 过小或 DPI 不足设置 LineWeight 不小于 0.008 英寸条码被截断LineLength 小于实际条码宽度调大 LineLength设置 Value 不生效在 Access 里绑定了控件来源未绑定显示时不要设置控件来源代码设置属性报错缺少 .Object 引用Access 中用控件名.Object访问接口发布后许可无效.lic 文件缺失将 .lic 文件随程序分发垂直条码扫不出扫描枪不支持旋转识别用水平方向或配置枪的旋转角度5.4 一个容易被忽略的中文字符问题有朋友拿这个控件生成中文条码发现控件不报错但扫描枪扫出来要么是乱码要么根本扫不出来。这里你要理解条码的本质它只是把字符串编码成黑白纹理并不是所有扫描枪都支持中文扩展编码。即使 Code 128 能编码 GBK 字节很多激光枪的解码固件不支持结果就是乱码。我的处理办法是物料名、客户名这类中文信息不要放进条码用拼音缩写、编码表或自增主键代替。条码里只放“经过设计的数据键”查询还是回数据库做这样最稳。还有那个 Interleaved 2 of 5要求长度为偶数位数字。如果你传了奇数位某些版本会自动在前面补 0某些版本直接画错码。所以用这个码制之前先保证内容是偶数位最好固定长度否则仓储扫描那边出问题很难排查。我自己在实际项目中踩过 MSCBCODE 的坑之后已经把这个控件用顺手了。现在凡是内部系统需要条码我基本都是先拿 Access 报表 Microsoft BarCode Control 15.0 出一版原型码制选 Code 128LineWeight 给 0.012 英寸打印到热敏标签上测试一下能扫就交付不能扫再调。这套流程效率很高而且稳定性足够应付绝大多数内部管理系统。最后再分享一个小技巧给条码下面那行人读文字留出足够高度别把 ShowText 的文字和条码本体挤在一起不然标签看起来乱人也容易看错。批量打印前先打一张实物用扫描枪实测一下再正式出这个习惯能帮你省下大量返工时间。
返回列表