Tạo ra một file ouput excel có chứa macro

tuhocvba

Administrator
Thành viên BQT
Cho tới nay, hầu hết output của chúng ta đều là data. Tức là Input đi qua quá trình xử lý của Macro, output đi ra là Data mà chúng ta mong muốn.

Tuy nhiên, xét một tình huống như sau:

Tôi là một người thiết kế kết nối dây điện trên xe oto. Với mỗi thị trường khác nhau, xe sẽ có trang bị điện tử khác nhau (chả hạn ở một số nước thì trang bị máy sưởi, một số nước thì trang bị máy làm lạnh,…). Vì vậy dây điện kết nối trên xe cũng khác nhau.

Tôi có một dữ liệu các dây điện (Input01), macro sẽ tính toán để từ đó liệt kê các tổ hợp dây điện kết nối có thể có (Input02).

Từ tổ hợp dây điện kết nối dây điện có thể có(Input02), người dùng nhập thông số giá thành (logic) để từ đó lại tính ra giá thành cho mỗi thiết kế là bao nhiêu tiền.

Input01 của chúng ta là data nhưng là data số liệu đơn thuần chưa có logic => Output là file macro mà data đã được thiết định ở những vị trí theo yêu cầu. Đây là file Input02. Người dùng sẽ nhập logic vào file Input02 và chạy macro trên file đó, để ra được Output cuối cùng là Output có Data mà chúng ta mong muốn.

Như vậy bài viết này sẽ trình bày câu chuyện từ Input01 => Input02 [Có chứa macro].
Bạn cần đăng nhập để thấy hình ảnh


Trước hết các bạn hãy thiết định trên file Tool như dưới đây:
File -> Options -> Trust Center -> Trust Center Setttings -> Macro Settings -> Trust Access to the VBA Project object model.
VB Editor > Tools > References > (Check) Microsoft Visual Basic for Applications Extensibility 5.3

Ở đây chúng ta sẽ có hai cách nghĩ:

Cách nghĩ thứ nhất:

File Tool của chúng ta đã có sẵn Macro cho file Input02.

Như vậy thuật toán sẽ là:

File tool xuất Module macro từ file Tool ra file .bas, lưu trữ trên thư mục có chứa File Tool. Để tránh xung đột, trước đó nên tiến hành kiểm tra file trùng tên đã tồn tại trong thư mục đó chưa?

Nhập file .bas vào workbook mới. Quá trình hoàn tất.

Ưu điểm: Code nhanh, gọn.

Nhược điểm: Cách nghĩ có vẻ đơn giản quá, nên thấy việc mình đang làm có vẻ tầm thường ^_^
Đùa vậy thôi, cái này chả có gì là nhược điểm cả.

Như vậy keyword cho cách nghĩ này là: VBA to copy Module from one Excel Workbook to another Workbook
Chúng ta có code như sau:
Mã:
Option Explicit

Public Sub Main()

Dim WB1 As Workbook
Dim WB2 As Workbook

Set WB1 = ThisWorkbook
Set WB2 = Workbooks("em.xlsm")

Call CopyModule(WB1, "Module1", WB2)

End Sub
Public Sub CopyModule(SourceWB As Workbook, strModuleName As String, TargetWB As Workbook)

    ' Description:  copies a module from one workbook to another
    ' example: CopyModule Workbooks(ThisWorkbook), "Module2",
    '          Workbooks("Food Specials Rolling Depot Memo 46 - 01.xlsm")
    ' Notes:   If Module to be copied already exists, it is removed first,
    '          and afterwards copied

    Dim strFolder                       As String
    Dim strTempFile                     As String
    Dim FName                           As String

    If Trim(strModuleName) = vbNullString Then
        Exit Sub
    End If

    If TargetWB Is Nothing Then
        MsgBox "Error: Target Workbook " & TargetWB.Name & " doesn't exist (or closed)", vbCritical
        Exit Sub
    End If

    strFolder = SourceWB.Path
    If Len(strFolder) = 0 Then strFolder = CurDir

    ' create temp file and copy "Module2" into it
    strFolder = strFolder & "\"
    strTempFile = strFolder & "~tmpexport.bas"

    On Error Resume Next
    FName = Environ("Temp") & "\" & strModuleName & ".bas"
    If Dir(FName, vbNormal + vbHidden + vbSystem) <> vbNullString Then
        Err.Clear
        Kill FName
        If Err.Number <> 0 Then
            MsgBox "Error copying module " & strModuleName & "  from Workbook " & SourceWB.Name & " to Workbook " & TargetWB.Name, vbInformation
            Exit Sub
        End If
    End If

    ' remove "Module2" if already exits in destination workbook
    With TargetWB.VBProject.VBComponents
        .Remove .Item(strModuleName)
    End With

    ' copy "Module2" from temp file to destination workbook
    SourceWB.VBProject.VBComponents(strModuleName).Export strTempFile
    TargetWB.VBProject.VBComponents.Import strTempFile

    Kill strTempFile
    On Error GoTo 0

End Sub
Như vậy cùng cách nghĩ này, chúng ta có thể import Userform được thiết kế sẵn để cho vào file output.
Nguồn bài viết:
Mã:
https://stackoverflow.com/questions/40956465/vba-to-copy-module-from-one-excel-workbook-to-another-workbook

Cách nghĩ thứ hai:

Dùng VBA ghi từng dòng lệnh lên Module của workbook mới. Cách này sẽ tốn công tốn sức hơn cách thứ nhất.

Ưu điểm: Chưa thấy ưu điểm gì ngoài việc trông sẽ ngầu và bí hiểm hihi.

Nhược điểm: Code vất vả.
Mình sẽ trình bày ở bài viết sau.
 

tuhocvba

Administrator
Thành viên BQT
Trở lại với bài học, ta ôn lại những gì đã làm.
cách nghĩ thứ nhất, từ file Tool đã chuẩn bị sẵn code trên module, chúng ta xuất module ra file .bas rồi add file .bas này vào file input02. Từ đó chúng ta có file input02 có chứa module được copy từ file Tool sang.
Bạn cần đăng nhập để thấy đính kèm


Chú ý rằng, để thực hiện thao tác với module, nhất định file Tool phải được thiết định theo như dưới đây:
File -> Options -> Trust Center -> Trust Center Setttings -> Macro Settings -> Trust Access to the VBA Project object model.
Và:
VB Editor > Tools > References > (Check) Microsoft Visual Basic for Applications Extensibility 5.3
Bạn cần đăng nhập để thấy đính kèm

cách nghĩ thứ hai, tôi sẽ trình bày phương pháp chèn trực tiếp code vào file Input02.
Chú ý rằng với hai thiết định như trên vẫn cần.

Bạn cần đăng nhập để thấy đính kèm

Chèn trực tiếp code vào thisworkbook của file input02:
Mã:
Sub test()
Dim WB1 As Workbook
Dim WB2 As Workbook

Set WB1 = ThisWorkbook
Set WB2 = Workbooks("em.xlsm")
    'Viet macro vao thisworkbook file input02 (tuhocvba.net)
    With WB2.VBProject.VBComponents.Item("ThisWorkbook").CodeModule
    .InsertLines 1, "Private Sub Workbook_Open()"
    .InsertLines 2, ""
    .InsertLines 3, "   Msgbox""tuhocvba"""
    .InsertLines 4, ""
    .InsertLines 5, "End Sub"
    End With
End Sub
Kết quả:
Bạn cần đăng nhập để thấy đính kèm


Chèn trực tiếp code vào sheet1 của file input02:
Mã:
Sub test2()
Dim WB1 As Workbook
Dim WB2 As Workbook

Set WB1 = ThisWorkbook
Set WB2 = Workbooks("em.xlsm")
    'Viet macro vao Sheet1 file input02 (tuhocvba.net)
    With WB2.VBProject.VBComponents.Item("Sheet1").CodeModule

        .InsertLines 1, "Private Sub Worksheet_Change(ByVal Target As Range)"
        .InsertLines 2, ""
        .InsertLines 3, " MsgBox ""Noi dung cells da bi thay doi"""
        .InsertLines 4, ""
        .InsertLines 5, "End Sub"

    End With
End Sub
Ta thu được kết quả:
Bạn cần đăng nhập để thấy hình ảnh


Chèn module1 vào file input02 có nội dung được chỉ định:
Mã:
Sub test3()
Dim WB1 As Workbook
Dim WB2 As Workbook

Set WB1 = ThisWorkbook
Set WB2 = Workbooks("em.xlsm")
    'Viet macro vao Sheet1 file input02 (tuhocvba.net)
    WB2.VBProject.VBComponents.Add (1) 'Module1 Add
    With WB2.VBProject.VBComponents.Item("Module1").CodeModule

    .InsertLines 1, "Sub TEST()"
    .InsertLines 2, ""
    .InsertLines 3, "   Msgbox""tuhocvba"""
    .InsertLines 4, ""
    .InsertLines 5, "End Sub"

    End With
End Sub
Ta thu được kết quả:
Bạn cần đăng nhập để thấy hình ảnh

Nguồn:
Mã:
https://oshiete.goo.ne.jp/qa/756026.html
 
Top