@@ -17,10 +17,17 @@ Attribute VB_Exposed = False
17
17
Option Compare Database
18
18
Option Explicit
19
19
20
+ Private Const ModuleName As String = "clsDbModule"
21
+
20
22
Private m_Module As VBComponent
21
23
Private m_AllItems As Collection
22
24
Private m_blnModifiedOnly As Boolean
23
25
26
+ Private Type udtVbaFileContent
27
+ strContent As String
28
+ blnIsClass As Boolean
29
+ End Type
30
+
24
31
' This requires us to use all the public methods and properties of the implemented class
25
32
' which keeps all the component classes consistent in how they are used in the export
26
33
' and import process. The implemented functions should be kept private as they are called
@@ -67,19 +74,51 @@ End Sub
67
74
'
68
75
Private Sub IDbComponent_Import (strFile As String )
69
76
70
- Dim proj As VBProject
77
+ Dim strName As String
71
78
Dim strTempFile As String
79
+ Dim udtFile As udtVbaFileContent
80
+
81
+ ' Only import files with the correct extension.
82
+ If Not (strFile Like "*.bas" Or strFile Like "*.cls" ) Then Exit Sub
83
+
84
+ ' Parse source file
85
+ strName = GetObjectNameFromFileName(strFile)
86
+ udtFile = ParseSourceFile(strFile, strName)
87
+
88
+ ' Check to see if we have an Access object with this name
89
+ If Not ModuleExists(strName) Then ImportModuleStub strName, udtFile.blnIsClass
90
+
91
+ ' Write to a new file using system encoding (converting from UTF-8)
92
+ strTempFile = GetTempFile
93
+ WriteFile udtFile.strContent, strTempFile, GetSystemEncoding
94
+
95
+ ' Import the source file to the code module
96
+ LoadVbeModuleFromFile strTempFile, strName
97
+
98
+ ' Save hash, update the index, and remove the temp file
99
+ VCSIndex.Update Me, eatImport, GetCodeModuleHash(IDbComponent_ComponentType, m_Module.Name)
100
+ DeleteFile strTempFile
101
+
102
+ End Sub
103
+
104
+
105
+ '---------------------------------------------------------------------------------------
106
+ ' Procedure : ParseSourceFile
107
+ ' Author : Adam Waller
108
+ ' Date : 7/13/2021
109
+ ' Purpose : Parse the source file to build VBE content
110
+ '---------------------------------------------------------------------------------------
111
+ '
112
+ Private Function ParseSourceFile (strFile As String , strName As String ) As udtVbaFileContent
113
+
72
114
Dim strLines() As String
115
+ Dim strTLine As String
73
116
Dim lngLine As Long
74
117
Dim cData As clsConcat
75
118
Dim blnIsClass As Boolean
76
119
Dim blnHasHeader As Boolean
77
-
78
- ' Only import files with the correct extension.
79
- If Not (strFile Like "*.bas" Or strFile Like "*.cls" ) Then Exit Sub
80
-
81
- ' Log performance of file conversion
82
- Perf.OperationStart "Enc. Module as " & GetSystemEncoding
120
+
121
+ Perf.OperationStart "Parse VBA Module"
83
122
84
123
' Read file contents into array of lines
85
124
strLines = Split(ReadFile(strFile), vbCrLf)
@@ -117,7 +156,7 @@ Private Sub IDbComponent_Import(strFile As String)
117
156
.Add " MultiUse = -1 'True"
118
157
.Add "END"
119
158
End If
120
- .Add "Attribute VB_Name = """ , GetObjectNameFromFileName(strFile) , """"
159
+ .Add "Attribute VB_Name = """ , strName , """"
121
160
End If
122
161
123
162
' Add in file contents
@@ -129,33 +168,106 @@ Private Sub IDbComponent_Import(strFile As String)
129
168
.Remove 2
130
169
End With
131
170
132
- ' Write to a new file using system encoding (converting from UTF-8)
133
- strTempFile = GetTempFile
134
- With New ADODB.Stream
135
- .Type = adTypeText
136
- .Open
137
- .Charset = GetSystemEncoding
138
- .WriteText cData.GetStr
139
- ' Write to disk
140
- .SaveToFile strTempFile, adSaveCreateOverWrite
141
- .Close
171
+ ' Return values
172
+ With ParseSourceFile
173
+ .blnIsClass = blnIsClass
174
+ .strContent = cData.GetStr
142
175
End With
143
176
144
177
Perf.OperationEnd
145
178
146
- ' Import the source file
179
+ End Function
180
+
181
+
182
+ '---------------------------------------------------------------------------------------
183
+ ' Procedure : LoadVbeModuleFromFile
184
+ ' Author : Adam Waller
185
+ ' Date : 7/12/2021
186
+ ' Purpose : Load the VBA standard/class module from a file through VBE. (This allows
187
+ ' : us to preserve hidden attributes not recognized in then LoadFromText
188
+ ' : import of code modules and classes.)
189
+ '---------------------------------------------------------------------------------------
190
+ '
191
+ Private Sub LoadVbeModuleFromFile (strFile As String , strName As String )
192
+
193
+ Dim proj As VBProject
194
+
195
+ If DebugMode(True ) Then On Error GoTo 0 Else On Error Resume Next
196
+
147
197
Set proj = GetVBProjectForCurrentDB
148
198
Perf.OperationStart "Import VBE Module"
149
- Set m_Module = proj.VBComponents.Import(strTempFile)
199
+ With proj.VBComponents
200
+
201
+ ' Remove any existing component (In most cases the module will exist)
202
+ If DebugMode(True ) Then On Error Resume Next Else On Error Resume Next
203
+ .Remove .Item(strName)
204
+ If DebugMode(False ) Then On Error GoTo 0 Else On Error Resume Next
205
+
206
+ ' Load from the file
207
+ Set m_Module = .Import(strFile)
208
+ End With
150
209
Perf.OperationEnd
210
+
211
+ CatchAny eelError, "Error importing VBA code for " & strName, ModuleName & ".LoadVbeModuleFromFile"
151
212
152
- ' Save hash, update the index, and remove the temp file
153
- VCSIndex.Update Me, eatImport, GetCodeModuleHash(IDbComponent_ComponentType, m_Module.Name)
213
+ End Sub
214
+
215
+
216
+ '---------------------------------------------------------------------------------------
217
+ ' Procedure : ImportModuleStub
218
+ ' Author : Adam Waller
219
+ ' Date : 7/12/2021
220
+ ' Purpose : Import a blank code module as text so it can be loaded into Access before
221
+ ' : overlaying the content through VBE. (This allows us to use DoCmd.Save to
222
+ ' : save the code changes, which is not available when a new module is created
223
+ ' : through a VBE import.
224
+ '---------------------------------------------------------------------------------------
225
+ '
226
+ Private Sub ImportModuleStub (strName As String , blnAsClass As Boolean )
227
+
228
+ Dim cContent As clsConcat
229
+ Dim strTempFile As String
230
+
231
+ Set cContent = New clsConcat
232
+
233
+ ' Save the template content as a file
234
+ strTempFile = GetTempFile
235
+ With New clsConcat
236
+ .AppendOnAdd = vbCrLf
237
+ If blnAsClass Then
238
+ .Add "Attribute VB_GlobalNameSpace = False"
239
+ .Add "Attribute VB_Creatable = False"
240
+ .Add "Attribute VB_PredeclaredId = False"
241
+ .Add "Attribute VB_Exposed = False"
242
+ End If
243
+ .Add "' Stub module for import by MSAccessVCS"
244
+ .Add "noncompilingcode 'issue here"
245
+ ' Load as text without BOM
246
+ WriteFile .GetStr, strTempFile, "Windows-1252"
247
+ End With
248
+
249
+ LoadFromText acModule, strName, strTempFile
154
250
DeleteFile strTempFile
155
251
156
252
End Sub
157
253
158
254
255
+ '---------------------------------------------------------------------------------------
256
+ ' Procedure : ModuleExists
257
+ ' Author : Adam Waller
258
+ ' Date : 7/13/2021
259
+ ' Purpose : Returns true if the module or class exists in the current database
260
+ '---------------------------------------------------------------------------------------
261
+ '
262
+ Private Function ModuleExists (strName As String ) As Boolean
263
+ Dim objTest As AccessObject
264
+ If DebugMode(True ) Then On Error Resume Next Else On Error Resume Next
265
+ Set objTest = CurrentProject.AllModules(strName)
266
+ CatchAny eelNoError, vbNullString, , False
267
+ ModuleExists = Not objTest Is Nothing
268
+ End Function
269
+
270
+
159
271
'---------------------------------------------------------------------------------------
160
272
' Procedure : Merge
161
273
' Author : Adam Waller
0 commit comments