パソリPC-S300で読み取ったデータをExcelに出力したい【VBA】

目次

環境

Windowsの仕様

エディション:Windows 10 Pro

バージョン:20H2

経緯

非接触ICカードリーダーを使って、そのカードの中の数値でいろいろできないか試したくて、

今回勉強しました。

ドライバーをインストール

はじめに以下のドライバーをダウンロードして、
https://www.sony.co.jp/Products/felica/consumer/support/download/nfcportsoftware.html

exeファイルをインストールしてください。

Windows APIを使う

次に、コードを書きます。モジュール1にコピペしてください。

'' Windows標準APIを使用するための宣言。エラーが発生した場合は"ERROR:"で始まるメッセージを返し、
'' 正常に読み込みができた場合はUIDを返す。カードリーダはSONY RC-S380のみが動作確認済み。
'' TypeBのカードは乱数値(PUPI)を返すため、このコードでは実用的ではない。

Public Function readUID() As String
'' readUIDという名前のPublic関数を定義。戻り値の型はString。

Const SCARD_SCOPE_USER As Integer = 0
'' SCARD_SCOPE_USERという定数を宣言し、0で初期化。この定数はスマートカードのスコープ定義に使用される。

Dim ret As LongPtr
Dim pcchReaders As Long
Dim mszReaders As String
Dim readerArray() As String
'' 必要な変数を宣言。
'' ret: API関数の戻り値を保持
'' pcchReaders: カードリーダのリスト長を保持
'' mszReaders: カードリーダのリストを保持
'' readerArray: カードリーダの名前を保持する文字列配列

ret = SCardEstablishContext(SCARD_SCOPE_USER, 0, 0, hContext)
'' スマートカードリソースマネージャの新しいコンテキストを確立。

If ret <> 0 Then
    readUID = "ERROR:初期化処理に失敗しました!"
    Exit Function
End If
'' 初期化が正常に行われなかった場合、エラーメッセージを返して関数を終了。

pcchReaders = 256
'' カードリーダのリスト長を256に設定。

If readerState.szReader = "" Then
'' 現在のリーダーの状態が未設定の場合、以下の処理を実行。

   ret = SCardListReaders(hContext, vbNullString, mszReaders, pcchReaders)
   '' カードリーダのリストを取得。

   If ret <> 0 Then
       readUID = "ERROR:カードリーダが見つかりません!"
       Exit Function
   End If
   '' カードリーダのリスト取得が失敗した場合、エラーメッセージを返して関数を終了。

   mszReaders = String$(pcchReaders, vbNullChar)
   '' カードリーダのリストを初期化。

   ret = SCardListReaders(hContext, vbNullString, mszReaders, pcchReaders)
   '' カードリーダのリストを取得。

   If ret <> 0 Then
       readUID = "ERROR:カードリーダが見つかりません!"
       Exit Function
   End If
   '' カードリーダのリスト取得が失敗した場合、エラーメッセージを返して関数を終了。

   readerArray = Split(mszReaders, vbNullChar)
   '' カードリーダのリストを配列に変換。

   readerState.dwCurrentState = 0
   readerState.szReader = readerArray(0)
   '' カードリーダの状態を設定。
End If

Dim hCard As LongPtr
Dim activeProtocol As Long
'' カードとプロトコルの変数を宣言。

ret = SCardConnectA(hContext, readerState.szReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, hCard, activeProtocol)
'' スマートカードリソースマネージャに接続。

If ret <> 0 Then
    readUID = "ERROR:正しいカードをセットしてください!"
    Exit Function
End If
'' 接続が失敗した場合、エラーメッセージを返して関数を終了。

Dim sendBuffer(4) As Byte
Dim recvBuffer(255) As Byte
Dim recvLen As Long
Dim ioSendReq As SCARD_IO_REQUEST
Dim ioRecvReq As SCARD_IO_REQUEST
'' 必要な変数を宣言。送信と受信用のバッファ、受信長、送受信リクエストオブジェクト。

ioSendReq.dwProtocol = activeProtocol
ioSendReq.cbPciLength = Len(ioSendReq)
ioRecvReq.dwProtocol = activeProtocol
ioRecvReq.cbPciLength = Len(ioSendReq)
'' 送受信リクエストオブジェクトを設定。

sendBuffer(0) = &HFF
sendBuffer(1) = &HCA
sendBuffer(2) = &H0
sendBuffer(3) = &H0
sendBuffer(4) = &H0
'' 送信バッファにデータを設定。

recvLen = 255
ret = SCardTransmit(hCard, ioSendReq, sendBuffer(0), 5, ioRecvReq, recvBuffer(0), recvLen)
'' スマートカードとの通信を行い、結果を受信バッファに格納。

If ret <> 0 Then
    readUID = "ERROR:ID取得エラー(Transmit:" & Hex(ret) & ")"
    GoTo ExitProc
End If
'' 通信が失敗した場合、エラーメッセージを返してExitProcラベルへジャンプ。

If recvBuffer(recvLen - 2) <> &H90 Then
    readUID = "ERROR:ID取得エラー(読込異常:" & Hex(recvBuffer(0)) & "," & Hex(recvBuffer(1)) & ")"
    GoTo ExitProc
End If
'' 受信データが正常でない場合、エラーメッセージを返してExitProcラベルへジャンプ。

ExitProc:
'' ExitProcラベル。

ret = SCardDisconnect(hCard, SCARD_LEAVE_CARD)
'' スマートカードリソースマネージャから切断。

If ret <> 0 Then
    MsgBox ("ERROR:切断エラー " + Hex(ret))
    Exit Function
End If
'' 切断が失敗した場合、エラーメッセージを表示して関数を終了。

Dim cardData As String
Dim i As Long
cardData = ""
For i = 0 To 8
    If Chr(recvBuffer(i)) <> Space(1) Then
        cardData = cardData & Hex(recvBuffer(i))
    End If
Next
'' 受信バッファからデータを取得し、文字列に変換。

readUID = cardData
'' 関数の戻り値にデータを設定。

End Function
'' 関数の終わり。

これは、

  1. API宣言: これらはWindowsのWinscard.dllライブラリに対するAPI呼び出しを宣言しています。これにより、カードリーダーへの接続、切断、カード情報の取得などの機能を利用することができます。
  2. readUID関数: これは実際のカード読み取りロジックを含む主要な関数です。ここでは、カードリーダーへの接続、カード情報の送受信、エラーチェック、そしてカードから読み取ったUIDの出力を行っています。
  3. エラーハンドリング: 各ステップでエラーチェックを行い、エラーメッセージを出力しています。

ということをしています。

実行マクロを作る

次にモジュール2を作って、以下のコードをコピペしてください。

Public Sub ExecuteReadUID()
    Dim result As String
    result = readUID()
    MsgBox result
End Sub

という感じです。

あとは、Excelの”挿入”からボタンとか作って、↑のコードをマクロ登録して、端末にICカードをかざして、ボタンを押すとカードの中の数値が出力されると思います。

参考になれば、幸いです。

ここまで読んでいただきありがとうございました。

スクールの紹介

最後に宣伝をさせてください。

夢見るAIエンジニアへ、今こそ一歩を踏み出せ!

最近、AI技術やデータサイエンスに興味を持ち始めたあなた。将来、AIエンジニアやデータサイエンティストとして活躍したいと考えているかもしれません。また、AIを使って業務課題や研究課題を解決したい、あるいは教養としてAIの知識を深めたいと思っている方もいるでしょう。

しかし、学び始めるとなると「どこから手をつけて良いのか分からない」「専門的すぎて理解できない」といった悩みが生じることも。そんなあなたのために、この3ヶ月間集中してAIプログラミングを習得するオンラインコーチングサービスがオススメです!

なぜこのサービスが選ばれるのか?その理由はこちら

  1. 初心者から上級者まで
    完全なプログラミング初心者から研究者まで、幅広い方々に優良なコンテンツが提供されます。
  2. 徹底的な進捗管理
    受講者の進捗をしっかりとチェックし、つまずきやすいポイントでのフォローが万全です。
  3. 専属メンターによる徹底サポート
    AIの学び方から、実際の適用まで、専属のメンターが手厚くサポートします。
  4. 場所を選ばず学べるオンライン完結
    東京以外の地域からも、気軽に学び始めることができます。

信頼の実績多数!
・日本最大級のプログラミングスクール実績
・受講者総数700名以上
・SaaS型学習サービス会員65,000名以上
・企業導入実績120社以上
・グッドデザイン賞受賞
・著名な賞受賞歴や経団連加盟も実現

夢を叶えるための第一歩を、一緒に踏み出しませんか?今なら、あなたもその一員として学び始めることができます!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次