見出し画像

VBAでBarCode_読込2

引き続きご覧いただき、ありがとうございます。
ここからVBA作成に着手します。

では、まずExcelさんに依頼する事柄を整理してみます。
 処理のきっかけ「9行目E列」にバーコードが読み込まれたら(前提)
・「9行目E列」の左2桁が24以外のとき「社員証ではない」⇒処理を中断
・右から6桁を抽出し、その左から5桁を社員番号としてシート「名簿」から     該当する社員データをシート「出退」に書き出す。
・読み込んだ時の時刻を、同社員の出社時刻または退社時刻としてシート「名簿」に書き出す。
 *注釈:シート「名簿」の出社時刻が、空白のときは「出社時刻」とし、空白でないときは「退社時刻」とする。

以上が、今思いあたる「依頼書」の内容です。
一見、良くできた「依頼書」に見えますが、Excelさんの身になって考えると、いくつかの不備があります。
たとえば、前提の「9行目E列に読み込んで」ですが、Excelで入力できるセルはActiveCell(緑色の縁・カーソルがあるセル)に限られます。なので、読み込む前に「9行目E列」をActiveCellにする必要があります。などなどありますが、少しずつ進めながら対処していきましょう。
この問題については、「シートの保護」機能を使い「9行目E列」以外を入力禁止にします。そして、読み込んで、社員データを書き出すときに、保護が外れるようにすれば大丈夫なはずです。

そこで、「シート名簿」の9行目E列をActiveCellにして、セルの書式設定>保護にある「ロック」のチェックを外してください。
つぎに、シート保護を掛ける作業をしますが、保護の解除までをまとめて、マクロで記録しておきましょう。
保護の操作は、ツールバーの校閲>シートの保護をクリックして表示されるダイアログボックスの「ロックされたセル範囲の選択」のチェックを外します。
こうして、たとえば「Macro1」に
ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True
ActiveSheet.Unprotect
ができてますか?
上の1行が保護を掛ける。下の1行が保護を解除する。ための依頼文です。
それでは、試しに

Sub aaa()

    ActiveSheet.Unprotect  'Sheet保護の解除

    Cells(9, "H") = Time           '時刻

    Cells(13, "E") = Sheets("名簿").Cells(6, "B") '社員№
    Cells(13, "F") = Sheets("名簿").Cells(6, "D") '部署
    Cells(13, "G") = Sheets("名簿").Cells(6, "C") '氏名

    ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True  'Sheet保護

End Sub

を作って実行してみてください。

すると、シート「出退」でEnterキーや矢印キーを押しても「9行目E列」から動かないことが確認できると思います。
再度、実行してみると時刻が変わるので、確かに処理されていることがわかります。
つまり、入力セル以外を保護することで「9行目E列にバーコードが読み込まれたら」の前提が整ったことになります。
(確認できたらProcedure「aaa」は削除して良いです)

段々と進むべき道が見えてきましたか?少し険しい道になりそうですが「完成の達成感」を信じて頑張りましょう。
それでは、依頼書1行目をコーディングします。(日本語(人間語)をVBA等のパソコン用語(プログラミング言語)で書くことをコーディングと呼びます。)

バーコードリーダーで読み込んだつもりで「9行目E列」に13桁の数値(例えば9910101456780など適当で良い)を入力してください。
ここでは左2桁が必要なので変数を例えば、社№とすると
社№=Left(cells(9,"E"),2)となります。(9行目E列の値の左から2文字を社№に代入しなさい)
そして「24でなければ社員証でない」はIf文を使います。これは、取り扱うデータが「与えられた条件」に合っているかを判別するときに使います。記述の例としては
If 社№ <> 24 Then
MsgBox "これは、当社の社員証ではありません。"
Exit Sub
End If
となります。
If 「条件」Then「なにかしらの処理」End If と覚えましょう。
「なにかしらの処理」はここでは、MsgBoxで「社員証でない」ことを伝えて、Exit Subで以下の処理を中断する。ことです。
この構文は、以前説明したFor to ~ Nextと同様、頻繁に使うので合わせて覚えて(保存して)おきましょう。

そして条件は、いくつかありますが、とりあえずこの「<>:Not Equal」と「=:Equal」を覚えておくと便利です。
ここで注意すべき点は、「=」です。前回までは「右辺を左辺に代入する」と言ってきましたが、この「条件」のときだけは日本語同様「等しい」の意味になるので注意です。

次に依頼書2行目は変数「社員」に5桁の社員№を取り出します。
社員=Right(cells(9,"E"),6)
社員=Left(社員,5)
ここで気になるのが、「社員=Left(社員,5)」です。変数「社員」が左右の辺に出てきます。
このとき、1行上の処理により今両辺の「社員」に13桁のうち右から6桁の数字が入っていますが、右辺の処理で左から5文字が取り出されて、左辺に戻る仕掛けです。結果的に13桁目の数字が切り落とされることになります。一見簡単そうでも気になる部分ですね。
では、この変数「社員」を使って該当する社員№を見つける処理を作ります。
考え方としては、変数「社員」とシート「名簿」の6行目B列~15行目B列の値をひとつずつ比較して等しいものが見つかるまで繰り返すことです。
では、6行目から15行まで繰り返すことにすると
For n = 6 To 15
 If 社員 = Sheets("名簿").Cells(n, "B") Then
  Cells(13, "E") = Sheets("名簿").Cells(n, "B") '社員№
  Cells(13, "F") = Sheets("名簿").Cells(n, "D") '部署
  Cells(13, "G") = Sheets("名簿").Cells(n, "C") '氏名
  Exit For
 End If
Next n

となります。
ここでもIfが出てきました。今回は条件が「=」なので、等しければ(見つかったら)となります。
そして、所定の処理をして「Exit For」で繰り返すのをやめなさい。となります。
これで、ひととおり完成ですが、厳密にいうと社員名簿の中に該当する社員№が見つからなかったらどうするか?などの処理も必要なのですが、今回のテーマはバーコードリーダーでの読込みなので、番号の間違いは無いものとして省略します。これは、手抜きでは無く仕様です。システムに関わりのある方は「仕様(スペック)」に聞き覚えがあるかと思いますが、開発者の言い訳として使われる場合もあるので注意しましょう(笑:個人的見解です)

最後の3行目は、9行H列に表示されている時刻を書き出すことになります。では、書き出す先はシート「名簿」のどのセルでしょうか。
依頼書では「出社時刻(F列)が、空白のときは出社時刻(F列)とし、空白でないときは退社時刻(G列)」と言っているので、ここでもIf文が使われます。
 If Sheets("名簿").Cells(n, "F")="" then
  Sheets("名簿").Cells(n, "F")=Cells(9,"H") '出社時刻
 Else
  Sheets("名簿").Cells(n, "G")=Cells(9,"H") '退社時刻
 End if
となります。
ここでもいくつかのポイントがあります。
日本語の「空白」は””で表し「なにもない(Null)」という意味です。
また「Else」は「~以外」
先ほどのIf文(条件)は、見つかったときだけの処理で、見つからなかったときの処理は特になかったので「Else」は省略してありました。
今回は空白でない(条件に合わないとき)ときの処理が必要なので「Else」が付きます。
つまり、Ifの条件に合うときは「Thenの処理」合わないときは「Elseの処理」となるわけです。

それでは、ここまでのCodeをまとめると

Sub 出退処理()

    社№ = Left(Cells(9, "E"), 2)
    If 社№ <> 24 Then
       MsgBox "これは、当社の社員証ではありません。" 'メッセージボックス
       Exit Sub
    End If

    ActiveSheet.Unprotect  'Sheet保護の解除

    Cells(9, "H") = Time   '時刻

    社員 = Right(Cells(9, "E"), 6) 'バーコードの右6桁を社員に代入
    社員 = Left(社員, 5)           '社員の左5桁を社員に代入(戻す)

    For n = 6 To 15

      If 社員 = Sheets("名簿").Cells(n, "B") Then

         Cells(13, "E") = Sheets("名簿").Cells(n, "B") '社員№
         Cells(13, "F") = Sheets("名簿").Cells(n, "D") '部署
         Cells(13, "G") = Sheets("名簿").Cells(n, "C") '氏名

         If Sheets("名簿").Cells(n, "F") = "" Then

            Sheets("名簿").Cells(n, "F") = Cells(9, "H") '出社時刻

         Else

            Sheets("名簿").Cells(n, "G") = Cells(9, "H") '退社時刻

         End If

         Exit For

      End If

    Next n

    ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True  'Sheet保護

End Sub

となります。
これでバーコードをリーダーで読み込むか、「9行目E列」に13桁の数値を入力した後「マクロの実行」をクリックすると動くには動くのですが、実用化へはもう一山登る必要があります。めげずに(気を取り直して)「VBAでBarCode_読込3」をご覧ください。

今回は大変険しい道程になりましたが、繰り返しお読みいただくとご理解いただけると思います。
このスキルを身に着けると、Excelさんが頼もしい右腕になりますよ。

この記事が気に入ったらサポートをしてみませんか?