UtilProperty.xba 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
  3. <script:module xmlns:script="http://openoffice.org/2000/script" script:name="UtilProperty" script:language="StarBasic">
  4. REM =======================================================================================================================
  5. REM === The Access2Base library is a part of the LibreOffice project. ===
  6. REM === Full documentation is available on http://www.access2base.com ===
  7. REM =======================================================================================================================
  8. &apos;**********************************************************************
  9. &apos; UtilProperty module
  10. &apos;
  11. &apos; Module of utilities to manipulate arrays of PropertyValue&apos;s.
  12. &apos;**********************************************************************
  13. &apos;**********************************************************************
  14. &apos; Copyright (c) 2003-2004 Danny Brewer
  15. &apos; d29583@groovegarden.com
  16. &apos;**********************************************************************
  17. &apos;**********************************************************************
  18. &apos; If you make changes, please append to the change log below.
  19. &apos;
  20. &apos; Change Log
  21. &apos; Danny Brewer Revised 2004-02-25-01
  22. &apos; Jean-Pierre Ledure Adapted to Access2Base coding conventions
  23. &apos; PropValuesToStr rewritten and addition of StrToPropValues
  24. &apos; Bug corrected on date values
  25. &apos; Addition of support of 2-dimensional arrays
  26. &apos; Support of empty arrays to allow JSON conversions
  27. &apos;**********************************************************************
  28. Option Explicit
  29. Private Const cstHEADER = &quot;### PROPERTYVALUES ###&quot;
  30. Private Const cstEMPTYARRAY = &quot;### EMPTY ARRAY ###&quot;
  31. REM =======================================================================================================================
  32. Public Function _MakePropertyValue(ByVal Optional psName As String, Optional pvValue As Variant) As com.sun.star.beans.PropertyValue
  33. &apos; Create and return a new com.sun.star.beans.PropertyValue.
  34. Dim oPropertyValue As New com.sun.star.beans.PropertyValue
  35. If Not IsMissing(psName) Then oPropertyValue.Name = psName
  36. If Not IsMissing(pvValue) Then oPropertyValue.Value = _CheckPropertyValue(pvValue)
  37. _MakePropertyValue() = oPropertyValue
  38. End Function &apos; _MakePropertyValue V1.3.0
  39. REM =======================================================================================================================
  40. Public Function _CheckPropertyValue(ByRef pvValue As Variant) As Variant
  41. &apos; Date BASIC variables give error. Change them to strings
  42. &apos; Empty arrays should be replaced by cstEMPTYARRAY
  43. If VarType(pvValue) = vbDate Then
  44. _CheckPropertyValue = Utils._CStr(pvValue, False)
  45. ElseIf IsArray(pvValue) Then
  46. If UBound(pvValue, 1) &lt; LBound(pvValue, 1) Then _CheckPropertyValue = cstEMPTYARRAY Else _CheckPropertyValue = pvValue
  47. Else
  48. _CheckPropertyValue = pvValue
  49. End If
  50. End Function &apos; _CheckPropertyValue
  51. REM =======================================================================================================================
  52. Public Function _NumPropertyValues(ByRef pvPropertyValuesArray As Variant) As Integer
  53. &apos; Return the number of PropertyValue&apos;s in an array.
  54. &apos; Parameters:
  55. &apos; pvPropertyValuesArray - an array of PropertyValue&apos;s, that is an array of com.sun.star.beans.PropertyValue.
  56. &apos; Returns zero if the array contains no elements.
  57. Dim iNumProperties As Integer
  58. If Not IsArray(pvPropertyValuesArray) Then iNumProperties = 0 Else iNumProperties = UBound(pvPropertyValuesArray) + 1
  59. _NumPropertyValues() = iNumProperties
  60. End Function &apos; _NumPropertyValues V1.3.0
  61. REM =======================================================================================================================
  62. Public Function _FindPropertyIndex(ByRef pvPropertyValuesArray As Variant, ByVal psPropName As String ) As Integer
  63. &apos; Find a particular named property from an array of PropertyValue&apos;s.
  64. &apos; Finds the index in the array of PropertyValue&apos;s and returns it, or returns -1 if it was not found.
  65. Dim iNumProperties As Integer, i As Integer, vProp As Variant
  66. iNumProperties = _NumPropertyValues(pvPropertyValuesArray)
  67. For i = 0 To iNumProperties - 1
  68. vProp = pvPropertyValuesArray(i)
  69. If UCase(vProp.Name) = UCase(psPropName) Then
  70. _FindPropertyIndex() = i
  71. Exit Function
  72. EndIf
  73. Next i
  74. _FindPropertyIndex() = -1
  75. End Function &apos; _FindPropertyIndex V1.3.0
  76. REM =======================================================================================================================
  77. Public Function _FindProperty(ByRef pvPropertyValuesArray As Variant, ByVal psPropName As String) As com.sun.star.beans.PropertyValue
  78. &apos; Find a particular named property from an array of PropertyValue&apos;s.
  79. &apos; Finds the PropertyValue and returns it, or returns Null if not found.
  80. Dim iPropIndex As Integer, vProp As Variant
  81. iPropIndex = _FindPropertyIndex(pvPropertyValuesArray, psPropName)
  82. If iPropIndex &gt;= 0 Then
  83. vProp = pvPropertyValuesArray(iPropIndex) &apos; access array subscript
  84. _FindProperty() = vProp
  85. EndIf
  86. End Function &apos; _FindProperty V1.3.0
  87. REM =======================================================================================================================
  88. Public Function _GetPropertyValue(ByRef pvPropertyValuesArray As Variant, ByVal psPropName As String, Optional pvDefaultValue) As Variant
  89. &apos; Get the value of a particular named property from an array of PropertyValue&apos;s.
  90. &apos; vDefaultValue - This value is returned if the property is not found in the array.
  91. Dim iPropIndex As Integer, vProp As Variant, vValue As Variant, vMatrix As Variant, i As Integer, j As Integer
  92. iPropIndex = _FindPropertyIndex(pvPropertyValuesArray, psPropName)
  93. If iPropIndex &gt;= 0 Then
  94. vProp = pvPropertyValuesArray(iPropIndex) &apos; access array subscript
  95. vValue = vProp.Value &apos; get the value from the PropertyValue
  96. If VarType(vValue) = vbString Then
  97. If vValue = cstEMPTYARRAY Then _GetPropertyValue() = Array() Else _GetPropertyValue() = vValue
  98. ElseIf IsArray(vValue) Then
  99. If IsArray(vValue(0)) Then &apos; Array of arrays
  100. vMatrix = Array()
  101. ReDim vMatrix(0 To UBound(vValue), 0 To UBound(vValue(0)))
  102. For i = 0 To UBound(vValue)
  103. For j = 0 To UBound(vValue(0))
  104. vMatrix(i, j) = vValue(i)(j)
  105. Next j
  106. Next i
  107. _GetPropertyValue() = vMatrix
  108. Else
  109. _GetPropertyValue() = vValue &apos; Simple vector OK
  110. End If
  111. Else
  112. _GetPropertyValue() = vValue
  113. End If
  114. Else
  115. If IsMissing(pvDefaultValue) Then pvDefaultValue = Null
  116. _GetPropertyValue() = pvDefaultValue
  117. EndIf
  118. End Function &apos; _GetPropertyValue V1.3.0
  119. REM =======================================================================================================================
  120. Public Sub _SetPropertyValue(ByRef pvPropertyValuesArray As Variant, ByVal psPropName As String, ByVal pvValue As Variant)
  121. &apos; Set the value of a particular named property from an array of PropertyValue&apos;s.
  122. Dim iPropIndex As Integer, vProp As Variant, iNumProperties As Integer
  123. iPropIndex = _FindPropertyIndex(pvPropertyValuesArray, psPropName)
  124. If iPropIndex &gt;= 0 Then
  125. &apos; Found, the PropertyValue is already in the array. Just modify its value.
  126. vProp = pvPropertyValuesArray(iPropIndex) &apos; access array subscript
  127. vProp.Value = _CheckPropertyValue(pvValue) &apos; set the property value.
  128. pvPropertyValuesArray(iPropIndex) = vProp &apos; put it back into array
  129. Else
  130. &apos; Not found, the array contains no PropertyValue with this name. Append new element to array.
  131. iNumProperties = _NumPropertyValues(pvPropertyValuesArray)
  132. If iNumProperties = 0 Then
  133. pvPropertyValuesArray = Array(_MakePropertyValue(psPropName, pvValue))
  134. Else
  135. &apos; Make array larger.
  136. Redim Preserve pvPropertyValuesArray(iNumProperties)
  137. &apos; Assign new PropertyValue
  138. pvPropertyValuesArray(iNumProperties) = _MakePropertyValue(psPropName, pvValue)
  139. EndIf
  140. EndIf
  141. End Sub &apos; _SetPropertyValue V1.3.0
  142. REM =======================================================================================================================
  143. Public Sub _DeleteProperty(ByRef pvPropertyValuesArray As Variant, ByVal psPropName As String)
  144. &apos; Delete a particular named property from an array of PropertyValue&apos;s.
  145. Dim iPropIndex As Integer
  146. iPropIndex = _FindPropertyIndex(pvPropertyValuesArray, psPropName)
  147. If iPropIndex &gt;= 0 Then _DeleteIndexedProperty(pvPropertyValuesArray, iPropIndex)
  148. End Sub &apos; _DeletePropertyValue V1.3.0
  149. REM =======================================================================================================================
  150. Public Sub _DeleteIndexedProperty(ByRef pvPropertyValuesArray As Variant, ByVal piPropIndex As Integer)
  151. &apos; Delete a particular indexed property from an array of PropertyValue&apos;s.
  152. Dim iNumProperties As Integer, i As Integer
  153. iNumProperties = _NumPropertyValues(pvPropertyValuesArray)
  154. &apos; Did we find it?
  155. If piPropIndex &lt; 0 Then
  156. &apos; Do nothing
  157. ElseIf iNumProperties = 1 Then
  158. &apos; Just return a new empty array
  159. pvPropertyValuesArray = Array()
  160. Else
  161. &apos; If it is NOT the last item in the array, then shift other elements down into it&apos;s position.
  162. If piPropIndex &lt; iNumProperties - 1 Then
  163. &apos; Bump items down lower in the array.
  164. For i = piPropIndex To iNumProperties - 2
  165. pvPropertyValuesArray(i) = pvPropertyValuesArray(i + 1)
  166. Next i
  167. EndIf
  168. &apos; Redimension the array to have one fewer element.
  169. Redim Preserve pvPropertyValuesArray(iNumProperties - 2)
  170. EndIf
  171. End Sub &apos; _DeleteIndexedProperty V1.3.0
  172. REM =======================================================================================================================
  173. Public Function _PropValuesToStr(ByRef pvPropertyValuesArray As Variant) As String
  174. &apos; Return a string with dumped content of the array of PropertyValue&apos;s.
  175. &apos; SYNTAX:
  176. &apos; NameOfProperty = This is a string (or 12 or 2016-12-31 12:05 or 123.45 or -0.12E-05 ...)
  177. &apos; NameOfArray = (10)
  178. &apos; 1;2;3;4;5;6;7;8;9;10
  179. &apos; NameOfMatrix = (2,10)
  180. &apos; 1;2;3;4;5;6;7;8;9;10
  181. &apos; A;B;C;D;E;F;G;H;I;J
  182. &apos; Semicolons and backslashes are escaped with a backslash (see _CStr and _CVar functions)
  183. Dim iNumProperties As Integer, sResult As String, i As Integer, j As Integer, vProp As Variant
  184. Dim sName As String, vValue As Variant, iType As Integer
  185. Dim cstLF As String
  186. cstLF = vbLf()
  187. iNumProperties = _NumPropertyValues(pvPropertyValuesArray)
  188. sResult = cstHEADER &amp; cstLF
  189. For i = 0 To iNumProperties - 1
  190. vProp = pvPropertyValuesArray(i)
  191. sName = vProp.Name
  192. vValue = vProp.Value
  193. iType = VarType(vValue)
  194. Select Case iType
  195. Case &lt; vbArray &apos; Scalar
  196. sResult = sResult &amp; sName &amp; &quot; = &quot; &amp; Utils._CStr(vValue, False) &amp; cstLF
  197. Case Else &apos; Vector or matrix
  198. If uBound(vValue, 1) &lt; 0 Then
  199. sResult = sResult &amp; sName &amp; &quot; = (0)&quot; &amp; cstLF
  200. &apos; 1-dimension but vector of vectors must also be considered
  201. ElseIf VarType(vValue(0)) &gt;= vbArray Then
  202. sResult = sResult &amp; sName &amp; &quot; = (&quot; &amp; UBound(vValue) + 1 &amp; &quot;,&quot; &amp; UBound(vValue(0)) + 1 &amp; &quot;)&quot; &amp; cstLF
  203. For j = 0 To UBound(vValue)
  204. sResult = sResult &amp; Utils._CStr(vValue(j), False) &amp; cstLF
  205. Next j
  206. Else
  207. sResult = sResult &amp; sName &amp; &quot; = (&quot; &amp; UBound(vValue, 1) + 1 &amp; &quot;)&quot; &amp; cstLF
  208. sResult = sResult &amp; Utils._CStr(vValue, False) &amp; cstLF
  209. End If
  210. End Select
  211. Next i
  212. _PropValuesToStr() = Left(sResult, Len(sResult) - 1) &apos; Remove last LF
  213. End Function &apos; _PropValuesToStr V1.3.0
  214. REM =======================================================================================================================
  215. Public Function _StrToPropValues(psString) As Variant
  216. &apos; Return an array of PropertyValue&apos;s rebuilt from the string parameter
  217. Dim vString() As Variant, i As Integer,iArray As Integer, iRows As Integer, iCols As Integer
  218. Dim lPosition As Long, sName As String, vValue As Variant, vResult As Variant, sDim As String
  219. Dim lSearch As Long
  220. Dim cstLF As String
  221. Const cstEqualArray = &quot; = (&quot;, cstEqual = &quot; = &quot;
  222. cstLF = Chr(10)
  223. _StrToPropValues = Array()
  224. vResult = Array()
  225. If psString = &quot;&quot; Then Exit Function
  226. vString = Split(psString, cstLF)
  227. If UBound(vString) &lt;= 0 Then Exit Function &apos; There must be at least one name-value pair
  228. If vString(0) &lt;&gt; cstHEADER Then Exit Function &apos; Check origin
  229. iArray = -1
  230. For i = 1 To UBound(vString)
  231. If vString(i) &lt;&gt; &quot;&quot; Then &apos; Skip empty lines
  232. If iArray &lt; 0 Then &apos; Not busy with array row
  233. lPosition = 1
  234. sName = Utils._RegexSearch(vString(i), &quot;^\b\w+\b&quot;, lPosition) &apos; Identifier
  235. If sName = &quot;&quot; Then Exit Function
  236. If InStr(vString(i), cstEqualArray) = lPosition + Len(sName) Then &apos; Start array processing
  237. lSearch = lPosition + Len(sName) + Len(cstEqualArray) - 1
  238. sDim = Utils._RegexSearch(vString(i), &quot;\([0-9]+\)&quot;, lSearch) &apos; e.g. (10)
  239. If sDim = &quot;(0)&quot; Then &apos; Empty array
  240. iRows = -1
  241. vValue = Array()
  242. _SetPropertyValue(vResult, sName, vValue)
  243. ElseIf sDim &lt;&gt; &quot;&quot; Then &apos; Vector with content
  244. iCols = CInt(Mid(sDim, 2, Len(sDim) - 2))
  245. iRows = 0
  246. ReDim vValue(0 To iCols - 1)
  247. iArray = 0
  248. Else &apos; Matrix with content
  249. lSearch = lPosition + Len(sName) + Len(cstEqualArray) - 1
  250. sDim = Utils._RegexSearch(vString(i), &quot;\([0-9]+,&quot;, lSearch) &apos; e.g. (10,
  251. iRows = CInt(Mid(sDim, 2, Len(sDim) - 2))
  252. sDim = Utils._RegexSearch(vString(i), &quot;,[0-9]+\)&quot;, lSearch) &apos; e.g. ,20)
  253. iCols = CInt(Mid(sDim, 2, Len(sDim) - 2))
  254. ReDim vValue(0 To iRows - 1)
  255. iArray = 0
  256. End If
  257. ElseIf InStr(vString(i), cstEqual) = lPosition + Len(sName) Then
  258. vValue = Utils._CVar(Mid(vString(i), Len(sName) + Len(cstEqual) + 1))
  259. _SetPropertyValue(vResult, sName, vValue)
  260. Else
  261. Exit Function
  262. End If
  263. Else &apos; Line is an array row
  264. If iRows = 0 Then
  265. vValue = Utils._CVar(vString(i), True) &apos; Keep dates as strings
  266. iArray = -1
  267. _SetPropertyValue(vResult, sName, vValue)
  268. Else
  269. vValue(iArray) = Utils._CVar(vString(i), True)
  270. If iArray &lt; iRows - 1 Then
  271. iArray = iArray + 1
  272. Else
  273. iArray = -1
  274. _SetPropertyValue(vResult, sName, vValue)
  275. End If
  276. End If
  277. End If
  278. End If
  279. Next i
  280. _StrToPropValues = vResult
  281. End Function
  282. </script:module>