SỬ DỤNG VBA ĐỂ CẬP NHẬT CODE TRONG MODULE CỦA BẠN.
Excel 97 hay các phiên bản sau này có khả năng cập nhật (update) mã (code) trong module. Nói cách khác, bạn có thể viết một đoạn code VBA để tạo ra một đoạn code VBA khác.
Tham khảo đến một module
Bước đầu tiên là tạo một đối tượng (object) tham chiếu đến code của module mà bạn dự định sửa chửa. Thuộc tính (property) CodeModule trả về một đối tượng đại diện cho code nằm đằng sau VB component. Trong đoạn ví dụ dưới đây, MyCodeMod là một biến đối tượng đại diện cho code trong Module1 của active workbook.
Set MyCodeMod = ActiveWorkbook.VBProject.VBComponents("Module1").CodeModule
Đếm số dòng code trong module
Bạn có thể sử dụng thuộc tính CountOfLines để xác định có bao nhiêu dòng code tồn tại trong module (kể cả các dòng trống). Ví dụ sau đây thông báo cho bạn số dòng code trong module:
MsgBox MyCodeMod.CountOfLines
Đoạn code bạn tham khảo đến trong module
Bạn có thể sử dụng thuộc tính Lines(dòng bắt đầu, số dòng) trả về biến kiểu String để lấy đọan mã từ dòng bắt đầu đến số dòng bạn cần lấy. Ví dụ trong module1 của tôi có đoạn mã như sau:
Dòng 1
Dòng 2
Dòng 3
Dòng 4
Dòng 5
Dòng 6
Sub testing()
Dim mycodemod
Set mycodemod = ActiveWorkbook.VBProject.VBComponents("Module1").codemodule
MsgBox mycodemod.countoflines
MsgBox mycodemod.Lines(1, 4)
End Sub
Xoá một đoạn code trong module
Bạn có thể sử dụng phương thức (method) Deletelines(dòng bắt đầu, số dòng) để xoá một dòng hay nhiều dòng code. Đọan code sau sẽ xoá dòng 4 trong module1.
Mycodemod.Deletelines 4
Thêm một dòng trong module
Bạn có thể sử dụng phương thức (method) Insertlines(vị trí dòng bạn muốn thêm vào, đoạn code bạn cần thêm vào). Ví dụ sau để thêm tại dòng số 2 của code trong module1 chuổi Dim MyString As String
Mycodemod.Insertlines(2, "Dim MyString As String")
Thay thế một dòng code trong module
Bạn có thể sử dụng phương thức (method) Replaceline(dòng cần thay thế, đoạn code thay thế) . Ví dụ sau để thay thế dòng số 2 của code trong module1 chuổi Dim MyNumber As Integer.
Mycodemod.Replaceline(2, "Dim MyNumber As Integer")
Đặt nội dung của một File vào trong module
Bạn có thể sử dụng phương thức (method) AddFromFile(đường dẫn đến File tham chiếu). Ví dụ sau thay thế đoạn code trong File book2.frm có đường dẫn là c:\Code Files\book2.frm vào trong module1
Mycodemod.AddFromFile "c:\Code Files\book2.frm"
Với việc sử dụng một số thuộc tính, phương thức trên tôi tin rằng bạn có thể làm cho các đoạn code trong module của bạn linh động hơn.
Sau đây là một số hàm bạn cần khi thao tác.
Thêm một thủ tục vào một module
Bạn có thể thêm trực tiếp đoạn mã vào một module mà không cần phải dùng một file text riêng. Thủ tục sau đây sẽ làm điều đó:
Sub InsertProcedureCode(ByVal wb As Workbook, ByVal InsertToModuleName As String)
Dim VBCM As CodeModule
Dim InsertLineIndex As Long
On Error Resume Next
Set VBCM = wb.VBProject.VBComponents(InsertToModuleName).CodeModule
If Not VBCM Is Nothing Then
With VBCM
InsertLineIndex = .CountOfLines + 1
' customize the next lines depending on the code you want to insert
.InsertLines InsertLineIndex, "Sub NewSubName()" & Chr(13)
InsertLineIndex = InsertLineIndex + 1
.InsertLines InsertLineIndex, " Msgbox ""Hello World!"",vbInformation,""Message Box Title""" & Chr(13)
InsertLineIndex = InsertLineIndex + 1
.InsertLines InsertLineIndex, "End Sub" & Chr(13)
' no need for more customizing
End With
Set VBCM = Nothing
End If
On Error GoTo 0
End Sub
Ví dụ:
InsertProcedureCode Workbooks("WorkBookName.xls"), "Module1"
Thêm đoạn mã vào một module từ một file
Nếu bạn không muốn thêm vào một module hoàn chỉnh, bạn có thể thêm vào chỉ một vài thủ tục bị thiếu vào module bằng cách sử dụng thủ tục dưới đây. Thủ tục này thêm dữ liệu chứa trong file text vào module hiện tại:
Sub ImportModuleCode(ByVal wb As Workbook, ByVal ModuleName As String, ByVal ImportFromFile As String)
' Nhap ma vao ModuleName trong wb tu mot textfile ten ImportFromFile
Dim VBCM As CodeModule
If Dir(ImportFromFile) = "" Then Exit Sub
On Error Resume Next
Set VBCM = wb.VBProject.VBComponents(ModuleName).CodeModule
If Not VBCM Is Nothing Then
VBCM.AddFromFile ImportFromFile
Set VBCM = Nothing
End If
On Error GoTo 0
End Sub
Ví dụ:
ImportModuleCode ActiveWorkbook, "TestModule", "C:\FolderName\NewCode.txt"
Kiểm tra xem một VBProject có được bảo vệ hay không
Với hàm dưới đây, bạn có thể kiểm tra xem một VBProject có được bảo vệ không trước khi bạn cố gắng sửa chữa nó:
Function ProtectedVBProject(ByVal wb As Workbook) As Boolean
'Tra ve TRUE neu VB project trong tai lieu hien tai duoc bao ve
Dim VBC As Integer
VBC = -1
On Error Resume Next
VBC = wb.VBProject.VBComponents.Count
On Error GoTo 0
If VBC = -1 Then
ProtectedVBProject = True
Else
ProtectedVBProject = False
End If
End Function
Ví dụ:
If ProtectedVBProject(ActiveWorkbook) Then Exit Sub
Tạo một module mới
Với thủ tục dưới đây bạn có thể tạo một module mới trong một workbook:
Sub CreateNewModule(ByVal wb As Workbook, ByVal ModuleTypeIndex As Integer, ByVal NewModuleName As String)
' Tao mot module moi kieu ModuleTypeIndex (1=standard module, 2=userform, 3=class module) trong wb
' Dat lai ten module moi sang NewModuleName (neu co the)
Dim VBC As VBComponent, mti As Integer
Set VBC = Nothing
mti = 0
Select Case ModuleTypeIndex
Case 1: mti = vbext_ct_StdModule ' standard module
Case 2: mti = vbext_ct_MSForm ' userform
Case 3: mti = vbext_ct_ClassModule ' class module
End Select
If mti <> 0 Then
On Error Resume Next
Set VBC = wb.VBProject.VBComponents.Add(mti)
If Not VBC Is Nothing Then
If NewModuleName <> "" Then
VBC.Name = NewModuleName
End If
End If
On Error GoTo 0
Set VBC = Nothing
End If
End Sub
Ví dụ:
CreateNewModule ActiveWorkbook, 1, "TestModule"
Xoá một module
Khi bạn muốn xoá một module, bạn có thể dùng thủ tục dưới đây:
Sub DeleteVBComponent(ByVal wb As Workbook, ByVal CompName As String)
' Xoa vbcomponent ten CompName tu wb
Application.DisplayAlerts = False
On Error Resume Next ' Neu co loi thi lam tiep cau lenh ke tiep
wb.VBProject.VBComponents.Remove wb.VBProject.VBComponents(CompName) ' Xoa component
On Error GoTo 0
Application.DisplayAlerts = True
End Sub
Ví dụ:
DeleteVBComponent ActiveWorkbook, "TestModule"
Xoá một thủ tục ra khỏi một module
Với thủ tục dưới đây, bạn có thể xoá thủ tục ra khỏi một module:
Sub DeleteProcedureCode(ByVal wb As Workbook, ByVal DeleteFromModuleName As String, ByVal ProcedureName As String)
' Xoa thu tuc ProcedureName tu DeleteFromModuleName trong wb
Dim VBCM As CodeModule, ProcStartLine As Long, ProcLineCount As Long
On Error Resume Next
Set VBCM = wb.VBProject.VBComponents(DeleteFromModuleName).CodeModule
If Not VBCM Is Nothing Then
' xem xet thu tuc co ton tai trong codemodule hay khong
ProcStartLine = 0
ProcStartLine = VBCM.ProcStartLine(ProcedureName, vbext_pk_Proc)
If ProcStartLine > 0 Then ' prosedyren finnes, slett den
ProcLineCount = VBCM.ProcCountLines(ProcedureName, vbext_pk_Proc)
VBCM.DeleteLines ProcStartLine, ProcLineCount
End If
Set VBCM = Nothing
End If
On Error GoTo 0
End Sub
Excel 97 hay các phiên bản sau này có khả năng cập nhật (update) mã (code) trong module. Nói cách khác, bạn có thể viết một đoạn code VBA để tạo ra một đoạn code VBA khác.
Tham khảo đến một module
Bước đầu tiên là tạo một đối tượng (object) tham chiếu đến code của module mà bạn dự định sửa chửa. Thuộc tính (property) CodeModule trả về một đối tượng đại diện cho code nằm đằng sau VB component. Trong đoạn ví dụ dưới đây, MyCodeMod là một biến đối tượng đại diện cho code trong Module1 của active workbook.
Set MyCodeMod = ActiveWorkbook.VBProject.VBComponents("Module1").CodeModule
Đếm số dòng code trong module
Bạn có thể sử dụng thuộc tính CountOfLines để xác định có bao nhiêu dòng code tồn tại trong module (kể cả các dòng trống). Ví dụ sau đây thông báo cho bạn số dòng code trong module:
MsgBox MyCodeMod.CountOfLines
Đoạn code bạn tham khảo đến trong module
Bạn có thể sử dụng thuộc tính Lines(dòng bắt đầu, số dòng) trả về biến kiểu String để lấy đọan mã từ dòng bắt đầu đến số dòng bạn cần lấy. Ví dụ trong module1 của tôi có đoạn mã như sau:
Dòng 1
Dòng 2
Dòng 3
Dòng 4
Dòng 5
Dòng 6
Sub testing()
Dim mycodemod
Set mycodemod = ActiveWorkbook.VBProject.VBComponents("Module1").codemodule
MsgBox mycodemod.countoflines
MsgBox mycodemod.Lines(1, 4)
End Sub
Xoá một đoạn code trong module
Bạn có thể sử dụng phương thức (method) Deletelines(dòng bắt đầu, số dòng) để xoá một dòng hay nhiều dòng code. Đọan code sau sẽ xoá dòng 4 trong module1.
Mycodemod.Deletelines 4
Thêm một dòng trong module
Bạn có thể sử dụng phương thức (method) Insertlines(vị trí dòng bạn muốn thêm vào, đoạn code bạn cần thêm vào). Ví dụ sau để thêm tại dòng số 2 của code trong module1 chuổi Dim MyString As String
Mycodemod.Insertlines(2, "Dim MyString As String")
Thay thế một dòng code trong module
Bạn có thể sử dụng phương thức (method) Replaceline(dòng cần thay thế, đoạn code thay thế) . Ví dụ sau để thay thế dòng số 2 của code trong module1 chuổi Dim MyNumber As Integer.
Mycodemod.Replaceline(2, "Dim MyNumber As Integer")
Đặt nội dung của một File vào trong module
Bạn có thể sử dụng phương thức (method) AddFromFile(đường dẫn đến File tham chiếu). Ví dụ sau thay thế đoạn code trong File book2.frm có đường dẫn là c:\Code Files\book2.frm vào trong module1
Mycodemod.AddFromFile "c:\Code Files\book2.frm"
Với việc sử dụng một số thuộc tính, phương thức trên tôi tin rằng bạn có thể làm cho các đoạn code trong module của bạn linh động hơn.
Sau đây là một số hàm bạn cần khi thao tác.
Thêm một thủ tục vào một module
Bạn có thể thêm trực tiếp đoạn mã vào một module mà không cần phải dùng một file text riêng. Thủ tục sau đây sẽ làm điều đó:
Sub InsertProcedureCode(ByVal wb As Workbook, ByVal InsertToModuleName As String)
Dim VBCM As CodeModule
Dim InsertLineIndex As Long
On Error Resume Next
Set VBCM = wb.VBProject.VBComponents(InsertToModuleName).CodeModule
If Not VBCM Is Nothing Then
With VBCM
InsertLineIndex = .CountOfLines + 1
' customize the next lines depending on the code you want to insert
.InsertLines InsertLineIndex, "Sub NewSubName()" & Chr(13)
InsertLineIndex = InsertLineIndex + 1
.InsertLines InsertLineIndex, " Msgbox ""Hello World!"",vbInformation,""Message Box Title""" & Chr(13)
InsertLineIndex = InsertLineIndex + 1
.InsertLines InsertLineIndex, "End Sub" & Chr(13)
' no need for more customizing
End With
Set VBCM = Nothing
End If
On Error GoTo 0
End Sub
Ví dụ:
InsertProcedureCode Workbooks("WorkBookName.xls"), "Module1"
Thêm đoạn mã vào một module từ một file
Nếu bạn không muốn thêm vào một module hoàn chỉnh, bạn có thể thêm vào chỉ một vài thủ tục bị thiếu vào module bằng cách sử dụng thủ tục dưới đây. Thủ tục này thêm dữ liệu chứa trong file text vào module hiện tại:
Sub ImportModuleCode(ByVal wb As Workbook, ByVal ModuleName As String, ByVal ImportFromFile As String)
' Nhap ma vao ModuleName trong wb tu mot textfile ten ImportFromFile
Dim VBCM As CodeModule
If Dir(ImportFromFile) = "" Then Exit Sub
On Error Resume Next
Set VBCM = wb.VBProject.VBComponents(ModuleName).CodeModule
If Not VBCM Is Nothing Then
VBCM.AddFromFile ImportFromFile
Set VBCM = Nothing
End If
On Error GoTo 0
End Sub
Ví dụ:
ImportModuleCode ActiveWorkbook, "TestModule", "C:\FolderName\NewCode.txt"
Kiểm tra xem một VBProject có được bảo vệ hay không
Với hàm dưới đây, bạn có thể kiểm tra xem một VBProject có được bảo vệ không trước khi bạn cố gắng sửa chữa nó:
Function ProtectedVBProject(ByVal wb As Workbook) As Boolean
'Tra ve TRUE neu VB project trong tai lieu hien tai duoc bao ve
Dim VBC As Integer
VBC = -1
On Error Resume Next
VBC = wb.VBProject.VBComponents.Count
On Error GoTo 0
If VBC = -1 Then
ProtectedVBProject = True
Else
ProtectedVBProject = False
End If
End Function
Ví dụ:
If ProtectedVBProject(ActiveWorkbook) Then Exit Sub
Tạo một module mới
Với thủ tục dưới đây bạn có thể tạo một module mới trong một workbook:
Sub CreateNewModule(ByVal wb As Workbook, ByVal ModuleTypeIndex As Integer, ByVal NewModuleName As String)
' Tao mot module moi kieu ModuleTypeIndex (1=standard module, 2=userform, 3=class module) trong wb
' Dat lai ten module moi sang NewModuleName (neu co the)
Dim VBC As VBComponent, mti As Integer
Set VBC = Nothing
mti = 0
Select Case ModuleTypeIndex
Case 1: mti = vbext_ct_StdModule ' standard module
Case 2: mti = vbext_ct_MSForm ' userform
Case 3: mti = vbext_ct_ClassModule ' class module
End Select
If mti <> 0 Then
On Error Resume Next
Set VBC = wb.VBProject.VBComponents.Add(mti)
If Not VBC Is Nothing Then
If NewModuleName <> "" Then
VBC.Name = NewModuleName
End If
End If
On Error GoTo 0
Set VBC = Nothing
End If
End Sub
Ví dụ:
CreateNewModule ActiveWorkbook, 1, "TestModule"
Xoá một module
Khi bạn muốn xoá một module, bạn có thể dùng thủ tục dưới đây:
Sub DeleteVBComponent(ByVal wb As Workbook, ByVal CompName As String)
' Xoa vbcomponent ten CompName tu wb
Application.DisplayAlerts = False
On Error Resume Next ' Neu co loi thi lam tiep cau lenh ke tiep
wb.VBProject.VBComponents.Remove wb.VBProject.VBComponents(CompName) ' Xoa component
On Error GoTo 0
Application.DisplayAlerts = True
End Sub
Ví dụ:
DeleteVBComponent ActiveWorkbook, "TestModule"
Xoá một thủ tục ra khỏi một module
Với thủ tục dưới đây, bạn có thể xoá thủ tục ra khỏi một module:
Sub DeleteProcedureCode(ByVal wb As Workbook, ByVal DeleteFromModuleName As String, ByVal ProcedureName As String)
' Xoa thu tuc ProcedureName tu DeleteFromModuleName trong wb
Dim VBCM As CodeModule, ProcStartLine As Long, ProcLineCount As Long
On Error Resume Next
Set VBCM = wb.VBProject.VBComponents(DeleteFromModuleName).CodeModule
If Not VBCM Is Nothing Then
' xem xet thu tuc co ton tai trong codemodule hay khong
ProcStartLine = 0
ProcStartLine = VBCM.ProcStartLine(ProcedureName, vbext_pk_Proc)
If ProcStartLine > 0 Then ' prosedyren finnes, slett den
ProcLineCount = VBCM.ProcCountLines(ProcedureName, vbext_pk_Proc)
VBCM.DeleteLines ProcStartLine, ProcLineCount
End If
Set VBCM = Nothing
End If
On Error GoTo 0
End Sub