如何获取Excel工作簿中定义的macros

在VBA或C#代码中,有没有办法获得工作簿中定义的现有macros的列表?

理想情况下,这个列表将有一个方法定义签名,但只是获得可用macros的列表将是很好的。

这可能吗?

我很久没做Excel的vba了,但是如果我记得的话,代码的对象模型是通过脚本无法访问的。

当您尝试访问它时,您收到以下错误。

Run-time error '1004': Programmatic access to Visual Basic Project is not trusted 

尝试:

 Tools | Macro | Security |Trusted Publisher Tab [x] Trust access to Visual Basic Project 

现在你可以访问VB IDE了,你可以导出这些模块,并使用vba / c#在其中进行文本search,使用正则expression式来查找子和函数声明,然后删除导出的模块。

我不确定是否有其他方式来做到这一点,但这应该工作。

你可以看看下面的链接,开始导出模块。 http://www.developersdex.com/vb/message.asp?p=2677&ID=%3C4FCD0AE9-5DCB-4A96-8B3C-F19C63CD3635%40microsoft.com%3E

这是我得到关于提供对VB IDE的访问的信息。

基于Martin的回答,在您信任VBP后,您可以使用这组代码来获取Excel工作簿的VB项目中所有公共子例程的数组。 你可以修改它只包括潜艇,或只是funcs,或只是私人或公正的…

 Private Sub TryGetArrayOfDecs() Dim Decs() As String DumpProcedureDecsToArray Decs End Sub Public Function DumpProcedureDecsToArray(ByRef Result() As String, Optional InDoc As Excel.Workbook) As Boolean Dim VBProj As Object Dim VBComp As Object Dim VBMod As Object If InDoc Is Nothing Then Set InDoc = ThisWorkbook ReDim Result(1 To 1500, 1 To 4) DumpProcedureDecsToArray = True On Error GoTo PROC_ERR Set VBProj = InDoc.VBProject Dim FuncNum As Long Dim FuncDec As String For Each VBComp In VBProj.vbcomponents Set VBMod = VBComp.CodeModule For i = 1 To VBMod.countoflines If IsSubroutineDeclaration(VBMod.Lines(i, 1)) Then FuncDec = RemoveBlanksAndDecsFromSubDec(RemoveAsVariant(VBMod.Lines(i, 1))) If LCase(Left(VBMod.Lines(i, 1), Len("private"))) <> "private" Then FuncNum = FuncNum + 1 Result(FuncNum, 1) = FindToLeftOfString(InDoc.Name, ".") ' Result(FuncNum, 2) = VBMod.Name Result(FuncNum, 3) = GetSubName(FuncDec) Result(FuncNum, 4) = VBProj.Name End If End If Next i Next VBComp PROC_END: Exit Function PROC_ERR: GoTo PROC_END End Function Private Function RemoveCharFromLeftOfString(TheString As String, RemoveChar As String) As String Dim Result As String Result = TheString While LCase(Left(Result, Len(RemoveChar))) = LCase(RemoveChar) Result = Right(Result, Len(Result) - Len(RemoveChar)) Wend RemoveCharFromLeftOfString = Result End Function Private Function RemoveBlanksAndDecsFromSubDec(TheLine As String) As String Dim Result As String Result = TheLine Result = RemoveCharFromLeftOfString(Result, " ") Result = RemoveCharFromLeftOfString(Result, " ") Result = RemoveCharFromLeftOfString(Result, "Public ") Result = RemoveCharFromLeftOfString(Result, "Private ") Result = RemoveCharFromLeftOfString(Result, " ") RemoveBlanksAndDecsFromSubDec = Result End Function Private Function RemoveAsVariant(TheLine As String) As String Dim Result As String Result = TheLine Result = Replace(Result, "As Variant", "") Result = Replace(Result, "As String", "") Result = Replace(Result, "Function", "") If InStr(1, Result, "( ") = 0 Then Result = Replace(Result, "(", "( ") End If RemoveAsVariant = Result End Function Private Function IsSubroutineDeclaration(TheLine As String) As Boolean If LCase(Left(RemoveBlanksAndDecsFromSubDec(TheLine), Len("Function "))) = "function " Or LCase(Left(RemoveBlanksAndDecsFromSubDec(TheLine), Len("sub "))) = "sub " Then IsSubroutineDeclaration = True End If End Function Private Function GetSubName(DecLine As String) As String GetSubName = FindToRightOfString(FindToLeftOfString(DecLine, "("), " ") End Function Function FindToLeftOfString(FullString As String, ToFind As String) As String If FullString = "" Then Exit Function Dim Result As String, ToFindPos As Integer ToFindPos = InStr(1, FullString, ToFind, vbTextCompare) If ToFindPos > 0 Then Result = Left(FullString, ToFindPos - 1) Else Result = FullString End If FindToLeftOfString = Result End Function Function FindToRightOfString(FullString As String, ToFind As String) As String If FullString = "" Then Exit Function Dim Result As String, ToFindPos As Integer ToFindPos = InStr(1, FullString, ToFind, vbTextCompare) Result = Right(FullString, Len(FullString) - ToFindPos + 1 - Len(ToFind)) If ToFindPos > 0 Then FindToRightOfString = Result Else FindToRightOfString = FullString End If End Function