2018年4月30日月曜日

AccessアクセスClassをVBAに移植してみた~Class本体~

けっこー大変だったorz
書式を直すだけなら、ふつーに正規表現とかでぱたぱたと出来たのだけど、
なにしろボクはVBAのお約束を知らない。
参照渡しをSetにするとかゆーのは、あちこちで見かけたので問題なかったのだけど、
まさか、引数を渡すのに括弧つけちゃダメな言語があったとはっ!と…
あとアレだ。Class内部のコーディングのミスを、
呼び出し側のPropertyの設定ミスとしてエラー吐くのはどうよ。
そこカプセル化しちゃダメだよね?てなトコロ。
Openさせたときにエラー吐かせて拾おうとしたら、
Class内部でのエラー回避処理には引っかからず、
Open Method読んでるトコでエラー吐くし。内部でのチェック意味ねー( ゚-゚)~゚

仕上がりはけっこーおざなり。
とりあえず動いたからいいや的な作りなので、丸写しで追求しないか、
使いやすいようカスタマイズしてください( ゚-゚)~゚

参考:AccessアクセスClassをVBAに移植してみた~呼び出し側~


(Class Module : SetDBtoTable )

  1. Option Explicit
  2. '指定したDBを読み込み、テーブルで返す。
  3. '----------
  4. 'Variable
  5. '----------
  6. Private m_Provider As String
  7. Private m_DataSource As String
  8. Private m_ConnectionString As String
  9. Private m_UserID As String
  10. Private m_Password As String
  11. Private m_RecordCount As Integer
  12. Private m_ColumnCount As Integer
  13. Private m_DataTable() As String 'テーブルデータ格納場所
  14. Private cn As ADODB.Connection
  15. Private rs As ADODB.Recordset
  16. '----------
  17. 'Property
  18. '----------
  19. '------------------------------
  20. 'DBへアクセスするために必要なProperty群
  21. '------------------------------
  22. 'プロバイダ指定。Accessなら"Microsoft.Jet.OLEDB.4.0;"みたいなの
  23. Property Get Provider() As String
  24. Provider = m_Provider
  25. End Property
  26. Property Let Provider(Provider As String)
  27. m_Provider = Provider
  28. End Property
  29. 'データソース指定。Accessならファイル名
  30. Property Get DataSource() As String
  31. DataSource = m_DataSource
  32. End Property
  33. Property Let DataSource(DataSource As String)
  34. m_DataSource = DataSource
  35. End Property
  36. 'コネクションストリング。テーブル名だったりSQLだったり
  37. Property Get ConnectionString() As String
  38. ConnectionString = m_ConnectionString
  39. End Property
  40. Property Let ConnectionString(ConnectionString As String)
  41. m_ConnectionString = ConnectionString
  42. End Property
  43. 'ユーザーID。テストしてないから動くかどうかわからない( ゚-゚)~゚
  44. Property Get UserID() As String
  45. UserID = m_UserID
  46. End Property
  47. Property Let UserID(UserID As String)
  48. m_UserID = UserID
  49. End Property
  50. 'パスワード。テストしてな(以下略
  51. Property Get Password() As String
  52. Password = m_Password
  53. End Property
  54. Property Let Password(Password As String)
  55. m_Password = Password
  56. End Property
  57. '------------------------------
  58. '得たデータを参照するProperty群
  59. '------------------------------
  60. 'レコード数
  61. Property Get RecordCount() As Long
  62. RecordCount = m_RecordCount
  63. End Property
  64. 'カラム数
  65. Property Get ColumnCount() As Long
  66. ColumnCount = m_ColumnCount
  67. End Property
  68. 'Value Override群 Start…って思ったら、Overrideできないでやんの( ゚-゚)~゚
  69. Property Get Value() As String()
  70. Value = m_DataTable
  71. End Property
  72. 'Item Override群 Start Default Property指定。Default指定もできないでやんの
  73. Property Get Item(ByVal i As Integer, ByVal j As Integer) As String
  74. Item = m_DataTable(i, j)
  75. End Property
  76. Property Get Record(ByVal i As Integer) As String()
  77. Record = m_Record(i)
  78. End Property
  79. Property Get Column(ByVal j As Integer) As String()
  80. Column = m_Column(j)
  81. End Property
  82. '----------
  83. 'Constructor
  84. '----------
  85. Private Sub Class_Initialize()
  86. Debug.Print ("Constructor:" & TypeName(Me))
  87. m_Provider = "Microsoft.Jet.OLEDB.4.0;"
  88. End Sub
  89. '----------
  90. 'Destructor
  91. '----------
  92. Private Sub Class_Terminate()
  93. Debug.Print ("Destructor:" & TypeName(Me))
  94. End Sub
  95. '----------
  96. 'Method
  97. '----------
  98. 'DBにアクセスし、レコード数、カラム数、データ本体を読み込み、Class変数に代入
  99. Public Function OpenDB() As Boolean
  100. Dim OnOK As Boolean
  101. OnOK = True
  102. Set cn = New ADODB.Connection
  103. Set rs = New ADODB.Recordset
  104. Dim i As Integer
  105. Dim j As Integer
  106. cn.Provider = m_Provider
  107. '_ConnectionStringが空か確認。空であればエラーを吐きFalseを返してMethod終了
  108. If m_ConnectionString = "" Then
  109. Debug.Print ("ERROR:" & TypeName(Me) & ":ConnectionString Property Not Assignment")
  110. OnOK = False
  111. OpenDB = OnOK
  112. End If
  113. 'DataSourceが空か確認。空であればエラーを吐きFalseを返してMethod終了
  114. If m_DataSource = "" Then
  115. Debug.Print ("ERROR:" & TypeName(Me) & ":DataSource Property Not Assignment")
  116. OnOK = False
  117. OpenDB = OnOK
  118. Exit Function
  119. End If
  120. 'DataSource設定
  121. cn.Properties("Data Source").Value = m_DataSource
  122. 'ID/Passwd設定(試してない
  123. If m_UserID <> "" Then
  124. cn.Properties("UserID").Value = m_UserID
  125. End If
  126. If m_Password <> "" Then
  127. cn.Properties("Password").Value = m_Password
  128. End If
  129. On Error GoTo Error_Handler
  130. cn.Open
  131. 'ConnectionString(テーブ名やSQL。DELETEとか書かれても、
  132. 'rs.open()のときにReadOnlyで開くからはじけると思う
  133. rs.Source = m_ConnectionString
  134. rs.ActiveConnection = cn
  135. rs.CursorType = ADODB.CursorTypeEnum.adOpenKeyset
  136. rs.LockType = ADODB.LockTypeEnum.adLockReadOnly
  137. rs.Open
  138. m_RecordCount = rs.RecordCount
  139. m_ColumnCount = rs.Fields.Count
  140. ReDim m_DataTable(m_RecordCount - 1, m_ColumnCount - 1)
  141. i = 0
  142. Do Until rs.EOF
  143. For j = 0 To m_ColumnCount - 1
  144. m_DataTable(i, j) = rs.Fields(j).Value
  145. Next j
  146. rs.MoveNext
  147. i = i + 1
  148. Loop
  149. OpenDB = OnOK
  150. Exit Function
  151. Error_Handler:
  152. 'Try中のエラーのとき cnとrsのopen、データ取り込み時それぞれで節を分ければError位置が特定できる。はず。
  153. Debug.Print ("ERROR:" & TypeName(Me) & ":DB or RS Open failed")
  154. OnOK = False
  155. Error_Handler_End:
  156. OpenDB = OnOK
  157. End Function
  158. 'クローズ。ホントは必要なさそうなんだけど、OpenしたからにはCloseしたくなるのは本能。
  159. 'VBAはちゃんとデストラクタくんが動いてくれるのでcallはしない。。
  160. Public Sub CloseDB()
  161. rs.Close
  162. cn.Close
  163. Erase m_DataTable
  164. End Sub
  165. Public Sub putData()
  166. rs.MoveFirst
  167. ActiveCell.CopyFromRecordset rs
  168. End Sub
  169. Public Sub putRange(Arg_Range As String, Optional Worksheet As String)
  170. rs.MoveFirst
  171. If Worksheet = vbNullString Then
  172. ActiveSheet.Range(Arg_Range).CopyFromRecordset rs
  173. Else
  174. Worksheets(Worksheet).Range(Arg_Range).CopyFromRecordset rs
  175. End If
  176. End Sub
  177. Public Sub putCells(ByVal Row As Integer, ByVal Col As Integer, Optional ByVal Worksheet As String)
  178. rs.MoveFirst
  179. If Worksheet = vbNullString Then
  180. ActiveSheet.Cells(Row, Col).CopyFromRecordset rs
  181. Else
  182. Worksheets(Worksheet).Cells(Row, Col).CopyFromRecordset rs
  183. End If
  184. End Sub
  185. '----------
  186. 'Private Function
  187. '----------
  188. 'データ要素単体渡し。stringで返す。範囲外のINDEX渡すと怒られるぞ。
  189. Private Function m_Item(ByVal i As Integer, ByVal j As Integer) As String
  190. m_Item = m_DataTable(i, j)
  191. End Function
  192. 'INDEXのRecordの要素全てを、Stringの1元配列型で返す。
  193. Private Function m_Record(ByVal i As Integer) As String()
  194. Dim ReturnTable() As String
  195. Dim j As Integer
  196. ReDim ReturnTable(m_ColumnCount - 1)
  197. For j = 0 To m_ColumnCount - 1
  198. ReturnTable(j) = m_DataTable(i, j)
  199. Next j
  200. m_Record = ReturnTable
  201. End Function
  202. 'INDEXのColumnの要素全てを、Stringの1元配列型で返す。
  203. Private Function m_Column(ByVal j As Integer) As String()
  204. Dim ReturnTable() As String
  205. Dim i As Integer
  206. ReDim ReturnTable(m_RecordCount - 1)
  207. For i = 0 To m_RecordCount - 1
  208. ReturnTable(i) = m_DataTable(i, j)
  209. Next i
  210. m_Column = ReturnTable
  211. End Function

0 件のコメント:

コメントを投稿