Skip to content

Commit 0db6d7a

Browse files
committed
Prevent duplicate modules like MyClass1 using Application.Ontime
1 parent a209079 commit 0db6d7a

File tree

1 file changed

+85
-71
lines changed

1 file changed

+85
-71
lines changed

src/vbaDeveloper.xlam/Build.bas

Lines changed: 85 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ Attribute VB_Name = "Build"
1919

2020
Option Explicit
2121

22+
Private Const IMPORT_DELAY As String = "00:00:03"
23+
24+
Private componentsToImport As Dictionary 'Key = componentName, Value = componentFilePath
25+
Private vbaProjectToImport As VBProject
26+
2227
Public Sub testImport()
2328
Dim proj_name As String
2429
proj_name = "vbaDeveloper"
@@ -38,6 +43,8 @@ Public Sub testExport()
3843
Build.exportVbaCode vbaProject
3944
End Sub
4045

46+
47+
4148
' Usually called after the given workbook is saved
4249
Public Sub exportVbaCode(vbaProject As VBProject)
4350
'locate and create the export directory if necessary
@@ -88,6 +95,7 @@ Public Sub exportVbaCode(vbaProject As VBProject)
8895
Next component
8996
End Sub
9097

98+
9199
Private Function hasCodeToExport(component As VBComponent) As Boolean
92100
hasCodeToExport = True
93101
If component.CodeModule.CountOfLines <= 2 Then
@@ -98,12 +106,14 @@ Private Function hasCodeToExport(component As VBComponent) As Boolean
98106
End If
99107
End Function
100108

109+
101110
'To export everything else but sheets
102111
Private Sub exportComponent(exportPath As String, component As VBComponent, Optional extension As String = ".cls")
103112
Debug.Print "exporting " & component.name & extension
104113
component.Export exportPath & "\" & component.name & extension
105114
End Sub
106115

116+
107117
'To export sheets
108118
Private Sub exportLines(exportPath As String, component As VBComponent)
109119
Dim extension As String: extension = ".sheet.cls"
@@ -118,6 +128,7 @@ Private Sub exportLines(exportPath As String, component As VBComponent)
118128
outStream.Close
119129
End Sub
120130

131+
121132
' Usually called after the given workbook is opened
122133
Public Sub importVbaCode(vbaProject As VBProject)
123134
'find project files
@@ -147,87 +158,99 @@ Public Sub importVbaCode(vbaProject As VBProject)
147158
Exit Sub
148159
End If
149160

150-
'for each file found:
151-
If fso.FolderExists(export_path) Then
152-
Dim proj_contents As Folder
153-
Set proj_contents = fso.GetFolder(export_path)
154-
155-
Dim file As Object
156-
For Each file In proj_contents.Files()
157-
158-
Dim fileName As String
159-
fileName = file.name
160-
'check if and how to import the file
161-
If Len(fileName) > 4 Then
162-
Dim lastPart As String
163-
lastPart = Right(fileName, 4)
164-
Select Case lastPart
165-
Case ".cls" ' 10 == Len(".sheet.cls")
166-
If Len(fileName) > 10 And Right(fileName, 10) = ".sheet.cls" Then
167-
'import lines into sheet
168-
importLines vbaProject, file
169-
Else
170-
'import component
171-
importComponent vbaProject, file
172-
End If
173-
Case ".bas", ".frm"
174-
'import component
175-
importComponent vbaProject, file
176-
Case Else
177-
'do nothing
178-
Debug.Print "Skipping file " & fileName
179-
End Select
180-
End If
181-
Next
182-
End If
183-
184-
Debug.Print "imported code for " & vbaProject.name
161+
'initialize globals for Application.OnTime
162+
Set componentsToImport = New Dictionary
163+
Set vbaProjectToImport = vbaProject
164+
165+
Dim projContents As Folder
166+
Set projContents = fso.GetFolder(export_path)
167+
Dim file As Object
168+
For Each file In projContents.Files()
169+
'check if and how to import the file
170+
checkHowToImport file
171+
Next
172+
173+
174+
'First remove all the files
175+
Dim componentName As String
176+
Dim vComponentName As Variant
177+
For Each vComponentName In componentsToImport.Keys
178+
componentName = vComponentName
179+
removeComponent vbaProject, componentName
180+
Next
181+
'Then import them
182+
Debug.Print "Invoking Application.Ontime with delay " & IMPORT_DELAY ' To prevent duplicate modules, like MyClass1 etc.
183+
Application.OnTime Now() + TimeValue(IMPORT_DELAY), "'Build.importComponents'"
184+
Debug.Print "Waiting to import code for " & vbaProject.name
185185
End Sub
186186

187-
'Not used anymore
188-
Private Function wantToImport(fileName As String) As Boolean
189-
wantToImport = False
187+
Private Sub checkHowToImport(file As Object)
188+
Dim fileName As String
189+
fileName = file.name
190+
Dim componentName As String
191+
componentName = Left(fileName, InStr(fileName, ".") - 1)
192+
If componentName = "Build" Then '"don't remove or import ourself
193+
Exit Sub
194+
End If
195+
190196
If Len(fileName) > 4 Then
191197
Dim lastPart As String
192198
lastPart = Right(fileName, 4)
193199
Select Case lastPart
194-
Case ".bas", ".frm"
195-
wantToImport = True
196200
Case ".cls" ' 10 == Len(".sheet.cls")
197201
If Len(fileName) > 10 And Right(fileName, 10) = ".sheet.cls" Then
198-
wantToImport = False 'For now we don't import these
202+
'import lines into sheet
203+
'TODO importLines vbaProject, file
199204
Else
200-
wantToImport = True
205+
'importComponent vbaProject, file
206+
componentsToImport.Add componentName, file.Path
201207
End If
208+
Case ".bas", ".frm"
209+
'importComponent vbaProject, file
210+
componentsToImport.Add componentName, file.Path
202211
Case Else
203-
wantToImport = False
212+
'do nothing
213+
Debug.Print "Skipping file " & fileName
204214
End Select
205215
End If
206-
End Function
207-
216+
End Sub
208217

209-
Private Sub importComponent(vbaProject As VBProject, file As Object)
210-
Dim component_name As String
211-
component_name = Left(file.name, InStr(file.name, ".") - 1)
212-
213-
If component_exists(vbaProject, component_name) Then
214-
'Remove it. (Sheets cannot be removed!)
218+
' Only removes the vba component if it exists
219+
Private Sub removeComponent(vbaProject As VBProject, componentName As String)
220+
If componentExists(vbaProject, componentName) Then
215221
Dim c As VBComponent
216-
Set c = vbaProject.VBComponents(component_name)
217-
Debug.Print "removing " & component_name & " " & c.name
222+
Set c = vbaProject.VBComponents(componentName)
223+
Debug.Print "removing " & c.name
218224
vbaProject.VBComponents.Remove c
219225
End If
220-
Debug.Print "Importing component " & component_name & " from " & file.Path
221-
' If we get duplicate modules, like MyClass1, try
222-
' Application.OnTime (Now + TimeValue("00:00:01")), "function_name" vbaProject.VBComponents.Import file.Path
223-
vbaProject.VBComponents.Import file.Path
224226
End Sub
225227

228+
Public Sub importComponents()
229+
Dim componentName As String
230+
Dim vComponentName As Variant
231+
For Each vComponentName In componentsToImport.Keys
232+
componentName = vComponentName
233+
importComponent vbaProjectToImport, componentsToImport(componentName)
234+
Next
235+
Debug.Print "Finished importing code for " & vbaProjectToImport.name
236+
'We're done, clear globals explicitly to free memory
237+
Set componentsToImport = Nothing
238+
Set vbaProjectToImport = Nothing
239+
End Sub
240+
241+
242+
' Assumes any component with same name has already been removed
243+
Private Sub importComponent(vbaProject As VBProject, filePath As String)
244+
Debug.Print "Importing component from " & filePath
245+
vbaProject.VBComponents.Import filePath
246+
End Sub
247+
248+
226249
Private Sub importLines(vbaProject As VBProject, file As Object)
227250
Dim component_name As String
228251
component_name = Left(file.name, InStr(file.name, ".") - 1)
229252

230-
If Not component_exists(vbaProject, component_name) Then
253+
If Not componentExists(vbaProject, component_name) Then
231254
'Create a sheet and component to import this into
232255
'...skipping that for now
233256
Exit Sub
@@ -239,23 +262,14 @@ Private Sub importLines(vbaProject As VBProject, file As Object)
239262
c.CodeModule.AddFromFile file.Path
240263
End Sub
241264

242-
Private Function component_exists(ByRef proj As VBProject, name As String) As Boolean
265+
266+
Public Function componentExists(ByRef proj As VBProject, name As String) As Boolean
243267
On Error GoTo doesnt
244268

245269
Dim c As VBComponent
246270
Set c = proj.VBComponents(name)
247-
248-
component_exists = True
271+
componentExists = True
249272
Exit Function
250273
doesnt:
251-
component_exists = False
274+
componentExists = False
252275
End Function
253-
254-
255-
256-
''''''''''''''''''
257-
258-
Public Function Hello() As String
259-
Hello = "hello it works"
260-
End Function
261-

0 commit comments

Comments
 (0)