Excel/VBA:按姓名匹配查找行并分列统计非空值求助
用VBA实现姓名对应列的非空条目统计
你这个需求用For Each循环完全可以实现,我给你整理了完整的代码和详细解释,你可以直接套用,还附带了后续加权求和的扩展方案~
核心思路
- 遍历Sheet1中A列的每个姓名
- 对每个姓名,在Sheet2中找到所有匹配的行
- 分别统计这些行中B、C、D列的非空单元格数量
- 将统计结果写入Sheet1对应行的后续列,方便后续加权计算
完整VBA代码
Sub CountNonEmptyEntries() ' 定义工作表对象 Dim ws1 As Worksheet, ws2 As Worksheet ' 定义遍历用的单元格变量 Dim nameCell As Range, cell2 As Range ' 存储最后一行行号 Dim lastRow1 As Long, lastRow2 As Long ' 存储各列非空计数 Dim countB As Integer, countC As Integer, countD As Integer ' 指定工作表(如果你的表名不是Sheet1/Sheet2,记得修改) Set ws1 = ThisWorkbook.Sheets("Sheet1") Set ws2 = ThisWorkbook.Sheets("Sheet2") ' 获取两个工作表中A列的最后一行(避免遍历空行) lastRow1 = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row lastRow2 = ws2.Cells(ws2.Rows.Count, "A").End(xlUp).Row ' 遍历Sheet1中A列的所有姓名(从A2开始,假设A1是表头) For Each nameCell In ws1.Range("A2:A" & lastRow1) ' 每次遍历新姓名前,重置计数器 countB = 0 countC = 0 countD = 0 ' 遍历Sheet2中A列的所有姓名(同样假设A1是表头) For Each cell2 In ws2.Range("A2:A" & lastRow2) ' 找到匹配的姓名 If cell2.Value = nameCell.Value Then ' 检查B列是否非空(排除纯空格的情况可以用 Len(Trim(cell2.Offset(0,1).Value)) > 0) If Not IsEmpty(cell2.Offset(0, 1)) Then countB = countB + 1 ' 检查C列 If Not IsEmpty(cell2.Offset(0, 2)) Then countC = countC + 1 ' 检查D列 If Not IsEmpty(cell2.Offset(0, 3)) Then countD = countD + 1 End If Next cell2 ' 将统计结果写入Sheet1的B、C、D列(可根据需求调整列位置) nameCell.Offset(0, 1) = countB nameCell.Offset(0, 2) = countC nameCell.Offset(0, 3) = countD ' ---------------------- 可选:直接计算加权求和结果 ---------------------- ' 假设B列权重0.3,C列0.5,D列0.2,结果写入E列 ' nameCell.Offset(0, 4) = countB * 0.3 + countC * 0.5 + countD * 0.2 Next nameCell MsgBox "统计完成!", vbInformation End Sub
代码关键部分解释
- 工作表与行号处理:先获取两个表的最后一行,避免遍历大量空行,提升效率
- 双层For Each循环:外层遍历Sheet1的姓名,内层遍历Sheet2找匹配项,完全符合你想要的循环逻辑
- 非空判断:用
IsEmpty检查单元格是否为空,如果要排除仅含空格的单元格,可以替换成Len(Trim(cell2.Offset(0,1).Value)) > 0 - 结果写入:用
Offset方法定位到当前姓名行的后续列,把统计值写入,方便后续处理
注意事项
- 如果Sheet2中的姓名不在A列,建议改用行号定位的方式,避免偏移出错。比如姓名在F列,内层循环可以改成:
For Each cell2 In ws2.Range("F2:F" & lastRow2) If cell2.Value = nameCell.Value Then If Not IsEmpty(ws2.Cells(cell2.Row, "B")) Then countB = countB + 1 If Not IsEmpty(ws2.Cells(cell2.Row, "C")) Then countC = countC + 1 If Not IsEmpty(ws2.Cells(cell2.Row, "D")) Then countD = countD + 1 End If Next cell2 - 如果数据量极大,双层循环效率偏低,可以改用
Find方法批量查找匹配项,减少遍历次数,不过对于常规数据量,双层循环完全够用。
内容的提问来源于stack exchange,提问作者quantumspores
相关产品推荐
相关产品推荐

