WorksheetChange事件连接行和名字的第一个字母+姓氏的第一个字母

我认为代码应该是这样的,但是我正在尝试处理名字和姓氏的这一行发生错误。 基本上,我想在列A中创build一个代码,这是人的名字的第一个字母和人的姓氏的第一个字母,与行号连接。 该行将是活动行(总是列A),并且姓和名将存储在列B中。

Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column <> 1 Then Exit Sub On Error GoTo ErrHandler Application.EnableEvents = False If Target.Column = 1 Then Target.Offset(0, 0).FormulaR1C1 = "=ROW()" TV1 = Target.Offset(0, 0).FormulaR1C1 Target.Offset(0, 0).FormulaR1C1 = "=UPPER(LEFT(R[" & "=ROW()" & "]C[1],1)&MID(R[" & "=ROW()" & "]C[1],FIND("" "",R[" & "=ROW()" & "]C[1],1)+1,1))" TV2 = Target.Offset(0, 0).FormulaR1C1 Target.Offset(0, 0).Value = TV2 & "-" & TV1 End If End Sub 

我不想避免处理多个单元格作为目标。 处理多个单元并不难。

在禁用事件并执行处理之后,您不会再将其重新打开。 您的代码只能运行一次,而无需手动重启事件。

如果您在名单B中input名字和姓氏,那么这个处理过程是否应该服从B列而不是列A?

 Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Columns("B")) Is Nothing Then On Error GoTo ErrHandler Application.EnableEvents = False Dim trgt As Range For Each trgt In Intersect(Target, Target.Parent.UsedRange, Columns("B")) trgt = StrConv(Trim(trgt.Value2), vbProperCase) If CBool(InStr(2, trgt.Value2, Chr(32))) Then trgt.Offset(0, -1) = _ UCase(Left(trgt.Value2, 1)) & _ UCase(Mid(trgt.Value2, InStr(1, trgt.Value2, Chr(32)) + 1, 1)) & _ Format(trgt.Row, "000") End If Next trgt End If ErrHandler: Application.EnableEvents = True End Sub 

我已经添加了一些修剪和适当的情况下转换来自动更正input到列B中的值。

在下面的图片中,我复制了G5:G8的名字,并将它们粘贴到B2:B5中。

在这里输入图像描述

我会做不同的。 为什么要在VBA中编写公式?

我也对你的原始代码做了一些注释:


 Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column <> 1 Then Exit Sub Application.EnableEvents = False ' No error handler in your code 'On Error GoTo ErrHandler ' don't need to check if column 1 since we already did that and exited the sub if it was not ' If Target.Column = 1 Then 'Target.Offset(0,0) = Target 'Target.Offset(0, 0).FormulaR1C1 = "=ROW()" 'TV1 = Target.Offset(0, 0).FormulaR1C1 'Target.Offset(0, 0).FormulaR1C1 = "=UPPER(LEFT(R[" & "=ROW()" & "]C[1],1)&MID(R[" & "=ROW()" & "]C[1],FIND("" "",R[" & "=ROW()" & "]C[1],1)+1,1))" 'TV2 = Target.Offset(0, 0).FormulaR1C1 'Target.Offset(0, 0).Value = TV2 & "-" & TV1 'Just do the creation in VB With Target .Value = .Row & Left(.Offset(0, 1), 1) & Left(Split(.Offset(0, 1))(1), 1) End With 'If you have more than two space-separated words in the name, then something like Dim V As Variant With Target V = Split(.Offset(0, 1)) .Value = .Row & Left(V(0), 1) & Left(V(UBound(V)), 1) End With 'Don't forget to reenable events Application.EnableEvents = True End Sub 

另外,由于名称在B列,所以为什么要testingA列的更改? 有可能是有原因的,但是如果没有,可以更顺利地检查B列的变化。

我想到了!!

 If Target.Column = 1 Then Target.Offset(0, 0).FormulaR1C1 = "=ROW()" TV1 = Target.Value Target.Offset(0, 0).FormulaR1C1 = "=UPPER(LEFT(RC[1],1)&MID(RC[1],FIND("" "",RC[1],1)+1,1))" TV2 = Target.Value Target.Value = TV2 & "-" & TV1 End If