我找到了许多使用自动化(example)从Excel获取宏名称的方法。它们大多是相同的,也不能1)检索宏描述(每个记录的宏可以使用Excel UI进行描述)或2)过滤掉普通的VBA函数(有Excel记录的宏,你有一个函数/宏)写自己)。似乎Excel将描述保留为源代码中的注释,但也在某些私有地方。如果删除代码注释,则Excel仍然可以看到描述。
我需要达到至少2)并且如果可能的话1)。我很欣赏C#或VBA解决方案,但真的会做任何事情。
答案 0 :(得分:2)
如果您在Excel中录制宏,将另一个“手写”宏添加到同一模块,然后将模块导出到文件,您将看到录制的宏具有手中缺少的其他属性进了一个。
Sub RecordedMacro()
Attribute RecordedMacro.VB_Description = "some description here"
Attribute RecordedMacro.VB_ProcData.VB_Invoke_Func = "g\n14"
'
' RecordedMacro Macro
' some description here
'
' Keyboard Shortcut: Ctrl+g
'
Range("C8").Select
ActiveCell.FormulaR1C1 = "sfhsf"
End Sub
您可以使用代码导出模块,因此您可以解析导出的文件以查找这些属性。
这是使用VBA访问/操作VBE内容的好资源: http://www.cpearson.com/excel/vbe.aspx
答案 1 :(得分:2)
我遇到了同样的问题,并通过您可以read Excel VBA macros and functions through csharp的网站解决了这个问题。我做了一些更改,并提出了下面的解决方案。我收到一个列表,其中包含可用的宏以及它们在创建时首先获得的描述。我使用正则表达式来解析描述。可能是一个更好的解决方案,但至少它适用于我的目的。
public List<Tuple<string,string>> GetAllMacrosInExcelFile(string fileName) {
List<Tuple<string,string>> listOfMacros = new List<Tuple<string,string>>();
var excel = new Excel.Application();
var workbook = excel.Workbooks.Open(fileName, false, true, Type.Missing, Type.Missing, Type.Missing, true, Type.Missing, Type.Missing, false, false, Type.Missing, false, true, Type.Missing);
var project = workbook.VBProject;
var projectName = project.Name;
var procedureType = Microsoft.Vbe.Interop.vbext_ProcKind.vbext_pk_Proc;
foreach (var component in project.VBComponents) {
VBA.VBComponent vbComponent = component as VBA.VBComponent;
if (vbComponent != null) {
string componentName = vbComponent.Name;
var componentCode = vbComponent.CodeModule;
int componentCodeLines = componentCode.CountOfLines;
int line = 1;
while (line < componentCodeLines) {
string procedureName = componentCode.get_ProcOfLine(line, out procedureType);
if (procedureName != string.Empty) {
int procedureLines = componentCode.get_ProcCountLines(procedureName, procedureType);
int procedureStartLine = componentCode.get_ProcStartLine(procedureName, procedureType);
var allCodeLines = componentCode.get_Lines(procedureStartLine, procedureLines);
Regex regex = new Regex("Macro\r\n' (.*?)\r\n'\r\n\r\n'");
var v = regex.Match(allCodeLines);
string comments = v.Groups[1].ToString();
if (comments.IsEmpty()) { comments = "No comment is written for this Macro"; }
line += procedureLines - 1;
listOfMacros.Add(procedureName.Tuple(comments));
}
line++;
}
}
}
excel.Quit();
return listOfMacros;
}