VCS_IE_Functions.bas 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. Option Compare Database
  2. Option Private Module
  3. Option Explicit
  4. Private Const AggressiveSanitize As Boolean = True
  5. Private Const StripPublishOption As Boolean = True
  6. ' Constants for Scripting.FileSystemObject API
  7. Public Const ForReading = 1, ForWriting = 2, ForAppending = 8
  8. Public Const TristateTrue = -1, TristateFalse = 0, TristateUseDefault = -2
  9. ' constants for names conversion
  10. Public Const ForbiddenCars = "34,42,47,58,60,62,63,92,124"
  11. ' Can we export without closing the form?
  12. ' Export a database object with optional UCS2-to-UTF-8 conversion.
  13. Public Sub ExportObject(ByVal obj_type_num As Integer, ByVal obj_name As String, _
  14. ByVal file_path As String, Optional ByVal Ucs2Convert As Boolean = False)
  15. VCS_Dir.MkDirIfNotExist Left$(file_path, InStrRev(file_path, "\"))
  16. If Ucs2Convert Then
  17. Dim tempFileName As String
  18. tempFileName = VCS_File.TempFile()
  19. Application.SaveAsText obj_type_num, obj_name, tempFileName
  20. VCS_File.ConvertUcs2Utf8 tempFileName, file_path
  21. Dim FSO As Object
  22. Set FSO = CreateObject("Scripting.FileSystemObject")
  23. FSO.DeleteFile tempFileName
  24. Else
  25. Application.SaveAsText obj_type_num, obj_name, file_path
  26. End If
  27. logger "ExportObject", "DEBUG", "Object of type " & obj_type_num & " named " & obj_name & " exported to " & file_path
  28. End Sub
  29. ' Import a database object with optional UTF-8-to-UCS2 conversion.
  30. Public Sub ImportObject(ByVal obj_type_num As Integer, ByVal obj_name As String, _
  31. ByVal file_path As String, Optional ByVal Ucs2Convert As Boolean = False)
  32. If Not VCS_Dir.FileExists(file_path) Then
  33. logger "ImportObject", "ERROR", "Can't find the file " & file_path
  34. Exit Sub
  35. End If
  36. On Error GoTo err
  37. If Ucs2Convert Then
  38. Dim tempFileName As String
  39. tempFileName = VCS_File.TempFile()
  40. VCS_File.ConvertUtf8Ucs2 file_path, tempFileName
  41. Application.LoadFromText obj_type_num, obj_name, tempFileName
  42. Dim FSO As Object
  43. Set FSO = CreateObject("Scripting.FileSystemObject")
  44. FSO.DeleteFile tempFileName
  45. Else
  46. Application.LoadFromText obj_type_num, obj_name, file_path
  47. End If
  48. logger "ImportObject", "DEBUG", "Object of type " & obj_type_num & " named " & obj_name & " imported from " & file_path
  49. Exit Sub
  50. err:
  51. logger "ImportObject", "CRITICAL", "Unable to import the object " & obj_name & " (" & obj_type_num & ")" & "[" & err.Description & "]"
  52. End Sub
  53. 'shouldn't this be SanitizeTextFile (Singular)?
  54. ' For each *.txt in `Path`, find and remove a number of problematic but
  55. ' unnecessary lines of VB code that are inserted automatically by the
  56. ' Access GUI and change often (we don't want these lines of code in
  57. ' version control).
  58. Public Sub SanitizeTextFiles(ByVal path As String, ByVal Ext As String)
  59. Dim FSO As Object
  60. Set FSO = CreateObject("Scripting.FileSystemObject")
  61. '
  62. ' Setup Block matching Regex.
  63. Dim rxBlock As Object
  64. Set rxBlock = CreateObject("VBScript.RegExp")
  65. rxBlock.ignoreCase = False
  66. '
  67. ' Match PrtDevNames / Mode with or without W
  68. Dim srchPattern As String
  69. srchPattern = "PrtDev(?:Names|Mode)[W]?"
  70. If (AggressiveSanitize = True) Then
  71. ' Add and group aggressive matches
  72. srchPattern = "(?:" & srchPattern
  73. srchPattern = srchPattern & "|GUID|""GUID""|NameMap|dbLongBinary ""DOL"""
  74. srchPattern = srchPattern & ")"
  75. End If
  76. ' Ensure that this is the begining of a block.
  77. srchPattern = srchPattern & " = Begin"
  78. 'Debug.Print srchPattern
  79. rxBlock.Pattern = srchPattern
  80. '
  81. ' Setup Line Matching Regex.
  82. Dim rxLine As Object
  83. Set rxLine = CreateObject("VBScript.RegExp")
  84. srchPattern = "^\s*(?:"
  85. srchPattern = srchPattern & "Checksum ="
  86. srchPattern = srchPattern & "|BaseInfo|NoSaveCTIWhenDisabled =1"
  87. If (StripPublishOption = True) Then
  88. srchPattern = srchPattern & "|dbByte ""PublishToWeb"" =""1"""
  89. srchPattern = srchPattern & "|PublishOption =1"
  90. End If
  91. srchPattern = srchPattern & ")"
  92. 'Debug.Print srchPattern
  93. rxLine.Pattern = srchPattern
  94. Dim filename As String
  95. filename = dir$(path & "*." & Ext)
  96. If Len(filename) = 0 Then
  97. logger "SanitizeTextFiles", "INFO", "> No file to sanitized"
  98. Exit Sub
  99. End If
  100. Dim isReport As Boolean
  101. isReport = False
  102. Do Until Len(filename) = 0
  103. DoEvents
  104. Dim obj_name As String
  105. obj_name = Mid$(filename, 1, InStrRev(filename, ".") - 1)
  106. Dim InFile As Object
  107. Set InFile = FSO.OpenTextFile(path & obj_name & "." & Ext, iomode:=ForReading, Create:=False, Format:=TristateFalse)
  108. Dim OutFile As Object
  109. Set OutFile = FSO.CreateTextFile(path & obj_name & ".sanitize", overwrite:=True, unicode:=False)
  110. Dim getLine As Boolean
  111. getLine = True
  112. Do Until InFile.AtEndOfStream
  113. DoEvents
  114. Dim txt As String
  115. '
  116. ' Check if we need to get a new line of text
  117. If getLine = True Then
  118. txt = InFile.readline
  119. Else
  120. getLine = True
  121. End If
  122. '
  123. ' Skip lines starting with line pattern
  124. If rxLine.test(txt) Then
  125. Dim rxIndent As Object
  126. Set rxIndent = CreateObject("VBScript.RegExp")
  127. rxIndent.Pattern = "^(\s+)\S"
  128. '
  129. ' Get indentation level.
  130. Dim matches As Object
  131. Set matches = rxIndent.Execute(txt)
  132. '
  133. ' Setup pattern to match current indent
  134. Select Case matches.count
  135. Case 0
  136. rxIndent.Pattern = "^" & vbNullString
  137. Case Else
  138. rxIndent.Pattern = "^(\s{0," & Len(matches(0).SubMatches(0)) & "})"
  139. End Select
  140. rxIndent.Pattern = rxIndent.Pattern + "\S"
  141. '
  142. ' Skip lines with deeper indentation
  143. Do Until InFile.AtEndOfStream
  144. txt = InFile.readline
  145. If rxIndent.test(txt) Then Exit Do
  146. Loop
  147. ' We've moved on at least one line so do get a new one
  148. ' when starting the loop again.
  149. getLine = False
  150. '
  151. ' skip blocks of code matching block pattern
  152. ElseIf rxBlock.test(txt) Then
  153. Do Until InFile.AtEndOfStream
  154. txt = InFile.readline
  155. If InStr(txt, "End") Then Exit Do
  156. Loop
  157. ElseIf InStr(1, txt, "Begin Report") = 1 Then
  158. isReport = True
  159. OutFile.WriteLine txt
  160. ElseIf isReport = True And (InStr(1, txt, " Right =") Or InStr(1, txt, " Bottom =")) Then
  161. 'skip line
  162. If InStr(1, txt, " Bottom =") Then
  163. isReport = False
  164. End If
  165. Else
  166. OutFile.WriteLine txt
  167. End If
  168. Loop
  169. OutFile.Close
  170. InFile.Close
  171. FSO.DeleteFile (path & filename)
  172. Dim thisFile As Object
  173. Set thisFile = FSO.GetFile(path & obj_name & ".sanitize")
  174. thisFile.Move (path & filename)
  175. logger "SanitizeTextFiles", "DEBUG", "> File " & path & filename & " sanitized"
  176. filename = dir$()
  177. Loop
  178. logger "SanitizeTextFiles", "INFO", "> Files " & path & "*." & Ext & " sanitized"
  179. End Sub
  180. Public Function to_filename(ByVal object_name As String) As String
  181. ' return a file name for the object's name
  182. ' 1- access does not accept brackets for object's names
  183. ' 2- file's names can not contain those caracters:
  184. ' \ [92]
  185. ' / [47]
  186. ' : [58]
  187. ' * [42]
  188. ' ? [63]
  189. ' " [34]
  190. ' < [60]
  191. ' > [62]
  192. ' | [124]
  193. '
  194. ' this function replaces caracters which are not allowed for file names by [x],
  195. 'where x is the ascii code of the character
  196. ' test: "test_\_/_:_*_?_""_<_>_|" should become test_[92]_[47]_[58]_[42]_[63]_[34]_[60]_[62]_[124]
  197. ' to convert back the string, use to_accessname
  198. Dim result As String
  199. Dim ascii_code As Variant
  200. result = object_name
  201. For Each ascii_code In Split(ForbiddenCars, ",")
  202. result = Replace(result, Chr(CInt(ascii_code)), "[" & ascii_code & "]")
  203. Next
  204. If result <> object_name Then
  205. logger "to_filename", "DEBUG", "> Object's name " & object_name & " transformed to " & result
  206. End If
  207. to_filename = result
  208. Exit Function
  209. err:
  210. Call logger("to_filename", "ERROR", "Unable to convert object's name " & object_name & " to file's name")
  211. to_filename = object_name
  212. End Function
  213. Public Function to_accessname(ByVal file_name As String) As String
  214. On Error GoTo err
  215. ' return an object name from a file's name
  216. ' see function 'to_filename' for more informations
  217. ' test: "test_[92]_[47]_[58]_[42]_[63]_[34]_[60]_[62]_[124]" should become test_\_/_:_*_?_"_<_>_|
  218. Dim result As String
  219. Dim ascii_code As Variant
  220. result = file_name
  221. For Each ascii_code In Split(ForbiddenCars, ",")
  222. result = Replace(result, "[" & ascii_code & "]", Chr(CInt(ascii_code)))
  223. Next
  224. If result <> file_name Then
  225. logger "to_accessname", "DEBUG", "> File's name " & file_name & " transformed to " & result
  226. End If
  227. to_accessname = result
  228. Exit Function
  229. err:
  230. Call logger("to_accessname", "ERROR", "Unable to convert file's name " & file_name & " to access object's name")
  231. to_accessname = file_name
  232. End Function