为什么 Microsoft Barcode Control 在通过互操作打开工作簿时中断?
Why does Microsoft Barcode Control break when the workbook is opened via interop?
我有一个工作表,我在其中添加了一个二维码。
二维码是ActiveX控件:Microsoft Barcode Control 14.0
QR 码链接到单元格 (A1),因此当单元格中的值更改时,QR 码也会更改。
当我正常打开工作簿时,一切正常。
但是,当我使用 vb.net Winforms 项目中的 Interop 打开它时,当链接单元格中的值发生变化时,QR 码不再响应。
更重要的是,当我右键单击条形码控件时,缺少 "Microsoft Barcode Control 14.0 Object" 上下文菜单选项(如下所示)。
我用来打开工作簿的互操作代码如下:
Dim XLApp As New Excel.Application
XLApp.Visible = True
Dim XLBook As Excel.Workbook = XLApp.Workbooks.Open(FilePath)
谁能告诉我是什么导致了这种情况发生?也许建议我可以做些什么来防止它发生。
每次需要更新二维码时,可以调用Worksheet
class的Calculate
方法。例如,VBA 中的原始草图:
Application.EnableEvents = True
Application.ScreenUpdating = True
Sheets("QR_CodeSheet").Calculate
我无法使 Microsoft 条码控件与互操作一起正常运行。
一种方法是使用 shell 命令打开文件,然后挂接到进程以使用它。但是我觉得这太乱了。
相反,我决定使用 google 的图表 API。这确实需要互联网连接。但这对我来说不是问题。
这里是 link 以获取更多信息:https://sites.google.com/site/e90e50fx/home/generate-qrcode-with-excel
和 VBA 代码:
Option Explicit
'other technical specifications about google chart API:
'https://developers.google.com/chart/infographics/docs/qr_codes
Function URL_QRCode_SERIES( _
ByVal PictureName As String, _
ByVal QR_Value As String, _
Optional ByVal PictureSize As Long = 150, _
Optional ByVal DisplayText As String = "", _
Optional ByVal Updateable As Boolean = True) As Variant
Dim oPic As Shape, oRng As Excel.Range
Dim vLeft As Variant, vTop As Variant
Dim sURL As String
Const sRootURL As String = "https://chart.googleapis.com/chart?"
Const sSizeParameter As String = "chs="
Const sTypeChart As String = "cht=qr"
Const sDataParameter As String = "chl="
Const sJoinCHR As String = "&"
If Updateable = False Then
URL_QRCode_SERIES = "outdated"
Exit Function
End If
Set oRng = Application.Caller.Offset(, 1)
On Error Resume Next
Set oPic = oRng.Parent.Shapes(PictureName)
If Err Then
Err.Clear
vLeft = oRng.Left + 4
vTop = oRng.Top
Else
vLeft = oPic.Left
vTop = oPic.Top
PictureSize = Int(oPic.Width)
oPic.Delete
End If
On Error GoTo 0
If Len(QR_Value) = 0 Then
URL_QRCode_SERIES = CVErr(xlErrValue)
Exit Function
End If
sURL = sRootURL & _
sSizeParameter & PictureSize & "x" & PictureSize & sJoinCHR & _
sTypeChart & sJoinCHR & _
sDataParameter & UTF8_URL_Encode(VBA.Replace(QR_Value, " ", "+"))
Set oPic = oRng.Parent.Shapes.AddPicture(sURL, True, True, vLeft, vTop, PictureSize, PictureSize)
oPic.Name = PictureName
URL_QRCode_SERIES = DisplayText
End Function
Function UTF8_URL_Encode(ByVal sStr As String)
'http://www.nonhostile.com/howto-convert-byte-array-utf8-string-vb6.asp
Dim i As Long
Dim a As Long
Dim res As String
Dim code As String
res = ""
For i = 1 To Len(sStr)
a = AscW(Mid(sStr, i, 1))
If a < 128 Then
code = Mid(sStr, i, 1)
ElseIf ((a > 127) And (a < 2048)) Then
code = URLEncodeByte(((a \ 64) Or 192))
code = code & URLEncodeByte(((a And 63) Or 128))
Else
code = URLEncodeByte(((a \ 144) Or 234))
code = code & URLEncodeByte((((a \ 64) And 63) Or 128))
code = code & URLEncodeByte(((a And 63) Or 128))
End If
res = res & code
Next i
UTF8_URL_Encode = res
End Function
Private Function URLEncodeByte(val As Integer) As String
Dim res As String
res = "%" & Right("0" & Hex(val), 2)
URLEncodeByte = res
End Function
我有一个工作表,我在其中添加了一个二维码。
二维码是ActiveX控件:Microsoft Barcode Control 14.0
QR 码链接到单元格 (A1),因此当单元格中的值更改时,QR 码也会更改。
当我正常打开工作簿时,一切正常。
但是,当我使用 vb.net Winforms 项目中的 Interop 打开它时,当链接单元格中的值发生变化时,QR 码不再响应。 更重要的是,当我右键单击条形码控件时,缺少 "Microsoft Barcode Control 14.0 Object" 上下文菜单选项(如下所示)。
我用来打开工作簿的互操作代码如下:
Dim XLApp As New Excel.Application
XLApp.Visible = True
Dim XLBook As Excel.Workbook = XLApp.Workbooks.Open(FilePath)
谁能告诉我是什么导致了这种情况发生?也许建议我可以做些什么来防止它发生。
每次需要更新二维码时,可以调用Worksheet
class的Calculate
方法。例如,VBA 中的原始草图:
Application.EnableEvents = True
Application.ScreenUpdating = True
Sheets("QR_CodeSheet").Calculate
我无法使 Microsoft 条码控件与互操作一起正常运行。 一种方法是使用 shell 命令打开文件,然后挂接到进程以使用它。但是我觉得这太乱了。
相反,我决定使用 google 的图表 API。这确实需要互联网连接。但这对我来说不是问题。
这里是 link 以获取更多信息:https://sites.google.com/site/e90e50fx/home/generate-qrcode-with-excel
和 VBA 代码:
Option Explicit
'other technical specifications about google chart API:
'https://developers.google.com/chart/infographics/docs/qr_codes
Function URL_QRCode_SERIES( _
ByVal PictureName As String, _
ByVal QR_Value As String, _
Optional ByVal PictureSize As Long = 150, _
Optional ByVal DisplayText As String = "", _
Optional ByVal Updateable As Boolean = True) As Variant
Dim oPic As Shape, oRng As Excel.Range
Dim vLeft As Variant, vTop As Variant
Dim sURL As String
Const sRootURL As String = "https://chart.googleapis.com/chart?"
Const sSizeParameter As String = "chs="
Const sTypeChart As String = "cht=qr"
Const sDataParameter As String = "chl="
Const sJoinCHR As String = "&"
If Updateable = False Then
URL_QRCode_SERIES = "outdated"
Exit Function
End If
Set oRng = Application.Caller.Offset(, 1)
On Error Resume Next
Set oPic = oRng.Parent.Shapes(PictureName)
If Err Then
Err.Clear
vLeft = oRng.Left + 4
vTop = oRng.Top
Else
vLeft = oPic.Left
vTop = oPic.Top
PictureSize = Int(oPic.Width)
oPic.Delete
End If
On Error GoTo 0
If Len(QR_Value) = 0 Then
URL_QRCode_SERIES = CVErr(xlErrValue)
Exit Function
End If
sURL = sRootURL & _
sSizeParameter & PictureSize & "x" & PictureSize & sJoinCHR & _
sTypeChart & sJoinCHR & _
sDataParameter & UTF8_URL_Encode(VBA.Replace(QR_Value, " ", "+"))
Set oPic = oRng.Parent.Shapes.AddPicture(sURL, True, True, vLeft, vTop, PictureSize, PictureSize)
oPic.Name = PictureName
URL_QRCode_SERIES = DisplayText
End Function
Function UTF8_URL_Encode(ByVal sStr As String)
'http://www.nonhostile.com/howto-convert-byte-array-utf8-string-vb6.asp
Dim i As Long
Dim a As Long
Dim res As String
Dim code As String
res = ""
For i = 1 To Len(sStr)
a = AscW(Mid(sStr, i, 1))
If a < 128 Then
code = Mid(sStr, i, 1)
ElseIf ((a > 127) And (a < 2048)) Then
code = URLEncodeByte(((a \ 64) Or 192))
code = code & URLEncodeByte(((a And 63) Or 128))
Else
code = URLEncodeByte(((a \ 144) Or 234))
code = code & URLEncodeByte((((a \ 64) And 63) Or 128))
code = code & URLEncodeByte(((a And 63) Or 128))
End If
res = res & code
Next i
UTF8_URL_Encode = res
End Function
Private Function URLEncodeByte(val As Integer) As String
Dim res As String
res = "%" & Right("0" & Hex(val), 2)
URLEncodeByte = res
End Function