[Access][VBA]MSAccess マクロでOLE型に埋め込まれたjpgファイルを取り出したい 単体テストしてみました
要約:AccessのOLE型フィールドに埋め込まれたjpgファイルを抽出する方法について説明しています。
VBAを使用してファイルデータからJPEGの開始マーカ(0xFFD8)と終了マーカ(0xFFD9)を見つけ、
その間のデータを新しいファイルとして保存
キーワード: #AccessVBA #MSAccess #OLE型 #jpg抽出 #VBA #マクロ #デバッグ #マイクロソフトアクセス
youtu.be
https://youtu.be/SjHwJ2JH83I
目次
00:00 やりたいこと
00:53 テストを開始する jpgファイルを埋め込み、レコードを作成する
02:54 1.2 埋込を証明したいので、元ファイルを削除する
03:45 1.3 テストコードを実行する 保存されたファイル ID.jpg をダブルクリックで確認する
2.コードの説明:
05:12 2.1 OLE型の中身を見る Packageになっていて場所が変化する
07:22 可変の長さでパッケージ名がバイナリデータの頭に入っていることを確認する
10:39 2.2 JPEGファイルの構造 開始マーカ(0xFFD8)と終了マーカ(0xFFD9)を探しバイナリ出力する
16:24 JPGファイルの位置が変化することを確認する
18:48 3.不具合、バグ BMP ビットマップで誤認するバグが残ってます
23:49 4.おわりの挨拶 最後にループの説明まとめ
やりたいこと:
OLE型のフィールドにjpgファイルが埋め込まれています。このjpgファイルを取り出したい。
リンクではなく埋め込まれたファイルを取得したい
似た処理:
Access OLE型のフィールドに埋め込まれているWordデータをファイルに保存 デバッグ マクロ作り方・使い方
Access OLE型のフィールドに埋め込まれているWordデータをファイルに保存 デバッグ マクロ作り方・使い方 - YouTube
で下記の質問コメントをいただきました。
質問内容:
>wordではなく、アクセスにold型で埋め込まれたjpgの写真ファイルを取り出す場合の
>vbaの書き方を教えて頂く事は可能でしょうか。
1.いきなり結果のテストを開始する
1.1 jpgファイルを埋め込み、レコードを作成する
1.2 埋込を証明したいので、元ファイルを削除する
1.3 テストコードを実行する
1.4 保存されたファイル ID.jpg をダブルクリックで起動する
2.コードの説明:
05:12 https://www.youtube.com/watch?v=SjHwJ2JH83I&t=312
2.1 OLE型の中身を見る
デバッグで止めて、
' OLEオブジェクトが埋め込みの場合 Dim fileData() As Byte fileData = Me!OLE型.Value
ここで、
? left(strconv(filedata,vbUnicode),400)
で、↑頭から400文字の中身を表示、ファイル名など、jpgに不要なデータが入っている?
可変の長さでパッケージ名がバイナリデータの頭に入っていることを確認する
07:22 https://www.youtube.com/watch?v=SjHwJ2JH83I&t=442
? left(strconv(filedata,vbUnicode),400)
? # 7 パッケージャー シェル オブジェクト Package Package 駻 おじさん02.jpg D:\2024\試作品ボツ企画\20240513AccessOLE画像\おじさん02.jpg ・
↑↓パッケージ名やファイル名が可変になることを確認する。
? left(strconv(filedata,vbUnicode),400)
? # 7 パッケージャー シェル オブジェクト Package Package ・ おじさん9999999 D:\2024\試作品ボツ企画\20240513AccessOLE画像\おじさん02.jpg ・
2.2 jpg専用処理 私は埋込パッケージの中からjpgの位置を探したかった
10:39 https://www.youtube.com/watch?v=SjHwJ2JH83I&t=639
JPEGファイルの構造
https://hp.vector.co.jp/authors/VA032610/JPEGFormat/StructureOfJPEG.htm
hp.vector.co.jp
より
>マーカとは、種別を表す2バイトのコードで、1バイト目は必ず0xFFです。
>
>SOI スタートマーカ (Start of Image) 0xFFD8
>EOI エンドマーカ (End of Image) 0xFFD9
上記のコードで
スタートからエンドまでを切り出すと、
もしかしたら、できるかも・・・
と、思い、下記のテストを行ってみた。
Private Sub コマンド7_Click() Dim strPATH As String '保存先のパス strPATH = Application.CurrentProject.Path & "\" 'DBと同じ位置に保存 If Me!OLE型.OLEType = acOLEEmbedded Then ' OLEオブジェクトが埋め込みの場合 Dim fileData() As Byte fileData = Me!OLE型.Value Dim n As Long Dim nSTART As Long nSTART = 0 'フラグも兼ねて0初期化 Dim nEND As Long nEND = 0 'フラグも兼ねて0初期化 'jpg先頭 0xFFD8を探す For n = 0 To UBound(fileData) If fileData(n) = &HFF And fileData(n + 1) = &HD8 Then '0xFFD8を探す Debug.Print n, fileData(n), fileData(n + 1) nSTART = n '開始位置を代入 Exit For End If Next n 'jpg終了 0xFFD9を探す For n = (UBound(fileData) - 1) To 1 Step -1 '終了を後ろから If fileData(n) = &HFF And fileData(n + 1) = &HD9 Then '0xFFD9を探す Debug.Print n, fileData(n), fileData(n + 1) nEND = n '終了位置を代入 Exit For End If Next n Debug.Print "場所:", nSTART, nEND '※bmpで FFD8などあるので、誤認する・・・おいおい・・・ If nSTART = 0 Or nEND = 0 Then 'jpgの位置が不明ならメッセージ MsgBox "jpgデータの位置を解析できません" Else '開始位置から終了まで、バイナリデータを書き出す 'ファイルに書き込む Dim strFNAME As String strFNAME = strPATH & Me!ID & ".jpg" 'ファイルパスとIDで名前を作成 Dim fileNO As Integer fileNO = FreeFile Open strFNAME For Binary Access Write As #fileNO For n = nSTART To nEND + 1 Put #fileNO, , fileData(n) '1バイト単位で書き込む Next n Close #fileNO MsgBox strFNAME & "へ書き込み終了、確認して下さい" End If Else MsgBox "OLEが埋込ではない、確認して下さい" End If End Sub
3.不具合、バグ
18:48 https://www.youtube.com/watch?v=SjHwJ2JH83I&t=1128
単純に
'jpg先頭 0xFFD8を探す
しているので、
BMPファイルやビットマップの埋め込みに反応してしまう・・・
本当は、エラー判断したいのに・・・
4.おわりの挨拶
作りかけのコードですが、
OLE型からjpgファイルを取り出す処理の参考となれば、、、
アレンジして使ってみてください。
1.要約:
AccessのOLE型フィールドに埋め込まれたjpgファイルを抽出する方法について説明しています。このプロセスは、VBAを使用してファイルデータからJPEGの開始マーカ(0xFFD8)と終了マーカ(0xFFD9)を見つけ、その間のデータを新しいファイルとして保存することによって行われます。
2.キーワード:
Access, OLE型, jpg抽出, VBA, マクロ, デバッグ, ファイル保存, JPEG, バイナリデータ
3.YouTubeタイトル案:
- AccessでOLE型jpgを抽出!VBAマクロの使い方
- OLE型フィールドからjpgを救出!Access VBAテクニック
- Access VBAで学ぶ:OLE型フィールド内jpgの抽出方法
4.似ている単語のペア:
- Accessとアクセス
- OLE型とオブジェクトリンキングと埋め込み
- jpgとJPEG
- VBAとビジュアルベーシック・フォー・アプリケーション
- マクロと自動化スクリプト
プロンプト:
おじさんプログラマーが表示されているコードを見て悩んでいる姿をイラストで描いてください。
↑と、指定すると、
かなりの確率で、お腹を出した男性のイラストが生成されます。
※太ったおじさん=お腹を出しているイメージ???