2013-08-28 38 views
15

Tôi đã sử dụng các dòng dưới đây để compy module VBA từ một workbook khác và tôi không biết nếu có một cách dễ dàng hơn, nhưng họ đã làm việc tốt:Sao chép mã VBA từ Trang tính trong sổ làm việc này sang sổ làm việc khác?

Set srcVba = srcWbk.VBProject 
Set srcModule = srcVba.VBComponents(moduleName) 

srcModule.Export (path) 'Export from source 
trgtVba.VBComponents.Remove VBComponent:=trgtVba.VBComponents.Item(moduleName) 'Remove from target 
trgtVba.VBComponents.Import (path) 'Import to target 

Tuy nhiên bây giờ tôi cần để sao chép mã VBA trong Bảng, không phải trong một Mô-đun. Phương thức trên không hoạt động cho kịch bản đó.

Tôi có thể sử dụng mã nào để sao chép mã VBA trong một trang tính từ sổ làm việc này sang sổ làm việc khác?

+1

Chỉ cần sao chép Trang tính. Mã sẽ đi cùng với nó. – RBarryYoung

+2

Tôi không muốn sao chép trang tính, tôi chỉ muốn sao chép mã VBA! – user1283776

+0

Thông thường mã trong Trang tính, * cần * nằm trong Trang tính, nó chỉ được viết theo cách đó. (nếu không, tại sao đặt mã trong Trang tính ở vị trí đầu tiên?) – RBarryYoung

Trả lời

27

Bạn không thể xóa và nhập lại VBComponent, vì điều đó sẽ xóa toàn bộ trang tính một cách logic. Thay vào đó bạn phải sử dụng CodeModule để thao tác văn bản trong các thành phần:

Dim src As CodeModule, dest As CodeModule 

Set src = ThisWorkbook.VBProject.VBComponents("Sheet1").CodeModule 
Set dest = Workbooks("Book3").VBProject.VBComponents("ThisWorkbook") _ 
    .CodeModule 

dest.DeleteLines 1, dest.CountOfLines 
dest.AddFromString src.Lines(1, src.CountOfLines) 
+1

Điều đó hoàn toàn rực rỡ! Làm sao tôi có thể trở thành VBA giỏi như bạn? Bạn có thể cho tôi biết những cuốn sách hoặc nguồn yêu thích của bạn mà từ đó bạn đã học được nhiều nhất không? – user1283776

+8

Ồ, đây chỉ là một vài tuần làm việc rải rác cố gắng giải quyết vấn đề chính xác đó. Điều duy nhất tôi có thể làm là poke và prod tại các đối tượng mở rộng VBA cho đến khi tôi tìm thấy một số phương pháp mơ hồ nghe như những gì tôi cần. – Chel

0

Đây là một mã tổng hợp từ nhiều nguồn khác nhau cũng từ này rất một bài viết. Đóng góp của tôi là mã sao chép TẤT CẢ các mã của bạn từ VBE (Sheets/Thisworkbook/Userforms/Modules/Classes) vào một Workbook mới.

tôi đã tạo điều này, vì tôi có sổ làm việc bị hỏng và tạo mã để khôi phục tất cả những thứ không bị hỏng, bao gồm cả mã. (Phần này chỉ phục hồi mã + tài liệu tham khảo):

'needs a reference to : Visual basic for Application Extensibility 5.3 , 
'or run this code : thisworkbook.VBProject.References.AddFromFile "C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" 
'from immediate window (ctrl+G) or create a small sub 

Option Explicit 

Sub CopyComponentsModules() 'copies sheets/Thisworkbook/Userforms/Modules/Classes to a new workbook 
Dim src As CodeModule, dest As CodeModule 
Dim i& 
Dim WB_Dest As Workbook 
'Dim sh As Worksheet 
Dim Comp As VBComponent 

'Set sh = ThisWorkbook.Sheets(1) 
'sh.Cells.Clear 

Set WB_Dest = Application.Workbooks.Add 
On Error Resume Next 'needed for testing if component already exists in destination WorkBook and for cross-references. 
For Each Comp In ThisWorkbook.VBProject.VBComponents 

      'i = i + 1 
      'sh.Cells(i, 1).Value = Comp.Name 

      'Set Source code module 
      Set src = Comp.CodeModule 'ThisWorkbook.VBProject.VBComponents("Sheet1").CodeModule 

      'test if destination component exists first 
      i = 0: i = Len(WB_Dest.VBProject.VBComponents(Comp.Name).Name) 
      If i <> 0 Then 'or: if err=0 then 
       Set dest =  WB_Dest.VBProject.VBComponents(Comp.Name).CodeModule 
      Else 'create component 
       With WB_Dest.VBProject.VBComponents.Add(Comp.Type) 
        .Name = Comp.Name 
        Set dest = .CodeModule 
       End With 
      End If 

      'copy module/Form/Sheet/Class 's code: 
      dest.DeleteLines 1, dest.CountOfLines 
      dest.AddFromString src.Lines(1, src.CountOfLines) 

Next Comp 

'Add references as well : 
Dim Ref As Reference 
For Each Ref In ThisWorkbook.VBProject.References 
    'Debug.Print Ref.Name 'Nom 
    WB_Dest.VBProject.References.AddFromFile Ref.FullPath 
    'Debug.Print Ref.FullPath 'Chemin complet 
    'Debug.Print Ref.Description 'Description de la référence 
    'Debug.Print Ref.IsBroken 'Indique si la référence est manquante 
    'Debug.Print Ref.Major & "." & Ref.Minor 'Version 
    'Debug.Print "---" 
Next Ref 

Err.Clear: On Error GoTo 0 

'WB_Dest.Activate 

Set Ref = Nothing 
Set src = Nothing 
Set dest = Nothing 
Set Comp = Nothing 
Set WB_Dest = Nothing 
End Sub 
1

Nếu khác vùng đất có ai ở đây tìm kiếm VSTO tương đương với câu trả lời Chel của, ở đây nó là:

void CopyMacros(Workbook src, Workbook dest) 
{ 
    var srcModule = src.VBProject.VBComponents.Item(1).CodeModule; 
    var destModule = dest.VBProject.VBComponents.Add(Microsoft.Vbe.Interop.vbext_ComponentType.vbext_ct_StdModule); 

    destModule.CodeModule.AddFromString(srcModule.Lines[1, srcModule.CountOfLines]); 
} 

Những điều cần lưu ý:

  1. Bạn phải thêm tham chiếu đến Microsoft.Vbe.Interop để thực hiện việc này.
  2. Tôi đang thêm mô-đun chung mới vào sổ làm việc đích, vì vậy tôi không cần phải gọi DeleteLines. YMMV.
+0

Bất cứ ai tìm cách làm điều này trong. Net thường cũng có thể xem mã nguồn cho [Công cụ đồng bộ hóa VBA] của tôi (https://github.com/chelh/VBASync) – Chel

Các vấn đề liên quan