利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)

以前在這篇有回答過qrcode的問題(2016-12-21)
是利用google線上轉碼功能做的簡易範例
優點是簡單
缺點是要上網,沒網路就用不了,資料多就會超lag
https://www.mobile01.com/topicdetail.php?f=511&t=5019053

在這篇有用lib、dll的簡易範例(2017-01-10)
優點是可離線使用
缺點是程式碼稍微複雜一些,還要註冊lib
https://www.mobile01.com/topicdetail.php?f=511&t=5037106


這幾天找資料意外發現原來google有提供原始碼,還有編譯好的exe檔
(不需上網,可離線執行)
可惜到2013年就停止更新了

好奇下載來玩看看,QrcodeGui.exe(視窗版),中文可正常編碼
可惜實用性不高,一次只能產生一個圖形
利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)





在cmd視窗用qrcode.exe(cmd版),直接打中文,會變亂碼
用vba直接送出去的文字也不行,(vba是utf16)
qrcode一樣會變亂碼,像下圖這樣

利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)
利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)

利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)

雖然可用chcp指令,檢查修改編碼,但反而會讓win7在cmd視窗出現中文無法輸入的問題
利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)



不過,測試後發現,確定qrcode.exe有支援"無bom的utf-8"
所以要讓vba送utf-8文字到cmd視窗給qrcode.exe,最簡單的方式就是用文字檔



'前置作業
一、去google下載檔案,直接最後版本就行
雖然下載的是安裝版,但裝好就變免安裝版,可隨便copy到任何位置、電腦
https://code.google.com/archive/p/qrencode-win32/downloads

利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)


利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)






Sub qrcodetest()

Dim report, oldpic As Shape, i As Integer, r As Integer
Dim qr As String, temppath As String, QrexePath As String, QrArgument As String, temppic As String

'二、在"桌面"上手動建立名稱"qrcodetest"的暫存資料匣,可自訂其它名稱、位置
temppath = Environ("USERPROFILE") & "\Desktop\qrcodetest\"
'QrexePath = Environ("USERPROFILE") & "\Desktop\qrcodetest\qrcode.exe"
'qrcode.exe的位置,可自訂
QrexePath = "C:\Program Files (x86)\QRCodeGui\qrcode.exe"

'注意:如果想自訂暫存檔案名稱,程式執行前,需100%確定暫存目錄的位置是否正確
'kill指令會在無任何提示下刪除所指定的檔案

If Dir(temppath & "*_pic.png") <> "" Then Kill temppath & "*_pic.png"
If Dir(temppath & "qrtxt*.txt") <> "" Then Kill temppath & "qrtxt*.txt"

For i = 1 To 5 '暫訂5筆資料

qr = ActiveSheet.Cells(i, 1).Value
If qr <> "" Then
report = StrToUTF8(qr, temppath & "qrtxt" & i & ".txt")
temppic = temppath & i & "_pic.png"
QrArgument = " -o " & temppic & " -s 3 -l H < " & temppath & "qrtxt" & i & ".txt"
'QrArgument = " -o " & temppic & " --foreground=ff0000 --background=FFFFFF -s 3 -l H < " & temppath & "qrtxt" & i & ".txt"
report = Shell("cmd.exe /c """ & QrexePath & """" & QrArgument, vbHide)
End If

Next i

Application.Wait (Now + TimeValue("0:00:03"))
'根據資料多少、電腦效能,調整等待時間
'這裡主要是等檔案寫入硬碟,跟網路無關(這是離線版的)


temppic = Dir(temppath & "*_pic.png")

Do While temppic <> ""
'Debug.Print temppic
r = Split(temppic, "_")(0)

'刪掉同位置上的舊圖形
For Each oldpic In ActiveSheet.Shapes
If oldpic.TopLeftCell.Address = ActiveSheet.Cells(r, 2).Address Then
oldpic.Delete
End If
Next

'插入新圖
'無內嵌圖片,如有excel檔案格式email需求,原始圖片需一起寄出,或轉成pdf
'Set q = ActiveSheet.Pictures.Insert(temppath & temppic)
'(20210227更新)因2樓高手ren1244指點,當使用原始檔案email時,無內嵌會使圖片不見
'程式碼修改如下ActiveSheet.Pictures.Insert 改成 ActiveSheet.Shapes.AddPicture

'有內嵌圖片,不需原始圖片,可原檔email
Set q = ActiveSheet.Shapes.AddPicture(temppath & temppic, False, True, 1, 1, 1, 1)
With q '位置、大小
.Left = ActiveSheet.Cells(r, 2).Left
.Top = ActiveSheet.Cells(r, 2).Top
.Height = 100
.Width = 100
End With
temppic = Dir()

Loop

End Sub





Function StrToUTF8(StrUtf16 As String, fileName As String)
'utf16轉成沒bom的utf8

Dim Utf8File As Object
Set Utf8File = CreateObject("ADODB.Stream")
Utf8File.Type = 1
Utf8File.Mode = 3
Utf8File.Open

With CreateObject("ADODB.Stream")
.Type = 2
.Mode = 3
.CharSet = "utf-8"
.Open
.WriteText StrUtf16
.Position = 3
.copyto Utf8File
.Flush
.Close
End With

Utf8File.savetofile fileName, 2
Utf8File.Flush

Set Utf8File = Nothing

End Function



如果要在win10使用,需信任暫存目錄的位置,才能正確執行
=>選項=>信任中心=>信任中心設定
(新增暫存目錄,範例中是桌面上的qrcodetest)

利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)


qrcode.exe 還有不少參數可用,詳細請參考說明
在dos(cmd)視窗下,打qrcode.exe --help
修改位置在<符號前面(藍色字體),前、後、參數之間,都要空一格
QrArgument = " -o " & temppic & " -s 3 -l H < " & temppath & "qrtxt" & i & ".txt"
QrArgument = " -o " & temppic & " --foreground=ff0000 --background=FFFFFF -s 3 -l H < " ……略

利用google提供的Qrcode.exe,改寫成vba+cmd範例(win10,excel x32 x64可用)



[點擊下載]
Pictures.Insert 好像是用外連的方式
所以如果把 excel 直接寄給別人的話
那些 qrcode 還會在嗎?
(手邊沒 excel 無法測試)

稍微查了一下,如果想內嵌圖片好像可以用
Shapes.AddPicture
(參考來源:stackoverflow
ren1244 wrote:
Pictures.Insert 好像是用外連的方式
所以如果把 excel 直接寄給別人的話
那些 qrcode 還會在嗎?
(手邊沒 excel 無法測試)

稍微查了一下,如果想內嵌圖片好像可以用
Shapes.AddPicture
(參考來源:stackoverflow)



我都沒注意到這個問題
還以為都是“本機”列印需求才會用到,或是另存pdf再寄出
通常不會把含vba的檔案寄給對方,根本沒想過要內嵌…

都沒注意到會有使用excel檔案格式寄出的可能
這樣用Pictures.Insert 就會出問題了,對方收到檔案時會是一片空白

不好意思,範例寫的太隨便
您非常厲害,試都沒試,就指出我沒注意到的地方
非常感謝您提出的建議

1樓程式碼修改如下
(只需改1行)
原,無內嵌,原始圖片需一起寄出
Set q = ActiveSheet.Pictures.Insert(temppath & temppic)
修改後,內嵌圖片,原始圖片可刪,可寄出
Set q = ActiveSheet.Shapes.AddPicture(temppath & temppic, False, True, 1, 1, 1, 1)
其實以VBA來說樓主研究得比我還深入
只是剛好關注的點有點不同而已
 
另外我想回一下關於先前線上版的部分
之前因為是用外連的方式
所以每次重新開啟 excel 檔案就要線上重抓一次圖片
才會有「資料多就會超lag」的現象
如果是用內嵌的話就可以改善了
 
閒來沒事,另外弄一個小程式
目的是「替代google線上轉碼」
檔案在這:https://mega.nz/file/gVhAyY4S#csknoRe_j-JpX0NmVuhFvaHAmB4Wc3RJGTC-VhKKXtA
 
  1. 解壓縮後,有一個 run.bat 檔案,直接點兩下執行。
  2. 第一次執行可能會出現要不要讓程式通過防火牆,可以直接按取消(不給予權限)。會出現這個是因為這是用 nodeJS 架設伺服器,原本是可以讓其他人連線,但今天我們只是自己連自己電腦,所以不用動防火牆。
  3. 會出現一個黑窗,代表服務運行中。在瀏覽器打網址:http://localhost:8080/要被編碼的內容/,就會出現qrcode。  
     
  4. Excel 執行 vba 插入 QR Code 圖片。
  5. 關閉黑窗,服務即中止。這時在瀏覽器中打網址就連不到了。
PS. 因為是跟自己連線,所以沒網路一樣可以執行(localhost 沒網路還是可以連)。
 
VBA 大概長這樣
(UTF8 的問題我猜可以用 ENCODEURL 內建函式解決)
 
str = Application.WorksheetFunction.ENCODEURL(要被編碼文字)
url = "http://localhost:8080/" & str & "/"
ActiveSheet.Shapes.AddPicture(url, ...略)
ren1244 wrote:
VBA 大概長這樣
(UTF8 的問題我猜可以用 ENCODEURL 內建函式解決)


在新版excel可以,很好用的函數,但舊版excel沒有
不用ENCODEURL的原因
是我寫vba範例時的壞習慣,基本上都用舊函數
舊版excel沒有的函數就用純vba解決
程式碼會以2003(舊版)、2007…新版(x32 x64),都可正常使用為主

關於那個範例中,是因為CreateObject("scriptcontrol") 不能在excel 64使用
用迴圈改字串程式碼比較長,字太多時,速度慢
所以才用 htmlfile execscript 來解決編碼問題

這樣只要有裝excel,就不太需要考慮版本、相容性的問題
下載後就可直接使用,也可根據自己的需求修改程式碼
(mac 版excel例外…一大堆相容性問題)


ren1244 wrote:
所以每次重新開啟 excel 檔案就要線上重抓一次圖片
才會有「資料多就會超lag」的現象
如果是用內嵌的話就可以改善了


當初想說是一次性列印,用過即丟,壓根沒想過存檔、email問題
根據您的建議,以後寫範例有圖形需求時,會改用內嵌為主


 
ren1244 wrote:
閒來沒事,另外弄一個小程式
目的是「替代google線上轉碼」


高手,這是用github qrcode module 做的離線web版qrcode產生器
一樣是用網址產生,但速度上有極大的差異,vba範例也只需改網址就好
很讚的程式,收下了


難得遇到願意提供範例、教學、意見…給我的,感動的學習中
太厲害了,我之前沒想過可以這樣用,都是用API產生,給你一個讚。
文章分享
評分
評分
複製連結

今日熱門文章 網友點擊推薦!