【VBA】Excelでバーコードコントロールを使用し生成する

こんにちは、Ryoです。
以前にバーコードフォントを使用した生成について記事を書いていますが、今回はリクエストいただいたこともあり、ExcelVBAでバーコードコントロール(Microsoft Access BarCode Control 14.0)を使った生成方法について書いていきたいと思います。



1.前提条件

今回使用するバーコードコントロール(Microsoft Access BarCode Control 14.0)は、その名の通りAccessのインストールされた環境が必須になります。私も数ヶ月前までは導入していませんでしたが、今はダウンロード版で単体を購入したので使えてますね。

インストールされていれば、エディタ画面の「ツール」から「参照設定」を選択し、その中にある「Microsoft Access BarCode Control14.0」にチェックを入れればOKです。

2.サンプル概要

Excelの表としては、A列にバーコード化したい「Code」が入力されていて、B列に生成したバーコードを貼り付けるものになります。貼り付けるセルの高さや幅については、コード内で設定しますのでSheet上で調整はしなくても大丈夫です。

動作としてCode39、Code128は確認していますが、各バーコードスタイルに合ったデータであれば、おそらく他のスタイルも大丈夫ではないかと思います。

サンプルコードを実行すると、以下画像のようにA列のデータがバーコード化され、B列に貼り付けられます。

サンプル画像内にCode128と書いているのは、英数字OKで一番汎用性が高そうなことを理由に選定しているだけで、Code128しか出来ないということではありません(笑)

また実行後のバーコード画像はセルに埋め込まれるので、Sheet上で選択したい場合は「開発」タブの「デザインモード」にすればOKです。

2.サンプルコード

Sub B_Code_Ctrl_Sample()

  Dim Str_Code As Variant
  Dim Start_Add, Col As String
  Dim Row_Pos, Col_Num, LastRow, Count As Long
  Dim BC_Data() As String
  Dim i As Integer
  
  '**バーコード化するCodeデータ読み込み**
  
  For Each Str_Code In Range("A:A")
       If Str_Code = "Code" Then
            Row_Pos = Str_Code.Row
            Start_Add = Str_Code.Address(True, False)
            Col = Left(Start_Add, InStr(Start_Add, "$") - 1)
            Col_Num = Asc(Col) - 64  '列番号アルファベットを数値化
            LastRow = Cells(Rows.Count, Col_Num).End(xlUp).Row  'データ入力最終行
            Count = LastRow - Row_Pos 'データ数
        End If
   Next

   ReDim BC_Data(1 To Count) As String

   'バーコードへのリンクセル設定用にデータ入力セルのアドレスを取得
   For i = 1 To Count
     BC_Data(i) = Cells(Row_Pos + i, Col_Num).Address(RowAbsolute:=False, ColumnAbsolute:=False)
   Next i
   
   '**バーコード貼付けセルのサイズ指定処理**

    'このサイズ設定はバーコード化する内容により適宜調整
    Rows(Row_Pos + 1 & ":" & LastRow).RowHeight = 70
    Columns(Col_Num + 1).ColumnWidth = 30
    
      
    '**バーコードコントロールプロパティ設定**
    
    'プロパティについては以下URLのMSDN参照
    'https://msdn.microsoft.com/ja-jp/library/cc427149.aspx
    
    Const BC_Style As Integer = 7
    'スタイル
    '0: UPC-A, 1: UPC-E, 2: JAN-13, 3: JAN-8, 4: Casecode, 5: NW-7,
    '6: Code-39, 7: Code-128, 8: U.S. Postnet, 9: U.S. Postal FIM, 10: 郵便物の表示用途(日本)
    
    Const BC_Substyle As Integer = 0
    'サブスタイル (下記URL参照)
    'https://msdn.microsoft.com/ja-jp/library/cc427156.aspx
    
    Const BC_Validation As Integer = 1
    'データの確認
    '0: 確認無し, 1: 無効なら計算を補正, 2: 無効なら非表示
    'Code39/NW-7の場合、「1」でスタート/ストップ文字(*)を自動的に追加
    
    Const BC_LineWeight As Integer = 3
    '線の太さ
    '0: 極細線, 1:細線, 2:中細線, 3:標準, 4:中太線, 5: 太線, 6:極太線, 7:超極太線
    
    Const BC_Direction As Integer = 0
    'バーコードの表示方向
    '0: 0度, 1: 90度, 2: 180度, 3: 270度 [0]が標準
    
    Const BC_ShowData As Integer = 1
    'データの表示
    '0: 表示無し, 1:表示有り
    
    Const BC_ForeColor As Long = rgbBlack
    '前景色の指定
    
    Const BC_BackColor As Long = rgbWhite
    '背景色の指定
    
    'rgbBlackなどの色定数は以下URLのMSDN参照
    'https://msdn.microsoft.com/ja-jp/VBA/Excel-VBA/articles/xlrgbcolor-enumeration-excel
    
   '**バーコード化の処理**
   
    Dim BC_OLE_Obj As OLEObject
    Dim BC_Obj As BARCODELib.BarCodeCtrl
      
    For i = 1 To Count
        'バーコードサイズ、及び貼り付ける位置の指定
        '上で設定したセルサイズに対し、枠内中央とする為にTop/Leftは+5、Height/Widthは-10
        With Cells(i + Row_Pos, Col_Num + 1)
           ActiveSheet.OLEObjects.Add(ClassType:="BARCODE.BarCodeCtrl.1", Link:=False, DisplayAsIcon:=False, _
            Top:=.Top + 5, Left:=.Left + 5, Height:=.Height - 10, Width:=.Width - 10).Select
        End With
                     
        Set BC_OLE_Obj = Selection
        Set BC_Obj = BC_OLE_Obj.Object
         
        'バーコードにプロパティ設定
        With BC_Obj
          .Style = BC_Style
          .SubStyle = BC_Substyle
          .Validation = BC_Validation
          .LineWeight = BC_LineWeight
          .Direction = BC_Direction
          .ShowData = BC_ShowData
          .ForeColor = BC_ForeColor
          .BackColor = BC_BackColor
          .Refresh
         End With
         
         'リンクするセルアドレスを指定
         With BC_OLE_Obj
           .Visible = False
           .LinkedCell = Range(BC_Data(i)).Address(RowAbsolute:=False, ColumnAbsolute:=False, _
            ReferenceStyle:=Application.ReferenceStyle)
           .Visible = True
         End With
                    
     Next i
   
End Sub

◆コードデータの読み込み

大まかな流れですが、まず表内の「Code」欄のデータ数を取得して処理数を把握します。
その後、配列BC_Dataに対象セルの各アドレス(行/列の相対参照形式)を格納しますが、
これは後にバーコード化で行う「リンクセル=データ元」を設定する為です。

処理内容としてはA列に対し「Code」の文字を検索し、そこを基点として行/列番号を取得、データ入力最終行も取得し総データ数を把握します。後はデータ数分繰り返し処理を行い、各データ入力セルのアドレスを取得する処理により、A列のデータ追加に対しては柔軟に対処出来る形としています。

◆バーコード貼り付け欄のセルサイズ調整

ここで設定するセル幅や高さを基にバーコードを貼付けますので、地味に重要です。
サンプルでは行高70、列幅30としていますが、バーコード化したい内容によってもサイズは変わりますので、スキャナなどで読めない場合は適宜調整してください。

私が確認した中ではCode39なら列幅40以上、Code128は列幅30以上あったほうが良いですねが、Code128でも英字が増えると、更に幅を増加させなければスキャナで読めませんので、ご注意ください。

◆バーコードコントロールのプロパティ

ここでスタイルや線の太さ、色などをセットしておきます。
詳細はMSDNのこちらがわかりやすいかと思いますので、よろしければご参照ください。

設定の中で「データの確認」がありますが、Code39やNW-7を使うのであれば「1」を設定しておくと、バーコード指定文字に無い場合に、スタート/ストップコードの”*”を自動的に追加してくれます。

色設定に関しては読取り精度に関わってきますので、無難に「前景=黒」、「背景=白」で良いと思います。記述内で使用している色定数(rgbBlackなど)もこちらのMSDNをご参照ください。

◆バーコード化の処理

処理対象のバーコードはActiveXコントロールなので、OLEObjectとバーコードコントロールライブラリー宣言は忘れずに!次にバーコードコントロールを使って、ここまで取得したデータや設定を基に処理を行います。

先ずFor~Nextを使ってデータ総数分繰り返し処理を行いますが、その中で貼り付ける位置とバーコード画像のサイズを指定します。

ActiveSheet.OLEObjects.Add(ClassType:=”BARCODE.BarCodeCtrl.1″, Link:=False, DisplayAsIcon:=False, Top:=.Top + 5, Left:=.Left + 5, Height:=.Height – 10, Width:=.Width – 10).Select

バーコードサイズはB列の枠内に収めたいので、TopとLeftは+5、高さと幅は-10としていますが、これは以下の考え方になります。

この辺りのサイズ調整はバーコード化したい内容によって様々だと思いますので、適宜変更してもらえれば良いと思います。

次に選択(.Select)しているオブジェクトに対し、プロパティ設定を反映する処理を行い、バーコード表示するデータが入力されているセルとリンクさせます。ここでの指定はセルアドレスになりますので、先程配列に格納した相対参照形式データを利用して指定すれば完了です。

バーコードにしている元データはリンク先のセルデータになるので、処理が終わったSheet上でもデータを変えれば、バーコードも変わります。

≪ 変更前 ≫

≪ 変更後 ≫

◆(参考)バーコード画像の削除

これは本題とは関係ありませんので参考程度なのですが、このサンプルコード動作確認する上で毎回画像を手動で削除するのが面倒でしたので設けたものです。

Sub All_Delete()

   Dim BC_Shape As Shape

   For Each BC_Shape In ActiveSheet.Shapes
      If InStr(BC_Shape.Name, "BarCodeCtrl") = 1 Then BC_Shape.Delete
   Next BC_Shape
  
End Sub

詳細な解説は割愛しますが、アクティブシートに対し全ての画像を順に抽出して名前に「BarCodeCtrl」が含まれていれば削除する処理になっています。ここの条件分岐入れておかないと「ボタン」や記事に載せる為に別に作った画像までも削除されますからね。

3.ラベルシートなどへの反映

バーコード化が済めば、当然ながら印刷して使うことも多いですからラベルシートへコピー、反映したいこともあるかと思いますので、以下に例を書いてみます。

もし生成したバーコードに対し、ラベル1枚ずつ反映したいような場合の例としては以下の記事をご参照ください。

こんにちは、Ryoです。 先日の記事「バーコードコントロールを使用し生成する」の中でも触れているラベルシートなどへの反映についてで...

本サンプルをベースとして考えていますが、先ずラベルシートに反映する際に対象Codeをまとめて実施することは無いでしょうからUserFormを使って、一覧を取得します。

リストからラベルシートへ反映したい対象Codeを選び、「ラベルシートへ反映」ボタンを押すと以下画像のように貼付けが実行されます。

◆ラベルシート反映のサンプルコード追加部分

ラベルシートなどへ反映しようとする場合、バーコードを生成する際に「オブジェクト名」を変更しておきます。理由としてはUserFormでリスト化した「Code」データを基に対象となるバーコード画像を検索~取得する為です。

先ずバーコード化する側のサンプルコードへの追加部分は以下になります。

Dim BC_Data(), BC_Code() As Stringで追加したBC_Code()はSheet内の「Code」データ取得用として宣言し、以下の部分で取り込みを行います。

追加や変更する部分は赤枠の部分です。
ReDim BC_Data(1 To Count), BC_Code(1 To Count) As String
BC_Code(i) = Cells(Row_Pos + i, Col_Num)

後は取得した「Code」名をバーコード化する際に名前として設定するので、以下の部分を追加すれば準備としてはOKです。

赤枠のようにBC_OLE_Obj.Name = BC_Code(i)とすることで、生成したバーコードの名前が変わります。

◆UserFormの設定、サンプルコード

ユーザーフォームの構成はListBoxが一つ、コマンドボタンが二つあればOKです。
記述するコードは以下になります。

≪ ListBoxに取得 ≫

Private Sub UserForm_Activate()
'フォームを読み込んだ際にリストボックスに「Code」を取得
    Dim i As Long
    Dim tgt As Variant
  
    ListBox1.Clear   
    Application.ScreenUpdating = False

    '対象Sheetから「Code」の文字を探し基点とする
    For Each tgt In Range("A:A")
       If tgt = "Code" Then Exit For
    Next
    
    tgt.Select
    
    '「Code」欄が空白になるまで取得しListBoxに反映する
    Do While ActiveCell <> ""
         ActiveCell.Offset(1, 0).Select
         ListBox1.AddItem ActiveCell
    Loop
 
    Application.ScreenUpdating = True

End Sub

これはPrivate Sub UserForm_Activate()としているので、ユーザーフォームが呼び出された(アクティブになった)際に実行されます。その際に「Code」欄に記載されたデータを読み、リストボックスへ反映しますので、表示されるときに既にリスト化されています。

≪ ラベルシートへの反映 ≫

Private Sub CommandButton1_Click()
  Dim BC_Shape As Shape

   For Each BC_Shape In ActiveSheet.Shapes
      'リストボックスの選択したデータを取得
      '該当するバーコードを図としてコピー
      If InStr(BC_Shape.Name, ListBox1.Text) = 1 Then
          BC_Shape.CopyPicture
          Exit For
      End If
   Next
   
   Worksheets("ラベル印刷用").Activate  
   '↓画像削除も一部変更が必要なので後述
  Call All_Delete 
   Cells(1, 1).Select
  
  '↓↓以下の部分は以前の記事「https://jizilog.com/vba-bcode4」を流用
   L = 0  '//貼り付け位置(Left)補正用//
   nm = 100  '//貼り付け画像のリネーム管理用//
   
   Dim Shp As Object
 
   For e = 1 To 4 '//ラベル4列//
       For i = 1 To 11  '//ラベル11行//
          Ct = Ct + 1
          ActiveSheet.Paste
          Bn = Selection.Name
             '//貼り付けた画像はSelect状態にあり、画像名を取得//
             With ActiveSheet.Shapes(Bn)
               '//取得した画像名をReNameする(Copy画像は全てName同一の為)//
               .Name = "Picture" & nm + Ct
             End With
              '//ReNameした画像を指定する//
              With ActiveSheet.Shapes("Picture" & nm + Ct)
               '//貼り付け位置をラベル印字部に合わせてシフトする//
               .Top = T + 10
               .Left = L + 4
              End With
            T = T + 78.8
       Next i
      '//Topは列完了後に初期位置に戻る//
      T = 0
      L = L + 148.5
    Next e
 
  Cells(1, 1).Select
  
  Unload UserForm1

End Sub
'↓↓これはFormの「閉じる」ボタン用
Private Sub CommandButton2_Click()

  Unload UserForm1

End Sub

この部分で行うのは、リストボックスで取得したCodeデータと合致するバーコード画像を抽出して、「図としてコピー」します。後はラベルシート用のSheet(シート名は「ラベル印刷用」)をアクティブ化して指定した位置に順次貼り付けていきますが、処理の都合上で画像に都度名前を付けています。

貼付け部分のサンプルコード内容やラベルシートなどは以前の記事「バーコードフォントを使用した生成」と同様になりますので、よろしければ以下をご参照ください。

こんにちは、Ryoです。 さて、今回はNo.3に続き、code39フォントに置換し画像化した バーコードをラベル様式に反映す...

≪ 画像の削除 ≫

ラベルシートの画像が残っている状態で実行すると、次々と画像が重ねられていくことになってしまうので削除する処理が必要になります。これは参考として書いた画像削除のサンプルコードを一部変更したものです。

Sub All_Delete()

   Dim BC_Shape As Shape

   For Each BC_Shape In ActiveSheet.Shapes
      If InStr(BC_Shape.Name, "Button") <> 1 Then BC_Shape.Delete
   Next BC_Shape
  
End Sub

バーコード画像の名前を変えてしまっているので、処理では”Button”が名前に含まれなければ削除するように変更しています。

コードなどは以上なので、後はUserFormを呼び出すボタンを設けて表示させればOKです。
ラベルシートへの貼付けなどは他にも色々な手段がありますが、その中の一例として参考程度に見てもらえれば良いかと思います。

3.まとめ

バーコードコントロールを使うことで多様なスタイルに対応出来ますが、データ自体がスタイルと整合していないと画像は真っ白になりますから、ご注意くださいませ!

また、処理自体は設定すべき内容さえ把握すれば困ることはなさそうなので、後は実施したい内容に合わせて対処していければMicroSoft Access BarCode Controlはかなり使いやすいように思います。やはりコントロールを使えると描画するバーコード自体の中身が充実するので、使用可能な環境で機会があれば、せひご検討くださいませ!




以上がバーコードコントロールを使って生成する内容についてでした!
フォントを使ってバーコードを生成する記事を書いていた頃は、コントロールの存在を知っていてもAccessを導入していなかったので出来ませんでしたが、今は導入済みということもあってMSDNや公開されている情報等も参考にさせていただきながら実運用に展開しやすそうな形で書いてみました。

今回の記事が何かの参考になれば幸いです。

Ryo

スポンサーリンク
スポンサーリンク

楽天トラベル

シェアする

フォローする

スポンサーリンク

楽天トラベル