★ExcelVBA ~ 【電子帳簿保存法・タイムスタンプがらみ】ファイルのハッシュ値をゲットする関数
※まだ書きかけです。すみません。
※間違ってたらすみません。
※メモ書きなので、自分でも意味不明な箇所も多いです。ごめんなさい。
参考
紙でもらった請求書はPDF化しないといけないか?→不要。
PDFやExcelなど、電子データでもらった請求書は紙にしていいか?→紙だけじゃダメ。デジタルデータのほうを保管しないといけない。
結局、「全部紙でちょうだい」が「何もしなくていい」となります。
ただし、せっかくもらった紙を「PDF化してしまう」と、
保存要件の対象になってしまうので、紙でもらったものは必ず紙のみで保管する。
======================
以下、本文です。
電子帳簿保存法の「電子データで交付や受取をした取引のデータ保存の義務化」について、猶予期間が、本年、2023年12月31日に終わります。
年明け・2024年1月1日からは、
「電子データで交付や受取をした取引のデータ保存」が「完全義務化」となります。
「紙に印刷して保存Only」が法的に「ダメ・違法」になります。
(※電子データのままの保存がちゃんとしてあれば、追加で紙に印刷することは違法ではない。万が一のために重要書類だけ電子と紙の両方で保管することは違法ではない。管理が大変になるかもしれませんけど。)
もちろん、その対象は「電子データでもらったもの」「だけ」です。
紙でもらった請求書は紙のままでOKです。PDF化する必要はないし、PDF化すると逆に「法律上の保存システム」が必要になってしまうので、むしろPDF化などをしてはいけません。
で、結局どのような方法が義務付けられるのかというと、結論から言うと、
「社内規約さえ作っておけばいい」
です。
基本的には、「もらったデータ(PDF等)を絶対に編集・改ざんしない」という原則にして、そういった、「取り扱いのルール(=社内規約書)」を書いたものを用意して、「日付、取引先、金額」での検索がすぐにできる状態におけば、巷でよく言われている「有料のタイムスタンプ付加」などは不要のようです。
(ただし、それは請求書や見積書などの書類のみ。「電子契約書」などの場合は別。「電子契約書」などの場合はタイムスタンプなどが必須。)
※参考:国税庁HP ~ 問9 電子取引の取引情報に係る電磁的記録の保存等を行う場合には、どのような要件を満たさなければならないのでしょうか。
以下、要件の引用です。↓
電子計算機処理システムの概要を記載した書類の備付け(自社開発のプログラムを使用する場合に限ります。)(規3![]() ![]() ![]() |
見読可能装置の備付け等(規3![]() ![]() |
検索機能の確保(規3![]() ![]() ![]() |
次のいずれかの措置を行う(規8![]()
|
上記の表の、一番下の、「四 訂正削除の防止に関する事務処理規程の備付け」が
前述した、
『基本的には、「もらったデータ(PDF等)を絶対に編集・改ざんしない」という原則にして、そういった、「取り扱いのルール(=社内規約書)」』
ということになります。
ただ、そのとき、「絶対に編集させない」ということを「助ける」意味で、「電帳法が言うところのタイムスタンプ」、「ファイルのハッシュ値と更新日付」を記録しておくのは1つの方法だと思います。
もちろん、Acrobat Readerで無料のタイムスタンプを付ける方法もよいかと思います。
参考:Acrobat Readerで無料のタイムスタンプを付けた場合の証拠?のミニ画面
↓
ただし、無料のタイムスタンプは、あくまでも、
電子契約書以外の電子データにて、
「四 訂正削除の防止に関する事務処理規程の備付け」、をする場合の、
「単に、より改ざんを予防するためだけの」、
「補完機能」、
としてでしか使ってはいけません。
「Acrobat Readerで無料でタイムスタンプを付ける方法」はタイムサーバーが国税庁が認めないタイプのサーバーの恐れもあるため、電子契約書には使えないかもしれません。だからです。
なので、もし無料のタイムスタンプを付けるなら、アクロバットではなくて、「みんなのタイムスタンプ」みたいなものが良いのかもしれません。
参考:みんなのタイムスタンプ
Acrobat Readerの無料タイムスタンプだと、結局、あとになって、
「このサーバーのタイムスタンプだと、要件を満たしたことにならないので、ここに保存してあるPDFは全部違法です」、
と言われてしまう恐れがあります。ぞっとしますね(^^)
そうならないようにするために、以下のようなことが必要だと思われます。
(01)電子契約書などの有料のタイムスタンプが必要な書類には、
しっかり有料のタイムスタンプを付ける。
無料なら、「みんなのタイムスタンプ」のようなサービス?
(02)電子契約書以外の、タイムスタンプが不要な書類には、
社内規約で対応し、保険(改ざん予防策)として無料のタイムスタンプか、
後述のような関数を使って、「ファイルのハッシュ値+更新日付」などの記録、
保管しておくといいと思います。
今回のプログラムは、上記の(02)に使うためのモノです。
(「みんなのタイムスタンプ」のような「Webに自社の書類をアップすること自体が嫌だ、怖い」、と言う場合も、使えるかもしれません。予防策としてだけ。)
では以下、指定したファイルからハッシュ値を取得する関数です。
(日付を付加まではしていませんので、その部分はまた自作する必要があります。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
' ' ' Option Explicit '指定したファイルのハッシュ値を、指定したセルに書き出す関数 ' '呼び出し方 'Call AddHashResult("ファイルパス", "ハッシュアルゴリズム", 出力先の単一セルのオブジェクト式) ' '【例】↓ 'Call AddHashResult("d:\1\タイムスタンプテスト01-01.pdf", "sha256", ActiveSheet.Range("B5")) Function AddHashResult(s_FilePath As String, _ s_HashStyle As String, _ o_Cell As Range) Dim v_HashResultAry As Variant Dim s_Result01 As String Dim s_Result02 As String v_HashResultAry = v_GetFileHash(s_FilePath, s_HashStyle) o_Cell.Value = v_HashResultAry(1) End Function '-------------------------------------------------------------------------------- '引数で指定したファイルのハッシュ値(ダイジェスト値)等を、 'Variant型の1次元配列で返します。 ' ' s_FilePath:ファイルパス。テキスト型のリテラルで指定。 ' s_HashAlgo:ハッシュアルゴリズムの種類。MD5,SHA1,SHA256などをテキスト型のリテラルで指定。 ' v_GetFileHash:コマンドの結果が配列で格納されます。 ' 要素(0)は検証したファイルのパスなど、が返り、 ' 要素(1)は検証したファイルのハッシュ値、が返ります。 '-------------------------------------------------------------------------------- Public Function v_GetFileHash(s_FilePath As String, s_HashAlgo As String) As Variant Dim o_WSH As Object Dim o_wshExec As Object Dim s_Cmd As String Dim s_Output As String Set o_WSH = CreateObject("WScript.Shell") s_Cmd = "certutil -hashfile " & _ """" & s_FilePath & """" & _ " " & s_HashAlgo & _ " | findstr /V CertUtil | findstr /V " & _ s_HashAlgo Set o_wshExec = o_WSH.Exec("%ComSpec% /c " & s_Cmd) Do While o_wshExec.Status = 0 DoEvents Loop s_Output = o_wshExec.stdOut.ReadAll Dim s_OutptStr01 As String Dim s_OutptStr02 As String ' Stop s_OutptStr01 = Left(s_Output, InStr(1, s_Output, vbCrLf)) s_OutptStr01 = Replace(s_OutptStr01, vbCrLf, "", , , vbBinaryCompare) s_OutptStr01 = Replace(s_OutptStr01, vbLf, "", , , vbBinaryCompare) s_OutptStr01 = Replace(s_OutptStr01, vbCr, "", , , vbBinaryCompare) s_OutptStr02 = Replace(s_Output, s_OutptStr01, "", , , vbBinaryCompare) s_OutptStr02 = Replace(s_OutptStr02, vbCrLf, "", , , vbBinaryCompare) s_OutptStr02 = Replace(s_OutptStr02, vbLf, "", , , vbBinaryCompare) s_OutptStr02 = Replace(s_OutptStr02, vbCr, "", , , vbBinaryCompare) Set o_wshExec = Nothing Set o_WSH = Nothing v_GetFileHash = Array(s_OutptStr01, s_OutptStr02) ' Stop End Function Sub GetHashResultAryTest01() Dim s_FilePath As String Dim v_HashResultAry As Variant Let s_FilePath = "d:\1\タイムスタンプテスト01-01.pdf" v_HashResultAry = v_GetFileHash(s_FilePath, "sha256") Dim s_01 As String Dim s_02 As String s_01 = v_HashResultAry(0) s_02 = v_HashResultAry(1) Debug.Print InStr(1, v_HashResultAry(0), vbCrLf) Debug.Print InStr(1, v_HashResultAry(1), vbCrLf) Debug.Print s_01 Debug.Print s_02 End Sub ' ' |
- 投稿タグ
- 「ニセモノ」への道, 「本物」に近づくために, AccessVBA, Accessの独学, Access操作の基礎, ADO/DAO, ExcelSQL, ExcelVBA, Excelの独学, Excel操作の基礎, Excel連携VBA, MicrosoftQuery, ODBC, SQL, パソコンでの自動化, ビジネスパソコンの基礎, ビジネス一般常識, マクロ, ワークシート関数, 独学, 自動化