excel - 没有为 If/Else 语句 + 连接产生预期结果
问题描述
我正在使用 3 个不同的表(工作表),它们都在同一个工作簿中。第一个工作表称为“转化事件”,它包含转化事件和日期。“Conv Event”中的数据如下所示:
第二个工作表称为“生态事件”,它包含名称和转换事件。“生态事件”中的数据如下所示:
第三个工作表称为“APM MASTER”,它包含名称和 EC 事件。名称在 G 列中,EC 事件在此工作表的 H 列中。
我试图用下面的代码完成的是 1)在“Eco Event”表中查找与“APM Master”表中的名称匹配/具有相同名称的名称
2)从这些匹配项(即,您在“APM Master”表和“Eco Event”表中具有相同名称)在“Eco Event”表中,并将事件与“Conv Event”表中的相同事件匹配 3)连接将“Conv Event”表中的转换事件和日期放入“APM Master”表的 H 列,其中“APM Master”表中 G 列中的名称与“Eco Event”表中 A 列中的名称匹配。
APM Master 表应如下所示:
代码运行时没有错误,但是,当我运行它时,“APM Master”工作表的 H 列中没有显示任何内容。有人可以帮我弄清楚为什么代码没有产生预期的结果,只是空白单元格吗?
Sub EarlyConversion()
With Worksheets("APM MASTER")
Dim i As Long
Dim LastRow As Long
Dim rng1 As Range
Dim rng2 As Range
Dim ws As Worksheet
Set rng1 = Worksheets("Eco Event").Range("A2:A387")
Set rng2 = Worksheets("Eco Event").Range("B2:B387")
Set ws = Worksheets("Conv Event")
LastRow = .Range("H" & Rows.Count).End(xlUp).Row
For i = 2 To LastRow
If Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A6")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A7")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A8")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A9")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A10")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A11")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A12")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A13")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A14")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A15")) > 0 Then
.Range("H" & i) = ws.Range("A6").Value & ": " &
ws.Range("B6") & ", " & ws.Range("A7").Value & ": " &
ws.Range("B7") & ", " & ws.Range("A8").Value & ": " &
ws.Range("B8") & ", " & ws.Range("A9").Value & ": " &
ws.Range("B9") & ", " & ws.Range("A10").Value & ": " &
ws.Range("B10") & ", " & ws.Range("A11").Value & ": " &
ws.Range("B11") & ", " & ws.Range("A12").Value & ": " &
ws.Range("B12") & ", " & ws.Range("A13").Value & ": " &
ws.Range("B13") & ", " & ws.Range("A14").Value & ": " &
ws.Range("B14") & ", " & ws.Range("A15").Value & ": " &
ws.Range("B15")
ElseIf Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A6")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A7")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A8")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A9")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A10")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A11")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A12")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A13")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A14")) > 0 Then
.Range("H" & i) = ws.Range("A6").Value & ": " &
ws.Range("B6") & ", " & ws.Range("A7").Value & ": " &
ws.Range("B7") & ", " & ws.Range("A8").Value & ": " &
ws.Range("B8") & ", " & ws.Range("A9").Value & ": " &
ws.Range("B9") & ", " & ws.Range("A10").Value & ": " &
ws.Range("B10") & ", " & ws.Range("A11").Value & ": " &
ws.Range("B11") & ", " & ws.Range("A12").Value & ": " &
ws.Range("B12") & ", " & ws.Range("A13").Value & ": " &
ws.Range("B13") & ", " & ws.Range("A14").Value & ": " &
ws.Range("B14")
ElseIf Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A6")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A7")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A8")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A9")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A10")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A11")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A12")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A13")) > 0 Then
.Range("H" & i) = ws.Range("A6").Value & ": " &
ws.Range("B6") & ", " & ws.Range("A7").Value & ": " &
ws.Range("B7") & ", " & ws.Range("A8").Value & ": " &
ws.Range("B8") & ", " & ws.Range("A9").Value & ": " &
ws.Range("B9") & ", " & ws.Range("A10").Value & ": " &
ws.Range("B10") & ", " & ws.Range("A11").Value & ": " &
ws.Range("B11") & ", " & ws.Range("A12").Value & ": " &
ws.Range("B12") & ", " & ws.Range("A13").Value & ": " &
ws.Range("B13")
ElseIf Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A6")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A7")) > 0 And
Application.CountIfs(rng1,
Worksheets("APM MASTER").Range("G" & i), rng2,
ws.Range("A8")) > 0 Then
.Range("H" & i) = ws.Range("A6").Value & ": " &
ws.Range("B6") & ", " & ws.Range("A7").Value & ": " &
ws.Range("B7") & ", " & ws.Range("A8").Value & ": " &
ws.Range("B8")
...
End If
Next i
End With
End Sub
解决方案
不寻常的数据转换
- 它的不寻常之处在于它依赖于标题和工作表名称,而不是像通常那样依赖于行和列。因此,在您使用它之前,请仔细检查所有前 9 个常量。它们必须与您的工作簿中的相同,否则程序将失败。当然,这些词(用于标题)中的任何一个都不能单独使用在实际标题之前(上面的行和前面的同一行)的单元格中。
- 根据需要更改分隔符的第 10 个和第 11 个常量。
- 所有 4 个程序都必须复制到一个标准
module
(例如Module1
)。您运行的第一个过程是 asub
调用(使用)其他 3functions
。 - 我以这种方式编写代码是因为您以如此罕见的精确度提出了您的问题,以至于我无法抗拒。我希望你会发现它有用。
编码
Option Explicit
Sub test()
' Constants
Const SheetCE As String = "Conv Event"
Const SheetEE As String = "Eco Event"
Const SheetAM As String = "APM Master"
Const hCE1 As String = "Conversion Event"
Const hCE2 As String = "Date"
Const hEE1 As String = "Name"
Const hEE2 As String = "Conversion Event"
Const NameHeader As String = "Name"
Const EventsHeader As String = "EC Events"
Const NameSeparator As String = ": "
Const EventSeparator As String = ", "
'Other Variables
Dim wsCE As Worksheet, wsEE As Worksheet, wsAM As Worksheet, rng As Range
Dim CE_Event, CE_Date, EE_Name, EE_Event, AM_Name, AM_Events
Dim CurrName As String, CurrEvent As String, CurrResult As String
Dim i As Long, j As Long, k As Long
' Define worksheets.
Set wsCE = ThisWorkbook.Worksheets(SheetCE)
Set wsEE = ThisWorkbook.Worksheets(SheetEE)
Set wsAM = ThisWorkbook.Worksheets(SheetAM)
' Write Source Columns to Source Arrays.
CE_Event = getColumnBelowHeader(wsCE, hCE1)
CE_Date = getColumnBelowHeader(wsCE, hCE2)
EE_Name = getColumnBelowHeader(wsEE, hEE1)
EE_Event = getColumnBelowHeader(wsEE, hEE2)
' Write from Source Arrays to Target Array.
AM_Name = getUniqueColumn(EE_Name)
ReDim AM_Events(1 To UBound(AM_Name), 1 To 1)
For i = 1 To UBound(AM_Name)
CurrName = AM_Name(i, 1)
For j = 1 To UBound(EE_Name)
If EE_Name(j, 1) = CurrName Then
CurrEvent = EE_Event(j, 1)
If Not IsError(Application.Match(CurrEvent, CE_Event, 0)) Then
GoSub writeAM_Events
Else
MsgBox CurrEvent & " not found."
End If
End If
Next j
Next i
' Write to Target Worksheet.
Set rng = getHeaderCell(wsAM, NameHeader)
If Not rng Is Nothing Then _
rng.Offset(1).Resize(UBound(AM_Name)) = AM_Name
Set rng = getHeaderCell(wsAM, EventsHeader)
If Not rng Is Nothing Then _
rng.Offset(1).Resize(UBound(AM_Events)) = AM_Events
' Inform user.
MsgBox "Operation finshed successfully.", vbInformation
' Debug.print
For i = 1 To UBound(AM_Name)
Debug.Print AM_Name(i, 1), AM_Events(i, 1)
Next i
GoTo exitProcedure
writeAM_Events:
k = Application.Match(CurrEvent, CE_Event, 0)
CurrResult = CE_Event(k, 1) & NameSeparator & CE_Date(k, 1)
If AM_Events(i, 1) <> "" Then _
CurrResult = AM_Events(i, 1) & EventSeparator & CurrResult
AM_Events(i, 1) = CurrResult
Return
exitProcedure:
End Sub
' Writes the values of the non-empty column range below the first found
' specified string to a 2D one-based one-column array.
Function getColumnBelowHeader(Sheet As Worksheet, Header As String) As Variant
Dim rng As Range, FirstCell As Range, LastCell As Range
Set rng = getHeaderCell(Sheet, Header)
With Sheet
Set rng = .Cells.Find(What:=Header, _
After:=.Cells(.Rows.Count, .Columns.Count), _
LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows)
If rng Is Nothing Then GoTo exitError
If rng.Row = .Rows.Count Then GoTo exitError
Set FirstCell = rng.Offset(1)
Set rng = .Range(FirstCell, .Cells(.Rows.Count, FirstCell.Column))
Set LastCell = rng.Find(What:="*", _
LookIn:=xlFormulas, SearchDirection:=xlPrevious)
If LastCell Is Nothing Then GoTo exitError
getColumnBelowHeader = .Range(FirstCell, LastCell)
End With
GoTo exitProcedure
exitError:
getColumnBelowHeader = Array()
exitProcedure:
End Function
' Returns the first cell range where a specified string was found.
Function getHeaderCell(Sheet As Worksheet, Header As String) As Range
Dim rng As Range
With Sheet
Set getHeaderCell = Sheet.Cells.Find(What:=Header, _
After:=Sheet.Cells(.Rows.Count, .Columns.Count), _
LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows)
End With
End Function
' Creates a 2D one-based one-column array with unique values of another
' 2D one-base one-column array (usually data from column in worksheet).
Function getUniqueColumn(ColumnArray As Variant) As Variant
Dim dict As Object, Key As Variant, TargetArray As Variant, i As Long
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(ColumnArray)
If Not IsMissing(ColumnArray(i, 1)) Then
dict(ColumnArray(i, 1)) = Empty
End If
Next i
ReDim TargetArray(1 To dict.Count, 1 To 1): i = 1
For Each Key In dict.Keys
TargetArray(i, 1) = Key
i = i + 1
Next Key
getUniqueColumn = TargetArray
End Function
推荐阅读
- wordpress - WordPress:如何使用 WooCommerce 插件从特定类别中获取所有品牌产品?
- c - IRremote.h“没有这样的文件或目录”
- javascript - Node.js 中的承诺链
- java - 使用 Mockito 验证多个方法调用的顺序
- python-3.x - boto3 方法 generate_presigned_url() 中的行为不一致,有时 SignatureDoesNotMatch
- jquery - 每当触发 AJAX 请求时页面变为空白
- sql - 有没有办法将 SELECT、FROM、GROUPBY 语句的结果转换为新表?
- google-apps-script - 如何将匹配搜索条件的线程的内容提取到 Google 工作表中?
- python-3.x - 为什么只有一位整数输入有效,而不是两位整数?
- c++ - Arduino Uno 串行监视器不会打印整个输出;怎么修?