2016-08-15 49 views
2

這是一個主題(據我所知)沒有觸及CPearson's resource site(這對於那些希望在宏中使用宏Excel以編程方式將代碼插入新工作表/工作簿或現有工作表/工作簿)。Excel VBA - 以編程方式將代碼插入工作表中的特定子宏代碼模塊

我目前有Sheet1包含一系列四到五個獨立的子宏,它們執行的功能目前不會相互影響。我編寫了一個宏,當用戶按下按鈕激活時,會創建一個新的工作表並在該工作表上插入幾行代碼(此任務已完成且功能正常)。

我的目標是在此過程中添加一行,以便一旦執行了上述操作,「code of line xyz#1」將被添加到此CodeModule中的特定過程中,即:「Sub MacroMain )」。

我目前能夠使用以下,其中「AddCode」是一個文本字符串(幾乎)達到這樣的結果:

ActiveWorkbook.VBProject.VBComponents(Sheets("Sheet1").CodeName).CodeModule.AddFromString AddCode 

但是這種解決方案的問題是,它只是增加了新線代碼到Sheet1的CodeModule的最上部分,而不是特定的子宏Sub MacroMain。試圖在上面的行中引用SubMacroMain不幸會產生「預期的函數或變量」錯誤。我認爲這是我的用戶格式錯誤。

我想知道是否應該使用上面列出的代碼行來遵循特定的語法,以便將此過程中插入的代碼放入Sheet1的CodeModule中的特定宏中。

謝謝。

回答

2

您有幾個選項。如果您知道確切的行號,則可以使用 InsertLines在特定行號處添加行。例如:

Sub AddLineToModule(LineNum as Long, StrLineText as String) 
    Dim VBProj As VBIDE.VBProject 
    Dim VBComp As VBIDE.VBComponent 
    Dim CodeMod As VBIDE.CodeModule 
    Const DQUOTE = """" ' one " character 

    Set VBProj = ActiveWorkbook.VBProject 
    Set VBComp = VBProj.VBComponents("Module1") 
    Set CodeMod = VBComp.CodeModule 

    CodeMod.InsertLines LineNum, StrLineText 

    Set VBProj = Nothing 
    Set VBComp = Nothing 
    Set CodeMod = Nothing 
End Sub 

斜體原液:如果你不知道確切的行號,你可以通過它讀取整個模塊爲一個字符串數組,然後循環和你想要的行之後添加一行。我手頭沒有示例,但如果需要,可以稍後添加。編輯:感謝Mikegrann,一個可能更好的解決方案是使用Module.Find;但是,下面的評論中有一些辯論是否這是一個可取的解決方案(請參閱Mat's Mug的更新)。根據OP的具體問題,這可能是一種可行的方法。 編輯2:每個評論,Module.Find不應該在大多數情況下(如果不是全部)使用。使用VBIDE API或自定義數組搜索功能可靠地查找一行代碼。最後,如果您不知道模塊中的確切行號,但知道相對於特定過程開始的確切行號,則可以使用上述第一個示例和ProcStarLine的組合。

Sub AddLineToProcedure(StrProcName as String, LineNum as Long, StrLineText as String) 
    Dim VBProj As VBIDE.VBProject 
    Dim VBComp As VBIDE.VBComponent 
    Dim CodeMod As VBIDE.CodeModule 
    Const DQUOTE = """" ' one " character 

    Set VBProj = ActiveWorkbook.VBProject 
    Set VBComp = VBProj.VBComponents("Module1") 
    Set CodeMod = VBComp.CodeModule 

    With CodeMod 
     LineNum = LineNum + .ProcStartLine(ProcName, vbext_pk_Proc) 
     .InsertLines LineNum, StrLineText 
    End With 

    Set VBProj = Nothing 
    Set VBComp = Nothing 
    Set CodeMod = Nothing 
End Sub 


    ProcName = "DeleteThisProc" 
    With CodeMod 
     StartLine = .ProcStartLine(ProcName, vbext_pk_Proc) 
     NumLines = .ProcCountLines(ProcName, vbext_pk_Proc) 
     .DeleteLines StartLine:=StartLine, Count:=NumLines 
    End With 
+0

在情況2中,與其自己編寫所有內容來構建強大的搜索工具來查找所需的行,爲什麼不使用'Module.Find'? (https://msdn.microsoft.com/en-us/library/office/ff195471.aspx) – Mikegrann

+0

哦,這是一個無限更好的解決方案!我對使用VBProject對象不是很熟悉,並且很驚訝我找不到「Find」函數或類似的東西。我會更新我的答案 - 謝謝! –

+2

@Mikegrann因爲'Module.Find'工作的純文本 - 盲目字符串搜索是完全危險的。使用VBIDE API檢索特定過程的起始行是定位過程的唯一安全方法,但實際上不能用正式語法解析代碼。 'Module.Find'無法告訴過程或關鍵字的變量:即使設置了「僅整個字」標誌,它也會最終中斷。我知道,在過去的兩年裏,我花了更多的時間編程解析VBA代碼。 –