2018年4月26日木曜日

Accessアクセス from VB ~Class化してみるよ~(5:とりえあず完成版)

20180428追記
なんかいろいろ勘違いしてた。動くけど、メソッドにする必要がないとかいろいろできそうなので、再開発決定

---
とりあえず実用レベルまでできた。

Public Class SetDBtoTable
    '----------
    'Variable
    '----------
    Private _Provider As String
    Private _DataSource As String
    Private _ConnectionString As String
    Private _UserID As String
    Private _Password As String
    Private _RecordCount As Long
    Private _ColumnCount As Long
    Private _DataTable(,) As String  'テーブルデータ格納場所
    '----------
    'Property
    '----------
    '------------------------------
    'DBへアクセスするために必要なProperty群
    '------------------------------
    'プロバイダ指定。Accessなら"Microsoft.Jet.OLEDB.4.0;"みたいなの
    Public Property Provider As String
        Get
            Return _Provider
        End Get
        Set(value As String)
            _Provider = value
        End Set
    End Property
    'データソース指定。Accessならファイル名
    Public Property DataSource As String
        Get
            Return _DataSource
        End Get
        Set(value As String)
            _DataSource = value
        End Set
    End Property
    'コネクションストリング。テーブル名だったりSQLだったり
    Public Property ConnectionString As String
        Get
            Return _ConnectionString
        End Get
        Set(value As String)
            _ConnectionString = value
        End Set
    End Property
    'ユーザーID。テストしてないから動くかどうかわからない( ゚-゚)~゚
    Public Property UserID As String
        Get
            Return _UserID
        End Get
        Set(value As String)
            _UserID = value
        End Set
    End Property
    'パスワード。テストしてな(以下略
    Public Property Password As String
        Get
            Return _Password
        End Get
        Set(value As String)
            _Password = value
        End Set
    End Property
    '------------------------------
    '得たデータを参照するProperty群
    '------------------------------
    'レコード数
    Public ReadOnly Property RecordCount As Long
        Get
            Return _RecordCount
        End Get
    End Property
    'カラム数
    Public ReadOnly Property ColumnCount As Long
        Get
            Return _ColumnCount
        End Get
    End Property
    'データの2次元配列の値返し。
    'てゆかPropertyじゃなくMethodにしたほがいくね?
    Public ReadOnly Property Value As String(,)
        Get
            Return _DataTable
        End Get
    End Property
    '----------
    'Constructor
    '----------
    Public Sub New()
        Debug.Print("Constructor:" & TypeName(Me))
        _Provider = "Microsoft.Jet.OLEDB.4.0;"
    End Sub
    '----------
    'Destructor
    '----------
    Private Sub Class_Terminate()
        Debug.Print("Destructor:" & TypeName(Me))
    End Sub
    '----------
    'Method
    '----------
    'DBにアクセスし、レコード数、カラム数、データ本体を読み込み、Class変数に代入
    Public Function Open() As Boolean
        Dim OnOK As Boolean = True
        Dim cn As ADODB.Connection
        Dim rs As ADODB.Recordset
        cn = New ADODB.Connection
        rs = New ADODB.Recordset
        Dim i As Integer
        Dim j As Integer
        cn.Provider = _Provider
        '_ConnectionStringが空か確認。空であればエラーを吐きFalseを返してMethod終了
        If _ConnectionString = Nothing Then
            Debug.Print("ERROR:" & TypeName(Me) & ":ConnectionString Property Not Assignment”)
            OnOK = False
            Return OnOK
        End If
        'DataSourceが空か確認。空であればエラーを吐きFalseを返してMethod終了
        If _DataSource = vbNullString Then
            Debug.Print("ERROR:" & TypeName(Me) & ":DataSource Property Not Assignment”)
            OnOK = False
            Return OnOK
        End If
        'DataSource設定(テーブ名やSQL。DELETEとか書かれても、rs.open()のときにReadOnlyで開くからはじけると思う
        cn.Properties("Data Source").Value = _DataSource
        'ID/Passwd設定(試してない
        If _UserID <> vbEmpty Then
            cn.Properties("UserID").Value = _UserID
        End If
        If _Password <> Nothing Then
            cn.Properties("Password").Value = _Password
        End If
        Try
            cn.Open()
            rs.Open(_ConnectionString, cn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockReadOnly)
            _RecordCount = rs.RecordCount
            _ColumnCount = rs.Fields.Count
            _DataTable = New String(_RecordCount - 1, _ColumnCount - 1) {}
            i = 0
            Do Until rs.EOF
                For j = 0 To _ColumnCount - 1
                    _DataTable(i, j) = rs.Fields(j).Value
                Next
                rs.MoveNext()
                i = i + 1
            Loop
            rs.Close()
            cn.Close()
        Catch ex As Exception
            'Try中のエラーのとき cnとrsのopen、データ取り込み時それぞれで節を分ければError位置が特定できる。はず。
            Debug.Print("ERROR:" & TypeName(Me) & ":DB or RS Open failed”)
            OnOK = False
        End Try
        Return OnOK
    End Function
    'クローズ。ホントは必要なさそうなんだけど、OpenしたからにはCloseしたくなるのは本能。
    'あと、いろいろ頑張って呼ぼうとしたけど出てきてくんないデストラクタくんを呼んでみる。なんもしてないんだけど。
    Public Sub close()
        _DataTable = Nothing
        Call Class_Terminate()
    End Sub
    'データ要素単体渡し。stringで返す。範囲外のINDEX渡すと怒られるぞ。
    Public Function Datas(i As Long, j As Long) As String
        Return (_DataTable(i, j))
    End Function
    'オーバーライドを試してみる。引数が数値一つだけなら、コッチが呼ばれる。
    '実動作はRecord()で。
    Public Function Datas(i As Long) As String()
        Return (Record(i))
    End Function
    'INDEXのRecordの要素全てを、Stringの1元配列型で返す。
    Public Function Record(i As Long) As String()
        Dim ReturnTable() As String
        Dim j As Long
        ReturnTable = New String(_ColumnCount - 1) {}
        For j = 0 To _ColumnCount - 1
            ReturnTable(j) = _DataTable(i, j)
        Next j
        Return (ReturnTable)
    End Function
    'INDEXのColumnの要素全てを、Stringの1元配列型で返す。
    Public Function Column(j As Long) As String()
        Dim ReturnTable() As String
        Dim i As Long
        ReturnTable = New String(_RecordCount - 1) {}
        For i = 0 To _RecordCount - 1
            ReturnTable(i) = _DataTable(i, j)
        Next i
        Return (ReturnTable)
    End Function
End Class

<<前  次>>

0 件のコメント:

コメントを投稿