2023/08/16

ノーツで QR コード:#12)エンコード文字列と QR コード

前回の調査で、これまで対応していたメインルーチンの EncodeBarcode 関数は、変換する文字列をエンコードしているだけで、QR コードとして表示するためには、もうひと手間必要であることがわかりました。

そこで、以前メインルーチンの掃除で 作画部分と判断し削除した bc_2Dms 関数を調査します。

なお、今回の作業はすべて Excel 状の作業となります。


作画部分に関して参照元のサイトに次の情報がありました。

追記:シェイプではなく、セルの色塗り方式に変更

今回参照させていただいた、サンプルコードはすでに、この対応が済んだものです。ただ、 サイト内に記載がありますが、bc_2Dms 関数には元となった Shape オブジェクトを操作するコードが残っています。

まずは、この部分を削除して、全体を把握しやすくします。Excel VBA のエディタを開き、コードをすっきりさせます。

Sub bc_2Dms(xBC As String, Optional xNam As String)
   Dim x, y, m, dm As Double
   Dim b%, n%, w%, p$
   p = Trim(xBC)
   b = Len(p)
   m = 2.5
   dm = m * 2#
   x = 0#
   y = 0#

   For n = 1 To b
      w = AscL(Mid(p, n, 1)) Mod 256
      If w = 10 Then
         y = y + dm
         x = 0#
      ElseIf (w >= 97 And w <= 112) Then
         w = w - 97

         Select Case w
         Case 1: Call drw(x, y, m, m)
         Case 2: Call drw(x + m, y, m, m)
                ・・・
         Case 15: Call drw(x, y, dm, dm)
         End Select

         x = x + dm
      End If
   Next n
End Sub

これで処理の流れが見ますね。細かな点はさておき、次のようなことがわかります。

  • For ループでエンコード文字列を1文字ずつ取得して、単純に処理
  • エンコード文字列は、文字コード 10(LF)と 97(a)から 112(p)で構成
  • 文字コード 16 種ごとに作画関数 drw を実行
  • 変数 x, y は座標、m, dm は作画に関連する値である

ここまで理解できた時点で、Excel をデバッグモードで実行します。bc_2Dms 関数のループ1回ごとに処理を止め、作画を確認します。

QR コードを 2 x 2 に分割し、左上から右に順に、4 マスごとに作画しています。これで、エンコード文字列の1文字が、QR コードの 4 マスにあたることがわかります。また、Select Case の分岐が 16 通り(= 4 ビット)ですべてのパターンを網羅していることもわかります。


作画関数

続いて、作画関数 drw の確認です。次のようなコードになっています。

Sub drw(a, b, c, d)
   Dim xc As Integer
   Dim yr As Integer
   Dim w As Integer
   Dim h As Integer
   xc = CInt((a / 2.5) + 1)
   yr = CInt((b / 2.5) + 1)
   w = CInt((c / 2.5) + 0)
   h = CInt((d / 2.5) + 0)
   Sheets("QR").Cells(yr, xc).Value = 1
   'w
   If w > 1 Then
      Sheets("QR").Cells(yr, xc + 1).Value = 1
   End If
   'h
   If h > 1 Then
      Sheets("QR").Cells(yr + 1, xc).Value = 1
   End If

   If w > 1 And h > 1 Then
      Sheets("QR").Cells(yr + 1, xc + 1).Value = 1
   End If
End Sub

yr と xc のセルを起点に 4 マス分のセルに必要に応じて 1 をセットしているだけです。気になるのは、2.5 で割る処理です。

元となった VBA のコードの bc_2Dms 関数を確認すると、次のような、コメントアウトされたコードが見つかります。

  ・・・
 m = 2.5
 dm = m * 2#
  ・・・
 ’ Set xShape = .AddShape(msoShapeRectangle, x, y + m, dm, m)
  ・・・

Shape を追加するときの座標 x, y の操作やサイズとして使用されているので、この 2.5 は Shape オブジェクトの1マス分の基準サイズであったことがわかります。

drw 関数は、AddShape と同等のインターフェースにして、呼び出し元関数の影響を最小限にするためこのような仕様にしたと考えられます。デバッグしただけだと意味不明な処理ですが、目的が見えてくると納得できますね。

前回 ノーツで QR コード 次回

0 件のコメント:

コメントを投稿