Excel 合并日期范圍的兩個重疊表
Excel 合并日期范圍的兩個重疊表,excel,vba,excel-2010,Excel,Vba,Excel 2010,我試圖在Excel中組合兩個具有日期范圍的表我的酒店有一定的季節性定價,我的套餐有其他季節性利潤,我需要將兩者的日期括號結合起來我可以在VBA中計算出所有的利潤/定價。之所以包含在這里excel里日期加減法,是因為在其他情況下,數據在某些情況下看起來是相同的,即使不是。但我連開始組合日期都沒有運氣這是主表;通過連接兩個表/范圍創建的任何日期都應包含在這些日期中:我需要將此類區域數據與特定屬性數據合并:當我把它們結合起來時,它需要看起來像這樣:我可以輕松地將數據轉儲到SQL中,但我需要公司中任何人都可
我試圖在Excel中組合兩個具有日期范圍的表
我的酒店有一定的季節性定價,我的套餐有其他季節性利潤,我需要將兩者的日期括號結合起來
我可以在VBA中計算出所有的利潤/定價。之所以包含在這里,是因為在其他情況下,數據在某些情況下看起來是相同的,即使不是。但我連開始組合日期都沒有運氣
這是主表;通過連接兩個表/范圍創建的任何日期都應包含在這些日期中:
我需要將此類區域數據與特定屬性數據合并:
當我把它們結合起來時,它需要看起來像這樣:
我可以輕松地將數據轉儲到SQL中,但我需要公司中任何人都可以復制的東西,比如Excel電子表格
我嘗試過各種配方方案——先做這個excel里日期加減法,然后做那個,然后做其他事情。我嘗試過使用power query進行交叉連接,然后嘗試消除我不想要的日期。這些都不管用
我從gitgo那里知道它想在VBA中完成,而我嘗試的其他一切都是拖延戰術。問題是,我似乎連必要的邏輯都繞不過去。對于這種邏輯,我有不止一個用例
所有屬性日期都必須存在于主表中(在一個范圍內)。屬性的日期可能根本不存在于主范圍中。
我確信有更有效的方法,但下面是我如何使用命名表來處理數據和輸出范圍。您應該能夠修改它以適應。邏輯比我想象的要復雜一些。代碼下面是我的測試輸出的屏幕抓取,它與您的表相匹配
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(maxoftwo(Table_1.DataBodyRange.Cells(j, Table_1.ListColumns("Start").Index), Table_2.DataBodyRange.Cells(i, Table_2.ListColumns("Start").Index)), prev_FINISH)
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
選項顯式
子表合并()
作為整數的Dim i
作為整數的Dim j
Dim insert_行為整數
Dim上一個完成日期
將表_1設置為列表對象
將表_2設置為列表對象
插入第行=2
上一次完成=日期(“1900年1月1日”)
Set Table_1=ActiveSheet.ListObjects(“表1”)
Set Table_2=ActiveSheet.ListObjects(“表2”)
對于表_2.ListRows.Count的i=1
對于表_1.ListRows.Count中的j=1
'假定標題已就位,使用表3的范圍L:R
如果(表2.DataBodyRange.Cells(i,表2.ListColumns(“REG”).Index)=表1.DataBodyRange.Cells(j,表1.ListColumns(“REG”).Index))和(表2.DataBodyRange.Cells(i,表2.ListColumns(“Finish”).Index)>表1.DataBodyRange.Cells(j,表1.ListColumns(“Start”).Index”)和(表2.DataBodyRange.Cells(i,表2.ListColumns(“Start”).Index)=Table_1.DataBodyRange.Cells(j,Table_1.ListColumns(“Start”).Index)),則
'如果(prev_FINISH=CDate(“01/01/1900”)和(Table_2.DataBodyRange.Cells(i,Table_2.ListColumns(“Start”).Index)日期1,則maxoftwo=date2

端函數
函數minoftwo(日期1為日期,日期2為日期)為日期
minoftwo=date1
如果date2
2017年7月6日的原始答案可能適用于上述數據集,但如果表2中的值的結束日期等于相關表1記錄的開始日期(在這種情況下,最終表中將省略一天),則該答案將無效。我相信我已通過添加“=”解決了該問題還注意到粘貼值時有兩個“”堆疊在一起,不知道為什么-代碼似乎只使用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
選項顯式
子表合并()
作為整數的Dim i
作為整數的Dim j
Dim insert_行為整數
Dim上一個完成日期
將表_1設置為列表對象
將表_2設置為列表對象
插入第行=2
上一次完成=日期(“1900年1月1日”)
Set Table_1=ActiveSheet.ListObjects(“表1”)
Set Table_2=ActiveSheet.ListObjects(“表2”)
對于表_2.ListRows.Count的i=1
對于表_1.ListRows.Count中的j=1
'假定標題已就位,使用表3的范圍L:R
If(表2.DataBodyRange.Cells(i,表2.ListColumns(“REG”).Index)=表1.DataBodyRange.Cells(j,表1.ListColumns(“REG”).Index))和(表2.DataBodyRange.Cells(i,表2.ListColumns(“Finish”).Index)>=表1.DataBodyRange.Cells(j,表1.ListColumns(“Start”).Index”)和(表2.DataBodyRange.Cells(i,表2.ListColumns(“Start”).Index)=表1.DataBodyRange.Cells(j,表1.ListColumns(“Start”).Index)),然后
'如果(prev_FINISH=CDate(“01/01/1900”)和(Table_2.DataBodyRange.Cells(i,Table_2.ListColumns(“Start”).Index)日期1,則maxoftwo=date2
端函數
函數minoftwo(日期1為日期,日期2為日期)為日期
minoftwo=date1
如果date2
已經嘗試了萬能的?我需要比第一組和第二組的計數更多的記錄。括號的創建取決于集合的相交位置。這就是為什么最后一組中有更多記錄(需要)設置比前兩個的總和大。在這種情況下沒有幫助。要清楚,第一個設置中的記錄數(區域/邊距)將在70到100之間。房地產記錄數(價格按日期變化)可能在1000或更多。5分鐘的時間不足以鍵入一個coher