Excel 基于多级字符串比较的单元格赋值

Excel 基于多级字符串比较的单元格赋值,excel,vba,Excel,Vba,简短而甜蜜:我有一个非常大的数据集,我试图为每个条目分配一个销售区域。销售区域取决于两个值:1)州和2)县。对于除WV、KY和TN以外的所有州,只能根据州值分配销售区域。对于WV、KY和TN,销售区域基于州和县的价值。对于这三个州,某些县属于不同的销售区域 以下是我运行代码前后示例数据集的屏幕截图: 我的代码标识STATE列和county(名为FIPS_CNTY_NM)列,然后在county列旁边插入一个新列,名为“TERRITORY”,我希望在其中分配销售地区 Sub assignTerr

简短而甜蜜:我有一个非常大的数据集,我试图为每个条目分配一个销售区域。销售区域取决于两个值:1)州和2)县。对于除WV、KY和TN以外的所有州,只能根据州值分配销售区域。对于WV、KY和TN,销售区域基于州和县的价值。对于这三个州,某些县属于不同的销售区域

以下是我运行代码前后示例数据集的屏幕截图:

我的代码标识STATE列和county(名为FIPS_CNTY_NM)列,然后在county列旁边插入一个新列,名为“TERRITORY”,我希望在其中分配销售地区

Sub assignTerritory()

Dim WS As Worksheet
Dim lastRow As Long
Dim countyName As String
Dim countyColumn As Long
Dim stateName As String
Dim stateColumn As Long
Dim stateValue As String
Dim countyValue As String
Dim i As Long

Set WS = Worksheets("Data")

With WS
    
    
    'Find numeric last row used on sheet
    lastRow = .Cells.Find(What:="*", After:=.Range("A1"), LookAt:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _
        SearchDirection:=xlPrevious, MatchCase:=False).Row
        
    MsgBox "The last row with entered data is " & lastRow
    
    
    'Find state column
    stateName = "STATE"

    stateColumn = .Rows(1).Find(What:=stateName, LookIn:=xlValues, LookAt:=xlWhole, _
        SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False).Column

    MsgBox "The " & stateName & " header is found in column " & stateColumn

    
    'Find county column
    countyName = "FIPS_CNTY_NM"

    countyColumn = .Rows(1).Find(What:=countyName, LookIn:=xlValues, LookAt:=xlWhole, _
        SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False).Column

    MsgBox "The " & countyName & " header is found in column " & countyColumn
    
    
    'Insert a row to the right of the county column
    .Columns(countyColumn + 1).Insert Shift:=xlToLeft, CopyOrigin:=xlFormatFromLeft
    
    
    'Give new column header "TERRITORY"
    .Cells(1, countyColumn + 1).Value = "TERRITORY"
    
    
    'Assign territory
    For i = 2 To lastRow
    
        stateValue = Trim(.Cells(i, stateColumn).Value)
        countyValue = Trim(.Cells(i, countyColumn).Value)
        
        If StrComp("PA", stateValue, vbTextCompare) Then .Cells(i, countyColumn + 1).Value = "Northern Appalachian"
        
        Next i
        
End With

End Sub
我不确定处理多个值的字符串比较的最佳方法。我的第一次尝试是处理一个州,我知道在这种情况下,我将只使用state值来分配领土,PA。我使用StrComp函数,但正如您从数据集_中看到的,我的代码将我想要的值(“北阿巴拉契亚”)分配给除PA以外的每个州。我不确定为什么会发生这种情况。我不知道它是否出现在我的语句中,或者我尝试过将.Cells更改为.Range并分配一个单元格,但我最终得到了相同的结果

数据集包括按州划分的销售区域,但不包括按县划分的销售区域。如果州值为PA、OH、MD、ME、NY、VT、DE、NJ、CT、NH、RI或MA,任何能够提供帮助的人(我希望可以推断到我的其他情况),该领土应被指定为“北阿巴拉契亚”。如果该州为WV,则该县(FIPS_CNTY_NM)等于以下任何一个:

[汉考克、布鲁克、俄亥俄州、马歇尔、韦策尔、莫农加利亚、普雷斯顿、马里恩、伍德、普莱森特、泰勒、威特、里奇、多德里奇、哈里森、吉尔默、刘易斯、泰勒、巴伯、厄普舒尔、塔克、伦道夫、彭德尔顿、格兰特、矿产、汉普郡、哈代、摩根、伯克利、杰斐逊]

然后,销售区域应指定为“北阿巴拉契亚”。如果州为WV,县(FIPS_CNTY_NM)不等于上述任何一个县,则销售区域应指定为“中阿巴拉契亚”

我怎样才能做到这一点


我大约2个月前才开始学习VBA,因为我在工作中有很多其他的职责,所以我没有能够尽可能充分地学习VBA。我不是一个软件开发人员,所以学习基础知识的速度比平常慢,但是这个社区到目前为止帮了我很大的忙,所以我期待着阅读任何答案

两层select case将对您有所帮助

  For i = 2 To lastRow

        stateValue = Trim(.Cells(i, stateColumn).Value)
        countyValue = Trim(.Cells(i, countyColumn).Value)

        Dim terr as String

        Select Case stateValue

            Case "PA","OH","MD","ME","NY","VT","DE","NJ","CT","NH","RI","MA"

                terr = "Northern Appalachian"

            Case "WV"

                 Select Case countyValue
                    Case "Hancock","Brooke","Ohio" ' keep adding
                        terr = "Northern Appalachian"
                    Case Else
                        terr = "Central Appalachian"
                 End Select

         End Select

   .Cells(i, countyColumn + 1).Value = terr

Next i

两层select case将对您有所帮助

  For i = 2 To lastRow

        stateValue = Trim(.Cells(i, stateColumn).Value)
        countyValue = Trim(.Cells(i, countyColumn).Value)

        Dim terr as String

        Select Case stateValue

            Case "PA","OH","MD","ME","NY","VT","DE","NJ","CT","NH","RI","MA"

                terr = "Northern Appalachian"

            Case "WV"

                 Select Case countyValue
                    Case "Hancock","Brooke","Ohio" ' keep adding
                        terr = "Northern Appalachian"
                    Case Else
                        terr = "Central Appalachian"
                 End Select

         End Select

   .Cells(i, countyColumn + 1).Value = terr

Next i

在您的工作表中,州和地区之间的关联由单元格颜色确定。因此,代码应该在State列中查找单元格颜色,并从键列表中颜色相同的单元格中选择区域名称


我不喜欢基于颜色的排序,但如果它对你有效,那就好了。另一种选择是一个2列键,您可以在其中将每个领土与州或县关联。键列表中的第二列将包含类似“PA,NY,Hancock,NJ”的字符串。代码将查看每行的County列,如果存在县名称,则使用县名称,否则切换到State列。在键表的第二列的字符串和从找到匹配项的行返回的区域中查找任一值。

在工作表中,状态和区域之间的关联由单元格颜色确定。因此,代码应该在State列中查找单元格颜色,并从键列表中颜色相同的单元格中选择区域名称


我不喜欢基于颜色的排序,但如果它对你有效,那就好了。另一种选择是一个2列键,您可以在其中将每个领土与州或县关联。键列表中的第二列将包含类似“PA,NY,Hancock,NJ”的字符串。代码将查看每行的County列,如果存在县名称,则使用县名称,否则切换到State列。在键表第二列的字符串和从找到匹配项的行返回的区域中查找任意一个值。

谢谢@BigBen I一定会返回并执行此操作。谢谢@BigBen I一定会返回并执行此操作。再次您好@Variatus!事实上,我对这个例子进行了颜色编码,只是为了帮助阅读我的问题的人更容易理解。我的实际值就像白色单元格中的文本一样存在。为了跟进您的回复,每个ID都有一个州和一个县,而不仅仅是一些。我认为从处理的角度来看,我可以使用只在需要时检查州,然后在需要时同时检查州和县的代码来实现我的目标。我肯定不是专家,但我认为当它只考虑一个值而不是两个值时,我可以最大限度地提高速度。我确实有将近90000个值要赋值,如果每一行都有州和县,那么你的例子就有误导性。但是,键是键表。它必须有两列,我上面描述的编码方法将以任何方式工作。添加一个额外的步骤来处理WV、KY和TN,通过查找县和所有其他州可能会更快!事实上,我对这个例子进行了颜色编码,只是为了帮助阅读我的问题的人更容易理解。我的实际值就像白色单元格中的文本一样存在。为了跟进您的回复,每个ID都有一个州和一个县,而不仅仅是一些。我认为从处理的角度来看,我可以使用只在需要时检查州,然后在需要时同时检查州和县的代码来实现我的目标。我肯定不是专家,但我认为当它只考虑一个值而不是两个值时,我可以最大限度地提高速度。我确实有将近90000个值要赋值,如果每一行都有州和县,那么你的例子就有误导性。然而,t