Recordset.xba 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274
  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="Recordset" 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. Option Compatible
  9. Option ClassModule
  10. Option Explicit
  11. REM -----------------------------------------------------------------------------------------------------------------------
  12. REM --- CLASS ROOT FIELDS ---
  13. REM -----------------------------------------------------------------------------------------------------------------------
  14. Private _Type As String &apos; Must be RECORDSET
  15. Private _This As Object &apos; Workaround for absence of This builtin function
  16. Private _Parent As Object
  17. Private _Name As String &apos; Unique, generated
  18. Private _Fields() As Variant
  19. Private _ParentName As String
  20. Private _ParentType As String
  21. Private _ParentDatabase As Object
  22. Private _ForwardOnly As Boolean
  23. Private _PassThrough As Boolean
  24. Private _ReadOnly As Boolean
  25. Private _CommandType As Long
  26. Private _Command As String
  27. Private _DataSet As Boolean &apos; True if execute() successful
  28. Private _BOF As Boolean
  29. Private _EOF As Boolean
  30. Private _Filter As String
  31. Private _EditMode As Integer &apos; dbEditxxx constants
  32. Private _BookmarkBeforeNew As Variant
  33. Private _BookmarkLastModified As Variant
  34. Private _IsClone As Boolean
  35. Private _ManageChunks As Variant &apos; Array of ChunkDescriptors
  36. Private RowSet As Object &apos; com.sun.star.comp.dba.ORowSet
  37. Type ChunkDescriptor
  38. ChunksRequested As Boolean
  39. FieldName As String
  40. ChunkType As Integer &apos; vbString or vbByte
  41. FileName As String
  42. FileHandler As Object
  43. End Type
  44. REM -----------------------------------------------------------------------------------------------------------------------
  45. REM --- CONSTRUCTORS / DESTRUCTORS ---
  46. REM -----------------------------------------------------------------------------------------------------------------------
  47. Private Sub Class_Initialize()
  48. _Type = OBJRECORDSET
  49. Set _This = Nothing
  50. Set _Parent = Nothing
  51. _Name = &quot;&quot;
  52. _Fields = Array()
  53. _ParentName = &quot;&quot;
  54. Set _ParentDatabase = Nothing
  55. _ParentType = &quot;&quot;
  56. _ForwardOnly = False
  57. _PassThrough = False
  58. _ReadOnly = False
  59. _CommandType = 0
  60. _Command = &quot;&quot;
  61. _DataSet = False
  62. _BOF = True
  63. _EOF = True
  64. _Filter = &quot;&quot;
  65. _EditMode = dbEditNone
  66. _BookmarkBeforeNew = Null
  67. _BookmarkLastModified = Null
  68. _IsClone = False
  69. Set _ManageChunks = Array()
  70. Set RowSet = Nothing
  71. End Sub &apos; Constructor
  72. REM -----------------------------------------------------------------------------------------------------------------------
  73. Private Sub Class_Terminate()
  74. On Local Error Resume Next
  75. mClose()
  76. End Sub
  77. REM -----------------------------------------------------------------------------------------------------------------------
  78. REM --- CLASS GET/LET/SET PROPERTIES ---
  79. REM -----------------------------------------------------------------------------------------------------------------------
  80. REM -----------------------------------------------------------------------------------------------------------------------
  81. Property Get AbsolutePosition() As Variant
  82. AbsolutePosition = _PropertyGet(&quot;AbsolutePosition&quot;)
  83. End Property &apos; AbsolutePosition (get)
  84. Property Let AbsolutePosition(ByVal pvValue As Variant)
  85. Call _PropertySet(&quot;AbsolutePosition&quot;, pvValue)
  86. End Property &apos; AbsolutePosition (set)
  87. REM -----------------------------------------------------------------------------------------------------------------------
  88. Property Get BOF() As Boolean
  89. BOF = _PropertyGet(&quot;BOF&quot;)
  90. End Property &apos; BOF (get)
  91. REM -----------------------------------------------------------------------------------------------------------------------
  92. Property Get Bookmark() As Variant
  93. Bookmark = _PropertyGet(&quot;Bookmark&quot;)
  94. End Property &apos; Bookmark (get)
  95. Property Let Bookmark(ByVal pvValue As Variant)
  96. Call _PropertySet(&quot;Bookmark&quot;, pvValue)
  97. End Property &apos; Bookmark (set)
  98. REM -----------------------------------------------------------------------------------------------------------------------
  99. Property Get Bookmarkable() As Boolean
  100. Bookmarkable = _PropertyGet(&quot;Bookmarkable&quot;)
  101. End Property &apos; Bookmarkable (get)
  102. REM -----------------------------------------------------------------------------------------------------------------------
  103. Property Get EOF() As Boolean
  104. EOF = _PropertyGet(&quot;EOF&quot;)
  105. End Property &apos; EOF (get)
  106. REM -----------------------------------------------------------------------------------------------------------------------
  107. Property Get EditMode() As Integer
  108. EditMode = _PropertyGet(&quot;EditMode&quot;)
  109. End Property &apos; EditMode (get)
  110. REM -----------------------------------------------------------------------------------------------------------------------
  111. Property Get Filter() As Variant
  112. Filter = _PropertyGet(&quot;Filter&quot;)
  113. End Property &apos; Filter (get)
  114. Property Let Filter(ByVal pvValue As Variant)
  115. Call _PropertySet(&quot;Filter&quot;, pvValue)
  116. End Property &apos; Filter (set)
  117. REM -----------------------------------------------------------------------------------------------------------------------
  118. Property Get LastModified() As Variant
  119. &apos; DO NOT PUBLISH
  120. LastModified = _PropertyGet(&quot;LastModified&quot;)
  121. End Property &apos; LastModified (get)
  122. REM -----------------------------------------------------------------------------------------------------------------------
  123. Property Get Name() As String
  124. Name = _PropertyGet(&quot;Name&quot;)
  125. End Property &apos; Name (get)
  126. REM -----------------------------------------------------------------------------------------------------------------------
  127. Property Get ObjectType() As String
  128. ObjectType = _PropertyGet(&quot;ObjectType&quot;)
  129. End Property &apos; ObjectType (get)
  130. REM -----------------------------------------------------------------------------------------------------------------------
  131. Property Get RecordCount() As Long
  132. RecordCount = _PropertyGet(&quot;RecordCount&quot;)
  133. End Property &apos; RecordCount (get)
  134. REM -----------------------------------------------------------------------------------------------------------------------
  135. REM --- CLASS METHODS ---
  136. REM -----------------------------------------------------------------------------------------------------------------------
  137. REM -----------------------------------------------------------------------------------------------------------------------
  138. Public Function AddNew() As Boolean
  139. &apos; Initiates the creation of a new record
  140. Const cstThisSub = &quot;Recordset.AddNew&quot;
  141. Dim i As Integer, iFieldsCount As Integer, oField As Object
  142. Dim sDefault As String, oColumn As Object
  143. Dim iValue As Integer, lValue As Long, sgValue As Single, dbValue As Double, dValue As Date
  144. Dim vTemp As Variant
  145. If _ErrorHandler() Then On Local Error Goto Error_Function
  146. Utils._SetCalledSub(cstThisSub)
  147. AddNew = False
  148. With RowSet
  149. &apos;Is inserting a new row allowed ?
  150. If _ForwardOnly Or _ReadOnly Then Goto Error_NoUpdate
  151. If Not .CanUpdateInsertedRows Then Goto Error_NoUpdate
  152. If Not .IsBookmarkable Then Goto Error_NoUpdate
  153. If _EditMode &lt;&gt; dbEditNone Then CancelUpdate()
  154. If _BOF And _EOF Then &apos; Records before first or after last do not have a bookmark
  155. _BookmarkBeforeNew = &quot;_BOF_&quot;
  156. ElseIf .isBeforeFirst() Then
  157. _BookmarkBeforeNew = &quot;_BOF_&quot;
  158. ElseIf .isAfterLast() Then
  159. _BookmarkBeforeNew = &quot;_EOF_&quot;
  160. Else
  161. _BookmarkBeforeNew = .getBookmark()
  162. End If
  163. .moveToInsertRow()
  164. &apos;Set all fields to their default value
  165. iFieldsCount = Fields().Count
  166. On Local Error Resume Next &apos; Do not stop if default setting fails
  167. For i = 0 To iFieldsCount - 1
  168. Set oField = Fields(i)
  169. Set oColumn = oField.Column
  170. sDefault = oField.DefaultValue
  171. If sDefault = &quot;&quot; Then &apos; No default value
  172. If oColumn.IsNullable = com.sun.star.sdbc.ColumnValue.NULLABLE Then oColumn.updateNull()
  173. Else
  174. With com.sun.star.sdbc.DataType
  175. Select Case oColumn.Type
  176. Case .BIT, .BOOLEAN
  177. If sDefault = &quot;1&quot; Then oColumn.updateBoolean(True) Else oColumn.updateBoolean(False)
  178. Case .TINYINT
  179. iValue = CInt(sDefault)
  180. If iValue &gt;= -128 And iValue &lt;= +127 Then oColumn.updateShort(iValue)
  181. Case .SMALLINT
  182. lValue = CLng(sDefault)
  183. If lValue &gt;= -32768 And lValue &lt;= 32767 Then oColumn.updateInt(lValue)
  184. Case .INTEGER
  185. lValue = CLng(sDefault)
  186. If lValue &gt;= -2147483648 And lValue &lt;= 2147483647 Then oColumn.updateInt(lValue)
  187. Case .BIGINT
  188. lValue = CLng(sDefault)
  189. Column.updateLong(lValue) &apos; No proper type conversion for HYPER data type
  190. Case .FLOAT
  191. sgValue = CSng(sDefault)
  192. If Abs(sgValue) &lt; 3.402823E38 And Abs(sgValue) &gt; 1.401298E-45 Then oColumn.updateFloat(sgValue)
  193. Case .REAL, .DOUBLE
  194. dbValue = CDbl(sDefault)
  195. &apos;If Abs(dbValue) &lt; 1.79769313486232E308 And Abs(dbValue) &gt; 4.94065645841247E-307 Then oColumn.updateDouble(dbValue)
  196. oColumn.updateDouble(dbValue)
  197. Case .NUMERIC, .DECIMAL
  198. dbValue = CDbl(sDefault)
  199. If Utils._hasUNOProperty(Column, &quot;Scale&quot;) Then
  200. If Column.Scale &gt; 0 Then
  201. &apos;If Abs(dbValue) &lt; 1.79769313486232E308 And Abs(dbValue) &gt; 4.94065645841247E-307 Then oColumn.updateDouble(dbValue)
  202. oColumn.updateDouble(dbValue)
  203. Else
  204. oColumn.updateString(sDefault)
  205. End If
  206. Else
  207. oColumn.updateString(sDefault)
  208. End If
  209. Case .CHAR, .VARCHAR, .LONGVARCHAR
  210. oColumn.updateString(sDefault) &apos; vbString
  211. Case .DATE
  212. dValue = DateValue(sDefault)
  213. vTemp = New com.sun.star.util.Date
  214. With vTemp
  215. .Day = Day(dValue)
  216. .Month = Month(dValue)
  217. .Year = Year(dValue)
  218. End With
  219. oColumn.updateDate(vTemp)
  220. Case .TIME
  221. dValue = TimeValue(sDefault)
  222. vTemp = New com.sun.star.util.Time
  223. With vTemp
  224. .Hours = Hour(dValue)
  225. .Minutes = Minute(dValue)
  226. .Seconds = Second(dValue)
  227. &apos;.HundredthSeconds = 0
  228. End With
  229. oColumn.updateTime(vTemp)
  230. Case .TIMESTAMP
  231. dValue = DateValue(sDefault)
  232. vTemp = New com.sun.star.util.DateTime
  233. With vTemp
  234. .Day = Day(dValue)
  235. .Month = Month(dValue)
  236. .Year = Year(dValue)
  237. .Hours = Hour(dValue)
  238. .Minutes = Minute(dValue)
  239. .Seconds = Second(dValue)
  240. &apos;.HundredthSeconds = 0
  241. End With
  242. oColumn.updateTimestamp(vTemp)
  243. &apos; Case .BINARY, .VARBINARY, .LONGVARBINARY
  244. &apos; Case .BLOB
  245. &apos; Case .CLOB
  246. Case Else
  247. End Select
  248. End With
  249. End If
  250. Next i
  251. End With
  252. If _ErrorHandler() Then On Local Error Goto Error_Function Else On Local Error Goto 0
  253. _EditMode = dbEditAdd
  254. AddNew = True
  255. Exit_Function:
  256. Utils._ResetCalledSub(cstThisSub)
  257. Exit Function
  258. Error_Function:
  259. TraceError(TRACEABORT, Err, cstThisSub, Erl)
  260. GoTo Exit_Function
  261. Error_NoUpdate:
  262. TraceError(TRACEFATAL, ERRNOTUPDATABLE, Utils._CalledSub(), 0)
  263. Goto Exit_Function
  264. End Function &apos; AddNew
  265. REM -----------------------------------------------------------------------------------------------------------------------
  266. Public Function CancelUpdate() As Boolean
  267. &apos; Cancel any edit action
  268. Const cstThisSub = &quot;Recordset.CancelUpdate&quot;
  269. If _ErrorHandler() Then On Local Error Goto Error_Function
  270. Utils._SetCalledSub(cstThisSub)
  271. CancelUpdate = False
  272. With RowSet
  273. Select Case _EditMode
  274. Case dbEditNone
  275. Case dbEditAdd
  276. _AppendChunkClose(True)
  277. If Not IsNull(_BookmarkBeforeNew) Then
  278. Select Case _BookmarkBeforeNew
  279. Case &quot;_BOF_&quot; : .beforeFirst()
  280. Case &quot;_EOF_&quot; : .afterLast()
  281. Case Else : .moveToBookmark(_BookmarkBeforeNew)
  282. End Select
  283. End If
  284. Case dbEditInProgress
  285. .cancelRowUpdates()
  286. _AppendChunkClose(True)
  287. End Select
  288. End With
  289. _EditMode = dbEditNone
  290. _BookmarkBeforeNew = Null
  291. _BookmarkLastModified = Null
  292. CancelUpdate = True
  293. Exit_Function:
  294. Utils._ResetCalledSub(cstThisSub)
  295. Exit Function
  296. Error_Function:
  297. TraceError(TRACEABORT, Err, cstThisSub, Erl)
  298. GoTo Exit_Function
  299. End Function &apos; CancelUpdate
  300. REM -----------------------------------------------------------------------------------------------------------------------
  301. Public Function Clone() As Object
  302. &apos; Duplicate an existing recordset
  303. Const cstThisSub = &quot;Recordset.Clone&quot;
  304. Const cstNull = -1
  305. Dim iType As Integer, iOptions As Integer, iLockEdit As Integer
  306. If _ErrorHandler() Then On Local Error Goto Error_Function
  307. Utils._SetCalledSub(cstThisSub)
  308. Set Clone = Nothing
  309. If _IsClone Then Goto Error_Clone
  310. If _ForwardOnly Then iType = dbOpenForwardOnly Else iType = cstNull
  311. If _PassThrough Then iOptions = dbSQLPassThrough Else iOptions = cstNull
  312. iLockEdit = dbReadOnly &apos; Always read-only
  313. Set Clone = OpenRecordset(iType, iOptions, iLockEdit, True)
  314. Exit_Function:
  315. Utils._ResetCalledSub(cstThisSub)
  316. Exit Function
  317. Error_Function:
  318. TraceError(TRACEABORT, Err, cstThisSub, Erl)
  319. GoTo Exit_Function
  320. Error_Clone:
  321. TraceError(TRACEFATAL, ERRRECORDSETCLONE, Utils._CalledSub(), 0)
  322. Goto Exit_Function
  323. End Function &apos; Clone
  324. REM -----------------------------------------------------------------------------------------------------------------------
  325. Public Function mClose(ByVal Optional pbRemove As Boolean) As Variant
  326. &apos; Dispose UNO objects
  327. &apos; If pbRemove = True, remove recordset from Recordsets collection
  328. Const cstThisSub = &quot;Recordset.Close&quot;
  329. Dim i As Integer
  330. If _ErrorHandler() Then On Local Error Goto Exit_Function &apos; Do not stop execution
  331. Utils._SetCalledSub(cstThisSub)
  332. If Not IsNull(RowSet) Then
  333. RowSet.close()
  334. RowSet.dispose()
  335. End If
  336. _ForwardOnly = False
  337. _PassThrough = False
  338. _ReadOnly = False
  339. _CommandType = 0
  340. _Command = &quot;&quot;
  341. _ParentName = &quot;&quot;
  342. _ParentType = &quot;&quot;
  343. _DataSet = False
  344. _BOF = True
  345. _EOF = True
  346. _Filter = &quot;&quot;
  347. _EditMode = dbEditNone
  348. _BookmarkBeforeNew = Null
  349. _BookmarkLastModified = Null
  350. _IsClone = False
  351. For i = 0 To UBound(_Fields)
  352. If Not IsNull(_Fields(i)) Then
  353. _Fields(i).Dispose()
  354. Set _Fields(i) = Nothing
  355. End If
  356. Next i
  357. _Fields = Array()
  358. Set RowSet = Nothing
  359. If IsMissing(pbRemove) Then pbRemove = True
  360. If pbRemove Then _ParentDatabase.RecordsetsColl.Remove(_Name)
  361. Set _ParentDatabase = Nothing
  362. Exit_Function:
  363. Utils._ResetCalledSub(cstThisSub)
  364. Exit Function
  365. End Function &apos; Close
  366. REM -----------------------------------------------------------------------------------------------------------------------
  367. Public Function Delete() As Boolean
  368. &apos; Deletes the current record
  369. Const cstThisSub = &quot;Recordset.Delete&quot;
  370. If _ErrorHandler() Then On Local Error Goto Error_Function
  371. Utils._SetCalledSub(cstThisSub)
  372. Delete = False
  373. &apos;Is deleting a row allowed ?
  374. If _ForwardOnly Or _ReadOnly Then Goto Error_NoUpdate
  375. If _EditMode &lt;&gt; dbEditNone Then
  376. CancelUpdate()
  377. Goto Error_Sequence
  378. End If
  379. If RowSet.rowDeleted() Then Goto Error_RowDeleted
  380. RowSet.deleteRow()
  381. Delete = True
  382. Exit_Function:
  383. Utils._ResetCalledSub(cstThisSub)
  384. Exit Function
  385. Error_Function:
  386. TraceError(TRACEABORT, Err, cstThisSub, Erl)
  387. GoTo Exit_Function
  388. Error_NoUpdate:
  389. TraceError(TRACEFATAL, ERRNOTUPDATABLE, Utils._CalledSub(), 0)
  390. Goto Exit_Function
  391. Error_RowDeleted:
  392. TraceError(TRACEFATAL, ERRROWDELETED, Utils._CalledSub(), 0)
  393. Goto Exit_Function
  394. Error_Sequence:
  395. TraceError(TRACEFATAL, ERRUPDATESEQUENCE, Utils._CalledSub(), 0, 1)
  396. Goto Exit_Function
  397. End Function &apos; Delete
  398. REM -----------------------------------------------------------------------------------------------------------------------
  399. Public Function Edit() As Boolean
  400. &apos; Updates the current record
  401. Const cstThisSub = &quot;Recordset.Edit&quot;
  402. If _ErrorHandler() Then On Local Error Goto Error_Function
  403. Utils._SetCalledSub(cstThisSub)
  404. Edit = False
  405. &apos;Is updating a row allowed ?
  406. If _ForwardOnly Or _ReadOnly Then Goto Error_NoUpdate
  407. If _EditMode &lt;&gt; dbEditNone Then CancelUpdate()
  408. If RowSet.rowDeleted() Then Goto Error_RowDeleted
  409. _EditMode = dbEditInProgress
  410. Edit = True
  411. Exit_Function:
  412. Utils._ResetCalledSub(cstThisSub)
  413. Exit Function
  414. Error_Function:
  415. TraceError(TRACEABORT, Err, cstThisSub, Erl)
  416. GoTo Exit_Function
  417. Error_NoUpdate:
  418. TraceError(TRACEFATAL, ERRNOTUPDATABLE, Utils._CalledSub(), 0)
  419. Goto Exit_Function
  420. Error_RowDeleted:
  421. TraceError(TRACEFATAL, ERRROWDELETED, Utils._CalledSub(), 0)
  422. Goto Exit_Function
  423. End Function &apos; Edit
  424. REM -----------------------------------------------------------------------------------------------------------------------
  425. Public Function Fields(ByVal Optional pvIndex As variant) As Object
  426. If _ErrorHandler() Then On Local Error Goto Error_Function
  427. Const cstThisSub = &quot;Recordset.Fields&quot;
  428. Utils._SetCalledSub(cstThisSub)
  429. Set Fields = Nothing
  430. If Not IsMissing(pvIndex) Then
  431. If Not Utils._CheckArgument(pvIndex, 1, Utils._AddNumeric(vbString)) Then Goto Exit_Function
  432. End If
  433. Dim sObjects() As String, sObjectName As String, oObject As Object
  434. Dim i As Integer, oFields As Object, iIndex As Integer
  435. &apos; No argument, return a collection
  436. If IsMissing(pvIndex) Then
  437. Set oObject = New Collect
  438. Set oObject._This = oObject
  439. oObject._CollType = COLLFIELDS
  440. Set oObject._Parent = _This
  441. oObject._Count = RowSet.getColumns().Count
  442. Goto Exit_Function
  443. End If
  444. Set oFields = RowSet.getColumns()
  445. sObjects = oFields.ElementNames()
  446. &apos; Argument is the field name
  447. If VarType(pvIndex) = vbString Then
  448. iIndex = -1
  449. &apos; Check existence of object and find its exact (case-sensitive) name
  450. For i = 0 To UBound(sObjects)
  451. If UCase(pvIndex) = UCase(sObjects(i)) Then
  452. sObjectName = sObjects(i)
  453. iIndex = i
  454. Exit For
  455. End If
  456. Next i
  457. If iIndex &lt; 0 Then Goto Trace_NotFound
  458. &apos; Argument is numeric
  459. Else
  460. If pvIndex &lt; 0 Or pvIndex &gt; UBound(sObjects) Then Goto Trace_IndexError
  461. sObjectName = sObjects(pvIndex)
  462. iIndex = pvIndex
  463. End If
  464. &apos; Check if field object already buffered in _Fields() array
  465. If UBound(_Fields) &lt; 0 Then &apos; Initialize _Fields
  466. ReDim _Fields(0 To UBound(sObjects))
  467. For i = 0 To UBound(sObjects)
  468. Set _Fields(i) = Nothing
  469. Next i
  470. End If
  471. If Not IsNull(_Fields(iIndex)) Then
  472. Set oObject = _Fields(iIndex)
  473. &apos; Otherwise create new field object
  474. Else
  475. Set oObject = New Field
  476. Set oObject._This = oObject
  477. oObject._Name = sObjectName
  478. Set oObject.Column = oFields.getByName(sObjectName)
  479. If Utils._hasUNOProperty(oObject.Column, &quot;Precision&quot;) Then oObject._Precision = oObject.Column.Precision
  480. oObject._ParentName = _Name
  481. oObject._ParentType = _Type
  482. Set oObject._ParentDatabase = _ParentDatabase
  483. Set oObject._ParentRecordset = _This
  484. Set _Fields(iIndex) = oObject
  485. End If
  486. Exit_Function:
  487. Set Fields = oObject
  488. Set oObject = Nothing
  489. Utils._ResetCalledSub(cstThisSub)
  490. Exit Function
  491. Error_Function:
  492. TraceError(TRACEABORT, Err, cstThisSub, Erl)
  493. GoTo Exit_Function
  494. Trace_NotFound:
  495. TraceError(TRACEFATAL, ERROBJECTNOTFOUND, Utils._CalledSub(), 0, , Array(_GetLabel(&quot;FIELD&quot;), pvIndex))
  496. Goto Exit_Function
  497. Trace_IndexError:
  498. TraceError(TRACEFATAL, ERRCOLLECTION, Utils._CalledSub(), 0)
  499. Goto Exit_Function
  500. End Function &apos; Fields
  501. REM -----------------------------------------------------------------------------------------------------------------------
  502. Public Function getProperty(Optional ByVal pvProperty As Variant) As Variant
  503. &apos; Return property value of psProperty property name
  504. Const cstThisSub = &quot;Recordset.getProperty&quot;
  505. Utils._SetCalledSub(cstThisSub)
  506. If IsMissing(pvProperty) Then Call _TraceArguments()
  507. getProperty = _PropertyGet(pvProperty)
  508. Utils._ResetCalledSub(cstThisSub)
  509. End Function &apos; getProperty
  510. REM -----------------------------------------------------------------------------------------------------------------------
  511. Public Function GetRows(ByVal Optional pvNumRows As variant, ByVal Optional pbStrDate As Boolean) As Variant
  512. &apos; UNPUBLISHED - pbStrDate = True forces all dates to be converted into strings
  513. If _ErrorHandler() Then On Local Error Goto Error_Function
  514. Const cstThisSub = &quot;Recordset.GetRows&quot;
  515. Utils._SetCalledSub(cstThisSub)
  516. If IsMissing(pbStrDate) Then pbStrDate = False
  517. Dim vMatrix() As Variant, lSize As Long, iNumFields As Integer, i As Integer
  518. vMatrix() = Array()
  519. If IsMissing(pvNumRows) Then Call _TraceArguments()
  520. If Not Utils._CheckArgument(pvNumRows, 1, Utils._AddNumeric()) Then Goto Exit_Function
  521. If pvNumRows &lt; 1 Then Goto Trace_Error
  522. If IsNull(RowSet) Then Goto Trace_Closed
  523. If Not _DataSet Then Goto Exit_Function
  524. If _EditMode &lt;&gt; dbEditNone Then CancelUpdate()
  525. If _EOF Then Goto Exit_Function
  526. lSize = -1
  527. iNumFields = RowSet.getColumns().Count - 1
  528. If iNumFields &lt; 0 Then Goto Exit_Function
  529. ReDim vMatrix(0 To iNumFields, 0 To pvNumRows - 1)
  530. Do While Not _EOF And lSize &lt; pvNumRows - 1
  531. lSize = lSize + 1
  532. For i = 0 To iNumFields
  533. vMatrix(i, lSize) = Utils._getResultSetColumnValue(RowSet, i + 1)
  534. If pbStrDate And IsDate(vMatrix(i, lSize)) Then vMatrix(i, lSize) = _CStr(vMatrix(i, lSize))
  535. Next i
  536. _Move(&quot;NEXT&quot;)
  537. Loop
  538. If lSize &lt; pvNumRows - 1 Then &apos; Resize to number of fetched records
  539. ReDim Preserve vMatrix(0 To iNumFields, 0 To lSize)
  540. End If
  541. Exit_Function:
  542. GetRows() = vMatrix()
  543. Utils._ResetCalledSub(cstThisSub)
  544. Exit Function
  545. Error_Function:
  546. TraceError(TRACEABORT, Err, cstThisSub, Erl)
  547. GoTo Exit_Function
  548. Trace_Error:
  549. TraceError(TRACEFATAL, ERRWRONGARGUMENT, Utils._CalledSub(), 0, , Array(1, pvNumRows))
  550. Set Controls = Nothing
  551. Goto Exit_Function
  552. Trace_Closed:
  553. TraceError(TRACEFATAL, ERRRECORDSETCLOSED, Utils._CalledSub(), 0)
  554. Goto Exit_Function
  555. End Function &apos; GetRows V1.1.0
  556. REM -----------------------------------------------------------------------------------------------------------------------
  557. Public Function hasProperty(ByVal Optional pvProperty As Variant) As Boolean
  558. &apos; Return True if object has a valid property called pvProperty (case-insensitive comparison !)
  559. Const cstThisSub = &quot;Recordset.hasProperty&quot;
  560. Utils._SetCalledSub(cstThisSub)
  561. If IsMissing(pvProperty) Then hasProperty = PropertiesGet._hasProperty(_Type, _PropertiesList()) Else hasProperty = PropertiesGet._hasProperty(_Type, _PropertiesList(), pvProperty)
  562. Utils._ResetCalledSub(cstThisSub)
  563. Exit Function
  564. End Function &apos; hasProperty
  565. REM -----------------------------------------------------------------------------------------------------------------------
  566. Public Function Move(ByVal Optional pvRelative As Variant, ByVal Optional pvBookmark As variant) As Boolean
  567. &apos; Move record pointer Relative rows vs. bookmark or current record
  568. If IsMissing(pvRelative) Then Call _TraceArguments()
  569. If Not Utils._CheckArgument(pvRelative, 1, Utils._AddNumeric()) Then Goto Exit_Function
  570. If IsMissing(pvBookmark) Then Move = _Move(pvRelative) Else Move = _Move(pvRelative, pvBookmark)
  571. Exit_Function:
  572. Exit Function
  573. End Function &apos; Move
  574. REM -----------------------------------------------------------------------------------------------------------------------
  575. Public Function MoveFirst() As Boolean
  576. MoveFirst = _Move(&quot;First&quot;)
  577. End Function &apos; MoveFirst
  578. REM -----------------------------------------------------------------------------------------------------------------------
  579. Public Function MoveLast() As Boolean
  580. MoveLast = _Move(&quot;Last&quot;)
  581. End Function &apos; MoveLast
  582. REM -----------------------------------------------------------------------------------------------------------------------
  583. Public Function MoveNext() As Boolean
  584. MoveNext = _Move(&quot;Next&quot;)
  585. End Function &apos; MoveNext
  586. REM -----------------------------------------------------------------------------------------------------------------------
  587. Public Function MovePrevious() As Boolean
  588. MovePrevious = _Move(&quot;Previous&quot;)
  589. End Function &apos; MovePrevious
  590. REM -----------------------------------------------------------------------------------------------------------------------
  591. Public Function OpenRecordset(ByVal Optional pvType As Variant _
  592. , ByVal Optional pvOptions As Variant _
  593. , ByVal Optional pvLockEdit As Variant _
  594. , ByVal Optional pbClone As Boolean) As Object
  595. &apos;Return a Recordset object based on current recordset object with filter addition
  596. If _ErrorHandler() Then On Local Error Goto Error_Function
  597. Dim cstThisSub As String
  598. cstThisSub = Utils._PCase(_Type) &amp; &quot;.OpenRecordset&quot;
  599. Utils._SetCalledSub(cstThisSub)
  600. Set OpenRecordset = Nothing
  601. Const cstNull = -1
  602. Dim oObject As Object
  603. Set oObject = Nothing
  604. If IsMissing(pvType) Then
  605. pvType = cstNull
  606. Else
  607. If Not Utils._CheckArgument(pvType, 1, Utils._AddNumeric(), Array(cstNull, dbOpenForwardOnly)) Then Goto Exit_Function
  608. End If
  609. If IsMissing(pvOptions) Then
  610. pvOptions = cstNull
  611. Else
  612. If Not Utils._CheckArgument(pvOptions, 2, Utils._AddNumeric(), Array(cstNull, dbSQLPassThrough)) Then Goto Exit_Function
  613. End If
  614. If IsMissing(pvLockEdit) Then
  615. pvLockEdit = cstNull
  616. Else
  617. If Not Utils._CheckArgument(pvLockEdit, 3, Utils._AddNumeric(), Array(cstNull, dbReadOnly)) Then Goto Exit_Function
  618. End If
  619. If IsMissing(pbClone) Then pbClone = False &apos; pbClone is a not published argument
  620. Set oObject = New Recordset
  621. With oObject
  622. ._CommandType = _CommandType
  623. ._Command = _Command
  624. ._ParentName = _Name
  625. ._ParentType = _Type
  626. Set ._ParentDatabase = _ParentDatabase
  627. Set ._This = oObject
  628. ._ForwardOnly = ( pvType = dbOpenForwardOnly )
  629. ._PassThrough = ( pvOptions = dbSQLPassThrough )
  630. ._ReadOnly = ( (pvLockEdit = dbReadOnly) Or _ReadOnly )
  631. Select Case True
  632. Case pbClone : Call ._Initialize(, RowSet)
  633. Case _Filter &lt;&gt; &quot;&quot; : Call ._Initialize(_Filter)
  634. Case Else : Call ._Initialize()
  635. End Select
  636. End With
  637. With _ParentDatabase
  638. .RecordsetMax = .RecordsetMax + 1
  639. oObject._Name = Format(.RecordsetMax, &quot;0000000&quot;)
  640. .RecordsetsColl.Add(oObject, UCase(oObject._Name))
  641. End With
  642. If Not ( oObject._BOF And oObject._EOF ) Then oObject.MoveFirst() &apos; Do nothing if resultset empty
  643. Exit_Function:
  644. Set OpenRecordset = oObject
  645. Set oObject = Nothing
  646. Utils._ResetCalledSub(cstThisSub)
  647. Exit Function
  648. Error_Function:
  649. TraceError(TRACEABORT, Err, Utils._CalledSub(), Erl)
  650. GoTo Exit_Function
  651. End Function &apos; OpenRecordset
  652. REM -----------------------------------------------------------------------------------------------------------------------
  653. Public Function Properties(ByVal Optional pvIndex As Variant) As Variant
  654. &apos; Return
  655. &apos; a Collection object if pvIndex absent
  656. &apos; a Property object otherwise
  657. Const cstThisSub = &quot;Recordset.Properties&quot;
  658. Utils._SetCalledSub(cstThisSub)
  659. Dim vProperty As Variant, vPropertiesList() As Variant, sObject As String
  660. vPropertiesList = _PropertiesList()
  661. sObject = Utils._PCase(_Type)
  662. If IsMissing(pvIndex) Then
  663. vProperty = PropertiesGet._Properties(sObject, _This, vPropertiesList)
  664. Else
  665. vProperty = PropertiesGet._Properties(sObject, _This, vPropertiesList, pvIndex)
  666. vProperty._Value = _PropertyGet(vPropertiesList(pvIndex))
  667. End If
  668. Set vProperty._ParentDatabase = _ParentDatabase
  669. Exit_Function:
  670. Set Properties = vProperty
  671. Utils._ResetCalledSub(cstThisSub)
  672. Exit Function
  673. End Function &apos; Properties
  674. REM -----------------------------------------------------------------------------------------------------------------------
  675. Public Function setProperty(ByVal Optional psProperty As String, ByVal Optional pvValue As Variant) As Boolean
  676. &apos; Return True if property setting OK
  677. Const cstThisSub = &quot;Recordset.setProperty&quot;
  678. Utils._SetCalledSub(cstThisSub)
  679. setProperty = _PropertySet(psProperty, pvValue)
  680. Utils._ResetCalledSub(cstThisSub)
  681. End Function
  682. REM -----------------------------------------------------------------------------------------------------------------------
  683. Public Function Update() As Boolean
  684. &apos; Finalize the updates of the current record
  685. Const cstThisSub = &quot;Recordset.Update&quot;
  686. If _ErrorHandler() Then On Local Error Goto Error_Function
  687. Utils._SetCalledSub(cstThisSub)
  688. Update = False
  689. &apos;Is updating a row allowed ?
  690. If _ForwardOnly Or _ReadOnly Then Goto Error_NoUpdate
  691. With RowSet
  692. If .rowDeleted() Then Goto Error_RowDeleted
  693. Select Case _EditMode
  694. Case dbEditNone
  695. Goto Trace_Error_Update
  696. Case dbEditAdd
  697. _AppendChunkClose(False)
  698. If .IsNew And .IsModified Then .insertRow()
  699. _BookmarkLastModified = .getBookmark()
  700. If Not IsNull(_BookmarkBeforeNew) Then
  701. Select Case _BookmarkBeforeNew
  702. Case &quot;_BOF_&quot; : .beforeFirst()
  703. Case &quot;_EOF_&quot; : .afterLast()
  704. Case Else : .moveToBookmark(_BookmarkBeforeNew)
  705. End Select
  706. End If
  707. Case dbEditInProgress
  708. _AppendChunkClose(False)
  709. If .IsModified Then
  710. .updateRow()
  711. _BookmarkLastModified = .getBookmark()
  712. End If
  713. End Select
  714. End With
  715. _EditMode = dbEditNone
  716. Update = True
  717. Exit_Function:
  718. Utils._ResetCalledSub(cstThisSub)
  719. Exit Function
  720. Error_Function:
  721. TraceError(TRACEABORT, Err, cstThisSub, Erl)
  722. GoTo Exit_Function
  723. Error_NoUpdate:
  724. TraceError(TRACEFATAL, ERRNOTUPDATABLE, Utils._CalledSub(), 0)
  725. Goto Exit_Function
  726. Trace_Error_Update:
  727. TraceError(TRACEFATAL, ERRUPDATESEQUENCE, Utils._CalledSub(), 0, 1)
  728. Goto Exit_Function
  729. Error_RowDeleted:
  730. TraceError(TRACEFATAL, ERRROWDELETED, Utils._CalledSub(), 0)
  731. Goto Exit_Function
  732. End Function &apos; Update
  733. REM -----------------------------------------------------------------------------------------------------------------------
  734. REM --- PRIVATE FUNCTIONS ---
  735. REM -----------------------------------------------------------------------------------------------------------------------
  736. REM -----------------------------------------------------------------------------------------------------------------------
  737. Public Function _AppendChunk(ByVal psFieldName As String, ByRef pvChunk As Variant, piChunkType) As Boolean
  738. &apos; Write chunk at the end of the file dedicated to the given field
  739. If _ErrorHandler() Then On Local Error GoTo Error_Function
  740. Dim oFileAccess As Object
  741. Dim i As Integer, oChunk As Object, iChunk As Integer
  742. &apos; Do nothing if chunk meaningless
  743. _AppendChunk = False
  744. If IsNull(pvChunk) Then GoTo Exit_Function
  745. If IsArray(pvChunk) Then
  746. If UBound(pvChunk) &lt; LBound(pvChunk) Then GoTo Exit_Function &apos; Empty array
  747. End If
  748. &apos; Find or create relevant chunk entry
  749. iChunk = -1
  750. For i = 0 To UBound(_ManageChunks)
  751. Set oChunk = _ManageChunks(i)
  752. If oChunk.FieldName = psFieldName Then
  753. iChunk = i
  754. Exit For
  755. End If
  756. Next i
  757. If iChunk = -1 Then
  758. _AppendChunkInit(psFieldName)
  759. iChunk = UBound(_ManageChunks)
  760. End If
  761. Set oChunk = _ManageChunks(iChunk)
  762. With oChunk
  763. If Not .ChunksRequested Then &apos; First chunk
  764. .ChunksRequested = True
  765. .ChunkType = piChunkType
  766. .FileName = Utils._GetRandomFileName(_Name)
  767. Set oFileAccess = CreateUnoService(&quot;com.sun.star.ucb.SimpleFileAccess&quot;)
  768. .FileHandler = oFileAccess.openFileWrite(.FileName)
  769. End If
  770. .FileHandler.writeBytes(pvChunk)
  771. End With
  772. _AppendChunk = True
  773. Exit_Function:
  774. Exit Function
  775. Error_Function:
  776. TraceError(TRACEABORT, Err, &quot;Recordset._AppendChunk&quot;, Erl)
  777. GoTo Exit_Function
  778. End Function &apos; AppendChunk V1.5.0
  779. REM -----------------------------------------------------------------------------------------------------------------------
  780. Public Function _AppendChunkClose(ByVal pbCancel As Boolean) As Boolean
  781. &apos; Stores file content to database field(s)
  782. &apos; Called from Update() [pbCancel = False] or CancelUpdate() [pbCancel = True]
  783. If _ErrorHandler() Then On Local Error GoTo Error_Function
  784. Dim oFileAccess As Object, oStream As Object, lFileLength As Long, oField As Object
  785. Dim i As Integer, oChunk As Object
  786. _AppendChunkClose = False
  787. For i = 0 To UBound(_ManageChunks)
  788. Set oChunk = _ManageChunks(i)
  789. With oChunk
  790. If Not .ChunksRequested Then GoTo Exit_Function
  791. If IsNull(.FileHandler) Then GoTo Exit_Function
  792. .Filehandler.closeOutput
  793. Set oFileAccess = CreateUnoService(&quot;com.sun.star.ucb.SimpleFileAccess&quot;)
  794. &apos; Copy file to field
  795. If Not pbCancel Then
  796. Set oStream = oFileAccess.openFileRead(.FileName)
  797. lFileLength = oStream.getLength()
  798. If lFileLength &gt; 0 Then
  799. Set oField = RowSet.getColumns.getByName(.FieldName)
  800. Select Case .ChunkType
  801. Case vbByte
  802. oField.updateBinaryStream(oStream, lFileLength)
  803. &apos; Case vbString &apos; DOES NOT WORK FOR CHARACTER TYPES
  804. &apos; oField.updateCharacterStream(oStream, lFileLength)
  805. End Select
  806. End If
  807. oStream.closeInput()
  808. End If
  809. If oFileAccess.exists(.FileName) Then oFileAccess.kill(.FileName)
  810. End With
  811. Next i
  812. Set _ManageChunks = Array()
  813. _AppendChunkClose = True
  814. Exit_Function:
  815. Exit Function
  816. Error_Function:
  817. TraceError(TRACEABORT, Err, &quot;Recordset._AppendChunkClose&quot;, Erl)
  818. GoTo Exit_Function
  819. End Function &apos; AppendChunkClose V1.5.0
  820. REM -----------------------------------------------------------------------------------------------------------------------
  821. Public Function _AppendChunkInit(psFieldName As String) As Boolean
  822. &apos; Initialize chunks manager
  823. Dim iSize As Integer
  824. iSize = UBound(_ManageChunks) + 1
  825. ReDim Preserve _ManageChunks(0 To iSize)
  826. Set _ManageChunks(iSize) = New ChunkDescriptor
  827. With _ManageChunks(iSize)
  828. .ChunksRequested = False
  829. .FieldName = psFieldName
  830. .FileName = &quot;&quot;
  831. Set .FileHandler = Nothing
  832. End With
  833. End Function &apos; AppendChunkInit V1.5.0
  834. REM -----------------------------------------------------------------------------------------------------------------------
  835. Public Sub _Initialize(ByVal Optional pvFilter As Variant, Optional poRowSet As Object)
  836. &apos; Initialize new recordset
  837. Dim sFilter As String
  838. If _Command = &quot;&quot; Then Exit Sub
  839. If _ErrorHandler() Then On Local Error Goto Error_Sub
  840. If VarType(pvFilter) = vbError Then
  841. sFilter = &quot;&quot;
  842. ElseIf IsMissing(pvFilter) Then
  843. sFilter = &quot;&quot;
  844. Else
  845. sFilter = pvFilter
  846. End If
  847. If Not IsMissing(poRowSet) Then &apos; Clone
  848. Set RowSet = poRowSet.createResultSet()
  849. _IsClone = True
  850. RowSet.last() &apos; Solves bookmark desynchro when parent bookmark is used ?!?
  851. Else
  852. Set RowSet = CreateUnoService(&quot;com.sun.star.sdb.RowSet&quot;)
  853. _IsClone = False
  854. With RowSet
  855. If IsNull(.ActiveConnection) Then Set .ActiveConnection = _ParentDatabase.Connection
  856. .CommandType = _CommandType
  857. .Command = _Command
  858. If _ForwardOnly Then .ResultSetType = com.sun.star.sdbc.ResultSetType.FORWARD_ONLY _
  859. Else .ResultSetType = com.sun.star.sdbc.ResultSetType.SCROLL_SENSITIVE
  860. If _PassThrough Then .EscapeProcessing = False _
  861. Else .EscapeProcessing = True
  862. If _ReadOnly Then
  863. .ResultSetConcurrency = com.sun.star.sdbc.ResultSetConcurrency.READ_ONLY
  864. .TransactionIsolation = com.sun.star.sdbc.TransactionIsolation.READ_UNCOMMITTED &apos; Dirty read
  865. Else
  866. .ResultSetConcurrency = com.sun.star.sdbc.ResultSetConcurrency.UPDATABLE
  867. .TransactionIsolation = com.sun.star.sdbc.TransactionIsolation.READ_COMMITTED
  868. End If
  869. End With
  870. If sFilter &lt;&gt; &quot;&quot; Then &apos; Filter must be set before execute()
  871. RowSet.Filter = sFilter
  872. RowSet.ApplyFilter = True
  873. End If
  874. On Local Error Goto SQL_Error
  875. RowSet.execute()
  876. On Local Error Goto Error_Sub
  877. End If
  878. _DataSet = True
  879. &apos;If the Recordset contains no records, the BOF and EOF properties are True, and there is no current record.
  880. _BOF = ( RowSet.IsRowCountFinal And RowSet.RowCount = 0 )
  881. _EOF = _BOF
  882. Exit_Sub:
  883. Exit Sub
  884. SQL_Error:
  885. TraceError(TRACEFATAL, ERRSQLSTATEMENT, Utils._CalledSub(), 0, , _Command)
  886. Goto Exit_Sub
  887. Error_Sub:
  888. TraceError(TRACEABORT, Err, &quot;Recordset._Initialize&quot;, Erl)
  889. GoTo Exit_Sub
  890. End Sub &apos; _Initialize
  891. REM -----------------------------------------------------------------------------------------------------------------------
  892. Public Function _Move(pvTarget As Variant, ByVal Optional pvBookmark As Variant, ByVal Optional pbAbsolute As Boolean) As Boolean
  893. &apos;Move to the first, last, next, or previous record in a specified Recordset object and make that record the current record.
  894. Dim cstThisSub As String
  895. cstThisSub = &quot;Recordset.Move&quot; &amp; Iif(VarType(pvTarget) = vbString, pvTarget, &quot;&quot;)
  896. Utils._SetCalledSub(cstThisSub)
  897. If _ErrorHandler() Then On Local Error Goto Error_Function
  898. If IsNull(RowSet) Then Goto Trace_Closed
  899. If Not _DataSet Then Goto Trace_NoData
  900. If _BOF And _EOF Then Goto Trace_NoData
  901. _Move = False
  902. CancelUpdate() &apos; Any Move cancels all updates, even Move(0) !
  903. Dim l As Long, lRow As Long
  904. With RowSet
  905. Select Case VarType(pvTarget)
  906. Case vbString
  907. Select Case UCase(pvTarget)
  908. Case &quot;FIRST&quot;
  909. If _ForwardOnly Then
  910. If Not ( .isBeforeFirst() Or .isFirst() ) Then
  911. Goto Trace_Forward
  912. Else
  913. .next()
  914. End If
  915. Else
  916. .first()
  917. End If
  918. Case &quot;LAST&quot;
  919. If _ForwardOnly Then
  920. If .isAfterLast() Then Goto Trace_Forward
  921. Do While Not ( .isRowCountFinal And .Row = .RowCount ) &apos; isLast() = True after reading of first records chunk
  922. .next()
  923. Loop
  924. Else
  925. .last()
  926. End If
  927. Case &quot;NEXT&quot;
  928. If _EOF Then Goto Trace_OutOfRange
  929. .next()
  930. Case &quot;PREVIOUS&quot;
  931. If _ForwardOnly Then Goto Trace_Forward
  932. If _BOF Then Goto Trace_OutOfRange
  933. .previous()
  934. End Select
  935. Case Else &apos; Relative or absolute move
  936. If IsMissing(pbAbsolute) Then pbAbsolute = False &apos; Relative move is default
  937. If _ForwardOnly And pvTarget &lt; 0 then Goto Trace_Forward
  938. If IsMissing(pvBookmark) Then
  939. If pvTarget = 0 Then Goto Exit_Function &apos; Do nothing
  940. If _ForwardOnly Then
  941. If pbAbsolute Then lRow = .getRow() Else lRow = 0
  942. For l = 1 To pvTarget - lRow
  943. If .isAfterLast() Then Exit For
  944. .next()
  945. Next l
  946. Else
  947. If pbAbsolute Then .absolute(pvTarget) Else .relative(pvTarget)
  948. End If
  949. Else &apos; Move is always relative when bookmark argument present
  950. If _ForwardOnly Then Goto Trace_Forward
  951. If pvTarget = 0 Then
  952. .moveToBookmark(pvBookmark)
  953. Else
  954. .moveRelativeToBookmark(pvBookmark, pvTarget)
  955. End If
  956. End If
  957. End Select
  958. _BOF = .isBeforeFirst() &apos; https://forum.openoffice.org/en/forum/viewtopic.php?f=47&amp;t=76640
  959. _EOF = .isAfterlast()
  960. If _BOF Or _EOF Then
  961. _Move = False
  962. Else
  963. If .rowDeleted() Then Goto Error_RowDeleted
  964. If .rowUpdated() Then .refreshRow()
  965. _Move = True
  966. End If
  967. End With
  968. Exit_Function:
  969. Utils._ResetCalledSub(cstThisSub)
  970. Exit Function
  971. Exit_Close: &apos; Force close of recordset when error raised
  972. mClose()
  973. Goto Exit_Function
  974. Error_Function:
  975. TraceError(TRACEABORT, Err, cstThisSub, Erl)
  976. GoTo Exit_Close
  977. Trace_Forward:
  978. TraceError(TRACEFATAL, ERRRECORDSETFORWARD, Utils._CalledSub(), 0)
  979. Goto Exit_Close
  980. Trace_NoData:
  981. TraceError(TRACEFATAL, ERRRECORDSETNODATA, Utils._CalledSub(), 0)
  982. Goto Exit_Close
  983. Trace_OutOfRange:
  984. TraceError(TRACEFATAL, ERRRECORDSETRANGE, Utils._CalledSub(), 0)
  985. Goto Exit_Close
  986. Error_RowDeleted:
  987. TraceError(TRACEFATAL, ERRROWDELETED, Utils._CalledSub(), 0)
  988. Goto Exit_Function
  989. Trace_Closed:
  990. TraceError(TRACEFATAL, ERRRECORDSETCLOSED, Utils._CalledSub(), 0)
  991. Goto Exit_Close
  992. End Function &apos; Move
  993. REM -----------------------------------------------------------------------------------------------------------------------
  994. Private Function _PropertiesList() As Variant
  995. _PropertiesList = Array(&quot;AbsolutePosition&quot;, &quot;BOF&quot;, &quot;Bookmarkable&quot;, &quot;Bookmark&quot;, &quot;EditMode&quot; _
  996. , &quot;EOF&quot;, &quot;Filter&quot;, &quot;LastModified&quot;, &quot;Name&quot;, &quot;ObjectType&quot; , &quot;RecordCount&quot; _
  997. )
  998. End Function &apos; _PropertiesList
  999. REM -----------------------------------------------------------------------------------------------------------------------
  1000. Private Function _PropertyGet(ByVal psProperty As String) As Variant
  1001. &apos; Return property value of the psProperty property name
  1002. If _ErrorHandler() Then On Local Error Goto Error_Function
  1003. Dim cstThisSub As String
  1004. cstThisSub = &quot;Recordset.get&quot;
  1005. Utils._SetCalledSub(cstThisSub &amp; psProperty)
  1006. _PropertyGet = EMPTY
  1007. Select Case UCase(psProperty)
  1008. Case UCase(&quot;AbsolutePosition&quot;)
  1009. If IsNull(RowSet) Then Goto Trace_Closed
  1010. With RowSet
  1011. Select Case True
  1012. Case _BOF And _EOF : _PropertyGet = -1
  1013. Case .isBeforeFirst() Or .isAfterLast() : _PropertyGet = -1
  1014. Case Else : _PropertyGet = .getRow() &apos; Not getRow() - 1 as MSAccess requires
  1015. End Select
  1016. End With
  1017. Case UCase(&quot;BOF&quot;)
  1018. If IsNull(RowSet) Then Goto Trace_Closed
  1019. Select Case True
  1020. Case _BOF And _EOF : _PropertyGet = True
  1021. Case RowSet.isBeforeFirst() : _PropertyGet = True
  1022. Case Else : _PropertyGet = False
  1023. End Select
  1024. Case UCase(&quot;Bookmarkable&quot;)
  1025. If IsNull(RowSet) Then Goto Trace_Closed
  1026. If _ForwardOnly Then _PropertyGet = False Else _PropertyGet = RowSet.IsBookmarkable
  1027. Case UCase(&quot;Bookmark&quot;)
  1028. If IsNull(RowSet) Then Goto Trace_Closed
  1029. If RowSet.IsBookmarkable And Not _ForwardOnly Then
  1030. If _BOF Or _EOF Then _PropertyGet = Null Else _PropertyGet = RowSet.getBookmark()
  1031. Else
  1032. _PropertyGet = Null
  1033. If _ForwardOnly Then Goto Trace_Forward
  1034. End If
  1035. Case UCase(&quot;EditMode&quot;)
  1036. If IsNull(RowSet) Then Goto Trace_Closed
  1037. _PropertyGet = _EditMode
  1038. Case UCase(&quot;EOF&quot;)
  1039. If IsNull(RowSet) Then Goto Trace_Closed
  1040. Select Case True
  1041. Case _BOF And _EOF : _PropertyGet = True
  1042. Case RowSet.isAfterLast() : _PropertyGet = True
  1043. Case Else : _PropertyGet = False
  1044. End Select
  1045. Case UCase(&quot;Filter&quot;)
  1046. If IsNull(RowSet) Then Goto Trace_Closed
  1047. _PropertyGet = RowSet.Filter
  1048. Case UCase(&quot;LastModified&quot;)
  1049. If IsNull(RowSet) Then Goto Trace_Closed
  1050. If RowSet.IsBookmarkable And Not _ForwardOnly Then
  1051. _PropertyGet = _BookmarkLastModified
  1052. Else
  1053. _PropertyGet = Null
  1054. If _ForwardOnly Then Goto Trace_Forward
  1055. End If
  1056. Case UCase(&quot;Name&quot;)
  1057. _PropertyGet = _Name
  1058. Case UCase(&quot;ObjectType&quot;)
  1059. _PropertyGet = _Type
  1060. Case UCase(&quot;RecordCount&quot;)
  1061. If IsNull(RowSet) Then Goto Trace_Closed
  1062. _PropertyGet = RowSet.RowCount
  1063. Case Else
  1064. Goto Trace_Error
  1065. End Select
  1066. Exit_Function:
  1067. Utils._ResetCalledSub(cstThisSub &amp; psProperty)
  1068. Exit Function
  1069. Trace_Error:
  1070. TraceError(TRACEFATAL, ERRPROPERTY, Utils._CalledSub(), 0, , psProperty)
  1071. _PropertyGet = EMPTY
  1072. Goto Exit_Function
  1073. Trace_Forward:
  1074. TraceError(TRACEFATAL, ERRRECORDSETFORWARD, Utils._CalledSub(), 0)
  1075. Goto Exit_Function
  1076. Trace_Closed:
  1077. TraceError(TRACEFATAL, ERRRECORDSETCLOSED, Utils._CalledSub(), 0)
  1078. Goto Exit_Function
  1079. Error_Function:
  1080. TraceError(TRACEABORT, Err, cstThisSub &amp; &quot;._PropertyGet&quot;, Erl)
  1081. _PropertyGet = EMPTY
  1082. GoTo Exit_Function
  1083. End Function &apos; _PropertyGet
  1084. REM -----------------------------------------------------------------------------------------------------------------------
  1085. Private Function _PropertySet(ByVal psProperty As String, ByVal pvValue As Variant) As Boolean
  1086. Dim cstThisSub As String
  1087. cstThisSub = &quot;Recordset.set&quot;
  1088. Utils._SetCalledSub(cstThisSub &amp; psProperty)
  1089. If _ErrorHandler() Then On Local Error Goto Error_Function
  1090. _PropertySet = True
  1091. &apos;Execute
  1092. Dim iArgNr As Integer
  1093. Dim oObject As Object
  1094. If _IsLeft(_A2B_.CalledSub, &quot;Recordset.&quot;) Then iArgNr = 1 Else iArgNr = 2
  1095. Select Case UCase(psProperty)
  1096. Case UCase(&quot;AbsolutePosition&quot;)
  1097. If Not Utils._CheckArgument(pvValue, iArgNr, Utils._AddNumeric(), , False) Then Goto Trace_Error_Value
  1098. If pvValue &lt; 1 Then Goto Trace_Error_Value
  1099. _Move(pvValue, , True)
  1100. Case UCase(&quot;Bookmark&quot;)
  1101. If IsNull(RowSet) Then Goto Trace_Closed
  1102. _Move(0, pvValue)
  1103. Case UCase(&quot;Filter&quot;)
  1104. If IsNull(RowSet) Then Goto Trace_Closed
  1105. If Not Utils._CheckArgument(pvValue, iArgNr, vbString, , False) Then Goto Trace_Error_Value
  1106. _Filter = _ParentDatabase._ReplaceSquareBrackets(pvValue)
  1107. Case Else
  1108. Goto Trace_Error
  1109. End Select
  1110. Exit_Function:
  1111. Utils._ResetCalledSub(cstThisSub &amp; psProperty)
  1112. Exit Function
  1113. Trace_Error:
  1114. TraceError(TRACEFATAL, ERRPROPERTY, Utils._CalledSub(), 0, 1, psProperty)
  1115. _PropertySet = False
  1116. Goto Exit_Function
  1117. Trace_Error_Value:
  1118. TraceError(TRACEFATAL, ERRPROPERTYVALUE, Utils._CalledSub(), 0, 1, Array(pvValue, psProperty))
  1119. _PropertySet = False
  1120. Goto Exit_Function
  1121. Trace_Closed:
  1122. TraceError(TRACEFATAL, ERRRECORDSETCLOSED, Utils._CalledSub(), 0)
  1123. Goto Exit_Function
  1124. Error_Function:
  1125. TraceError(TRACEABORT, Err, Utils._CalledSub(), Erl)
  1126. _PropertySet = False
  1127. GoTo Exit_Function
  1128. End Function &apos; _PropertySet
  1129. </script:module>