キーエンスのVHXというデジタルマイクロスコープをよく使っているが、寸法計測した値をたくさん処理するときに面倒があった。
csvファイルを保存してそのデータを読み込む。→面倒くさい
しかし、VHXの画面上でjpg画像を見るとデータありみたいなアイコンになるので、jpgファイルにデータが埋め込まれているはずだと考えた。
自動でまとめまでできれば、jpgだけ持って帰って処理すればいいので楽になる。
バイナリデータを見る限り、末尾に測定値が埋め込まれているようだ。しかもプレーンテキストで。ラッキー。
では、これらを取り出して必要なデータを取り出せばcsvファイル出力の一手間が省略できる。
[メイン]以下のデータだけで済むだろうから、そこを取り出す。おそらくバイナリを比較して[ メイン ]の文字を探して行けばいいが、作り始めたときはjpgデータ無いに文字列と同じバイナリ列があるかもと思ってjpgファイルのFFD9(0xFF 0xD9)のデータを探したあとに文字列を探すことにした。
jpgファイルは、0xFFが特徴的な識別子になっていて、jpg構造の最後には0xFF 0xD9の2バイト並びでファイルが終了する。しかし、サムネイルを含んでいる場合はサムネイルもまたjpg構造を持っているので、ファイルの最後の0xFF 0xD9を探し、それ以降のテキストを比較することにした。
command button1,2は上のボタンです。出力行が21だったり、変数固定の部分がいくらかあります。赤文字は上の表の当該セルなので場所を変えたらソースも変えてください。
Const StartCol = 20 Option Explicit Private Sub CommandButton1_Click() Dim FileName Dim FileNames FileNames = Application.GetOpenFilename("VHX jpg files,*.jpg", , , , True) If TypeName(FileNames) <> "Variant()" Then Exit Sub End If For Each FileName In FileNames Call ConvertVHXimageFile(FileName, ConvertFileName(FileName)) Next FileName MsgBox "done" End Sub
Function ConvertFileName(VHXimageFileName) As String 'ファイル名の拡張子をtxtにするだけ。関数にせんでもよかったな。 ConvertFileName = Left(VHXimageFileName, InStrRev(VHXimageFileName, ".")) & "csv" End Function
Sub ConvertVHXimageFile(VHXimageFileName, OutputTextFileName As String) Dim Fn As Integer 'ファイル入出力番号として Dim i As Long 'どっかで使う Dim j As Long Dim EOBinary As Long 'jpgのバイナリが終わる位置 Dim TxtStart As Long 'テキスト開始位置 Dim VHXimage() As Byte 'jpg画像のバイナリを入れる配列 'ファイルを開いて配列に入れる Fn = FreeFile Open VHXimageFileName For Binary As #Fn ReDim VHXimage(LOF(Fn)) Get #Fn, , VHXimage Close #Fn 'jpgデータ終わりを示すFFD9を探す 'なぜかVHXの画像には複数のFFD9があるから最後まで探す For i = 0 To UBound(VHXimage) - 1 If VHXimage(i) = &HFF And VHXimage(i + 1) = &HD9 Then EOBinary = i End If Next i '[ メイン ]の文字列を探す Dim HeaderOfText() As Byte HeaderOfText = StrConv("""[ メイン ]""", vbFromUnicode) '文字列をバイナリ配列にしておく Dim SizeOfHeader As Long SizeOfHeader = UBound(HeaderOfText) 'データ探し For i = EOBinary To UBound(VHXimage) - SizeOfHeader For j = 0 To SizeOfHeader If VHXimage(i + j) <> HeaderOfText(j) Then '文字列が違ったらすっ飛ばし Exit For End If If j = 9 Then '文字列合致が9回?連続したら本物 ■9回じゃなくて、変数にできるやろ TxtStart = i 'そこがtextの開始行だ! Exit For End If Next j Next i '出力ファイルの準備。 Dim OutTxt() As Byte 'サイズの定義 ReDim OutTxt(UBound(VHXimage) - TxtStart) For i = TxtStart To UBound(VHXimage) OutTxt(i - TxtStart) = VHXimage(i) Next i 'ファイル出力 Fn = FreeFile Open OutputTextFileName For Binary As #Fn For i = 0 To UBound(OutTxt) - 1 Put #Fn, , OutTxt(i) Next i Close #Fn End Sub