2013-08-28 7 views
15

나는 하나의 통합 문서에서 다른 VBA 모듈의 compy 아래의 라인을 사용하고 및 쉬운 방법이 있는지 모르겠지만, 그들은 잘 작동되었습니다VBA 코드를 한 통합 문서의 시트에서 다른 통합 문서로 복사합니까?

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 

을하지만 지금은 필요 시트가 아닌 모듈에있는 VBA 코드를 복사하는 것입니다. 위의 방법은 해당 시나리오에서 작동하지 않습니다.

시트의 VBA 코드를 통합 문서에서 다른 통합 문서로 복사하는 데 사용할 수있는 코드는 무엇입니까?

+1

시트를 복사하기 만하면됩니다. 코드가 함께 올 것이다. – RBarryYoung

+2

나는 시트를 복사하고 싶지 않다. 단지 VBA 코드 만 복사하고 싶다. – user1283776

+0

일반적으로 시트의 코드 *는 시트에 있어야합니다. 단지 그 방법으로 작성되었습니다. (그렇지 않으면 왜 시트에 코드를 넣어야합니까?) – RBarryYoung

답변

27

VBComponent은 전체 워크 시트를 논리적으로 삭제하기 때문에 제거하고 다시 가져올 수 없습니다. 대신 구성 요소 내에서 텍스트를 조작 할 수 CodeModule을 사용해야합니다 :

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

그건 절대적으로 훌륭합니다! VBA에서 당신만큼 잘할 수 있습니까? 가장 많이 배운 책이나 근원을 말해 줄 수 있습니까? – user1283776

+8

아, 이건 똑같은 문제를 풀려고 몇 주 동안 흩어져있는 일에서 온 것입니다. 내가 할 수있는 유일한 방법은 내가 필요로하는 것과 같이 막연하게 들리는 몇 가지 방법을 찾을 때까지 VBA 확장 성 개체를 찌르거나 찌르다는 것이 었습니다. – Chel

0

이 바로이 하나의 포스트에서뿐만 아니라 다른 소스에서 컴파일 된 코드입니다. 저의 기여 글은 VBE (Sheets/Thisworkbook/Userforms/Modules/Classes)의 모든 코드를 새로운 통합 문서로 복사하는 코드입니다.

손상된 통합 문서가 있고 코드를 포함하여 손상되지 않은 코드를 모두 복구하기 때문에 코드를 만들었습니다. (이 부분은 코드 + 참조를 복구) :

'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

다른 사람의 땅 여기 Chel의 대답의 VSTO 동등한를 검색 할 경우, 여기있다 :

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

것들 참고 :

  1. 이 항목을 수행하려면 Microsoft.Vbe.Interop에 대한 참조를 추가해야합니다.
  2. 대상 통합 문서에 새 일반 모듈이 추가되어 있으므로 DeleteLines을 호출 할 필요가 없습니다. YMMV.
+0

.Net에서이 작업을 수행하려는 사람은 일반적으로 내 [VBA 동기화 도구] (https://github.com/chelh/VBASync)의 소스 코드를 볼 수도 있습니다. – Chel

관련 문제