Reputation: 14877
I have found many ways for getting macro names from Excel using automation (example). They are mostly the same and neither can 1) retrieve macro descriptions (each recorded macro can be decorated with a description using Excel UI) or 2) filter out ordinary VBA functions (there are Excel recorded macros and there are funcs/macros that you an write yourself). It seems as if Excel is keeping descriptions as comments in the source code but also in some private place too. If one deletes code comments the description is still visible to Excel.
I need to achieve at least 2) and if possible 1) too. I'd appreciate a C# or VBA solution, but really anything will do.
Upvotes: 1
Views: 3426
Reputation: 151
I encountered the same problem and solved it by help of a website where you could read Excel VBA macros and functions through csharp. I made some changes and came up with the solution seen below. I receive a list with the available macros and the description they got when they first where created. I use regex to parse the description. Might be some better solution for this, but at least it works for my purpose.
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;
}
Upvotes: 2
Reputation: 166735
If you record a macro in excel, add another "hand-written" one to the same module, and then export the module to a file, you'll see that the recorded macro has additional Attributes which are missing from the hand-entered one.
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
You can use code to export modules, so you could parse the exported files looking for those attributes.
This is a good resource for using VBA to access/manipulate contents of the VBE: http://www.cpearson.com/excel/vbe.aspx
Upvotes: 2