VCS_Table.bas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. Option Compare Database
  2. Option Private Module
  3. Option Explicit
  4. ' --------------------------------
  5. ' Structures
  6. ' --------------------------------
  7. ' Structure to keep track of "on Update" and "on Delete" clauses
  8. ' Access does not in all cases execute such queries
  9. Private Type structEnforce
  10. foreignTable As String
  11. foreignFields() As String
  12. table As String
  13. refFields() As String
  14. isUpdate As Boolean
  15. End Type
  16. ' keeping "on Update" relations to be complemented after table creation
  17. Private K() As structEnforce
  18. Public Sub ExportLinkedTable(ByVal tbl_name As String, ByVal obj_path As String)
  19. On Error GoTo Err_LinkedTable
  20. Dim tempFilePath As String
  21. tempFilePath = VCS_File.TempFile()
  22. Dim fso As Object
  23. Dim OutFile As Object
  24. Set fso = CreateObject("Scripting.FileSystemObject")
  25. ' open file for writing with Create=True, Unicode=True (USC-2 Little Endian format)
  26. VCS_Dir.MkDirIfNotExist obj_path
  27. Set OutFile = fso.CreateTextFile(tempFilePath, overwrite:=True, Unicode:=True)
  28. OutFile.Write CurrentDb.TableDefs(tbl_name).name
  29. OutFile.Write vbCrLf
  30. If InStr(1, CurrentDb.TableDefs(tbl_name).connect, "DATABASE=" & CurrentProject.Path) Then
  31. 'change to relatave path
  32. Dim connect() As String
  33. connect = Split(CurrentDb.TableDefs(tbl_name).connect, CurrentProject.Path)
  34. OutFile.Write connect(0) & "." & connect(1)
  35. Else
  36. OutFile.Write CurrentDb.TableDefs(tbl_name).connect
  37. End If
  38. OutFile.Write vbCrLf
  39. OutFile.Write CurrentDb.TableDefs(tbl_name).SourceTableName
  40. OutFile.Write vbCrLf
  41. Dim Db As DAO.Database
  42. Set Db = CurrentDb
  43. Dim td As DAO.TableDef
  44. Set td = Db.TableDefs(tbl_name)
  45. Dim idx As DAO.Index
  46. For Each idx In td.Indexes
  47. If idx.Primary Then
  48. OutFile.Write Right$(idx.Fields, Len(idx.Fields) - 1)
  49. OutFile.Write vbCrLf
  50. End If
  51. Next
  52. Err_LinkedTable_Fin:
  53. On Error Resume Next
  54. OutFile.Close
  55. 'save files as .odbc
  56. VCS_File.ConvertUcs2Utf8 tempFilePath, obj_path & tbl_name & ".LNKD"
  57. Exit Sub
  58. Err_LinkedTable:
  59. OutFile.Close
  60. MsgBox err.Description, vbCritical, "ERROR: EXPORT LINKED TABLE"
  61. Resume Err_LinkedTable_Fin
  62. End Sub
  63. ' This requires Microsoft ADO Ext. 2.x for DLL and Security
  64. ' See reference: https://social.msdn.microsoft.com/Forums/office/en-US/883087ba-2c25-4571-bd3c-706061466a11/how-can-i-programmatically-access-scale-property-of-a-decimal-data-type-field?forum=accessdev
  65. Private Function formatDecimal(ByVal tableName As String, ByVal fieldName As String) As String
  66. Dim cnn As ADODB.Connection
  67. Dim cat As ADOX.Catalog
  68. Dim col As ADOX.Column
  69. Set cnn = New ADODB.Connection
  70. Set cat = New ADOX.Catalog
  71. Set cnn = CurrentProject.Connection
  72. Set cat.ActiveConnection = cnn
  73. Set col = cat.Tables(tableName).Columns(fieldName)
  74. formatDecimal = "(" & col.Precision & ", " & col.NumericScale & ")"
  75. Set col = Nothing
  76. Set cat = Nothing
  77. Set cnn = Nothing
  78. End Function
  79. ' Save a Table Definition as SQL statement
  80. Public Sub ExportTableDef(Db As DAO.Database, td As DAO.TableDef, ByVal tableName As String, _
  81. ByVal directory As String)
  82. Dim fileName As String
  83. fileName = directory & tableName & ".sql"
  84. Dim sql As String
  85. Dim fieldAttributeSql As String
  86. Dim idx As DAO.Index
  87. Dim fi As DAO.Field
  88. Dim fso As Object
  89. Dim OutFile As Object
  90. Dim ff As Object
  91. 'Debug.Print tableName
  92. Set fso = CreateObject("Scripting.FileSystemObject")
  93. Set OutFile = fso.CreateTextFile(fileName, overwrite:=True, Unicode:=False)
  94. sql = "CREATE TABLE " & strName(tableName) & " (" & vbCrLf
  95. For Each fi In td.Fields
  96. sql = sql & " " & strName(fi.name) & " "
  97. If (fi.Attributes And dbAutoIncrField) Then
  98. sql = sql & "AUTOINCREMENT"
  99. Else
  100. sql = sql & strType(fi.Type) & " "
  101. End If
  102. Select Case fi.Type
  103. Case dbText, dbVarBinary
  104. sql = sql & "(" & fi.Size & ")"
  105. Case dbDecimal
  106. sql = sql & formatDecimal(tableName, fi.name)
  107. Case Else
  108. End Select
  109. For Each idx In td.Indexes
  110. fieldAttributeSql = vbNullString
  111. If idx.Fields.count = 1 And idx.Fields(0).name = fi.name Then
  112. If idx.Primary Then fieldAttributeSql = fieldAttributeSql & " PRIMARY KEY "
  113. If idx.Unique Then fieldAttributeSql = fieldAttributeSql & " UNIQUE "
  114. If idx.Required Then fieldAttributeSql = fieldAttributeSql & " NOT NULL "
  115. If idx.Foreign Then
  116. Set ff = idx.Fields
  117. fieldAttributeSql = fieldAttributeSql & formatReferences(Db, ff, tableName)
  118. End If
  119. If Len(fieldAttributeSql) > 0 Then fieldAttributeSql = " CONSTRAINT " & strName(idx.name) & fieldAttributeSql
  120. End If
  121. sql = sql & fieldAttributeSql
  122. Next
  123. sql = sql & "," & vbCrLf
  124. Next
  125. sql = Left$(sql, Len(sql) - 3) ' strip off last comma and crlf
  126. Dim constraintSql As String
  127. For Each idx In td.Indexes
  128. If idx.Fields.count > 1 Then
  129. If Len(constraintSql) = 0 Then constraintSql = constraintSql & " CONSTRAINT "
  130. If idx.Primary Then constraintSql = constraintSql & formatConstraint("PRIMARY KEY", idx)
  131. If Not idx.Foreign Then
  132. If Len(constraintSql) > 0 Then
  133. sql = sql & "," & vbCrLf & " " & constraintSql
  134. sql = sql & formatReferences(Db, idx.Fields, tableName)
  135. End If
  136. End If
  137. End If
  138. Next
  139. sql = sql & vbCrLf & ")"
  140. 'Debug.Print sql
  141. OutFile.WriteLine sql
  142. OutFile.Close
  143. 'exort Data Macros
  144. VCS_DataMacro.ExportDataMacros tableName, directory
  145. End Sub
  146. Private Function formatReferences(Db As DAO.Database, ff As Object, _
  147. ByVal tableName As String) As String
  148. Dim rel As DAO.Relation
  149. Dim sql As String
  150. Dim f As DAO.Field
  151. For Each rel In Db.Relations
  152. If (rel.foreignTable = tableName) Then
  153. If FieldsIdentical(ff, rel.Fields) Then
  154. sql = " REFERENCES "
  155. sql = sql & strName(rel.table) & " ("
  156. For Each f In rel.Fields
  157. sql = sql & strName(f.name) & ","
  158. Next
  159. sql = Left$(sql, Len(sql) - 1) & ")"
  160. If rel.Attributes And dbRelationUpdateCascade Then
  161. sql = sql + " ON UPDATE CASCADE "
  162. End If
  163. If rel.Attributes And dbRelationDeleteCascade Then
  164. sql = sql + " ON DELETE CASCADE "
  165. End If
  166. Exit For
  167. End If
  168. End If
  169. Next
  170. formatReferences = sql
  171. End Function
  172. Private Function formatConstraint(ByVal keyw As String, ByVal idx As DAO.Index) As String
  173. Dim sql As String
  174. Dim fi As DAO.Field
  175. sql = strName(idx.name) & " " & keyw & " ("
  176. For Each fi In idx.Fields
  177. sql = sql & strName(fi.name) & ", "
  178. Next
  179. sql = Left$(sql, Len(sql) - 2) & ")" 'strip off last comma and close brackets
  180. 'return value
  181. formatConstraint = sql
  182. End Function
  183. Private Function strName(ByVal s As String) As String
  184. strName = "[" & s & "]"
  185. End Function
  186. Private Function strType(ByVal i As Integer) As String
  187. Select Case i
  188. Case dbLongBinary
  189. strType = "LONGBINARY"
  190. Case dbBinary
  191. strType = "BINARY"
  192. Case dbBoolean
  193. strType = "BIT"
  194. Case dbAutoIncrField
  195. strType = "COUNTER"
  196. Case dbCurrency
  197. strType = "CURRENCY"
  198. Case dbDate, dbTime
  199. strType = "DATETIME"
  200. Case dbGUID
  201. strType = "GUID"
  202. Case dbMemo
  203. strType = "LONGTEXT"
  204. Case dbDouble
  205. strType = "DOUBLE"
  206. Case dbSingle
  207. strType = "SINGLE"
  208. Case dbByte
  209. strType = "BYTE"
  210. Case dbInteger
  211. strType = "SHORT"
  212. Case dbLong
  213. strType = "LONG"
  214. Case dbNumeric
  215. strType = "NUMERIC"
  216. Case dbText
  217. strType = "VARCHAR"
  218. Case dbDecimal
  219. strType = "DECIMAL"
  220. Case Else
  221. strType = "VARCHAR"
  222. End Select
  223. End Function
  224. Private Function FieldsIdentical(ff As Object, gg As Object) As Boolean
  225. Dim f As DAO.Field
  226. If ff.count <> gg.count Then
  227. FieldsIdentical = False
  228. Exit Function
  229. End If
  230. For Each f In ff
  231. If Not FieldInFields(f, gg) Then
  232. FieldsIdentical = False
  233. Exit Function
  234. End If
  235. Next
  236. FieldsIdentical = True
  237. End Function
  238. Private Function FieldInFields(fi As DAO.Field, ff As DAO.Fields) As Boolean
  239. Dim f As DAO.Field
  240. For Each f In ff
  241. If f.name = fi.name Then
  242. FieldInFields = True
  243. Exit Function
  244. End If
  245. Next
  246. FieldInFields = False
  247. End Function
  248. ' Determine if a table or exists.
  249. ' based on sample code of support.microsoftcom
  250. ' ARGUMENTS:
  251. ' TName: The name of a table or query.
  252. '
  253. ' RETURNS: True (it exists) or False (it does not exist).
  254. Private Function TableExists(ByVal TName As String) As Boolean
  255. Dim Db As DAO.Database
  256. Dim Found As Boolean
  257. Dim test As String
  258. Const NAME_NOT_IN_COLLECTION As Integer = 3265
  259. ' Assume the table or query does not exist.
  260. Found = False
  261. Set Db = CurrentDb()
  262. ' Trap for any errors.
  263. On Error Resume Next
  264. ' See if the name is in the Tables collection.
  265. test = Db.TableDefs(TName).name
  266. If err.number <> NAME_NOT_IN_COLLECTION Then Found = True
  267. ' Reset the error variable.
  268. err = 0
  269. TableExists = Found
  270. End Function
  271. ' Build SQL to export `tbl_name` sorted by each field from first to last
  272. Private Function TableExportSql(ByVal tbl_name As String) As String
  273. Dim rs As Object ' DAO.Recordset
  274. Dim fieldObj As Object ' DAO.Field
  275. Dim sb() As String, count As Integer
  276. Set rs = CurrentDb.OpenRecordset(tbl_name)
  277. sb = VCS_String.Sb_Init()
  278. VCS_String.Sb_Append sb, "SELECT "
  279. count = 0
  280. For Each fieldObj In rs.Fields
  281. If count > 0 Then VCS_String.Sb_Append sb, ", "
  282. VCS_String.Sb_Append sb, "[" & fieldObj.name & "]"
  283. count = count + 1
  284. Next
  285. VCS_String.Sb_Append sb, " FROM [" & tbl_name & "] ORDER BY "
  286. count = 0
  287. For Each fieldObj In rs.Fields
  288. DoEvents
  289. If count > 0 Then VCS_String.Sb_Append sb, ", "
  290. VCS_String.Sb_Append sb, "[" & fieldObj.name & "]"
  291. count = count + 1
  292. Next
  293. TableExportSql = VCS_String.Sb_Get(sb)
  294. End Function
  295. ' Export the lookup table `tblName` to `source\tables`.
  296. Public Sub ExportTableData(ByVal tbl_name As String, ByVal obj_path As String)
  297. Dim fso As Object
  298. Dim OutFile As Object
  299. Dim rs As DAO.Recordset ' DAO.Recordset
  300. Dim fieldObj As Object ' DAO.Field
  301. Dim c As Long, value As Variant
  302. ' Checks first
  303. If Not TableExists(tbl_name) Then
  304. Debug.Print "Error: Table " & tbl_name & " missing"
  305. Exit Sub
  306. End If
  307. Set rs = CurrentDb.OpenRecordset(TableExportSql(tbl_name))
  308. If rs.RecordCount = 0 Then
  309. 'why is this an error? Debug.Print "Error: Table " & tbl_name & " empty"
  310. rs.Close
  311. Exit Sub
  312. End If
  313. Set fso = CreateObject("Scripting.FileSystemObject")
  314. ' open file for writing with Create=True, Unicode=True (USC-2 Little Endian format)
  315. VCS_Dir.MkDirIfNotExist obj_path
  316. Dim tempFileName As String
  317. tempFileName = VCS_File.TempFile()
  318. Set OutFile = fso.CreateTextFile(tempFileName, overwrite:=True, Unicode:=True)
  319. c = 0
  320. For Each fieldObj In rs.Fields
  321. If c <> 0 Then OutFile.Write vbTab
  322. c = c + 1
  323. OutFile.Write fieldObj.name
  324. Next
  325. OutFile.Write vbCrLf
  326. rs.MoveFirst
  327. Do Until rs.EOF
  328. c = 0
  329. For Each fieldObj In rs.Fields
  330. DoEvents
  331. If c <> 0 Then OutFile.Write vbTab
  332. c = c + 1
  333. value = rs(fieldObj.name)
  334. If IsNull(value) Then
  335. value = vbNullString
  336. Else
  337. value = Replace(value, "\", "\\")
  338. value = Replace(value, vbCrLf, "\n")
  339. value = Replace(value, vbCr, "\n")
  340. value = Replace(value, vbLf, "\n")
  341. value = Replace(value, vbTab, "\t")
  342. End If
  343. OutFile.Write value
  344. Next
  345. OutFile.Write vbCrLf
  346. rs.MoveNext
  347. Loop
  348. rs.Close
  349. OutFile.Close
  350. VCS_File.ConvertUcs2Utf8 tempFileName, obj_path & tbl_name & ".txt"
  351. fso.DeleteFile tempFileName
  352. End Sub
  353. ' Kill Table if Exists
  354. Private Sub KillTable(ByVal tblName As String, Db As Object)
  355. If TableExists(tblName) Then
  356. Db.execute "DROP TABLE [" & tblName & "]"
  357. End If
  358. End Sub
  359. Public Sub ImportLinkedTable(ByVal tblName As String, ByRef obj_path As String)
  360. Dim Db As DAO.Database
  361. Dim fso As Object
  362. Dim InFile As Object
  363. Set Db = CurrentDb
  364. Set fso = CreateObject("Scripting.FileSystemObject")
  365. Dim tempFilePath As String
  366. tempFilePath = VCS_File.TempFile()
  367. ConvertUtf8Ucs2 obj_path & tblName & ".LNKD", tempFilePath
  368. ' open file for reading with Create=False, Unicode=True (USC-2 Little Endian format)
  369. Set InFile = fso.OpenTextFile(tempFilePath, iomode:=ForReading, create:=False, Format:=TristateTrue)
  370. On Error GoTo err_notable:
  371. DoCmd.DeleteObject acTable, tblName
  372. GoTo err_notable_fin
  373. err_notable:
  374. err.Clear
  375. Resume err_notable_fin
  376. err_notable_fin:
  377. On Error GoTo Err_CreateLinkedTable:
  378. Dim td As DAO.TableDef
  379. Set td = Db.CreateTableDef(InFile.readline())
  380. Dim connect As String
  381. connect = InFile.readline()
  382. If InStr(1, connect, "DATABASE=.\") Then 'replace relative path with literal path
  383. connect = Replace(connect, "DATABASE=.\", "DATABASE=" & CurrentProject.Path & "\")
  384. End If
  385. td.connect = connect
  386. td.SourceTableName = InFile.readline()
  387. Db.TableDefs.Append td
  388. GoTo Err_CreateLinkedTable_Fin
  389. Err_CreateLinkedTable:
  390. MsgBox err.Description, vbCritical, "ERROR: IMPORT LINKED TABLE"
  391. Resume Err_CreateLinkedTable_Fin
  392. Err_CreateLinkedTable_Fin:
  393. 'this will throw errors if a primary key already exists or the table is linked to an access database table
  394. 'will also error out if no pk is present
  395. On Error GoTo Err_LinkPK_Fin:
  396. Dim Fields As String
  397. Fields = InFile.readline()
  398. Dim Field As Variant
  399. Dim sql As String
  400. sql = "CREATE INDEX __uniqueindex ON " & td.name & " ("
  401. For Each Field In Split(Fields, ";+")
  402. sql = sql & "[" & Field & "]" & ","
  403. Next
  404. 'remove extraneous comma
  405. sql = Left$(sql, Len(sql) - 1)
  406. sql = sql & ") WITH PRIMARY"
  407. CurrentDb.execute sql
  408. Err_LinkPK_Fin:
  409. On Error Resume Next
  410. InFile.Close
  411. End Sub
  412. ' Import Table Definition
  413. Public Sub ImportTableDef(ByVal tblName As String, ByVal directory As String)
  414. Dim filePath As String
  415. filePath = directory & tblName & ".sql"
  416. Dim Db As Object ' DAO.Database
  417. Dim fso As Object
  418. Dim InFile As Object
  419. Dim buf As String
  420. Dim p As Integer
  421. Dim p1 As Integer
  422. Dim strMsg As String
  423. Dim s As Variant
  424. Dim n As Integer
  425. Dim i As Integer
  426. Dim j As Integer
  427. Dim tempFileName As String
  428. tempFileName = VCS_File.TempFile()
  429. n = -1
  430. Set fso = CreateObject("Scripting.FileSystemObject")
  431. VCS_File.ConvertUtf8Ucs2 filePath, tempFileName
  432. ' open file for reading with Create=False, Unicode=True (USC-2 Little Endian format)
  433. Set InFile = fso.OpenTextFile(tempFileName, iomode:=ForReading, create:=False, Format:=TristateTrue)
  434. Set Db = CurrentDb
  435. KillTable tblName, Db
  436. buf = InFile.readline()
  437. Do Until InFile.AtEndOfStream
  438. buf = buf & InFile.readline()
  439. Loop
  440. ' The following block is needed because "on update" actions may cause problems
  441. For Each s In Split("UPDATE|DELETE", "|")
  442. p = InStr(buf, "ON " & s & " CASCADE")
  443. Do While p > 0
  444. n = n + 1
  445. ReDim Preserve K(n)
  446. K(n).table = tblName
  447. K(n).isUpdate = (s = "UPDATE")
  448. buf = Left$(buf, p - 1) & Mid$(buf, p + 18)
  449. p = InStrRev(buf, "REFERENCES", p)
  450. p1 = InStr(p, buf, "(")
  451. K(n).foreignFields = Split(VCS_String.SubString(p1, buf, "(", ")"), ",")
  452. K(n).foreignTable = Trim$(Mid$(buf, p + 10, p1 - p - 10))
  453. p = InStrRev(buf, "CONSTRAINT", p1)
  454. p1 = InStrRev(buf, "FOREIGN KEY", p1)
  455. If (p1 > 0) And (p > 0) And (p1 > p) Then
  456. ' multifield index
  457. K(n).refFields = Split(VCS_String.SubString(p1, buf, "(", ")"), ",")
  458. ElseIf p1 = 0 Then
  459. ' single field
  460. End If
  461. p = InStr(p, "ON " & s & " CASCADE", buf)
  462. Loop
  463. Next
  464. On Error Resume Next
  465. For i = 0 To n
  466. strMsg = K(i).table & " to " & K(i).foreignTable
  467. strMsg = strMsg & "( "
  468. For j = 0 To UBound(K(i).refFields)
  469. strMsg = strMsg & K(i).refFields(j) & ", "
  470. Next j
  471. strMsg = Left$(strMsg, Len(strMsg) - 2) & ") to ("
  472. For j = 0 To UBound(K(i).foreignFields)
  473. strMsg = strMsg & K(i).foreignFields(j) & ", "
  474. Next j
  475. strMsg = Left$(strMsg, Len(strMsg) - 2) & ") Check "
  476. If K(i).isUpdate Then
  477. strMsg = strMsg & " on update cascade " & vbCrLf
  478. Else
  479. strMsg = strMsg & " on delete cascade " & vbCrLf
  480. End If
  481. Next
  482. On Error GoTo 0
  483. Db.execute buf
  484. InFile.Close
  485. If Len(strMsg) > 0 Then MsgBox strMsg, vbOKOnly, "Correct manually"
  486. End Sub
  487. ' Import the lookup table `tblName` from `source\tables`.
  488. Public Sub ImportTableData(ByVal tblName As String, ByVal obj_path As String)
  489. Dim Db As Object ' DAO.Database
  490. Dim rs As Object ' DAO.Recordset
  491. Dim fieldObj As Object ' DAO.Field
  492. Dim fso As Object
  493. Dim InFile As Object
  494. Dim c As Long, buf As String, Values() As String, value As Variant
  495. Set fso = CreateObject("Scripting.FileSystemObject")
  496. Dim tempFileName As String
  497. tempFileName = VCS_File.TempFile()
  498. VCS_File.ConvertUtf8Ucs2 obj_path & tblName & ".txt", tempFileName
  499. ' open file for reading with Create=False, Unicode=True (USC-2 Little Endian format)
  500. Set InFile = fso.OpenTextFile(tempFileName, iomode:=ForReading, create:=False, Format:=TristateTrue)
  501. Set Db = CurrentDb
  502. Db.execute "DELETE FROM [" & tblName & "]"
  503. Set rs = Db.OpenRecordset(tblName)
  504. buf = InFile.readline()
  505. Do Until InFile.AtEndOfStream
  506. buf = InFile.readline()
  507. If Len(Trim$(buf)) > 0 Then
  508. Values = Split(buf, vbTab)
  509. c = 0
  510. rs.AddNew
  511. For Each fieldObj In rs.Fields
  512. DoEvents
  513. value = Values(c)
  514. If Len(value) = 0 Then
  515. value = Null
  516. Else
  517. value = Replace(value, "\t", vbTab)
  518. value = Replace(value, "\n", vbCrLf)
  519. value = Replace(value, "\\", "\")
  520. End If
  521. rs(fieldObj.name) = value
  522. c = c + 1
  523. Next
  524. rs.update
  525. End If
  526. Loop
  527. rs.Close
  528. InFile.Close
  529. fso.DeleteFile tempFileName
  530. End Sub