如何用C#从XLSM宏文件匹配宏代码对应的Excel文件名?
解决方案
核心结论
宏代码本身不会默认存储所属Excel文件的原始文件名,但可以通过读取XLSM文件的元数据、直接关联文件路径的方式,将宏代码与对应Excel文件绑定。如果宏录制时明确操作了具体文件名(如Workbooks.Open("xxx.xlsm")),也可以解析宏代码提取,但这种方式可靠性低,仅作补充。
具体实现方案
方案1:通过文件路径+EPPlus读取宏代码并关联文件名
EPPlus库可以读取XLSM文件中的VBA宏代码,同时直接通过文件路径获取文件名,实现一一关联。
示例代码:
using OfficeOpenXml; using OfficeOpenXml.VBA; using System.IO; // 设置EPPlus许可上下文(EPPlus 4.x适用非商业场景) ExcelPackage.LicenseContext = LicenseContext.NonCommercial; // 遍历目标文件夹下的所有XLSM文件 string folderPath = @"C:\Your\XLSM\Folder"; foreach (string filePath in Directory.GetFiles(folderPath, "*.xlsm")) { string fileName = Path.GetFileName(filePath); using (var package = new ExcelPackage(new FileInfo(filePath))) { if (package.Workbook.VbaProject != null) { // 遍历VBA项目中的所有模块 foreach (var module in package.Workbook.VbaProject.Modules) { string macroCode = module.Code; // 此时fileName即为当前宏代码所属的Excel文件名,可按需存储关联关系 Console.WriteLine($"文件:{fileName},模块:{module.Name},宏代码片段:{macroCode.Substring(0, 100)}..."); } } } }
方案2:读取Excel文件自定义属性补充关联
如果需要在宏文件内部存储文件名,可以手动给XLSM文件添加自定义属性,再用C#读取该属性并关联宏代码。
添加自定义属性:右键Excel文件→属性→详细信息→添加自定义属性(如OriginalFileName)并赋值。
读取自定义属性示例代码:
using System.IO; using Microsoft.WindowsAPICodePack.Shell; using Microsoft.WindowsAPICodePack.Shell.PropertySystem; string filePath = @"C:\Your\File.xlsm"; var shellFile = ShellFile.FromFilePath(filePath); // 读取自定义属性(假设属性名为"OriginalFileName") var prop = shellFile.Properties.GetProperty("System.Custom.OriginalFileName"); if (prop != null && !string.IsNullOrEmpty(prop.ValueAsObject?.ToString())) { string originalFileName = prop.ValueAsObject.ToString(); // 关联宏代码即可 }
注:需通过NuGet安装
Microsoft.WindowsAPICodePack-Shell包,该方式读取文件属性更稳定。
方案3:解析宏代码提取文件名(可靠性低)
如果宏录制时明确使用了具体文件名(如打开、保存操作),可以通过正则表达式匹配提取:
示例代码:
using System.Text.RegularExpressions; string macroCode = "YourMacroCodeContent"; // 匹配Workbooks.Open或SaveAs操作中的xlsm文件名 Regex regex = new Regex(@"Workbooks\.(Open|SaveAs)\(""(.*?)\.xlsm""\)"); Match match = regex.Match(macroCode); if (match.Success) { string extractedFileName = match.Groups[2].Value + ".xlsm"; Console.WriteLine("提取到的文件名:" + extractedFileName); }
注:仅适用于宏代码中明确包含文件名的场景,若宏使用
ThisWorkbook或ActiveWorkbook等相对引用,无法提取有效信息。
内容的提问来源于stack exchange,提问作者Anitha B
相关产品推荐
相关产品推荐

