【发布时间】:2016-05-24 01:48:18
【问题描述】:
我正在尝试比较两个工作表,它们都有我想要比较的“EMAIL”列。一列包含已发送的电子邮件,另一列包含人们实际点击的电子邮件。
我已将两列定义为数组,EmailList 和 ClickthroughsList,并且对于 EmailList 数组中的每个位置,我都有一个 If 循环循环通过 ClickthroughList 直到找到匹配项:
For i = 1 To lRow
EmailList(i) = ThisWorkbook.Sheets(2).Cells(i, col).Value
Sheets(7).Cells(i, 1).Value = EmailList(i)
If i = 1 Then
Sheets(7).Cells(i, 2).Value = "Sent"
Sheets(7).Cells(i, 5).Value = "Unique Clickthroughs"
Else
Sheets(7).Cells(i, 2).Value = 1
For bi = 1 To bRow
If EmailList(i) = ClickthroughsList(bi) Then
Sheets(7).Cells(i, 5).Value = 1
End If
Next bi
End If
Next i
如果找到匹配项,我希望它在 Sheets(7) 上显示“1”,如上所述。这意味着该特定电子邮件已被点击。
当数组为 700k+ 行或以上时,对于两个数组,此代码需要几个小时才能运行。
有人建议我可以先进行排序,然后再进行二进制搜索。但是,我仍然需要数组在 EmailList 中的位置,以便我可以在它旁边放一个“1”(并且该行将包含更多特定于该电子邮件的信息)。
想到的是定义一个新的排序数组,同时保留旧数组,并且当我在新排序数组中找到匹配项时,将其匹配回旧数组以知道位置?
Option Explicit
Private wsSent As Worksheet
Private aCell As Range, Rng As Range
Private col As Long, lRow As Long
Private colName As String
Private i As Long
Private EmailList() As String
Private wsClickthroughs As Worksheet
Private bCell As Range, bRng As Range
Private bcol As Long, bRow As Long
Private bcolName As String
Private bi As Long
Private ClickthroughsList() As String
Sub EmailArrayClickthroughs()
Application.ScreenUpdating = False
GetClickthroughsArray
'~~> Change this to the relevant sheet
Set wsSent = ThisWorkbook.Sheets(2)
With wsSent
Set aCell = .Range("A1:DZ1").Find(What:="EMAIL", LookIn:=xlValues, LookAt:=xlWhole, _
MatchCase:=False, SearchFormat:=False)
'~~> If Found
If Not aCell Is Nothing Then
col = aCell.Column
colName = Split(.Cells(, col).Address, "$")(1)
lRow = .Range(colName & .Rows.Count).End(xlUp).Row
'~~> This is your range
Set Rng = .Range(colName & "2:" & colName & lRow)
Else
MsgBox "EMAIL (Clickthroughs) Not Found"
End If
End With
ReDim EmailList(lRow)
For i = 1 To lRow
EmailList(i) = ThisWorkbook.Sheets(2).Cells(i, col).Value
Sheets(7).Cells(i, 1).Value = EmailList(i)
If i = 1 Then
Sheets(7).Cells(i, 2).Value = "Sent"
Sheets(7).Cells(i, 5).Value = "Unique Clickthroughs"
Else
Sheets(7).Cells(i, 2).Value = 1
For bi = 1 To bRow
If EmailList(i) = ClickthroughsList(bi) Then
Sheets(7).Cells(i, 5).Value = 1
End If
Next bi
End If
Next i
Debug.Print Rng.Address
Application.ScreenUpdating = True
End Sub
Sub GetClickthroughsArray()
'~~> Change this to the relevant sheet
Set wsClickthroughs = ThisWorkbook.Sheets(5)
With wsClickthroughs
Set bCell = .Range("A1:DZ1").Find(What:="EMAIL", LookIn:=xlValues, LookAt:=xlWhole, _
MatchCase:=False, SearchFormat:=False)
'~~> If Found
If Not bCell Is Nothing Then
bcol = bCell.Column
bcolName = Split(.Cells(, bcol).Address, "$")(1)
bRow = .Range(bcolName & .Rows.Count).End(xlUp).Row
'~~> This is your range
Set bRng = .Range(bcolName & "2:" & bcolName & bRow)
Else
MsgBox "EMAIL (opens) Not Found"
End If
End With
Debug.Print bRng.Address
ReDim ClickthroughsList(bRow)
For bi = 1 To bRow
ClickthroughsList(bi) = ThisWorkbook.Sheets(5).Cells(bi, bcol).Value
Next bi
End Sub
【问题讨论】:
标签: arrays excel vba sorting binary