VCS_Table.bas 20 KB

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