2017 年 7 月 6 日的原始答案可能适用于上述数据集,但如果 Table2 中的值的结束日期等于关联 Table1 记录的开始日期(在这种情况下,一天将从决赛桌中省略)。我相信我已经通过在第一个 IF 语句中添加“=”来解决这个问题。还注意到粘贴值时有两个“maxoftwo”堆叠在一起,不知道为什么 - 代码似乎只用 1 就可以正常工作。
很长一段时间以来,我一直在寻求帮助来实现这一目标,而这个主题是我迄今为止找到的唯一答案。如果其他人注意到错误或有更好的方法来增强它,请告诉。谢谢
Option Explicit
Sub TableMerge()
Dim i As Integer
Dim j As Integer
Dim insert_row As Integer
Dim prev_FINISH As Date
Dim Table_1 As ListObject
Dim Table_2 As ListObject
insert_row = 2
prev_FINISH = CDate("01/01/1900")
Set Table_1 = ActiveSheet.ListObjects("Table1")
Set Table_2 = ActiveSheet.ListObjects("Table2")
For i = 1 To Table_2.ListRows.Count
For j = 1 To Table_1.ListRows.Count
' assumes the headers are in place, using range L:R for Table3
If (Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("REG").Index) = Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("REG").Index)) And (Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Finish").Index) >= Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Start").Index)) And (Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("sTART").Index) <= Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Finish").Index)) Then
If (prev_FINISH = CDate("01/01/1900") And (Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Start").Index) <= Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Finish").Index))) Or (prev_FINISH >= Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Start").Index)) Or (Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Finish").Index) >= Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Start").Index)) Then
'If (prev_FINISH = CDate("01/01/1900") And (Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Start").Index) <= Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Finish").Index)) 'Or (Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Finish").Index) >= Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Finish").Index))) Then
' add new entry
ActiveSheet.Range("L" & insert_row).Value = Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("REG").Index)
ActiveSheet.Range("M" & insert_row).Value = Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Name").Index)
ActiveSheet.Range("N" & insert_row).Value = maxoftwo(Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Start").Index), Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Start").Index))
ActiveSheet.Range("O" & insert_row).Value = minoftwo(Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Finish").Index), Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Finish").Index))
ActiveSheet.Range("P" & insert_row).Value = Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("MARG").Index)
ActiveSheet.Range("Q" & insert_row).Value = Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("COST").Index)
ActiveSheet.Range("R" & insert_row).Formula = "=Q:Q/(1-P:P)"
If ActiveSheet.Range("O" & insert_row).Value <> Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Finish").Index) Then
prev_FINISH = ActiveSheet.Range("O" & insert_row).Value
Else
prev_FINISH = CDate("01/01/1900")
j = 1
insert_row = insert_row + 1
GoTo Next_i
End If
insert_row = insert_row + 1
End If
End If
Next j
prev_FINISH = CDate("01/01/1900")
Next_i:
Next i
End Sub
Function maxoftwo(date1 As Date, date2 As Date) As Date
maxoftwo = date1
If date2 > date1 Then maxoftwo = date2
End Function
Function minoftwo(date1 As Date, date2 As Date) As Date
minoftwo = date1
If date2 < date1 Then minoftwo = date2
End Function