投稿者 魔界の仮面弁士  (社会人) 投稿日時 2019/11/27 14:33:55
添付ファイル型以外(たとえば数値や文字列)の読み書きに関する基本的な知識はあるという前提で回答します。

TBL 表において、ID 列(テキスト型)が主キー、
CONTENTS 列が添付ファイル型になっているとした場合、
 TBL.CONTENTS.FileName で添付ファイル名
 TBL.CONTENTS.FileType で拡張子
 TBL.CONTENTS.FileData で添付データ
が返されます。

FileData の先頭にはヘッダ部が含まれていますので、
先頭 4 バイトをオフセットとして読み取った位置が
添付ファイルの本体データとなります。


Imports System.Data.OleDb
Imports System.IO

Public Class Form1
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Me.FlowLayoutPanel1.AutoScroll = True
        Me.FlowLayoutPanel1.BorderStyle = BorderStyle.Fixed3D
        Me.FlowLayoutPanel1.FlowDirection = FlowDirection.TopDown
        Me.FlowLayoutPanel1.WrapContents = False
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        ClearItems()

        Dim sql As String = "SELECT TBL.CONTENTS.FileName AS NM, TBL.CONTENTS.FileType AS EXT, TBL.CONTENTS.FileData AS BIN FROM TBL WHERE TBL.ID=?"
        Using conn As New OleDbConnection(My.Settings.ConnectionString)
            conn.Open()
            Using cmd As New OleDbCommand(sql, conn)
                cmd.Parameters.Add("id", OleDbType.VarChar, 3)
                cmd.Parameters("id").Value = TextBox1.Text

                Dim reader = cmd.ExecuteReader()
                Do While reader.Read()
                    Dim nm As String = CStr(reader!NM)
                    Dim ext As String = CStr(reader!EXT)
                    Dim bin() As Byte = DirectCast(reader!BIN, Byte())
                    AddItem(nm, ext, bin)
                Loop
            End Using
            conn.Close()
        End Using
    End Sub


    Private Sub AddItem(attachName As String, extension As String, contents As Byte())
        Debug.WriteLine(attachName)
        Debug.WriteLine(extension)
        Debug.WriteLine(BitConverter.ToString(contents))

        Dim offset As Integer = BitConverter.ToInt32(contents, 0)
        Dim bin() As Byte = contents.Skip(offset).ToArray()

        Dim lblFileName As New Label()
        lblFileName.Text = attachName
        lblFileName.AutoSize = True
        lblFileName.UseMnemonic = False
        lblFileName.ForeColor = Color.Blue
        Me.FlowLayoutPanel1.Controls.Add(lblFileName)

        Dim lblSize As New Label()
        lblSize.Text = String.Format("{0:N0} Bytes", contents.Length)
        lblSize.AutoSize = True
        Me.FlowLayoutPanel1.Controls.Add(lblSize)

        Dim pic As New PictureBox()
        pic.BorderStyle = BorderStyle.FixedSingle
        pic.BackColor = Color.White
        pic.Margin = New Padding(0, 0, 0, 20)
        Dim stm As New MemoryStream(bin)
        Try
            pic.Image = Image.FromStream(stm)
            pic.Size = pic.Image.Size
            lblSize.Text &= String.Format(", ({0}x{1})", pic.Width, pic.Height)
        Catch
            stm.Dispose()
            pic.Image = pic.ErrorImage
        End Try
        Me.FlowLayoutPanel1.Controls.Add(pic)
    End Sub

    Private Sub ClearItems()
        Me.FlowLayoutPanel1.SuspendLayout()
        For Each ctrl In Me.FlowLayoutPanel1.Controls.OfType(Of Control)().ToArray()
            Using ctrl
                Me.FlowLayoutPanel1.Controls.Remove(ctrl)
            End Using
        Next
        Me.FlowLayoutPanel1.ResumeLayout(True)
    End Sub
End Class