pingaan

Untitled

Aug 27th, 2025
18
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.76 KB | Software | 0 0
  1. Option Compare Database
  2. Option Explicit
  3.  
  4.  
  5. ' usage: FieldUsage_Report "[table name]"
  6.  
  7.  
  8. ' ============================================================
  9. ' Field usage report -> text file (+ optional table)
  10. ' - TableName: specific table or "*ALL*"
  11. ' - FilePath: target .txt path; default: <db folder>\<Table>_FieldUsage.txt
  12. ' - Append: append to existing file (useful for *ALL*)
  13. ' - IncludeSystemTables: include MSys/hidden/temp tables (False = skip)
  14. ' - WriteToTable: also fill FieldUsageReport table (one row per hit)
  15. ' ============================================================
  16. Public Sub FieldUsage_Report(TableName As String, _
  17. Optional FilePath As String = "", _
  18. Optional Append As Boolean = False, _
  19. Optional IncludeSystemTables As Boolean = False, _
  20. Optional WriteToTable As Boolean = False)
  21.  
  22. Dim db As DAO.Database: Set db = CurrentDb
  23. Dim tdf As DAO.TableDef
  24. Dim tblList As Collection
  25. Dim fnum As Integer
  26. Dim started As Boolean
  27. Dim runStamp As String
  28.  
  29. runStamp = Format(Now, "yyyy-mm-dd hh:nn:ss")
  30.  
  31. If WriteToTable Then EnsureReportTable
  32.  
  33. ' Build list of tables to process
  34. Set tblList = New Collection
  35. If UCase$(TableName) = "*ALL*" Then
  36. For Each tdf In db.TableDefs
  37. If ShouldIncludeTable(tdf, IncludeSystemTables) Then _
  38. tblList.Add tdf.Name
  39. Next
  40. Else
  41. On Error Resume Next
  42. Set tdf = db.TableDefs(TableName)
  43. On Error GoTo 0
  44. If tdf Is Nothing Then
  45. MsgBox "Table '" & TableName & "' not found.", vbCritical
  46. Exit Sub
  47. End If
  48. tblList.Add TableName
  49. End If
  50.  
  51. ' Default file path
  52. If Len(FilePath) = 0 Then
  53. If tblList.Count = 1 Then
  54. FilePath = CurrentProject.Path & "\" & tblList(1) & "_FieldUsage.txt"
  55. Else
  56. FilePath = CurrentProject.Path & "\ALL_FieldUsage.txt"
  57. End If
  58. End If
  59.  
  60. ' Open file
  61. fnum = FreeFile
  62. If Append Then
  63. Open FilePath For Append As #fnum
  64. Else
  65. Open FilePath For Output As #fnum
  66. End If
  67.  
  68. Print #fnum, "=== Field usage report === " & runStamp
  69. Print #fnum, "Database: " & CurrentProject.FullName
  70. Print #fnum,
  71.  
  72. ' Process each table
  73. Dim i As Long
  74. For i = 1 To tblList.Count
  75. WriteTableSection tblList(i), fnum, WriteToTable
  76. started = True
  77. Next i
  78.  
  79. Print #fnum, "=== End of report ==="
  80. Close #fnum
  81.  
  82. MsgBox "Report written to:" & vbCrLf & FilePath, vbInformation
  83. End Sub
  84.  
  85. ' Decide whether to include a table in *ALL* mode
  86. Private Function ShouldIncludeTable(tdf As DAO.TableDef, IncludeSystem As Boolean) As Boolean
  87. Dim nm As String: nm = tdf.Name
  88. If Not IncludeSystem Then
  89. If Left$(nm, 4) = "MSys" Then Exit Function
  90. If Left$(nm, 1) = "~" Then Exit Function
  91. If (tdf.Attributes And dbSystemObject) <> 0 Then Exit Function
  92. If (tdf.Attributes And dbHiddenObject) <> 0 Then Exit Function
  93. End If
  94. ' Exclude linked system temp names
  95. If InStr(1, nm, "MSys", vbTextCompare) > 0 And Not IncludeSystem Then Exit Function
  96. ShouldIncludeTable = True
  97. End Function
  98.  
  99. ' Write one table section to file, optionally to FieldUsageReport table
  100. Private Sub WriteTableSection(TableName As String, fnum As Integer, WriteToTable As Boolean)
  101. Dim db As DAO.Database: Set db = CurrentDb
  102. Dim tdf As DAO.TableDef, fld As DAO.Field
  103. Dim hits As Collection
  104. Dim i As Long
  105.  
  106. On Error Resume Next
  107. Set tdf = db.TableDefs(TableName)
  108. On Error GoTo 0
  109. If tdf Is Nothing Then
  110. Print #fnum, "Table '" & TableName & "' not found."
  111. Print #fnum,
  112. Exit Sub
  113. End If
  114.  
  115. Print #fnum, "------------------------------------------------------------"
  116. Print #fnum, "TABLE: " & TableName
  117. Print #fnum, "------------------------------------------------------------"
  118. Print #fnum,
  119.  
  120. For Each fld In tdf.Fields
  121. Set hits = FindAllReferences(fld.Name)
  122.  
  123. ' Optional DB table output
  124. If WriteToTable Then
  125. If hits.Count = 0 Then
  126. WriteUsageRow TableName, fld.Name, "(none)", "", "", "", ""
  127. Else
  128. For i = 1 To hits.Count
  129. WriteParsedHit TableName, fld.Name, CStr(hits(i))
  130. Next i
  131. End If
  132. End If
  133.  
  134. ' Pretty, grouped text
  135. Print #fnum, "[" & fld.Name & "]"
  136. WriteCategory fnum, "Queries:", hits, "Query:"
  137. WriteCategory fnum, "Forms:", hits, "Form:"
  138. WriteCategory fnum, "Reports:", hits, "Report:"
  139. Print #fnum,
  140. Next fld
  141.  
  142. Print #fnum,
  143. End Sub
  144.  
  145. ' ---------- File print helpers ----------
  146. Private Sub WriteCategory(fnum As Integer, Header As String, hits As Collection, prefix As String)
  147. Dim found As Boolean, h As Variant
  148. found = False
  149. Print #fnum, " " & Header
  150. For Each h In hits
  151. If Left$(h, Len(prefix)) = prefix Then
  152. Print #fnum, " - " & Mid$(h, Len(prefix) + 2)
  153. found = True
  154. End If
  155. Next
  156. If Not found Then Print #fnum, " (none)"
  157. End Sub
  158.  
  159. ' ---------- Core search ----------
  160. ' Returns strings like:
  161. ' "Query: qrySales"
  162. ' "Form: frmX (txtY.ControlSource)"
  163. ' "Report: rptZ (RecordSource)"
  164. Private Function FindAllReferences(FieldName As String) As Collection
  165. Dim results As New Collection
  166. Dim s As String
  167.  
  168. ' Queries
  169. Dim q As DAO.QueryDef
  170. For Each q In CurrentDb.QueryDefs
  171. If InStr(1, q.sql, FieldName, vbTextCompare) > 0 Then
  172. results.Add "Query: " & q.Name
  173. End If
  174. Next q
  175.  
  176. ' Forms
  177. Dim ao As AccessObject, ctl As Control
  178. For Each ao In CurrentProject.AllForms
  179. DoCmd.OpenForm ao.Name, acDesign, , , , acHidden
  180. With Forms(ao.Name)
  181. If InStr(1, Nz(.RecordSource, ""), FieldName, vbTextCompare) > 0 Then _
  182. results.Add "Form: " & ao.Name & " (RecordSource)"
  183. If InStr(1, Nz(.Filter, ""), FieldName, vbTextCompare) > 0 Then _
  184. results.Add "Form: " & ao.Name & " (Filter)"
  185. If InStr(1, Nz(.OrderBy, ""), FieldName, vbTextCompare) > 0 Then _
  186. results.Add "Form: " & ao.Name & " (OrderBy)"
  187. End With
  188. For Each ctl In Forms(ao.Name).Controls
  189. On Error Resume Next
  190. s = ctl.ControlSource
  191. If Len(s) > 0 And InStr(1, s, FieldName, vbTextCompare) > 0 Then _
  192. results.Add "Form: " & ao.Name & " (" & ctl.Name & ".ControlSource)"
  193. s = ctl.RowSource
  194. If Len(s) > 0 And InStr(1, s, FieldName, vbTextCompare) > 0 Then _
  195. results.Add "Form: " & ao.Name & " (" & ctl.Name & ".RowSource)"
  196. On Error GoTo 0
  197. Next ctl
  198. DoCmd.Close acForm, ao.Name, acSaveNo
  199. Next ao
  200.  
  201. ' Reports
  202. Dim ro As AccessObject
  203. For Each ro In CurrentProject.AllReports
  204. DoCmd.OpenReport ro.Name, acViewDesign, , , acHidden
  205. With Reports(ro.Name)
  206. If InStr(1, Nz(.RecordSource, ""), FieldName, vbTextCompare) > 0 Then _
  207. results.Add "Report: " & ro.Name & " (RecordSource)"
  208. If InStr(1, Nz(.Filter, ""), FieldName, vbTextCompare) > 0 Then _
  209. results.Add "Report: " & ro.Name & " (Filter)"
  210. If InStr(1, Nz(.OrderBy, ""), FieldName, vbTextCompare) > 0 Then _
  211. results.Add "Report: " & ro.Name & " (OrderBy)"
  212. End With
  213. For Each ctl In Reports(ro.Name).Controls
  214. On Error Resume Next
  215. s = ctl.ControlSource
  216. If Len(s) > 0 And InStr(1, s, FieldName, vbTextCompare) > 0 Then _
  217. results.Add "Report: " & ro.Name & " (" & ctl.Name & ".ControlSource)"
  218. s = ctl.RowSource
  219. If Len(s) > 0 And InStr(1, s, FieldName, vbTextCompare) > 0 Then _
  220. results.Add "Report: " & ro.Name & " (" & ctl.Name & ".RowSource)"
  221. On Error GoTo 0
  222. Next ctl
  223. DoCmd.Close acReport, ro.Name, acSaveNo
  224. Next ro
  225.  
  226. ' Table-level validation props that might reference field names
  227. Dim tdf As DAO.TableDef
  228. For Each tdf In CurrentDb.TableDefs
  229. On Error Resume Next
  230. s = tdf.ValidationRule
  231. If Len(s) > 0 And InStr(1, s, FieldName, vbTextCompare) > 0 Then _
  232. results.Add "TableProp: " & tdf.Name & " (ValidationRule)"
  233. s = tdf.ValidationText
  234. If Len(s) > 0 And InStr(1, s, FieldName, vbTextCompare) > 0 Then _
  235. results.Add "TableProp: " & tdf.Name & " (ValidationText)"
  236. On Error GoTo 0
  237. Next tdf
  238.  
  239. Set FindAllReferences = results
  240. End Function
  241.  
  242. ' ---------- Optional: write to FieldUsageReport ----------
  243. Private Sub EnsureReportTable()
  244. Dim db As DAO.Database: Set db = CurrentDb
  245. Dim t As DAO.TableDef
  246. On Error Resume Next
  247. Set t = db.TableDefs("FieldUsageReport")
  248. On Error GoTo 0
  249.  
  250. If t Is Nothing Then
  251. Set t = db.CreateTableDef("FieldUsageReport")
  252. t.Fields.Append t.CreateField("TableName", dbText, 128)
  253. t.Fields.Append t.CreateField("FieldName", dbText, 128)
  254. t.Fields.Append t.CreateField("LocationType", dbText, 32) ' Query/Form/Report/TableProp/(none)
  255. t.Fields.Append t.CreateField("ObjectName", dbText, 128) ' object/table name
  256. t.Fields.Append t.CreateField("ControlName", dbText, 128) ' control if applicable
  257. t.Fields.Append t.CreateField("Property", dbText, 32) ' ControlSource/RowSource/RecordSource/Filter/OrderBy
  258. t.Fields.Append t.CreateField("Snippet", dbMemo) ' reserved
  259. db.TableDefs.Append t
  260. Else
  261. db.Execute "DELETE FROM FieldUsageReport"
  262. End If
  263. End Sub
  264.  
  265. Private Sub WriteParsedHit(TableName As String, FieldName As String, Hit As String)
  266. Dim locType As String, objName As String, propPart As String
  267. Dim ctrlName As String, PropName As String
  268. Dim p As Long, q As Long, r As Long
  269.  
  270. p = InStr(1, Hit, ":")
  271. If p > 0 Then
  272. locType = Trim$(Left$(Hit, p - 1))
  273. objName = Trim$(Mid$(Hit, p + 1))
  274. q = InStr(1, objName, "(")
  275. If q > 0 Then
  276. objName = Trim$(Left$(objName, q - 1))
  277. propPart = Mid$(Hit, InStr(1, Hit, "(") + 1)
  278. propPart = Left$(propPart, Len(propPart) - 1) ' remove ")"
  279. r = InStr(1, propPart, ".")
  280. If r > 0 Then
  281. ctrlName = Left$(propPart, r - 1)
  282. PropName = Mid$(propPart, r + 1)
  283. Else
  284. PropName = propPart
  285. End If
  286. End If
  287. End If
  288.  
  289. WriteUsageRow TableName, FieldName, locType, objName, ctrlName, PropName, ""
  290. End Sub
  291.  
  292. Private Sub WriteUsageRow(TableName As String, FieldName As String, _
  293. LocationType As String, ObjectName As String, _
  294. ControlName As String, PropName As String, Snippet As String)
  295. Dim sql As String
  296. sql = "PARAMETERS p1 Text(128), p2 Text(128), p3 Text(32), p4 Text(128), p5 Text(128), p6 Text(32), p7 Memo;" & _
  297. "INSERT INTO FieldUsageReport (TableName, FieldName, LocationType, ObjectName, ControlName, Property, Snippet) " & _
  298. "VALUES (p1,p2,p3,p4,p5,p6,p7);"
  299. Dim q As DAO.QueryDef: Set q = CurrentDb.CreateQueryDef("", sql)
  300. q.Parameters("p1") = TableName
  301. q.Parameters("p2") = FieldName
  302. q.Parameters("p3") = LocationType
  303. q.Parameters("p4") = ObjectName
  304. q.Parameters("p5") = ControlName
  305. q.Parameters("p6") = PropName
  306. q.Parameters("p7") = Snippet
  307. q.Execute dbFailOnError
  308. q.Close
  309. End Sub
  310.  
  311.  
  312.  
Tags: access
Advertisement
Add Comment
Please, Sign In to add comment