Excel宏执行异常:多工作表参与者出席情况查询需求及代码问题
完善Excel多工作表出席情况检查VBA宏
需求说明
- 工作簿中Sheet1为主表:A列存储姓名,B列存储参与者编号,需在C列标注该参与者是否出席活动,以及出席的活动工作表名称
- 其余工作表为活动记录表:A列存储参与者编号,B列存储姓名
- 数据量较大,普通公式效率不足,需通过VBA宏实现
完整可运行VBA代码
Sub CheckAttendance() Dim wsMain As Worksheet Dim wsEvents As Worksheet Dim lastRowMain As Long Dim lastRowEvents As Long Dim mainRow As Long Dim eventRow As Long Dim participantID As String Dim presentSheets As String ' 设置主工作表 Set wsMain = ThisWorkbook.Sheets("Sheet1") ' 获取主表数据最后一行 lastRowMain = wsMain.Cells(wsMain.Rows.Count, "B").End(xlUp).Row ' 先清空主表C列原有内容(表头除外,假设表头在第1行) wsMain.Range("C2:C" & lastRowMain).ClearContents ' 遍历每一行主表数据(从第2行开始,跳过表头) For mainRow = 2 To lastRowMain participantID = wsMain.Cells(mainRow, "B").Value presentSheets = "" ' 遍历所有活动工作表 For Each wsEvents In ThisWorkbook.Sheets If wsEvents.Name <> "Sheet1" Then lastRowEvents = wsEvents.Cells(wsEvents.Rows.Count, "A").End(xlUp).Row ' 在当前活动表中查找参与者编号 For eventRow = 2 To lastRowEvents If wsEvents.Cells(eventRow, "A").Value = participantID Then ' 记录活动工作表名称,用逗号分隔多个活动 If presentSheets = "" Then presentSheets = wsEvents.Name Else presentSheets = presentSheets & ", " & wsEvents.Name End If ' 找到后跳出当前活动表的循环,提升效率 Exit For End If Next eventRow End If Next wsEvents ' 根据记录结果填写主表C列 If presentSheets <> "" Then wsMain.Cells(mainRow, "C").Value = "已出席:" & presentSheets Else wsMain.Cells(mainRow, "C").Value = "未出席任何活动" End If Next mainRow MsgBox "出席情况检查完成!" End Sub
代码关键点说明
- 效率优化:找到参与者在活动表中的记录后立即跳出当前活动表的循环,避免不必要的遍历;先清空C列原有内容,防止残留旧数据
- 结果展示:如果参与者出席多个活动,用逗号分隔活动工作表名称;未出席则明确标注
- 表头处理:默认表头在第1行,遍历从第2行开始,若你的表头位置不同,可修改
mainRow = 2和eventRow = 2的起始值 - 数据匹配:通过参与者编号(B列/活动表A列)进行匹配,比姓名匹配更准确,避免重名问题
运行说明
- 打开Excel工作簿,按下
Alt + F11打开VBA编辑器 - 插入新模块:右键点击工作簿名称 → 插入 → 模块
- 将上述代码粘贴到模块中
- 回到Excel界面,按下
Alt + F8,选择CheckAttendance宏并执行
内容的提问来源于stack exchange,提问作者Solomon Tikhonov
相关产品推荐
相关产品推荐

