|
|
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
VBA代码的详细解释,涵盖函数/子过程功能、关键变量作用、正则表达式规则及整体执行流程:
一、整体代码结构
代码包含 1个自定义函数 和 2个子过程,核心功能是:
解析字符串中的日期时间(RegExDate函数);
批量处理指定文件夹内的Excel文件和图片文件,为Excel单元格添加图片文件的超链接(lll主过程 + Xls_Img_RngImgColl辅助函数)。
二、自定义函数:RegExDate(Str As String) As Variant
功能:使用正则表达式从字符串中提取日期时间信息,并转换为VBA可识别的Date类型(含日期+时间)。
1. 关键变量说明
变量名 类型 作用
RegEx VBScript_RegExp_55.RegExp 正则表达式对象,用于定义匹配规则和执行匹配。
Match VBScript_RegExp_55.Match 存储正则匹配的结果(单个匹配项)。
oYear/oMonth/oDay String 提取的年、月、日字符串(必选部分)。
oHour/oMinute/oSecond String 提取的时、分、秒字符串(可选部分,默认"00")。
2. 正则表达式规则解析
.Pattern = "(\d{4})(?:[./-]|年)(\d{2})(?:[./-]|月)(\d{2})(?:日)?\s*(?:T|[-/:\s]|时)?\s*(\d{2})?(?:[:]|分)?(\d{2})?(?:[:]|秒)?(\d{2})?(?:秒)?"
该正则用于匹配带日期+可选时间的字符串,结构拆分如下:
日期部分(必选):
(\d{4}):匹配4位年份(捕获组1,对应oYear);
(?:[./-]|年):非捕获组,匹配年份与月份的分隔符(支持.、/、-、年,如2023年或2023/);
(\d{2}):匹配2位月份(捕获组2,对应oMonth);
(?:[./-]|月):非捕获组,匹配月份与日期的分隔符(支持.、/、-、月);
(\d{2}):匹配2位日期(捕获组3,对应oDay);
(?:日)?:非捕获组,可选匹配“日”字(如15日或15)。
时间部分(可选):
\s*:匹配任意空白字符(空格、制表符等);
(?:T|[-/:\s]|时)?:非捕获组,匹配日期与时间的分隔符(支持T、-、/、:、空格、时,如T12:30或12时);
(\d{2})?:可选匹配2位小时(捕获组4,对应oHour);
(?:[:]|分)?:非捕获组,匹配小时与分钟的分隔符(支持:或分);
(\d{2})?:可选匹配2位分钟(捕获组5,对应oMinute);
(?:[:]|秒)?:非捕获组,匹配分钟与秒的分隔符(支持:或秒);
(\d{2})?:可选匹配2位秒(捕获组6,对应oSecond);
(?:秒)?:非捕获组,可选匹配末尾的“秒”字。
3. 函数执行流程
初始化正则对象:设置Global=False(仅匹配第一个结果)、IgnoreCase=False(区分大小写),并加载上述Pattern。
执行匹配:用RegEx.Test(Str)判断字符串是否符合规则。
匹配成功:
通过Match.SubMatches提取年、月、日(必选)及时、分、秒(可选,空则补"00");
用DateSerial(oYear, oMonth, oDay)生成日期,TimeSerial(oHour, oMinute, oSecond)生成时间,拼接为Date类型返回;
(调试代码)Debug.Print输出结果,Stop暂停程序(实际使用需删除)。
匹配失败:返回空字符串""。
释放对象:销毁RegEx和Match对象,避免内存泄漏。
三、主过程:Sub lll()
功能:批量处理指定文件夹(Excel文件所在目录的\IMG和\xls子文件夹),为Excel单元格添加图片文件的超链接。
1. 关键变量说明
变量名 类型 作用
t Variant 记录过程开始时间(用于计算执行耗时)。
Fso Scripting.FileSystemObject 文件系统对象,用于操作文件夹、文件(需引用Microsoft Scripting Runtime)。
oFile Scripting.File 循环变量,遍历文件夹内的文件。
ImgDict Scripting.Dictionary 存储\IMG文件夹内的图片文件(键:文件名,值:File对象)。
XlsDict Scripting.Dictionary 存储\xls文件夹内的Excel文件(未实际使用,可能为预留)。
XlsImgRng_Coll Collection 存储Xls_Img_RngImgColl返回的结果(Excel单元格+图片文件的对应关系)。
2. 执行流程
初始化对象:创建Fso(文件系统)、ImgDict(图片字典)、XlsDict(Excel字典)。
加载图片文件:遍历ThisWorkbook.Path & "\IMG"文件夹内的所有文件,将文件名作为键、File对象作为值存入ImgDict。
处理Excel文件:遍历ThisWorkbook.Path & "\xls"文件夹内的所有文件:
跳过临时文件(路径含$的文件,如Excel自动生成的~$xxx.xlsx);
对有效Excel文件,调用Xls_Img_RngImgColl函数,传入Excel文件和ImgDict(图片字典),执行超链接添加逻辑。
输出耗时:Debug.Print Format(Time - t, "h:m:ss")打印总执行时间。
四、辅助函数:Xls_Img_RngImgColl(xlsFile As File, ImgDict As Dictionary)
功能:打开指定Excel文件,为工作表中指定范围的单元格添加图片文件的超链接(区分_original后缀的图片)。
1. 关键变量说明
变量名 类型 作用
XlApp Excel.Application Excel应用程序对象(后台运行,Visible = False)。
Wk Workbook 打开的Excel工作簿对象。
Sht Worksheet 操作的工作表(默认第1个工作表:Wk.Sheets(1))。
ImgRng Range 要处理的单元格范围(第1列,从第5行到数据最后一行:.Range(.Cells(5, 1), .Cells(.Cells(20000, 1).End(xlUp).Row, 1)))。
oRng Range 循环变量,遍历ImgRng内的每个单元格。
Coll Collection 存储单元格与图片文件的对应关系(返回给主过程)。
Arr(2) Variant数组 临时存储:Arr(0)=单元格、Arr(1)=普通图片文件、Arr(2)=_original图片文件。
2. 执行流程
启动Excel后台实例:Set XlApp = New Excel.Application,XlApp.Visible = False避免界面干扰。
打开Excel文件:Set Wk = XlApp.Workbooks.Open(xlsFile.Path),定位到第1个工作表Sht。
定义处理范围:ImgRng为第1列(A列)的第5行到最后一行数据(假设A列存图片关联的关键字)。
遍历单元格匹配图片:对ImgRng内的每个单元格oRng:
遍历ImgDict中的所有图片文件(Key为文件名);
匹配规则:图片文件名包含oRng单元格的前19个字符(Left(oRng(, 1), 19));
添加超链接:
若图片文件名不含_original:为oRng所在行的A列单元格添加超链接(链接到图片路径),并将单元格和文件存入Arr(0)/Arr(1);
若图片文件名含_original:为oRng所在行的B列单元格添加超链接,并存入Arr(2);
将Arr添加到Coll集合。
保存并关闭:Wk.Save保存修改,Wk.Close关闭工作簿,销毁XlApp对象释放资源。
返回结果:Set Xls_Img_RngImgColl = Coll将匹配结果返回给主过程。
五、核心逻辑总结
文件关联逻辑:通过Excel单元格内容的前19个字符与图片文件名的包含关系,建立“单元格-图片”的映射。
超链接区分:将普通图片链接到A列,带_original后缀的原图链接到B列。
效率优化:
使用Dictionary存储图片文件,通过键值对快速匹配(比遍历文件夹更高效);
Excel后台运行(Visible = False)避免界面卡顿。
六、注意事项
引用依赖:代码需引用两个库(VBE中工具→引用勾选):
Microsoft VBScript Regular Expressions 5.5(正则表达式支持);
Microsoft Scripting Runtime(文件系统FileSystemObject支持)。
调试代码:RegExDate函数中的Stop语句会暂停程序,实际使用需删除。
路径兼容性:确保\IMG和\xls文件夹存在于当前Excel文件所在目录,否则会报错。
通过以上逻辑,代码实现了自动化批量处理Excel与图片的关联,适用于需要批量为Excel添加图片超链接的场景(如档案管理、数据可视化等)。
- Sub lll()
- Dim t: t = Time
- Dim Fso As Scripting.FileSystemObject
- Set Fso = New Scripting.FileSystemObject
- Dim oFile As Scripting.file
- Dim ImgDict As Scripting.Dictionary
- Set ImgDict = New Scripting.Dictionary
- Dim ImgFile As Scripting.file
- Dim XlsDict As Scripting.Dictionary
- Dim XlsImgRng_Coll As Collection
- Set XlsDict = New Scripting.Dictionary
- ''
- For Each oFile In Fso.GetFolder(ThisWorkbook.Path & "\IMG").Files
- 'Debug.Print oFile.Name
- Set ImgDict(oFile.Name) = oFile
- Next
- ''
- For Each oFile In Fso.GetFolder(ThisWorkbook.Path & "\xls").Files
- 'Debug.Print oFile.Name
- If InStr(oFile.Path, "$") = 0 Then
- Set XlsImgRng_Coll = Xls_Img_RngImgColl(oFile, ImgDict)
- ElseIf InStr(oFile.Path, "$") > 0 Then
- oFile.Delete True
- ''Stop
- End If
- Next
- Debug.Print Format(Time - t, "h:m:ss")
- End Sub
- Function Xls_Img_RngImgColl(xlsFile As file, ImgDict As Dictionary)
- Dim tt: t = Time
- Dim XlApp As Excel.Application
- Set XlApp = New Excel.Application
- XlApp.Visible = False
-
- ''
- Dim oFile As Scripting.file
-
- Dim Wk As Workbook
- Set Wk = XlApp.Workbooks.Open(xlsFile.Path)
- Dim Sht As Worksheet
- Set Sht = Wk.Sheets(1)
- Dim ImgRng As Range
- Dim oRng As Range
- Dim Coll As Collection
- Set Coll = New Collection
- Dim Arr(2)
- With Sht
- Set ImgRng = .Range(.Cells(5, 1), .Cells(.Cells(20000, 1).End(xlUp).Row, 1))
- End With
- For Each oRng In ImgRng
- 'Debug.Print Left(oRng(, 1), 19), oRng(, 2), oRng(, 3), oRng(, 4), oRng(, 5), oRng(, 6), oRng(, 7)
- For Each Key In ImgDict.Keys
- Set oFile = ImgDict(Key)
- '''Debug.Print oFile.Name, Left(oRng(, 1), 19)
- If InStr(oFile.Name, Left(oRng(, 1), 19)) > 0 Then
- '''
- If InStr(oFile, "_original") = 0 Then
- Arr(0) = oRng
- Arr(1) = oFile
- oRng(, "A").Hyperlinks.Add Anchor:=oRng(, 1), Address:=oFile.Path
- ElseIf InStr(oFile, "_original") > 0 Then
- Arr(2) = oFile
- oRng(, "B").Hyperlinks.Add Anchor:=oRng(, 2), Address:=oFile.Path
- End If
- End If
- Next
- ''
- Coll.Add Arr
- Next
- Set Xls_Img_RngImgColl = Coll
- Debug.Print Wk.FullName
- ''
- Wk.Save
- Wk.Close
- Set Wk = Nothing
- Set XlApp = Nothing
- Debug.Print Format(Time - t, "h:m:ss")
- End Function
复制代码
|
|