数组,匹配,sorting
我有两个数据集,每个在3个单独的列,在同一张表内。
第一个数据集包含发票数据,第二个数据集包含发票上包含的各个项目的数据。
- 第一个数据集(发票):CustomerNumber(长),InvoiceDate(date),InvoiceAmount(双)
- 第二个数据集(Items):CustomerNumber(long),ItemPurchaseDate(date),ItemCost(double)
没有唯一的标识符来关联两个数据集。
一般规则是:
- 其中CustomerNumber = X和ItemPurchaseDate <InvoiceDate的项目应与发票相关,其中CustomerNumber = X和InvoiceDate> ItemPurchaseDate,但InvoiceDate <nextInvoiceDate为同一个CustomerNumber(如果有多个发票)
(试着想象一下你试图将项目与最近的发票进行匹配的情况。)
比如像这样
因此,并非所有项目都可以与发票相关联,有时我们将无法find发票的任何项目。
我写了代码,但效率不高,因为它会遍历所有发票的所有项目。 在我的情况下,有9000个发票和260K项目。
但是为了certificate(我忽略了那些不重要的部分):
For Each InvCustNo In InvList 'look into every Invoice For Each ItemCustNo In ItemList 'look into every Item 'check if we're looking at the new client, ' if yes - reset the date holder If prevInvCustNo <> InvCustNo Then prevInvDate = 0 End If InvDate = InvCustNo.Offset(0, 1).Value 'define the InvoiceDate ItemDate = ItemCustNo.Offset(0, 1).Value 'define ItemDate If InvCustNo = ItemCustNo And InvDate > ItemDate And _ InvDate >= prevInvDate And _ prevInvDate <= ItemDate Then 'perform comparison TempSum = TempSum + ItemCustNo.Offset(0, 2) End If Next ItemCustNo prevInvDate = InvDate 'update the date-1 prevInvCustNo = InvCustNo 'update the client-1 InvCustNo.Offset(0, 7).Value = TempSum 'print values TempSum = 0 'reset sum Next InvCustNo
上面的代码应该做的工作,但不是我有数据量,主要有两个原因:
- 它将通过9.000×260.000行= 23.4亿次操作
- 它会一次写入9000个结果
想到两个问题
- 我可以一口气写出所有的结果吗? (arrays?)
- 我可以以某种方式限制我的匹配,所以我不做23.4亿次操作(我想用sorting我可以)
任何想法和例子(我可以用作出发点)将是非常有帮助的。
我有一个非vba的解决scheme,我认为可能会为你工作。
鉴于截图中的数据(这反映了你的例子)
确保列A:C中的数据仅进行sorting
- A到Z由CustomerNumber
- 然后通过InvoiceDate最新到最旧
然后将下面的公式放在G1中(并向下拖动):
=IF(E2>MAX(IF(A:A=D2,B:B)),"No Invoice Yet",INDEX(B:B,(MATCH(E2,IF(A:A=D2,B:B),-1))))
作为数组 (按Ctrl + Shft + Enter)而不是Enter。
该公式的工作原理如下
- 将ItemDate与给定客户编号的Max InvoiceDate进行比较。 如果ItemDate比最新发票date更新,则返回“尚未开具发票”
- 否则,它会查找与ItemDate最接近的InvoiceDate(请考虑ItemDate后的下一个可能的InvoiceDate),然后返回该date。