ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 25939|回复: 85

[原创] VBA 二维码、条形码的批量生成与识别技术

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2021-3-13 21:26 | 显示全部楼层 |阅读模式
本帖最后由 ivccav 于 2021-3-14 09:22 编辑

现在条形码、二维码越来越火,且已应用到社会生活中的方方面面。
不少人在工作中为高效的管理设备、文件和物料,也有使用条码的需求。

搜了一下论坛,提供二维码生成控件的帖子真不少。记得有一帖是用VBA
语音生成二维码,真的很强大,可惜只是一个技术原型,网友使用中发现有
2-3%的条码无法识别,应该存在bug,且没有识别二维码的模块,而稍微能
应用于实际的二维码控件,基本全部都是以 注册收费 的形式提供。

今天中午看到论坛有人求价格便宜的生成data matrix二维码的控件,说网上
都是要价千元以上的。于是就想要介绍一个永久免费、开源的条码生产工具,该
工具是ZXing.Net,有人测评过,是目前最高效的二维码开源项目,支持VBA语言,
且能高效生成和识别各种条形码,足够满足普通使用者的需求了。支持的格式如下:

image.png


因为没有官方文档,只能根据可能的实际遇到的应用做几个示例,当抛砖引玉吧!
主要示例如下:

0.ZXing.Net的官方下载(本帖也提供下载)
1.生成二维码并放进系统剪贴板供使用
2.批量生成二维码并插入到指定单元格
3.生成二维码并导出为各种文件
4.生成条形码并导出为各种文件
5.二维码图片文件的识别示例
6.在窗体中生成并显示二维码
7.批量给二维码中间添加Logo

程序文件和示例代码.zip (731.18 KB, 下载次数: 1381)


评分

15

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-2-2 09:34 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 ivccav 于 2023-2-2 14:12 编辑


2023-02-02_092134.png

interop.zip (651.37 KB, 下载次数: 201)


纯代码生成二维码(32 & 64 bit).zip (232.41 KB, 下载次数: 226)



interop C#源代码.zip (31.51 KB, 下载次数: 94)

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-3-13 21:44 | 显示全部楼层



第一步:下载与安装ZXing.Net

1.复制上面附件中的ZXING.NET文件夹到系统盘Windows目录下(也可以不用这么做,放在电脑哪个地方都可以,找得到就行)
ZXING.NET官方github下载地址也在附件使用说明的记事本中。

2.选中register文件,右键——以管理员身份运行,这个非常重要!!!

管理员身份.png

3.注册成功后,在Excel VBE界面引用zxing.interop.tlb即可。

注册成功.png

引用控件接口.png


(如果勾选“信任对于‘Visual Basic项目’的访问”,在工具——宏——安全性——可靠发行商 中设置,可以运行代码:
ThisWorkbook.VBProject.References.AddFromGuid "{ECE3AB74-9DD1-4CFB-9D48-FCBFB30E06D6}", 0, 16
这样即可引用ZXing.NET了!

未注册成功的朋友,还得耐心看一下这里:

注册未成功.png
4.如果没有安装过office 2010以上的系统,可能没有Microsoft .NET Framework 4.5,版本太低是安装不成功的,
需先下载安装,49Mb的小文件。官方下载:

https://www.microsoft.com/zh-cn/download/details.aspx?id=30653

或者点这里下载在线安装(微软官方的):

dotNetFx45_Full_setup.zip (883.18 KB, 下载次数: 127)

安装成功之后再次以管理员身份运行运行register文件。



补充内容 (2023-2-2 09:09):
ZXing.Net下载地址:

https://github.com/micjahn/ZXing.Net

评分

3

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2021-3-13 22:24 | 显示全部楼层


2.生成QR二维码并导出为文件

  1. Function Encode_To_QR_Code_To_File()
  2.    Dim Writer As IBarcodeWriter
  3.    Dim qrCodeOptions As QrCodeEncodingOptions
  4.    Set qrCodeOptions = New QrCodeEncodingOptions
  5.    Set Writer = New BarcodeWriter
  6.    Writer.Format = BarcodeFormat_QR_CODE
  7.    Set Writer.Options = qrCodeOptions
  8.    Rem 尺寸单位:像素
  9.    qrCodeOptions.Height = 200
  10.    qrCodeOptions.Width = 200
  11.    qrCodeOptions.Margin = 10
  12.    qrCodeOptions.CharacterSet = "UTF-8"
  13.    qrCodeOptions.ErrorCorrection = ErrorCorrectionLevel_H
  14.    Writer.WriteToFile Sheet2.[A1], ThisWorkbook.path & "\test.png", ImageFileFormat_Png
  15. End Function
复制代码


QRCode,即 Quick Response Code,快速响应码,为丰田旗下的电装(DENSO)公司发明,
其特点是容量大(能容纳数千个字符,汉字能容纳1800多个),扫描识别快,所以应用
最为广泛,工作、生活中到处都是QR二维码。

QR二维码使用QrCodeEncodingOptions设置参数。



a.如果要支持汉字,请选UTF-8字符集。


b.二维码容错率等级分为:L、M、Q、H四级,
Level L  –   7%损毁还能被识别
Level M – 15%损毁还能被识别
Level Q – 25%损毁还能被识别
Level H – 30%损毁还能被识别

等级越高,抗污损的能力越强,扫描识别也越快,但容纳的字符就更少。

c.高度Height和宽度Width根据内容多寡合理设置,单位为像素。白边Margin设置没什么用。
早期版本根本没这个参数。程序会根据内容长度计算二维码的版本。二维码一共有40个尺寸规格,
专业叫法叫版本Version。Version 1是21 x 21的矩阵,Version 2是 25 x 25的矩阵,
每增加一级version,就会增加4的尺寸,公式是:(V-1)*4 + 21(V是版本号) 最高Version 40,
(40-1)*4+21 = 177,所以最高是177 x 177 的正方形。程序会根据内容长度选择最小的版本。
现在我们假设要生成一个 200x200像素的二维码图片,若版本为 40, 即二维码矩阵为 177x177,
那么,剩下的23x23就需要白边来填充; 而如果程序计算出版本为2,因为二维码矩阵为 25x25,
放大8倍时正好 200x200,白边就不会剩余。Margin参数随便设置为1到5就行了。

d.导出的文件格式支持:bmp,gif,jpeg,png,tiff和wmf


TA的精华主题

TA的得分主题

 楼主| 发表于 2021-3-13 22:32 | 显示全部楼层


3.批量生成二维码并插入到指定单元格,二维码放进系统剪贴板

可以利用BarcodeWriter对象GetStdPicture方法获取StdPicture图片对象,
然后放进剪贴板,然后粘贴到Excel表的单元格中,而无需使用Pictures.Insert
从磁盘文件中重新导入到Excel。

  1. Rem 生成二维码并转为StdPicture对象

  2. Function Encode_To_QR_Code(cont As String) As IPictureDisp
  3.    Dim Writer As IBarcodeWriter
  4.    Dim qrCodeOptions As QrCodeEncodingOptions
  5.    Set qrCodeOptions = New QrCodeEncodingOptions
  6.    Set Writer = New BarcodeWriter
  7.    Writer.Format = BarcodeFormat_QR_CODE
  8.    Set Writer.Options = qrCodeOptions
  9.    qrCodeOptions.Height = 200
  10.    qrCodeOptions.Width = 200
  11.    qrCodeOptions.Margin = 5
  12.    qrCodeOptions.CharacterSet = "UTF-8"
  13.    qrCodeOptions.ErrorCorrection = ErrorCorrectionLevel_H
  14.    Set Encode_To_QR_Code = Writer.GetStdPicture(cont)
  15. End Function
复制代码

  1. #If VBA7 Then
  2.     Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hwnd As LongPtr) As Long
  3.     Declare PtrSafe Function SetClipboardData Lib "user32" (ByVal Format As Long, ByVal hMem As LongPtr) As Long
  4.     Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
  5.     Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
  6. #Else
  7.     Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
  8.     Declare Function SetClipboardData Lib "user32" (ByVal Format As Long, ByVal hMem As Long) As Long
  9.     Declare Function CloseClipboard Lib "user32" () As Long
  10.     Declare Function EmptyClipboard Lib "user32" () As Long
  11. #End If

  12. Const CF_BITMAP = 2&

  13. Rem 把图片放进剪贴板

  14. Function SetClipboard(cont As String) As Boolean
  15.     Dim hwnd As LongPtr
  16.     On Error GoTo ErrHandler
  17.     hwnd = 0
  18.     If OpenClipboard(hwnd) Then
  19.         EmptyClipboard
  20.         SetClipboardData CF_BITMAP, Encode_To_QR_Code(cont)
  21.         CloseClipboard
  22.         SetClipboard = True
  23.         Exit Function
  24.     End If
  25. ErrHandler: SetClipboard = False
  26. End Function
复制代码

  1. Rem 批量生成QR二维码并插入指定单元格

  2. Sub MakeQRCode()
  3.     Dim Rng As Range, Shp As Shape, r&
  4.     Application.ScreenUpdating = False
  5.     r = Range("a" & Rows.Count).End(3).Row
  6.     For Each Shp In ActiveSheet.Shapes
  7.         If Shp.Type = msoPicture Then Shp.Delete
  8.     Next
  9.     For Each Rng In Range("a1:a" & r)
  10.         If SetClipboard(Rng.Value) Then
  11.             ActiveSheet.Paste Rng.Offset(, 2)
  12.             With Selection.ShapeRange
  13.                 .LockAspectRatio = msoTrue
  14.                 .Top = Rng.Offset(, 2).Top + 2
  15.                 .Left = Rng.Offset(, 2).Left + 2
  16.                 .Height = Rng.Offset(, 2).Height - 4
  17.             End With
  18.         End If
  19.     Next
  20.     Application.ScreenUpdating = True
  21. End Sub
复制代码


TA的精华主题

TA的得分主题

 楼主| 发表于 2021-3-13 22:42 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助


4.再举例:Code128条形码和Datamatrix二维码

  1. Rem 生成条形码并导出为图片文件

  2. Rem 128码:可表示从ASCII 0 到ASCII 127 共128个字符,故称

  3. Function Encode_To_CODE_128_To_File()
  4.    Dim EnCodeOptions As New EncodingOptions
  5.    Dim Writer As IBarcodeWriter
  6.    Set Writer = New BarcodeWriter
  7.    Writer.Format = BarcodeFormat_CODE_128
  8.    Set Writer.Options = EnCodeOptions
  9.    EnCodeOptions.Height = 50
  10.    EnCodeOptions.Width = 200
  11.    EnCodeOptions.Margin = 2
  12.    Writer.WriteToFile "hello world!", ThisWorkbook.path & "\test.png", ImageFileFormat_Png
  13. End Function
复制代码



条形码用EncodingOptions设置参数,要设置好条码格式:


条码格式.png

“Hello World”的条形码效果如下:

hello world条码.png

  1. Rem 生成DATA MATRIX 二维码

  2. Function Encode_To_DM_Code_To_File()
  3.     Dim Writer As IBarcodeWriter, cont As String
  4.     Dim DMCodeOptions As New DatamatrixEncodingOptions
  5.     Set Writer = New BarcodeWriter
  6.     cont = "{ECE3AB74-9DD1-4CFB-9D48-FCBFB30E06D6}"
  7.     Writer.Format = BarcodeFormat_DATA_MATRIX
  8.     Set Writer.Options = DMCodeOptions
  9.     DMCodeOptions.Height = 200
  10.     DMCodeOptions.Width = 200
  11.     DMCodeOptions.Margin = 5
  12.     DMCodeOptions.SymbolShape = SymbolShapeHint_FORCE_SQUARE
  13.     Writer.WriteToFile cont, "D:\test.png", ImageFileFormat_Png
  14. End Function
复制代码
DATA MATRIX 二维码使用DatamatrixEncodingOptions设置参数,注意ymbolShape的选择。
字符串{ECE3AB74-9DD1-4CFB-9D48-FCBFB30E06D6}的DM码效果如下:


DataMatrix.png




TA的精华主题

TA的得分主题

 楼主| 发表于 2021-3-13 22:51 | 显示全部楼层



5.二维码图片的识别

  1. Rem 读取图片文件数据进行解码

  2. Function Decode_QR_Code_From_File()
  3.    Dim Reader As IBarcodeReader
  4.    Dim Res As Result
  5.    Set Reader = New BarcodeReader
  6.    Reader.Options.PossibleFormats.Add BarcodeFormat_QR_CODE
  7.    Set Res = Reader.DecodeImageFile(ThisWorkbook.path & "\test.png")
  8.    Debug.Print Res.Text
  9. End Function

  10. Rem 从Byte数组数据进行二维码解码

  11. Function Decode_QR_Code_From_Byte_Array()
  12.    Dim Reader As IBarcodeReader
  13.    Dim rawRGB(1000) As Byte
  14.    Dim Res As Result
  15.    Set Reader = New BarcodeReader
  16.    Reader.Options.PossibleFormats.Add BarcodeFormat_QR_CODE
  17.    Rem TODO: load bitmap data to byte array rawRGB
  18.    Set Res = Reader.DecodeImageBytes(rawRGB, 10, 10, BitmapFormat.BitmapFormat_Gray8)
  19. End Function
复制代码


6.给二维码添加Logo

二维码程序本身是不能添加Logo的,但利用二维码容错率原理,在生成的二维码图片中添加一张较小的
图片,只要遮挡的面积在容错率范围内,二维码就能被识别。一般Logo图片的尺寸取二维码尺寸的20%以下为宜。


  1. Rem 批量给图片添加Logo

  2. Sub addlogo()
  3.     Dim logo As Object, img As Object, ip As Object
  4.     Dim path As String, filename As String, i As Long
  5.     On Error Resume Next
  6.     Set img = CreateObject("wia.imagefile")
  7.     Set logo = CreateObject("wia.imagefile")
  8.     Set ip = CreateObject("wia.imageprocess")
  9.     path = ThisWorkbook.path & Application.PathSeparator
  10.     logo.LoadFile path & "logo.png"
  11.     ip.Filters.Add ip.FilterInfos("Stamp").FilterID
  12.     Set ip.Filters(1).Properties("ImageFile") = logo
  13.     filename = Dir(path & "*.png")
  14.     Do While Len(filename)
  15.         If filename <> "Logo.png" Then
  16.             img.LoadFile path & filename
  17.             ip.Filters(1).Properties("Left") = (img.Width - logo.Width) / 2
  18.             ip.Filters(1).Properties("Top") = (img.Height - logo.Height) / 2
  19.             Set img = ip.Apply(img)
  20.             i = i + 1
  21.             Kill path & "Result\result_" & i & ".png"
  22.             img.SaveFile path & "result\result_" & i & ".png"
  23.         End If
  24.         filename = Dir
  25.     Loop
  26.     MsgBox "处理完成的图片在Result文件夹中!"
  27. End Sub
复制代码


完整示例和代码见1楼的附件。

Logo.png

P01.png

添加Logo后的效果
result_1.png


TA的精华主题

TA的得分主题

 楼主| 发表于 2021-3-13 23:04 | 显示全部楼层


总结:

在Windows7 64bit 和 Windows10 64bit 系统上,用WPS 2019完美运行ZXing.Net。
如果是Windows7系统,未安装office 2010以上版本,Microsoft .NET Framework 版本为2,
版本太低会注册不成功ZXing.DLL,可以安装Office2010以上版本,或者下载一个49MB的
Microsoft .NET Framework 4.5安装再注册。其他环境未模拟测试过。

ZXing.Net是一个基于.Net平台的二维码工具,支持大多数主流条码和二维码的生产和识别,
同时支持C#、VBA等多种编程语言,高效、免费开源,值得使用。

TA的精华主题

TA的得分主题

发表于 2021-3-13 23:24 | 显示全部楼层
谢谢分享,支持原创

TA的精华主题

TA的得分主题

发表于 2021-3-14 00:30 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2021-3-14 01:16 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-11 08:08 , Processed in 0.058817 second(s), 16 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表