如何统计机场设施内ULD停留时长并修正VBA输出排序问题
ULD停留时长统计需求及实现逻辑参考
需求背景
我是某国际机场的主力地勤工作人员,需要统计ULD在机场设施内的停留时长。
现有数据集结构
| Airline Code | Flight | Flight Act. DateTime | Type | Number | Owner | Flight Direction |
|---|---|---|---|---|---|---|
| AB | AB1234 | 10-10-2021 | ABC | 12345 | AB | Outbound |
| AB | AB1234 | 13-10-2021 | ABC | 12345 | AB | Inbound |
| AB | AB1234 | 15-10-2021 | ABC | 12345 | AB | Outbound |
| CD | CD3456 | 9-10-2021 | ACE | 54321 | CD | Inbound |
| CD | CD3456 | 14-10-2021 | ACE | 54321 | CD | Outbound |
| CD | CD3456 | 15-10-2021 | ACE | 54321 | CD | Inbound |
现有VBA代码
Sub MultipleSearch() Sheet9.Activate Dim ULD As String: Dim ULD_Procedure As Variant Dim i As Long Dim rgSearch As Range Dim ILastCol As Long Dim cell As Range Dim ColumnResult As Variant Dim Result As Variant Dim DateFlight As Variant With Sheet9 LastRow = WorksheetFunction.CountA(Range("B:B")) For i = 1 To LastRow ULD = Cells(i, 2).Value Sheet3.Activate ' Get search range Set rgSearch = Range("I:I") Set cell = rgSearch.Find(ULD) ' Store first cell address Dim firstCellAddress As Variant firstCellAddress = cell.Address ' Find all cells containing set ULD number Do Sheet9.Activate ILastCol = (1 + Cells(i, Columns.Count).End(xlToLeft).Column) 'Adjust CellAdres to only give me the correct Row number RowResult = cell.Address Result = Replace(RowResult, "$I$", "") Sheet3.Activate DateFlight = Cells(Result, 4).Value Sheet9.Activate Cells(i, ILastCol).Value = DateFlight Set cell = rgSearch.FindNext(cell) Loop While firstCellAddress <> cell.Address Next i If cell Is Nothing Then Debug.Print "Not found" End If End With End Sub
当前问题
这段代码可以获取ULD进入或离开系统的日期,结合基础Excel公式可以计算ULD的停留间隔,但输出的日期顺序不符合要求:
- 并非所有ULD的首条记录都是Inbound(进港),部分ULD初始就存放于机场,首条记录为Outbound(出港)
- 部分ULD存在出港或进港登记缺失的情况,并不遵循进港-出港-进港-出港的固定顺序
预期输出结构
| ULD Number | First entry | Inbound | Outbound | Inbound | Outbound | Inbound | Outbound | Inbound | Outbound |
|---|---|---|---|---|---|---|---|---|---|
| 12345 | Outbound | 10-10-2021 | 11-10-2021 | 12-10-2021 | 14-10-2021 | 17-10-2021 | 19-10-2021 | ||
| 12345 | Inbound | 08-10-2021 | 08-10-2021 | 12-10-2021 | 15-10-2021 | 16-10-2021 | 17-10-2021 | 20-10-2021 |
实际输出结构
| ULD Number | First entry | Inbound | Outbound | Inbound | Outbound | Inbound | Outbound | Inbound | Outbound |
|---|---|---|---|---|---|---|---|---|---|
| 12345 | Outbound | 10-10-2021 | 11-10-2021 | 12-10-2021 | 14-10-2021 | 17-10-2021 | 19-10-2021 | ||
| 12345 | Inbound | 08-10-2021 | 08-10-2021 | 12-10-2021 | 15-10-2021 | 16-10-2021 | 17-10-2021 | 20-10-2021 |
实现逻辑参考
VBA代码逻辑框架
- 原始数据预处理:先将所有原始记录按ULD编号分组,每组内按照
Flight Act. DateTime升序排序,保证时间顺序正确。 - 单ULD记录遍历填充:
- 读取该ULD排序后的第一条记录的进出类型,填入结果表
First entry字段 - 初始化两个列指针:
in_ptr初始指向第一个Inbound列的列号,out_ptr初始指向第一个Outbound列的列号 - 按时间顺序遍历该ULD的所有记录:
- 若当前记录为Inbound:将日期填入当前行
in_ptr对应的单元格,in_ptr = in_ptr + 2(指向下一个Inbound列) - 若当前记录为Outbound:将日期填入当前行
out_ptr对应的单元格,out_ptr = out_ptr + 2(指向下一个Outbound列)
- 若当前记录为Inbound:将日期填入当前行
- 读取该ULD排序后的第一条记录的进出类型,填入结果表
- 遍历完成后未填充的单元格自动留空即可,无需额外处理。
公式实现方案(适合数据量小于1万行的场景)
Excel 365版本可以直接用FILTER+SORT+INDEX组合实现:
- 假设原始数据Sheet3中I列是ULD编号,D列是日期,G列是进出类型;结果表A列是ULD编号,C列为第一个Inbound列,D列为第一个Outbound列
- 对应第N个Inbound列的单元格公式:
=IFERROR(INDEX(SORT(FILTER(Sheet3!$D:$D,(Sheet3!$I:$I=$A2)*(Sheet3!$G:$G="Inbound"))), (COLUMN()-2)/2),"") - 对应第N个Outbound列的单元格公式:
=IFERROR(INDEX(SORT(FILTER(Sheet3!$D:$D,(Sheet3!$I:$I=$A2)*(Sheet3!$G:$G="Outbound"))), (COLUMN()-3)/2),"")
低版本Excel可以将上述逻辑替换为SMALL+IF数组公式实现。
内容的提问来源于stack exchange,提问作者Corn026
相关产品推荐
相关产品推荐

