2013-08-28 2 views
15

Я использую следующие строки Compy модулей VBA из одной книги в другую, и я не знаю, если есть более простой способ, но они работают отлично: Однако теперь мне нужноСкопируйте код 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 (Таблицы/Эта рабочая книга/Пользовательские формы/Модули/Классы) в новую Рабочую книгу.

Я создал это, потому что у меня есть коррумпированная книга и код, чтобы восстановить все, что не повреждено, включая код. (Эта часть только восстанавливает код + ссылки):

'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

Если кто-то земли здесь в поисках 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]); 
} 

Things отметить:

  1. Вы должны добавить ссылку на Microsoft.Vbe.Interop, чтобы сделать это.
  2. Я добавляю новый общий модуль в рабочую книгу назначения, поэтому мне не нужно было звонить DeleteLines. YMMV.
+0

Любой, кто хочет сделать это в .Net, также может посмотреть исходный код моего [VBA Sync Tool] (https://github.com/chelh/VBASync) – Chel

Смежные вопросы