2013-08-28 10 views
15

Ich habe die Zeilen unter Verwendung von VBA-Module aus einer Arbeitsmappe in einer anderen compy und ich weiß nicht, ob es ein einfacher Weg ist, aber sie haben gearbeitet, fein:Kopieren Sie VBA-Code von einem Blatt in einer Arbeitsmappe in eine andere?

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 

jetzt aber ich brauche Kopieren von VBA-Code, der sich in einem Sheet und nicht in einem Modul befindet. Die obige Methode funktioniert nicht für dieses Szenario.

Welchen Code kann ich verwenden, um VBA-Code in einem Arbeitsblatt von einer Arbeitsmappe in eine andere zu kopieren?

+1

Kopieren Sie einfach das Blatt. Der Code wird mitkommen. – RBarryYoung

+2

Ich möchte das Blatt nicht kopieren, ich möchte nur den VBA-Code kopieren! – user1283776

+0

Normalerweise muss der Code in einem Sheet * in dem Sheet sein, es ist nur so geschrieben. (sonst, warum den Code in ein Blatt an erster Stelle?) – RBarryYoung

Antwort

27

Sie können die VBComponent nicht entfernen und neu importieren, da dies das gesamte Arbeitsblatt logisch löschen würde. Stattdessen haben Sie CodeModule zu verwenden, um den Text innerhalb der Komponente zu manipulieren:

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

Das ist absolut brillant! Wie kann ich bei VBA so gut werden wie Sie? Kannst du mir deine Lieblingsbücher oder Quellen nennen, von denen du am meisten gelernt hast? – user1283776

+8

Oh, das kommt nur von ein paar Wochen verstreuter Arbeit, die versuchen, genau dasselbe Problem zu lösen. Das einzige, was ich tun konnte, war, an den VBA-Erweiterbarkeitsobjekten herumzustochern und herumzustochern, bis ich einige Methoden fand, die vage wie das klang, was ich brauchte. – Chel

0

Dies ist ein kompilierte Code aus verschiedenen Quellen als auch aus dieser einer Post. Mein Beitrag ist ein Code, der ALLE Ihre Codes von VBE (Sheets/Thisworkbook/Userforms/Module/Classes) in ein neues Arbeitsbuch kopiert.

Ich habe dies erstellt, weil ich eine korrupte Arbeitsmappe habe und einen Code mache, um alles wiederherzustellen, was nicht korrupt ist, einschließlich Code. (Dieser Teil erholt sich nur Code + Referenzen):

'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

Wenn jemand anderes Land hier für VSTO Äquivalent Chel Antwort suchen, hier ist es:

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]); 
} 

Dinge zu beachten:

  1. Sie müssen einen Verweis auf Microsoft.Vbe.Interop hinzufügen, um dieses Zeug zu tun.
  2. Ich füge ein neues allgemeines Modul zur Zielarbeitsmappe hinzu, also musste ich DeleteLines nicht anrufen. YMMV.
+0

Wer dies in .NET machen möchte, kann auch den Quellcode für mein [VBA Sync Tool] ansehen (https://github.com/chelh/VBASync) – Chel

Verwandte Themen