書式を直すだけなら、ふつーに正規表現とかでぱたぱたと出来たのだけど、
なにしろボクはVBAのお約束を知らない。
参照渡しをSetにするとかゆーのは、あちこちで見かけたので問題なかったのだけど、
まさか、引数を渡すのに括弧つけちゃダメな言語があったとはっ!と…
あとアレだ。Class内部のコーディングのミスを、
呼び出し側のPropertyの設定ミスとしてエラー吐くのはどうよ。
そこカプセル化しちゃダメだよね?てなトコロ。
Openさせたときにエラー吐かせて拾おうとしたら、
Class内部でのエラー回避処理には引っかからず、
Open Method読んでるトコでエラー吐くし。内部でのチェック意味ねー( ゚-゚)~゚
仕上がりはけっこーおざなり。
とりあえず動いたからいいや的な作りなので、丸写しで追求しないか、
使いやすいようカスタマイズしてください( ゚-゚)~゚
参考:AccessアクセスClassをVBAに移植してみた~呼び出し側~
(Class Module : SetDBtoTable )
- Option Explicit
- '指定したDBを読み込み、テーブルで返す。
- '----------
- 'Variable
- '----------
- Private m_Provider As String
- Private m_DataSource As String
- Private m_ConnectionString As String
- Private m_UserID As String
- Private m_Password As String
- Private m_RecordCount As Integer
- Private m_ColumnCount As Integer
- Private m_DataTable() As String 'テーブルデータ格納場所
- Private cn As ADODB.Connection
- Private rs As ADODB.Recordset
- '----------
- 'Property
- '----------
- '------------------------------
- 'DBへアクセスするために必要なProperty群
- '------------------------------
- 'プロバイダ指定。Accessなら"Microsoft.Jet.OLEDB.4.0;"みたいなの
- Property Get Provider() As String
- Provider = m_Provider
- End Property
- Property Let Provider(Provider As String)
- m_Provider = Provider
- End Property
- 'データソース指定。Accessならファイル名
- Property Get DataSource() As String
- DataSource = m_DataSource
- End Property
- Property Let DataSource(DataSource As String)
- m_DataSource = DataSource
- End Property
- 'コネクションストリング。テーブル名だったりSQLだったり
- Property Get ConnectionString() As String
- ConnectionString = m_ConnectionString
- End Property
- Property Let ConnectionString(ConnectionString As String)
- m_ConnectionString = ConnectionString
- End Property
- 'ユーザーID。テストしてないから動くかどうかわからない( ゚-゚)~゚
- Property Get UserID() As String
- UserID = m_UserID
- End Property
- Property Let UserID(UserID As String)
- m_UserID = UserID
- End Property
- 'パスワード。テストしてな(以下略
- Property Get Password() As String
- Password = m_Password
- End Property
- Property Let Password(Password As String)
- m_Password = Password
- End Property
- '------------------------------
- '得たデータを参照するProperty群
- '------------------------------
- 'レコード数
- Property Get RecordCount() As Long
- RecordCount = m_RecordCount
- End Property
- 'カラム数
- Property Get ColumnCount() As Long
- ColumnCount = m_ColumnCount
- End Property
- 'Value Override群 Start…って思ったら、Overrideできないでやんの( ゚-゚)~゚
- Property Get Value() As String()
- Value = m_DataTable
- End Property
- 'Item Override群 Start Default Property指定。Default指定もできないでやんの
- Property Get Item(ByVal i As Integer, ByVal j As Integer) As String
- Item = m_DataTable(i, j)
- End Property
- Property Get Record(ByVal i As Integer) As String()
- Record = m_Record(i)
- End Property
- Property Get Column(ByVal j As Integer) As String()
- Column = m_Column(j)
- End Property
- '----------
- 'Constructor
- '----------
- Private Sub Class_Initialize()
- Debug.Print ("Constructor:" & TypeName(Me))
- m_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 OpenDB() As Boolean
- Dim OnOK As Boolean
- OnOK = True
- Set cn = New ADODB.Connection
- Set rs = New ADODB.Recordset
- Dim i As Integer
- Dim j As Integer
- cn.Provider = m_Provider
- '_ConnectionStringが空か確認。空であればエラーを吐きFalseを返してMethod終了
- If m_ConnectionString = "" Then
- Debug.Print ("ERROR:" & TypeName(Me) & ":ConnectionString Property Not Assignment")
- OnOK = False
- OpenDB = OnOK
- End If
- 'DataSourceが空か確認。空であればエラーを吐きFalseを返してMethod終了
- If m_DataSource = "" Then
- Debug.Print ("ERROR:" & TypeName(Me) & ":DataSource Property Not Assignment")
- OnOK = False
- OpenDB = OnOK
- Exit Function
- End If
- 'DataSource設定
- cn.Properties("Data Source").Value = m_DataSource
- 'ID/Passwd設定(試してない
- If m_UserID <> "" Then
- cn.Properties("UserID").Value = m_UserID
- End If
- If m_Password <> "" Then
- cn.Properties("Password").Value = m_Password
- End If
- On Error GoTo Error_Handler
- cn.Open
- 'ConnectionString(テーブ名やSQL。DELETEとか書かれても、
- 'rs.open()のときにReadOnlyで開くからはじけると思う
- rs.Source = m_ConnectionString
- rs.ActiveConnection = cn
- rs.CursorType = ADODB.CursorTypeEnum.adOpenKeyset
- rs.LockType = ADODB.LockTypeEnum.adLockReadOnly
- rs.Open
- m_RecordCount = rs.RecordCount
- m_ColumnCount = rs.Fields.Count
- ReDim m_DataTable(m_RecordCount - 1, m_ColumnCount - 1)
- i = 0
- Do Until rs.EOF
- For j = 0 To m_ColumnCount - 1
- m_DataTable(i, j) = rs.Fields(j).Value
- Next j
- rs.MoveNext
- i = i + 1
- Loop
- OpenDB = OnOK
- Exit Function
- Error_Handler:
- 'Try中のエラーのとき cnとrsのopen、データ取り込み時それぞれで節を分ければError位置が特定できる。はず。
- Debug.Print ("ERROR:" & TypeName(Me) & ":DB or RS Open failed")
- OnOK = False
- Error_Handler_End:
- OpenDB = OnOK
- End Function
- 'クローズ。ホントは必要なさそうなんだけど、OpenしたからにはCloseしたくなるのは本能。
- 'VBAはちゃんとデストラクタくんが動いてくれるのでcallはしない。。
- Public Sub CloseDB()
- rs.Close
- cn.Close
- Erase m_DataTable
- End Sub
- Public Sub putData()
- rs.MoveFirst
- ActiveCell.CopyFromRecordset rs
- End Sub
- Public Sub putRange(Arg_Range As String, Optional Worksheet As String)
- rs.MoveFirst
- If Worksheet = vbNullString Then
- ActiveSheet.Range(Arg_Range).CopyFromRecordset rs
- Else
- Worksheets(Worksheet).Range(Arg_Range).CopyFromRecordset rs
- End If
- End Sub
- Public Sub putCells(ByVal Row As Integer, ByVal Col As Integer, Optional ByVal Worksheet As String)
- rs.MoveFirst
- If Worksheet = vbNullString Then
- ActiveSheet.Cells(Row, Col).CopyFromRecordset rs
- Else
- Worksheets(Worksheet).Cells(Row, Col).CopyFromRecordset rs
- End If
- End Sub
- '----------
- 'Private Function
- '----------
- 'データ要素単体渡し。stringで返す。範囲外のINDEX渡すと怒られるぞ。
- Private Function m_Item(ByVal i As Integer, ByVal j As Integer) As String
- m_Item = m_DataTable(i, j)
- End Function
- 'INDEXのRecordの要素全てを、Stringの1元配列型で返す。
- Private Function m_Record(ByVal i As Integer) As String()
- Dim ReturnTable() As String
- Dim j As Integer
- ReDim ReturnTable(m_ColumnCount - 1)
- For j = 0 To m_ColumnCount - 1
- ReturnTable(j) = m_DataTable(i, j)
- Next j
- m_Record = ReturnTable
- End Function
- 'INDEXのColumnの要素全てを、Stringの1元配列型で返す。
- Private Function m_Column(ByVal j As Integer) As String()
- Dim ReturnTable() As String
- Dim i As Integer
- ReDim ReturnTable(m_RecordCount - 1)
- For i = 0 To m_RecordCount - 1
- ReturnTable(i) = m_DataTable(i, j)
- Next i
- m_Column = ReturnTable
- End Function