Đưa câu trả lời của @Demosthenex tiến thêm một bước, nếu bạn cũng muốn theo dõi mã trong các Đối tượng Microsoft Excel và UserForms, bạn phải có một chút khó khăn.
Đầu tiên tôi đã thay đổi SaveCodeModules()
chức năng của mình để giải thích cho các loại mã khác nhau mà tôi dự định xuất:
Sub SaveCodeModules(dir As String)
'This code Exports all VBA modules
Dim moduleName As String
Dim vbaType As Integer
With ThisWorkbook.VBProject
For i = 1 To .VBComponents.count
If .VBComponents(i).CodeModule.CountOfLines > 0 Then
moduleName = .VBComponents(i).CodeModule.Name
vbaType = .VBComponents(i).Type
If vbaType = 1 Then
.VBComponents(i).Export dir & moduleName & ".vba"
ElseIf vbaType = 3 Then
.VBComponents(i).Export dir & moduleName & ".frm"
ElseIf vbaType = 100 Then
.VBComponents(i).Export dir & moduleName & ".cls"
End If
End If
Next i
End With
End Sub
UserForms có thể được xuất và nhập giống như mã VBA. Sự khác biệt duy nhất là hai tệp sẽ được tạo khi xuất một biểu mẫu (bạn sẽ nhận được một .frm
và một .frx
tệp cho mỗi UserForm). Một trong số này chứa phần mềm bạn đã viết và phần còn lại là tệp nhị phân (tôi khá chắc chắn) xác định bố cục của biểu mẫu.
Microsoft Excel Objects (MEOs) (có nghĩa là Sheet1
, Sheet2
, ThisWorkbook
vv) có thể được xuất ra dưới dạng một .cls
tập tin. Tuy nhiên, khi bạn muốn lấy lại mã này vào sổ làm việc của mình, nếu bạn cố nhập nó giống như cách bạn sử dụng mô-đun VBA, bạn sẽ gặp lỗi nếu bảng đó đã tồn tại trong sổ làm việc.
Để giải quyết vấn đề này, tôi quyết định không thử nhập tệp .cls vào Excel mà thay vào đó là đọc .cls
tệp vào excel dưới dạng chuỗi, sau đó dán chuỗi này vào MEO trống. Đây là ImportCodeModules của tôi:
Sub ImportCodeModules(dir As String)
Dim modList(0 To 0) As String
Dim vbaType As Integer
' delete all forms, modules, and code in MEOs
With ThisWorkbook.VBProject
For Each comp In .VBComponents
moduleName = comp.CodeModule.Name
vbaType = .VBComponents(moduleName).Type
If moduleName <> "DevTools" Then
If vbaType = 1 Or _
vbaType = 3 Then
.VBComponents.Remove .VBComponents(moduleName)
ElseIf vbaType = 100 Then
' we can't simply delete these objects, so instead we empty them
.VBComponents(moduleName).CodeModule.DeleteLines 1, .VBComponents(moduleName).CodeModule.CountOfLines
End If
End If
Next comp
End With
' make a list of files in the target directory
Set FSO = CreateObject("Scripting.FileSystemObject")
Set dirContents = FSO.getfolder(dir) ' figure out what is in the directory we're importing
' import modules, forms, and MEO code back into workbook
With ThisWorkbook.VBProject
For Each moduleName In dirContents.Files
' I don't want to import the module this script is in
If moduleName.Name <> "DevTools.vba" Then
' if the current code is a module or form
If Right(moduleName.Name, 4) = ".vba" Or _
Right(moduleName.Name, 4) = ".frm" Then
' just import it normally
.VBComponents.Import dir & moduleName.Name
' if the current code is a microsoft excel object
ElseIf Right(moduleName.Name, 4) = ".cls" Then
Dim count As Integer
Dim fullmoduleString As String
Open moduleName.Path For Input As #1
count = 0 ' count which line we're on
fullmoduleString = "" ' build the string we want to put into the MEO
Do Until EOF(1) ' loop through all the lines in the file
Line Input #1, moduleString ' the current line is moduleString
If count > 8 Then ' skip the junk at the top of the file
' append the current line `to the string we'll insert into the MEO
fullmoduleString = fullmoduleString & moduleString & vbNewLine
End If
count = count + 1
Loop
' insert the lines into the MEO
.VBComponents(Replace(moduleName.Name, ".cls", "")).CodeModule.InsertLines .VBComponents(Replace(moduleName.Name, ".cls", "")).CodeModule.CountOfLines + 1, fullmoduleString
Close #1
End If
End If
Next moduleName
End With
End Sub
Trong trường hợp bạn bối rối bởi dir
đầu vào của cả hai chức năng này, đó chỉ là kho lưu trữ mã của bạn! Vì vậy, bạn sẽ gọi các chức năng này như:
SaveCodeModules "C:\...\YourDirectory\Project\source\"
ImportCodeModules "C:\...\YourDirectory\Project\source\"