我有1000个excel行的值,有些是重复的,我想在VBA的另一个选项卡上找到这些值存在的列号

z18hc3ub  于 2023-08-08  发布在  其他
关注(0)|答案(2)|浏览(127)

我有一个有两个标签的工作簿。我的第一个选项卡每天都有不同的人添加行,其中一个单元格输入的是城市名称。每个人输入的城市名称不同,例如,纽约可以输入为NYC,NY,NwYrk,New York,NewYkCty等。在第二个选项卡上,我创建了一个“查找”数据库,其中第2行是拼写城市名称的正确方法,每次我看到有人如何拼写它的新版本时,我都会将其版本复制到它下面。我正在寻找一个公式或一种方法,在VBA中能够迭代通过数千行,我可以在一个月内对数千个城市的名字,我在我的迷你数据库,并提供给我的列号中找到的匹配,所以我可以从它运行偏移公式。还有一件事要注意,前一天的位置可以编辑,所以我将需要有这个总是更新,如果一个变化已作出的城市名称。
我已经尝试了下面的代码,但它需要5-8分钟来运行每个单元格,并继续需要更长的时间,因为更多的细胞得到添加。

With Sheets("Billings").Range("b1")
                Set columnLocationList = Range(.Offset(1, 0), .End(xlDown))
            End With

            For Each columnLocations In columnLocationList
                For Each locations In Sheets("Database Names").UsedRange
                    If columnLocations = locations Then
                        columnLocations.Offset(0, 1).Value = locations.Column
                        GoTo nextBill
                    End If
                Next locations
nextBill:
            Next columnLocations

字符串
标签:账单
| 城市名称|色谱柱编号| Column Number |
| --|--| ------------ |
| NYC| 3个| 3 |
| 洛杉矶国际机场|二个| 2 |
选项卡:数据库名称
| 洛杉矶|纽约| New York |
| --|--| ------------ |
| LA|数控| NC |
| | LAX | NYC |

wa7juj8i

wa7juj8i1#

填充列索引


的数据

主要

Sub PopulateColumnIndexes()
    
    Const PROC_TITLE As String = "Populate Column Indexes"
    Const WORKSHEET_NAME As String = "Billings"
    Const FIRST_ROW As Long = 2
    Const SRC_COLUMN As Long = 2
    Const DST_COLUMN As Long = 3
    Const NOT_FOUND_VALUE As Variant = Empty
    Const MESSAGE_YES As String = "Column indexes populated."
    Const MESSAGE_NO As String = "Couldn't find the following locations:"
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    Dim ws As Worksheet: Set ws = wb.Sheets(WORKSHEET_NAME)
    Dim RowOffset As Long: RowOffset = FIRST_ROW - 1
    
    Dim srg As Range, drg As Range
    
    With ws.UsedRange
        With .Resize(.Rows.Count - RowOffset).Offset(RowOffset)
            Set srg = .Columns(SRC_COLUMN)
            Set drg = .Columns(DST_COLUMN)
        End With
    End With
    
    Dim Data(): Data = srg.Value
    Dim Locations As Object: Set Locations = LocationsToDictionary
    Dim NoLocs As Object: Set NoLocs = CreateObject("Scripting.Dictionary")
    NoLocs.CompareMode = vbTextCompare
    
    Dim r As Long, rStr As String, sAddress As String, IsFound As Boolean
    
    For r = 1 To UBound(Data, 1)
        rStr = CStr(Data(r, 1))
        If Len(rStr) > 0 Then
            If Locations.Exists(rStr) Then IsFound = True
        End If
        If IsFound Then
            IsFound = False
            Data(r, 1) = Locations(rStr)
        Else
            Data(r, 1) = NOT_FOUND_VALUE
            sAddress = srg.Cells(r).Address(0, 0)
            If NoLocs.Exists(rStr) Then
                NoLocs(rStr) = NoLocs(rStr) & ", " & sAddress
            Else
                NoLocs(rStr) = """" & rStr & """ in " & sAddress
            End If
        End If
    Next r
    
    drg.Value = Data
    
    If NoLocs.Count = 0 Then
        MsgBox MESSAGE_YES, vbInformation, PROC_TITLE
    Else
        MsgBox MESSAGE_NO & vbLf & vbLf & Join(NoLocs.Items, vbLf), _
            vbExclamation, PROC_TITLE
    End If

End Sub

字符串

帮助

Function LocationsToDictionary() As Object
    
    Const WORKSHEET_NAME As String = "Database Names"
    Const FIRST_ROW As Long = 1
    Const FIRST_COLUMN As Long = 2
    Const NEXT_COLUMN_ON_FIRST_BLANK As Boolean = True ' boosts efficiency
    
    Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
    Dim ws As Worksheet: Set ws = wb.Sheets(WORKSHEET_NAME)
    
    Dim Data(): Data = ws.UsedRange.Value
    Dim rCount As Long: rCount = UBound(Data, 1)
    Dim cCount As Long: cCount = UBound(Data, 2)
    
    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
    dict.CompareMode = vbTextCompare
    
    Dim c As Long, r As Long, rStr As String
    
    For c = FIRST_COLUMN To cCount
        For r = FIRST_ROW To rCount
            rStr = CStr(Data(r, c))
            If Len(rStr) = 0 Then
                If NEXT_COLUMN_ON_FIRST_BLANK Then Exit For
            Else
                If Not dict.Exists(rStr) Then dict(rStr) = c
            End If
        Next r
    Next c
       
    Set LocationsToDictionary = dict

End Function

Excel公式(Microsoft365)

=LET(dlData,B2:B11,slData,'Database Names'!B1:C4,sfcIndex,2,Er,"",
    sl,TOCOL(IF(slData="","",slData),,1),lm,XMATCH(dlData,sl),
    dr,IFERROR(INT((lm-1)/ROWS(slData))+sfcIndex,Er),
dr)


或者是

=LET(dlData,B2:B11,slData,'Database Names'!B1:C4,sfcIndex,2,Er,"",
    sl,TOCOL(IF(slData="","",slData),,1),
    sr,INT((SEQUENCE(ROWS(sl))-1)/ROWS(slData)),
    dr,IFERROR(XLOOKUP(dlData,sl,sr)+sfcIndex,Er),
dr)

ajsxfq5m

ajsxfq5m2#

此解决方案使用Scripting.Dictionary来存储要查找的城市代码。除此之外,它遵循与OP使用的大致相同的结构和名称。

'// ALWAYS use option explicit
    Option Explicit
    
        '// Declare the variables to be used
        Dim columnLocationList As Range
        Dim columnLocations As Range
        Dim locations As Range
        
        '// Lookup dictionary for location -> column number
        Dim dictLocations As Scripting.Dictionary
        
    Public Sub GetCityColumnNumbers()
    
        Debug.Print "Start", Now

        '// Load the dictionary with city -> column lookups
        loadDictLocations
        
        '// Establish the list of cities
        With Sheets("Billings").Range("b1")
            Set columnLocationList = Range(.Cells(2), .End(xlDown))
            columnLocationList.Offset(0, 1).ClearContents
            columnLocationList.Style = "Normal"
        End With
        
        '// Process all the cities
        For Each columnLocations In columnLocationList
            With columnLocations
                If dictLocations.Exists(.Value) Then
                    .Offset(0, 1).Value = dictLocations.Item(.Value)
                Else
                    '// Highlight entries not found
                    .Offset(0, 1).ClearContents
                    .Style = "Bad"
                End If
            End With
        Next columnLocations
        
        
        Debug.Print "End", Now
        
    End Sub
    
    
    Public Sub loadDictLocations()
        
        Set dictLocations = New Scripting.Dictionary
        For Each locations In Sheets("Database Names").UsedRange
            Select Case True
            '// Ignore empty, blank or duplicate cells
            Case Len(locations.Value) = 0
            Case dictLocations.Exists(locations.Value)
                '// Highlight duplicate city code
                locations.Style = "Bad"
            Case Else
                dictLocations.Add locations.Value, locations.Column
            End Select
        Next locations

        Debug.Print "Dictionary loaded"
        
    End Sub

字符串

相关问题