实例需求:在A列输入样品名称之后,在B列字段填写编号,其规则如下:
- 如果A列已经存在相同
样品名称
,则将编号递增,例如:A15输入沥青,最后一行相同样品名称在第12行,B15填写递增的编号YP-2023-LQJ-003
- 如果A列并不存在相同
样品名称
,那么在Sheet2工作表中查找其编号规则,例如:A16输入土,找到其编号规则为YP-2023-TGJ-
,B16填写编号YP-2023-TGJ-001
示例代码如下。
Private Sub Worksheet_Change(ByVal Target As Range)
Dim sKey As String, iMatch, strIndex, strNum, iRow, arr, brr
With Target
If .CountLarge = 1 Then
If .Column = 1 Then
Application.EnableEvents = False
sKey = .Value
If sKey = "" Then
.Offset(0, 1) = ""
Else
iMatch = 0
arr = Range("A1:A" & .Row)
For iRow = .Row - 1 To 2 Step -1
If arr(iRow, 1) = sKey Then
iMatch = iRow
Exit For
End If
Next
If iMatch > 0 Then
strIndex = Cells(iMatch, 2)
strNum = Format(Val(Right(strIndex, 3)) + 1, "000")
.Offset(0, 1).Value = Left(strIndex, Len(strIndex) - 3) & strNum
Else
Set dic = CreateObject("scripting.dictionary")
brr = Sheet2.[a1].CurrentRegion
For iRow = 2 To UBound(brr)
dic(brr(iRow, 1)) = brr(iRow, 2)
Next
If dic.exists(sKey) Then
.Offset(0, 1).Value = dic(sKey) & "001"
Else
MsgBox "样品类型错误!"
End If
End If
End If
Application.EnableEvents = True
End If
End If
End With
End Sub
【代码解析】
自动填写或者自动更新之类的需求,多数都需要使用工作表的Change事件来实现。
第4行代码判断发生变化的单元格(下文简称为目标单元格)是否为单个单元格。
第5行代码判断目标单元格是否位于第一列。
第6行代码禁用系统事件激活,避免修改单元格时,此事件代码被再次触发。
第7行代码将目标单元格的值保存在变量sKey中。
第8行代码判断目标单元格是否为空,如果为空说明删除了A的内容,那么第9行代码清空对应行B列编号。
第12行代码将A列已经输入的内容加载到数组中。
第13~18行代码查找是否已经存在相同的“样品名称”。
第13行代码采用倒序循环,这样可以查找最后一次出现的关键字。
第14行代码判断相应行的内容是否与目标单元格的值相同。
如果相同,第15行代码将行号保存在变量iMatch中,第16行代码退出For循环。
第19行代码判断iMatch的值是否大于0。
- 如果找到了与目标单元格相同的值,那么第20行代码获取匹配行的编号。
第21行代码将提取编号后3位,递增1之后,再格式化为3位数字的格式。
第22行代码拼接新的编号,并写入目标单元格对应行的B列单元格。 - 如果iMatch值为零,说明目标单元格输入值为新的“样品名称”。
第24行代码创建字典对象。
第25行代码将Sheet2中的编号规则加载到数组中。
第26~28行代码将编号规则添加到字典对象中。
第29行代码判断目标单元格的值是否存在于字典对象中。- 如果存在,第30行代码将在B列填写编号,最后三位设置为
001
。 - 如果不存在,第32行代码将显示错误提升消息框。
- 如果存在,第30行代码将在B列填写编号,最后三位设置为
第36行代码恢复系统事件。