OA_Properties.bas 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. Option Compare Database
  2. Option Private Module
  3. Option Explicit
  4. '****
  5. '*
  6. '* Import/Export the properties of DAO Objects
  7. '*
  8. '****
  9. Public Sub ExportProperties(ByVal daoObject As Object, ByVal file_path As String)
  10. 'exports the properties of an Access DAO object (Database, Cintainer, TableDef, Querydef, Field)
  11. ' to a file, with a TAB separator
  12. '
  13. On Error GoTo err
  14. mktree parent_dir(file_path)
  15. Dim prp As Object
  16. Dim prp_name, prp_value, Line As String
  17. Dim prp_type As Integer
  18. Dim count As Integer
  19. count = 0
  20. Call logger("ExportProperties", "INFO", "Try to export the properties of '" & daoObject.name & "' to '" & file_path & "'")
  21. Dim objStream As ADODB.Stream
  22. Set objStream = CreateObject("ADODB.Stream")
  23. objStream.Open
  24. objStream.Type = 2 'Text
  25. objStream.Charset = "x-ansi"
  26. For Each prp In daoObject.Properties
  27. If Not isReadOnly(prp) Then
  28. prp_name = prp.name
  29. prp_value = CStr(prp.value)
  30. Line = prp_name & vbTab & prp_value & vbTab & CStr(prp.Type)
  31. objStream.WriteText Line, adWriteLine
  32. count = count + 1
  33. End If
  34. Next prp
  35. Call logger("ExportProperties", "INFO", "> " & count & " properties exported")
  36. exitsub:
  37. objStream.SaveToFile file_path, adSaveCreateOverWrite
  38. objStream.Close
  39. Exit Sub
  40. err:
  41. Call logger("ExportProperties", "ERROR", "Error during database properties export: " & err.Description)
  42. GoTo exitsub
  43. 'err_prop:
  44. ' Call logger("ExportProperties", "ERROR", "Error while exporting property " & prp_name & "")
  45. ' GoTo next_prop
  46. End Sub
  47. Public Sub ImportProperties(daoObject As Object, file_path As String)
  48. 'Import the properties of an EXISTING Access DAO object (Database, Cintainer, TableDef, Querydef, Field)
  49. '! warning, it is not really stable
  50. On Error GoTo err
  51. Dim splitted_line As Variant
  52. Dim Line, prp_name, prp_value As String
  53. Dim prp_type As Integer
  54. Dim buffer As String
  55. Dim count As Integer
  56. Call logger("ImportProperties", "INFO", "Try to import the properties of '" & daoObject.name & "' from '" & file_path & "'")
  57. buffer = ReadFile(file_path, "x-ansi")
  58. count = 0
  59. For Each Line In Split(buffer, vbNewLine)
  60. If Len(Line) = 0 Then Exit For
  61. count = count + 1
  62. splitted_line = Split(Line, vbTab)
  63. prp_name = splitted_line(0)
  64. prp_value = splitted_line(1)
  65. prp_type = CInt(splitted_line(2))
  66. If prp_value <> vbNullString Then
  67. Call SetOrCreateProperty(daoObject, prp_name, prp_value, prp_type, True)
  68. End If
  69. Next
  70. Call logger("ImportProperties", "INFO", "> Done")
  71. Exit Sub
  72. err:
  73. Call logger("ImportProperties", "ERROR", "Error during database properties import (line " & count & "): " & err.Description)
  74. End Sub
  75. Public Sub test_prop()
  76. Dim db As DAO.Database
  77. Dim td As DAO.TableDef
  78. Call set_debug_mode
  79. '
  80. ' Set db = CurrentDb
  81. ' Set td = db.TableDefs("test")
  82. '
  83. ' ExportTableDef db, td, CurrentProject.path
  84. ' db.Close
  85. ' Set td = Nothing
  86. ' Set db = Nothing
  87. '
  88. 'Call ExportTableProperties("test", CurrentProject.path)
  89. '
  90. 'ImportTableDef "test", CurrentProject.path
  91. Call ImportTableProperties("test", CurrentProject.path & "\test.properties.xml")
  92. End Sub
  93. Public Sub ExportTableProperties(table_name As String, dirpath As String)
  94. Dim db As DAO.Database
  95. Dim td, field As Object
  96. Dim prp As Property
  97. Dim oXML As MSXML2.DOMDocument60
  98. Dim oNode, oSubNode, oFieldNode As MSXML2.IXMLDOMNode
  99. Dim oElt As MSXML2.IXMLDOMElement
  100. Dim oAttribut As IXMLDOMAttribute
  101. dirpath = norm_dir_path(dirpath)
  102. mktree dirpath
  103. Set oXML = New MSXML2.DOMDocument60
  104. oXML.appendChild oXML.createProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8""")
  105. Set oNode = oXML.appendChild(oXML.createElement("properties"))
  106. Set oSubNode = oNode.appendChild(oXML.createElement("table"))
  107. Set db = Application.CurrentDb
  108. Set td = db.Containers("tables").Documents(table_name)
  109. For Each prp In td.Properties
  110. If Not isReadOnly(prp) Then
  111. Set oElt = oSubNode.appendChild(oXML.createElement(prp.name))
  112. If prp.Type = 1 Then
  113. oElt.Text = CStr(CByte(prp.value))
  114. Else
  115. oElt.Text = CStr(prp.value)
  116. End If
  117. Set oAttribut = oXML.createAttribute("type")
  118. oAttribut.Text = CStr(prp.Type)
  119. oElt.setAttributeNode oAttribut
  120. End If
  121. Next prp
  122. Set oSubNode = oNode.appendChild(oXML.createElement("fields"))
  123. For Each field In db.TableDefs(table_name).Fields
  124. Set oFieldNode = oSubNode.appendChild(oXML.createElement(field.name))
  125. For Each prp In field.Properties
  126. If Not isReadOnly(prp) Then
  127. Set oElt = oFieldNode.appendChild(oXML.createElement(prp.name))
  128. If prp.Type = 1 Then
  129. oElt.Text = CStr(CByte(prp.value))
  130. Else
  131. oElt.Text = CStr(prp.value)
  132. End If
  133. Set oAttribut = oXML.createAttribute("type")
  134. oAttribut.Text = CStr(prp.Type)
  135. oElt.setAttributeNode oAttribut
  136. End If
  137. Next prp
  138. Next field
  139. Dim file_path As String
  140. file_path = joinpaths(dirpath, table_name & ".properties.xml")
  141. oXML.Save file_path
  142. Call logger("ExportTableProperties", "DEBUG", "> " & table_name & " properties exported to " & file_path)
  143. end_:
  144. Set oNode = Nothing
  145. Set oXML = Nothing
  146. End Sub
  147. Public Sub ImportTableProperties(table_name As String, filepath As String)
  148. Dim db As DAO.Database
  149. Dim td As Object
  150. Dim field As Object
  151. Dim prp As Property
  152. Dim prp_name As String
  153. Dim prp_value As String
  154. Dim prp_type As String
  155. Dim buffer As String
  156. Dim oXML As MSXML2.DOMDocument60
  157. Dim oNode As MSXML2.IXMLDOMNode
  158. Dim oSubNode As MSXML2.IXMLDOMNode
  159. Dim oFieldNode As MSXML2.IXMLDOMNode
  160. Dim oElt As MSXML2.IXMLDOMElement
  161. Dim oAttribut As IXMLDOMAttribute
  162. filepath = norm_path(filepath)
  163. buffer = ReadFile(filepath, "x-ansi")
  164. Set oXML = New MSXML2.DOMDocument60
  165. oXML.loadXML buffer
  166. Set db = Application.CurrentDb
  167. 'Set td = db.Containers("tables").Documents(table_name)
  168. Set td = db.TableDefs(table_name)
  169. Set oNode = oXML.childNodes(1)
  170. ' "table" node
  171. Set oSubNode = oNode.childNodes(0)
  172. For Each oElt In oSubNode.childNodes
  173. prp_name = oElt.nodeName
  174. prp_value = oElt.Text
  175. prp_type = oElt.Attributes(0).Text
  176. SetOrCreateProperty td, prp_name, prp_value, prp_type
  177. Next oElt
  178. ' "fields" node
  179. Set oSubNode = oNode.childNodes(1)
  180. For Each oFieldNode In oSubNode.childNodes
  181. Set field = db.TableDefs(table_name).Fields(oFieldNode.nodeName)
  182. For Each oElt In oFieldNode.childNodes
  183. prp_name = oElt.nodeName
  184. prp_value = oElt.Text
  185. prp_type = oElt.Attributes(0).Text
  186. SetOrCreateProperty field, prp_name, prp_value, prp_type
  187. Next oElt
  188. Next oFieldNode
  189. Call logger("ImportTableProperties", "DEBUG", "> " & table_name & " properties imported from " & filepath)
  190. end_:
  191. Set oNode = Nothing
  192. Set oXML = Nothing
  193. End Sub
  194. Sub SetOrCreateProperty(ByRef daoObject As Object, ByVal prp_name As String, ByVal prp_value As String, ByVal prp_type As Integer, Optional ByVal IgnoreReadOnly As Boolean = False)
  195. Dim prp As Object
  196. On Error GoTo err
  197. Set prp = daoObject.Properties(prp_name)
  198. If prp.Inherited = True Then Exit Sub
  199. prp.value = convert(prp_value, prp_type)
  200. Exit Sub
  201. err:
  202. Select Case err.Number
  203. Case 3270
  204. ' property not found
  205. CreateProperty daoObject, prp_name, prp_value, prp_type
  206. Case 3421
  207. logger "SetOrCreateProperty", "ERROR", daoObject.name & " - " & prp_name & " : Type is not compatible with property (" & prp_value & ", " & prp_type & ")"
  208. Case Else
  209. logger "SetOrCreateProperty", "ERROR", daoObject.name & " - " & prp_name & " : " & err.Description
  210. End Select
  211. End Sub
  212. Public Sub CreateProperty(ByRef daoObject As Variant, ByVal prp_name As String, ByVal prp_value As String, ByVal prp_type As Integer)
  213. On Error GoTo err
  214. Dim prp As Object
  215. prp_value = convert(prp_value, prp_type)
  216. Set prp = daoObject.CreateProperty(prp_name, prp_type, prp_value)
  217. daoObject.Properties.Append prp
  218. Exit Sub
  219. err:
  220. Call logger("CreateProperty", "ERROR", "> Unable to create the property (" & daoObject.name & " - " & prp_name & ": " & prp_value & ", " & prp_type & "): " & err.Description)
  221. End Sub
  222. Function convert(value As String, dbType As Integer)
  223. Select Case dbType
  224. Case dbBoolean
  225. convert = CBool(convert)
  226. Case dbByte
  227. convert = CByte(value)
  228. Case dbInteger
  229. convert = CInt(value)
  230. Case dbLong
  231. convert = CLng(value)
  232. Case dbCurrency
  233. convert = CCur(value)
  234. Case dbSingle
  235. convert = CSng(value)
  236. Case dbDouble
  237. convert = CDbl(value)
  238. Case dbDate
  239. convert = CDate(value)
  240. Case dbText
  241. convert = CStr(value)
  242. Case dbLongBinary
  243. convert = CStr(value)
  244. Case dbMemo
  245. convert = CStr(value)
  246. Case dbGUID
  247. convert = CStr(value)
  248. Case Else
  249. convert = CVar(value)
  250. End Select
  251. End Function
  252. Public Function isReadOnly(prp As DAO.Property) As Boolean
  253. On Error GoTo err
  254. If prp.Inherited = True Then GoTo err
  255. DAO.BeginTrans
  256. prp.value = prp.value
  257. isReadOnly = False
  258. DAO.Rollback
  259. Exit Function
  260. err:
  261. isReadOnly = True
  262. DAO.Rollback
  263. End Function