VCS_ImportExport.bas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. Attribute VB_Name = "VCS_ImportExport"
  2. Option Compare Database
  3. Option Explicit
  4. ' List of lookup tables that are part of the program rather than the
  5. ' data, to be exported with source code
  6. ' Set to "*" to export the contents of all tables
  7. 'Only used in ExportAllSource
  8. Private Const INCLUDE_TABLES As String = ""
  9. ' This is used in ImportAllSource
  10. Private Const DebugOutput As Boolean = False
  11. 'this is used in ExportAllSource
  12. 'Causes the VCS_ code to be exported
  13. Private Const ArchiveMyself As Boolean = False
  14. 'returns true if named module is NOT part of the VCS code
  15. Private Function IsNotVCS(ByVal name As String) As Boolean
  16. If name <> "VCS_ImportExport" And _
  17. name <> "VCS_IE_Functions" And _
  18. name <> "VCS_File" And _
  19. name <> "VCS_Dir" And _
  20. name <> "VCS_String" And _
  21. name <> "VCS_Loader" And _
  22. name <> "VCS_Table" And _
  23. name <> "VCS_Reference" And _
  24. name <> "VCS_DataMacro" And _
  25. name <> "VCS_Report" And _
  26. name <> "VCS_Relation" Then
  27. IsNotVCS = True
  28. Else
  29. IsNotVCS = False
  30. End If
  31. End Function
  32. ' Main entry point for EXPORT. Export all forms, reports, queries,
  33. ' macros, modules, and lookup tables to `source` folder under the
  34. ' database's folder.
  35. Public Sub ExportAllSource()
  36. Dim Db As Object ' DAO.Database
  37. Dim source_path As String
  38. Dim obj_path As String
  39. Dim qry As Object ' DAO.QueryDef
  40. Dim doc As Object ' DAO.Document
  41. Dim obj_type As Variant
  42. Dim obj_type_split() As String
  43. Dim obj_type_label As String
  44. Dim obj_type_name As String
  45. Dim obj_type_num As Integer
  46. Dim obj_count As Integer
  47. Dim obj_data_count As Integer
  48. Dim ucs2 As Boolean
  49. Set Db = CurrentDb
  50. CloseFormsReports
  51. 'InitUsingUcs2
  52. source_path = VCS_Dir.ProjectPath() & "source\"
  53. VCS_Dir.MkDirIfNotExist source_path
  54. Debug.Print
  55. obj_path = source_path & "queries\"
  56. VCS_Dir.ClearTextFilesFromDir obj_path, "bas"
  57. Debug.Print VCS_String.PadRight("Exporting queries...", 24);
  58. obj_count = 0
  59. For Each qry In Db.QueryDefs
  60. DoEvents
  61. If Left$(qry.name, 1) <> "~" Then
  62. VCS_IE_Functions.ExportObject acQuery, qry.name, obj_path & qry.name & ".bas", VCS_File.UsingUcs2
  63. obj_count = obj_count + 1
  64. End If
  65. Next
  66. Debug.Print VCS_String.PadRight("Sanitizing...", 15);
  67. VCS_IE_Functions.SanitizeTextFiles obj_path, "bas"
  68. Debug.Print "[" & obj_count & "]"
  69. For Each obj_type In Split( _
  70. "forms|Forms|" & acForm & "," & _
  71. "reports|Reports|" & acReport & "," & _
  72. "macros|Scripts|" & acMacro & "," & _
  73. "modules|Modules|" & acModule _
  74. , "," _
  75. )
  76. obj_type_split = Split(obj_type, "|")
  77. obj_type_label = obj_type_split(0)
  78. obj_type_name = obj_type_split(1)
  79. obj_type_num = Val(obj_type_split(2))
  80. obj_path = source_path & obj_type_label & "\"
  81. obj_count = 0
  82. VCS_Dir.ClearTextFilesFromDir obj_path, "bas"
  83. Debug.Print VCS_String.PadRight("Exporting " & obj_type_label & "...", 24);
  84. For Each doc In Db.Containers(obj_type_name).Documents
  85. DoEvents
  86. If (Left$(doc.name, 1) <> "~") And _
  87. (IsNotVCS(doc.name) Or ArchiveMyself) Then
  88. If obj_type_label = "modules" Then
  89. ucs2 = False
  90. Else
  91. ucs2 = VCS_File.UsingUcs2
  92. End If
  93. VCS_IE_Functions.ExportObject obj_type_num, doc.name, obj_path & doc.name & ".bas", ucs2
  94. If obj_type_label = "reports" Then
  95. VCS_Report.ExportPrintVars doc.name, obj_path & doc.name & ".pv"
  96. End If
  97. obj_count = obj_count + 1
  98. End If
  99. Next
  100. Debug.Print VCS_String.PadRight("Sanitizing...", 15);
  101. If obj_type_label <> "modules" Then
  102. VCS_IE_Functions.SanitizeTextFiles obj_path, "bas"
  103. End If
  104. Debug.Print "[" & obj_count & "]"
  105. Next
  106. VCS_Reference.ExportReferences source_path
  107. '-------------------------table export------------------------
  108. obj_path = source_path & "tables\"
  109. VCS_Dir.MkDirIfNotExist Left$(obj_path, InStrRev(obj_path, "\"))
  110. VCS_Dir.ClearTextFilesFromDir obj_path, "txt"
  111. Dim td As DAO.TableDef
  112. Dim tds As DAO.TableDefs
  113. Set tds = Db.TableDefs
  114. obj_type_label = "tbldef"
  115. obj_type_name = "Table_Def"
  116. obj_type_num = acTable
  117. obj_path = source_path & obj_type_label & "\"
  118. obj_count = 0
  119. obj_data_count = 0
  120. VCS_Dir.MkDirIfNotExist Left$(obj_path, InStrRev(obj_path, "\"))
  121. 'move these into Table and DataMacro modules?
  122. ' - We don't want to determin file extentions here - or obj_path either!
  123. VCS_Dir.ClearTextFilesFromDir obj_path, "sql"
  124. VCS_Dir.ClearTextFilesFromDir obj_path, "xml"
  125. VCS_Dir.ClearTextFilesFromDir obj_path, "LNKD"
  126. Dim IncludeTablesCol As Collection
  127. Set IncludeTablesCol = StrSetToCol(INCLUDE_TABLES, ",")
  128. Debug.Print VCS_String.PadRight("Exporting " & obj_type_label & "...", 24);
  129. For Each td In tds
  130. ' This is not a system table
  131. ' this is not a temporary table
  132. If Left$(td.name, 4) <> "MSys" And _
  133. Left$(td.name, 1) <> "~" Then
  134. If Len(td.connect) = 0 Then ' this is not an external table
  135. VCS_Table.ExportTableDef Db, td, td.name, obj_path
  136. If INCLUDE_TABLES = "*" Then
  137. DoEvents
  138. VCS_Table.ExportTableData CStr(td.name), source_path & "tables\"
  139. If Len(Dir$(source_path & "tables\" & td.name & ".txt")) > 0 Then
  140. obj_data_count = obj_data_count + 1
  141. End If
  142. ElseIf (Len(Replace(INCLUDE_TABLES, " ", vbNullString)) > 0) And INCLUDE_TABLES <> "*" Then
  143. DoEvents
  144. On Error GoTo Err_TableNotFound
  145. If InCollection(IncludeTablesCol,td.name) Then
  146. VCS_Table.ExportTableData CStr(td.name), source_path & "tables\"
  147. obj_data_count = obj_data_count + 1
  148. End If
  149. Err_TableNotFound:
  150. 'else don't export table data
  151. End If
  152. Else
  153. VCS_Table.ExportLinkedTable td.name, obj_path
  154. End If
  155. obj_count = obj_count + 1
  156. End If
  157. Next
  158. Debug.Print "[" & obj_count & "]"
  159. If obj_data_count > 0 Then
  160. Debug.Print VCS_String.PadRight("Exported data...", 24) & "[" & obj_data_count & "]"
  161. End If
  162. Debug.Print VCS_String.PadRight("Exporting Relations...", 24);
  163. obj_count = 0
  164. obj_path = source_path & "relations\"
  165. VCS_Dir.MkDirIfNotExist Left$(obj_path, InStrRev(obj_path, "\"))
  166. VCS_Dir.ClearTextFilesFromDir obj_path, "txt"
  167. Dim aRelation As DAO.Relation
  168. For Each aRelation In CurrentDb.Relations
  169. ' Exclude relations from system tables and inherited (linked) relations
  170. If Not (aRelation.name = "MSysNavPaneGroupsMSysNavPaneGroupToObjects" _
  171. Or aRelation.name = "MSysNavPaneGroupCategoriesMSysNavPaneGroups" _
  172. Or (aRelation.Attributes And DAO.RelationAttributeEnum.dbRelationInherited) = _
  173. DAO.RelationAttributeEnum.dbRelationInherited) Then
  174. VCS_Relation.ExportRelation aRelation, obj_path & aRelation.name & ".txt"
  175. obj_count = obj_count + 1
  176. End If
  177. Next
  178. Debug.Print "[" & obj_count & "]"
  179. Debug.Print "Done."
  180. End Sub
  181. ' Main entry point for IMPORT. Import all forms, reports, queries,
  182. ' macros, modules, and lookup tables from `source` folder under the
  183. ' database's folder.
  184. Public Sub ImportAllSource()
  185. Dim FSO As Object
  186. Dim source_path As String
  187. Dim obj_path As String
  188. Dim obj_type As Variant
  189. Dim obj_type_split() As String
  190. Dim obj_type_label As String
  191. Dim obj_type_num As Integer
  192. Dim obj_count As Integer
  193. Dim fileName As String
  194. Dim obj_name As String
  195. Dim ucs2 As Boolean
  196. Set FSO = CreateObject("Scripting.FileSystemObject")
  197. CloseFormsReports
  198. 'InitUsingUcs2
  199. source_path = VCS_Dir.ProjectPath() & "source\"
  200. If Not FSO.FolderExists(source_path) Then
  201. MsgBox "No source found at:" & vbCrLf & source_path, vbExclamation, "Import failed"
  202. Exit Sub
  203. End If
  204. Debug.Print
  205. If Not VCS_Reference.ImportReferences(source_path) Then
  206. Debug.Print "Info: no references file in " & source_path
  207. Debug.Print
  208. End If
  209. obj_path = source_path & "queries\"
  210. fileName = Dir$(obj_path & "*.bas")
  211. Dim tempFilePath As String
  212. tempFilePath = VCS_File.TempFile()
  213. If Len(fileName) > 0 Then
  214. Debug.Print VCS_String.PadRight("Importing queries...", 24);
  215. obj_count = 0
  216. Do Until Len(fileName) = 0
  217. DoEvents
  218. obj_name = Mid$(fileName, 1, InStrRev(fileName, ".") - 1)
  219. VCS_IE_Functions.ImportObject acQuery, obj_name, obj_path & fileName, VCS_File.UsingUcs2
  220. VCS_IE_Functions.ExportObject acQuery, obj_name, tempFilePath, VCS_File.UsingUcs2
  221. VCS_IE_Functions.ImportObject acQuery, obj_name, tempFilePath, VCS_File.UsingUcs2
  222. obj_count = obj_count + 1
  223. fileName = Dir$()
  224. Loop
  225. Debug.Print "[" & obj_count & "]"
  226. End If
  227. VCS_Dir.DelIfExist tempFilePath
  228. ' restore table definitions
  229. obj_path = source_path & "tbldef\"
  230. fileName = Dir$(obj_path & "*.sql")
  231. If Len(fileName) > 0 Then
  232. Debug.Print VCS_String.PadRight("Importing tabledefs...", 24);
  233. obj_count = 0
  234. Do Until Len(fileName) = 0
  235. obj_name = Mid$(fileName, 1, InStrRev(fileName, ".") - 1)
  236. If DebugOutput Then
  237. If obj_count = 0 Then
  238. Debug.Print
  239. End If
  240. Debug.Print " [debug] table " & obj_name;
  241. Debug.Print
  242. End If
  243. VCS_Table.ImportTableDef CStr(obj_name), obj_path
  244. obj_count = obj_count + 1
  245. fileName = Dir$()
  246. Loop
  247. Debug.Print "[" & obj_count & "]"
  248. End If
  249. ' restore linked tables - we must have access to the remote store to import these!
  250. fileName = Dir$(obj_path & "*.LNKD")
  251. If Len(fileName) > 0 Then
  252. Debug.Print VCS_String.PadRight("Importing Linked tabledefs...", 24);
  253. obj_count = 0
  254. Do Until Len(fileName) = 0
  255. obj_name = Mid$(fileName, 1, InStrRev(fileName, ".") - 1)
  256. If DebugOutput Then
  257. If obj_count = 0 Then
  258. Debug.Print
  259. End If
  260. Debug.Print " [debug] table " & obj_name;
  261. Debug.Print
  262. End If
  263. VCS_Table.ImportLinkedTable CStr(obj_name), obj_path
  264. obj_count = obj_count + 1
  265. fileName = Dir$()
  266. Loop
  267. Debug.Print "[" & obj_count & "]"
  268. End If
  269. ' NOW we may load data
  270. obj_path = source_path & "tables\"
  271. fileName = Dir$(obj_path & "*.txt")
  272. If Len(fileName) > 0 Then
  273. Debug.Print VCS_String.PadRight("Importing tables...", 24);
  274. obj_count = 0
  275. Do Until Len(fileName) = 0
  276. DoEvents
  277. obj_name = Mid$(fileName, 1, InStrRev(fileName, ".") - 1)
  278. VCS_Table.ImportTableData CStr(obj_name), obj_path
  279. obj_count = obj_count + 1
  280. fileName = Dir$()
  281. Loop
  282. Debug.Print "[" & obj_count & "]"
  283. End If
  284. 'load Data Macros - not DRY!
  285. obj_path = source_path & "tbldef\"
  286. fileName = Dir$(obj_path & "*.xml")
  287. If Len(fileName) > 0 Then
  288. Debug.Print VCS_String.PadRight("Importing Data Macros...", 24);
  289. obj_count = 0
  290. Do Until Len(fileName) = 0
  291. DoEvents
  292. obj_name = Mid$(fileName, 1, InStrRev(fileName, ".") - 1)
  293. 'VCS_Table.ImportTableData CStr(obj_name), obj_path
  294. VCS_DataMacro.ImportDataMacros obj_name, obj_path
  295. obj_count = obj_count + 1
  296. fileName = Dir$()
  297. Loop
  298. Debug.Print "[" & obj_count & "]"
  299. End If
  300. 'import Data Macros
  301. For Each obj_type In Split( _
  302. "forms|" & acForm & "," & _
  303. "reports|" & acReport & "," & _
  304. "macros|" & acMacro & "," & _
  305. "modules|" & acModule _
  306. , "," _
  307. )
  308. obj_type_split = Split(obj_type, "|")
  309. obj_type_label = obj_type_split(0)
  310. obj_type_num = Val(obj_type_split(1))
  311. obj_path = source_path & obj_type_label & "\"
  312. fileName = Dir$(obj_path & "*.bas")
  313. If Len(fileName) > 0 Then
  314. Debug.Print VCS_String.PadRight("Importing " & obj_type_label & "...", 24);
  315. obj_count = 0
  316. Do Until Len(fileName) = 0
  317. ' DoEvents no good idea!
  318. obj_name = Mid$(fileName, 1, InStrRev(fileName, ".") - 1)
  319. If obj_type_label = "modules" Then
  320. ucs2 = False
  321. Else
  322. ucs2 = VCS_File.UsingUcs2
  323. End If
  324. If IsNotVCS(obj_name) Then
  325. VCS_IE_Functions.ImportObject obj_type_num, obj_name, obj_path & fileName, ucs2
  326. obj_count = obj_count + 1
  327. Else
  328. If ArchiveMyself Then
  329. MsgBox "Module " & obj_name & " could not be updated while running. Ensure latest version is included!", vbExclamation, "Warning"
  330. End If
  331. End If
  332. fileName = Dir$()
  333. Loop
  334. Debug.Print "[" & obj_count & "]"
  335. End If
  336. Next
  337. 'import Print Variables
  338. Debug.Print VCS_String.PadRight("Importing Print Vars...", 24);
  339. obj_count = 0
  340. obj_path = source_path & "reports\"
  341. fileName = Dir$(obj_path & "*.pv")
  342. Do Until Len(fileName) = 0
  343. DoEvents
  344. obj_name = Mid$(fileName, 1, InStrRev(fileName, ".") - 1)
  345. VCS_Report.ImportPrintVars obj_name, obj_path & fileName
  346. obj_count = obj_count + 1
  347. fileName = Dir$()
  348. Loop
  349. Debug.Print "[" & obj_count & "]"
  350. 'import relations
  351. Debug.Print VCS_String.PadRight("Importing Relations...", 24);
  352. obj_count = 0
  353. obj_path = source_path & "relations\"
  354. fileName = Dir$(obj_path & "*.txt")
  355. Do Until Len(fileName) = 0
  356. DoEvents
  357. VCS_Relation.ImportRelation obj_path & fileName
  358. obj_count = obj_count + 1
  359. fileName = Dir$()
  360. Loop
  361. Debug.Print "[" & obj_count & "]"
  362. DoEvents
  363. Debug.Print "Done."
  364. End Sub
  365. ' Main entry point for ImportProject.
  366. ' Drop all forms, reports, queries, macros, modules.
  367. ' execute ImportAllSource.
  368. Public Sub ImportProject()
  369. On Error GoTo errorHandler
  370. If MsgBox("This action will delete all existing: " & vbCrLf & _
  371. vbCrLf & _
  372. Chr$(149) & " Tables" & vbCrLf & _
  373. Chr$(149) & " Forms" & vbCrLf & _
  374. Chr$(149) & " Macros" & vbCrLf & _
  375. Chr$(149) & " Modules" & vbCrLf & _
  376. Chr$(149) & " Queries" & vbCrLf & _
  377. Chr$(149) & " Reports" & vbCrLf & _
  378. vbCrLf & _
  379. "Are you sure you want to proceed?", vbCritical + vbYesNo, _
  380. "Import Project") <> vbYes Then
  381. Exit Sub
  382. End If
  383. Dim Db As DAO.Database
  384. Set Db = CurrentDb
  385. CloseFormsReports
  386. Debug.Print
  387. Debug.Print "Deleting Existing Objects"
  388. Debug.Print
  389. Dim rel As DAO.Relation
  390. For Each rel In CurrentDb.Relations
  391. If Not (rel.name = "MSysNavPaneGroupsMSysNavPaneGroupToObjects" Or _
  392. rel.name = "MSysNavPaneGroupCategoriesMSysNavPaneGroups") Then
  393. CurrentDb.Relations.Delete (rel.name)
  394. End If
  395. Next
  396. Dim dbObject As Object
  397. For Each dbObject In Db.QueryDefs
  398. DoEvents
  399. If Left$(dbObject.name, 1) <> "~" Then
  400. ' Debug.Print dbObject.Name
  401. Db.QueryDefs.Delete dbObject.name
  402. End If
  403. Next
  404. Dim td As DAO.TableDef
  405. For Each td In CurrentDb.TableDefs
  406. If Left$(td.name, 4) <> "MSys" And _
  407. Left$(td.name, 1) <> "~" Then
  408. CurrentDb.TableDefs.Delete (td.name)
  409. End If
  410. Next
  411. Dim objType As Variant
  412. Dim objTypeArray() As String
  413. Dim doc As Object
  414. '
  415. ' Object Type Constants
  416. Const OTNAME As Byte = 0
  417. Const OTID As Byte = 1
  418. For Each objType In Split( _
  419. "Forms|" & acForm & "," & _
  420. "Reports|" & acReport & "," & _
  421. "Scripts|" & acMacro & "," & _
  422. "Modules|" & acModule _
  423. , "," _
  424. )
  425. objTypeArray = Split(objType, "|")
  426. DoEvents
  427. For Each doc In Db.Containers(objTypeArray(OTNAME)).Documents
  428. DoEvents
  429. If (Left$(doc.name, 1) <> "~") And _
  430. (IsNotVCS(doc.name)) Then
  431. ' Debug.Print doc.Name
  432. DoCmd.DeleteObject objTypeArray(OTID), doc.name
  433. End If
  434. Next
  435. Next
  436. Debug.Print "================="
  437. Debug.Print "Importing Project"
  438. ImportAllSource
  439. Exit Sub
  440. errorHandler:
  441. Debug.Print "VCS_ImportExport.ImportProject: Error #" & Err.Number & vbCrLf & _
  442. Err.Description
  443. End Sub
  444. ' Expose for use as function, can be called by query
  445. Public Sub make()
  446. ImportProject
  447. End Sub
  448. '===================================================================================================================================
  449. '-----------------------------------------------------------'
  450. ' Helper Functions - these should be put in their own files '
  451. '-----------------------------------------------------------'
  452. ' Close all open forms.
  453. Private Sub CloseFormsReports()
  454. On Error GoTo errorHandler
  455. Do While Forms.Count > 0
  456. DoCmd.Close acForm, Forms(0).name
  457. DoEvents
  458. Loop
  459. Do While Reports.Count > 0
  460. DoCmd.Close acReport, Reports(0).name
  461. DoEvents
  462. Loop
  463. Exit Sub
  464. errorHandler:
  465. Debug.Print "VCS_ImportExport.CloseFormsReports: Error #" & Err.Number & vbCrLf & _
  466. Err.Description
  467. End Sub
  468. 'errno 457 - duplicate key (& item)
  469. Public Function StrSetToCol(ByVal strSet As String, ByVal delimiter As String) As Collection 'throws errors
  470. Dim strSetArray() As String
  471. Dim col As Collection
  472. Set col = New Collection
  473. strSetArray = Split(strSet, delimiter)
  474. Dim item As Variant
  475. For Each item In strSetArray
  476. col.Add item, item
  477. Next
  478. Set StrSetToCol = col
  479. End Function
  480. ' Check if an item or key is in a collection
  481. Public Function InCollection(col As Collection, Optional vItem, Optional vKey) As Boolean
  482. On Error Resume Next
  483. Dim vColItem As Variant
  484. InCollection = False
  485. If Not IsMissing(vKey) Then
  486. col.item vKey
  487. '5 if not in collection, it is 91 if no collection exists
  488. If Err.Number <> 5 And Err.Number <> 91 Then
  489. InCollection = True
  490. End If
  491. ElseIf Not IsMissing(vItem) Then
  492. For Each vColItem In col
  493. If vColItem = vItem Then
  494. InCollection = True
  495. GoTo Exit_Proc
  496. End If
  497. Next vColItem
  498. End If
  499. Exit_Proc:
  500. Exit Function
  501. Err_Handle:
  502. Resume Exit_Proc
  503. End Function