在循环内的个案陈述

如何在VBA的循环中创build一个case语句(或多个if语句)?

在这个例子中,我有一个与4个不同组对应的4个名字的列表。 名称位于电子表格的“C”列中,我想创build一个新的列“D”列,其中列出了每个人的组名。

这是我目前正在使用的代码:

Sub AddGroupColumn() 'Counts number of rows in sheet. Loops through rows. For i = 1 To Range("C1048576").End(xlUp).Row If Range("C2:C" & i).Value = "john.doe" Then Set Range("D2:D" & i).Value = "group 1" If Range("C2:C" & i).Value = "jane.doe" Then Range("D2:D" & i).Value = "group 2" If Range("C2:C" & i).Value = "james.doe" Then Range("D2:D" & i).Value = "group 3" If Range("C2:C" & i).Value = "jenn.doe" Then Range("D2:D" & i).Value = "group 4" Next i End Sub 

请提供关于如何修复上面的代码的build议。 我知道语法是closures的,我不确定是否应该使用“If / Then / Else / Elseif”的“Case”语句。 这是我目前收到的错误:

编译错误:下一个没有For

另外,请告知是否有更有效的方法来解决这个问题。 真实情况下,有12个名字,12个组和10万行的名字。

你可能把名字和组放入数组中。

 Sub AddGroupColumn() Dim rCell As Range Dim rRng As Range Dim vaNames As Variant Dim vaGroups As Variant Dim lMatch As Long vaNames = Array("john.doe", "jane.doe", "james.doe", "jenn.doe") vaGroups = Array("group 1", "group 2", "group 3", "group 4") With Sheet1 Set rRng = .Range("C1", .Cells(.Rows.Count, 3).End(xlUp)) End With For Each rCell In rRng.Cells lMatch = Application.WorksheetFunction.Match(rCell.Value, vaNames, False) rCell.Offset(0, 1).Value = vaGroups(lMatch - 1) Next rCell End Sub 

请注意,在您的示例中,您不指定范围适用于哪个工作表。 这些被称为非限定范围的引用,可能会导致一些意外的行为。 如果您的代码位于标准模块中,则不合格的范围将引用ActiveSheet。 如果您的代码位于图纸类模块中,则不合格范围引用该图纸。

如果C列中的某些名称没有组,则必须更改该循环来解决此问题。 喜欢这个

 For Each rCell In rRng.Cells On Error Resume Next lMatch = Application.WorksheetFunction.Match(rCell.Value, vaNames, False) On Error GoTo 0 If lMatch - 1 > LBound(vaGroups) Then rCell.Offset(0, 1).Value = vaGroups(lMatch - 1) Else rCell.Offset(0, 1).Value = "No group" End If Next rCell 

您所写的IF语句都需要在第二个IF语句中有ELSE IFELSE IF在分组结束时有一个END IF语句。

你当然可以做一个CASE语句,如下所示:

 Sub AddGroupColumn() 'Counts number of rows in sheet. Loops through rows. For i = 1 To Range("C1048576").End(xlUp).Row Select Case Range("C2:C" & i).Value Case "john.doe" Range("D2:D" & i).Value = "group 1" Case "jane.doe" Range("D2:D" & i).Value = "group 2" ' The rest of your case statements go here ... End Select Next i End Sub 

你可以使用数组完成所有这些,不需要IfSelect Case语句。 这样可以避免每次将一个值写入工作表。

经过testing并使用您的示例input进行工作(假定input数据为单列):

 Sub AddGroupColumn() Dim inputRange As Excel.Range Dim inputData As Variant Dim outputData As Variant Dim i As Long, j As Long Dim nameslist As Variant Dim groupslist As Variant ' **** EDIT THESE AS NEEDED, however they MUST correspond Const NAMES_LIST As String = "john.doe,jane.doe,james.doe,jenn.doe" Const GROUPS_LIST As String = "group 1,group 2,group 3,group 4" ' create arrays of names and groups nameslist = Split(NAMES_LIST, ",") groupslist = Split(GROUPS_LIST, ",") ' define input range Set inputRange = Range("C2:C" & Range("C" & Rows.Count).End(xlUp).row) ' read column C values into array inputData = inputRange.value ' resize output array to match input array ReDim outputData(LBound(inputData) To UBound(inputData), 1 To 1) ' evaluate input array, output to another array For i = LBound(inputData) To UBound(inputData) For j = LBound(nameslist) To UBound(nameslist) If inputData(i, 1) = nameslist(j) Then ' given input value is matched on the names list outputData(i, 1) = groupslist(j) ' output array is the corresponding group name Exit For ' exit loop since we found what we need in this loop End If Next j Next i ' write output data to output range inputRange.Offset(, 1).value = outputData End Sub 

此过程将在您将其应用于实际数据时进行缩放。 只需编辑两个常量, 确保它们的值相符

通过使用Rows.Count它将总是抓住正确的范围,不pipeExcel的版本。 不pipe你有多less数据,数组都会调整自己的大小。 唯一的假设是你的input数据在一列中。

另请注意,我们只触摸三次工作表:一次定义input范围,一次获取C列中的值,一次将计算值写回D列。

示例input

样本输入

运行代码后

样本输出