问题描述
我正在尝试找出解决此问题的最佳方法,但我的头有些转动,我不确定是否应该使用For Each Cell
或Arrays
或{{1}进行一些比较并将整个行复制到新的工作表中。我想使用Collections
,但是我的代码仅使用column的值,但随后我必须返回并重新遍历column以查找“缺少值”并复制整个行,这似乎使部分内容无效使用数组的要点(速度/效率)。
我正在寻找有关解决此问题的最佳方法的建议,但我也会发布我的数组代码。
首先,示例数据:
Sheet1:
Sheet2:
这个想法是Sheet1是昨天的报告,而sheet2是今天的报告。
我的目标是再增加两张工作表(或一张组合工作表,但这似乎没有必要,因为我需要通过总计一列而不是A列中的值来分别对每个结果表搜索结果进行总计计算)
物品收藏夹:
A6 AV6
已删除项目:
A5 AV5
因此,基本上,它是在将sheet2与sheet1列A进行比较的过程中找到要删除的项以及添加的项。
到目前为止,我能够获得该部分,而没有行值,我真的很想知道我是否在正确地进行攻击。
IE:这将获得丢失/添加的项目。现在,我需要为每张工作表中的值获取整行,但是不确定如何,代码开始看起来又长又重复。
Arrays
解决方法
假设您想要实现以下目标:
在Sheet1
和Sheet2
中有标头(在我的情况下,我使用了Header 1
和Header 2
。
在结果表中:
-
Yesterday
列包含有关A(x)
中Sheet1
数据计数的信息。 -
Today
列包含有关A(x)
中Sheet2
数据计数的信息。
我使用了以下代码:
Option Explicit
Sub CompareData()
Dim wbk As Workbook
Dim wshYesterday As Worksheet,wshToday As Worksheet,wshResult As Worksheet
Dim i As Integer,j As Integer,k As Integer
On Error Resume Next
Set wbk = ThisWorkbook
Set wshResult = wbk.Worksheets("Result")
On Error GoTo Err_CompareData
If Not wshResult Is Nothing Then
Application.DisplayAlerts = False
wbk.Worksheets("Result").Delete
Application.DisplayAlerts = True
End If
Set wshYesterday = wbk.Worksheets("Sheet1")
Set wshToday = wbk.Worksheets("Sheet2")
Set wshResult = wbk.Worksheets.Add(After:=wshToday)
wshResult.Name = "Result"
wshResult.Range("A1") = "Header 1"
wshResult.Range("B1") = "Header 2"
wshResult.Range("C1") = "Yesterday"
wshResult.Range("D1") = "Today"
'find last entry in yesterdays data
i = wshYesterday.Range("A" & wshYesterday.Rows.Count).End(xlUp).Row
j = 2
'copy into result sheet
wshYesterday.Range("A2:B" & i).Copy wshResult.Range("A" & j)
j = j + i - 1
'find last entry in todays data and copy into result sheet
i = wshToday.Range("A" & wshToday.Rows.Count).End(xlUp).Row
wshToday.Range("A2:B" & i).Copy wshResult.Range("A" & j)
'remove duplicates
i = wshResult.Range("A" & wshResult.Rows.Count).End(xlUp).Row
wshResult.Range("A2:B" & i).RemoveDuplicates Columns:=Array(1,2),Header:=xlNo
j = 2
i = wshResult.Range("A" & wshResult.Rows.Count).End(xlUp).Row
Do While j <= i
'count values stored in column #1 in yesterdays data
k = Application.WorksheetFunction.CountIf(wshYesterday.UsedRange,wshResult.Range("A" & j))
wshResult.Range("C" & j) = k
'count todays data
k = Application.WorksheetFunction.CountIf(wshToday.UsedRange,wshResult.Range("A" & j))
wshResult.Range("D" & j) = k
j = j + 1
Loop
Exit_CompareData:
On Error Resume Next
Set wshYesterday = Nothing
Set wshToday = Nothing
Set wshResult = Nothing
Set wbk = Nothing
Exit Sub
Err_CompareData:
MsgBox Err.Description,vbExclamation,Err.Number
Resume Exit_CompareData
End Sub
随时根据您的需求进行改进。
,很难确切知道您想要什么,但是这里有一个Power Query解决方案(在Excel 2010+中可用),该解决方案创建了一个表,该表汇总了已删除和/或添加的内容。
我假设您的数据位于名为Yesterday
和Today
的表中。更改Source =
行中的表名称以匹配您的实际数据。
M代码
let
//Read in the data tables
Source = Excel.CurrentWorkbook(){[Name="Yesterday"]}[Content],Yesterday = Table.TransformColumnTypes(Source,{{"Column1",type text},{"Column2",type text}}),Source2 = Excel.CurrentWorkbook(){[Name="Today"]}[Content],Today = Table.TransformColumnTypes(Source2,/*Using the appropriate JoinKind,create two different tables for
itemsAdded and itemsRemove*/
itemsAddedTBL = Table.NestedJoin(Today,"Column1",Yesterday,"TBL",JoinKind.LeftAnti),//Remove the unneeded TBL column
itemsAdded = Table.RemoveColumns(itemsAddedTBL,"TBL"),//Add a column stating "Added"
itemsAddedLBL = Table.AddColumn(itemsAdded,"Add/Remove",each "Added",type text),//Repeat the above for removed items
itemsRemovedTBL = Table.NestedJoin(Yesterday,Today,itemsRemoved = Table.RemoveColumns(itemsRemovedTBL,itemsRemovedLBL = Table.AddColumn(itemsRemoved,each "Removed",//combine (append) the two tables into one
comb = Table.Combine({itemsAddedLBL,itemsRemovedLBL})
in
comb
,
实际上我最终使用@AceErno的注释并使用AutoFilter
来提取EntireRows
的数据,这些数据是通过使用原始问题中的代码比较数组而找到的。我不确定自己的代码是否满意,但是它可以正常工作,等我感到满意后再进行研究。