我有一种结合两张数据的工作方法;然而,它比我希望的要慢一点。我想知道是否有人知道更快的方法来组合数据。
我分别比较了大约700和400行的两张纸。表1中的数据包含唯一的飞机航班号以及该航班的每个航段的单独行(一个任务号可以具有5或6个“航程”的航段,每个航段都在其自己的行上)。表2包含相同的任务编号,但告诉我有多少乘客和多少货物(称为“升降机”),如果有的话,在某些腿上。本表中仅列出了具有“升降机”的腿。有些升降机可以在船上停留多条腿。没有显示空腿。
我需要将两者结合起来,以便将表2中的乘客和货物信息添加到表1中正确的任务中。这使我能够完整,详细地了解该任务。我将这些数据显示在我在Excel中创建的图形地图上。
以下是我目前使用的代码:
Sub combineDataTest()
Application.ScreenUpdating = False
Dim i As Long, j As Long
Dim lastRow As Long, lastRow2 As Long
Dim ws2 As Worksheet, ws3 As Worksheet
Set ws2 = ThisWorkbook.Sheets("Full Missions")
Set ws3 = ThisWorkbook.Sheets("Passengers and Cargo")
ws2.Columns("H:J").Cells.Clear
lastRow = findLastRow("Passengers and Cargo") 'calls a function that returns the last row
lastRow2 = findLastRow("Full Missions") 'calls a function that returns the last row
' Add column names on mission sheet
ws2.Range("H1").Value = "LIFT CODE"
ws2.Range("I1").Value = "LIFT PASSENGERS"
ws2.Range("J1").Value = "LIFT CARGO"
For i = 2 To lastRow
For j = 2 To lastRow2
' If the mission numbers match
If ws3.Range("A" & i).Value = Left(ws2.Range("D" & j).Value, 9) And _
ws2.Range("E" & j).Value >= ws3.Range("C" & i).Value And _
ws2.Range("E" & j).Value <= ws3.Range("D" & i).Value - 1 Then
If ws2.Range("H" & j).Value = "" Then
ws2.Range("H" & j).Value = ws3.Range("Q" & i).Value
ws2.Range("I" & j).Value = ws3.Range("O" & i).Value
ws2.Range("J" & j).Value = ws3.Range("P" & i).Value
Else
ws2.Range("H" & j).Value = ws2.Range("H" & j).Value & ", " & ws3.Range("Q" & i).Value
ws2.Range("I" & j).Value = ws2.Range("I" & j).Value + ws3.Range("O" & i).Value
ws2.Range("J" & j).Value = ws2.Range("J" & j).Value + ws3.Range("P" & i).Value
End If
End If
Next j
Next i
如果您对如何运行代码有更好的了解,我将非常感激。我不确定通过数组运行它会更快,或者它是否会像它将获得的那样好。
编辑:这是一些示例数据表。这不是真实的数据。
完全使命:
ICAO | LONG | LAT | MISSION_ACFT |LEG| ARRIVAL | DEPART
-------------------------------------------------------------------------------
KRIC | -77.32 | 37.5 | ABC155894_C26 | 1 | 20-JUN-2015 1101 | 20-JUN-2015 1101
KGTR | -88.58 | 33.43 | ABC155894_C26 | 2 | 20-JUN-2015 1433 | 20-JUN-2015 1348
KNGU | -76.28 | 36.93 | ABC155894_C26 | 3 | 20-JUN-2015 1800 | 20-JUN-2015 1715
KCLT | -80.93 | 35.2 | ABC155894_C26 | 4 | 20-JUN-2015 1940 | 20-JUN-2015 1910
KGSO | -79.93 | 36.1 | ABC155894_C26 | 5 | 20-JUN-2015 2035 | 20-JUN-2015 2005
KRDU | -78.78 | 35.87 | ABC155894_C26 | 6 | 20-JUN-2015 2130 | 20-JUN-2015 2100
KNGU | -76.28 | 36.93 | ABC155894_C26 | 7 | 20-JUN-2015 2235 | 20-JUN-2015 2205
KRIC | -77.32 | 37.5 | ABC155894_C26 | 8 | 20-JUN-2015 2300 | 20-JUN-2015 2300
KRIC | -77.32 | 37.5 | ABC156469_C26 | 1 | 26-JUN-2015 1101 | 26-JUN-2015 1101
KVQQ | -81.87 | 30.22 | ABC156469_C26 | 2 | 26-JUN-2015 1408 | 26-JUN-2015 1323
KHST | -80.38 | 25.48 | ABC156469_C26 | 3 | 26-JUN-2015 1616 | 26-JUN-2015 1531
KMCF | -82.52 | 27.83 | ABC156469_C26 | 4 | 26-JUN-2015 1748 | 26-JUN-2015 1703
KVQQ | -81.87 | 30.22 | ABC156469_C26 | 5 | 26-JUN-2015 1910 | 26-JUN-2015 1825
KRIC | -77.32 | 37.5 | ABC156469_C26 | 6 | 26-JUN-2015 2121 | 26-JUN-2015 2121
KRIC | -77.32 | 37.5 | ABC156733_C26 | 1 | 27-JUN-2015 1533 | 27-JUN-2015 1533
KDAA | -77.17 | 38.7 | ABC156733_C26 | 2 | 27-JUN-2015 1643 | 27-JUN-2015 1558
KCHS | -80.03 | 32.88 | ABC156733_C26 | 3 | 27-JUN-2015 1916 | 27-JUN-2015 1831
KRIC | -77.32 | 37.5 | ABC156733_C26 | 4 | 27-JUN-2015 2038 | 27-JUN-2015 2038
KRIC | -77.32 | 37.5 | ABC156773_C26 | 1 | 28-JUN-2015 1113 | 28-JUN-2015 1113
KNCA | -77.43 | 34.7 | ABC156773_C26 | 2 | 28-JUN-2015 1246 | 28-JUN-2015 1201
KLSF | -84.98 | 32.32 | ABC156773_C26 | 3 | 28-JUN-2015 1526 | 28-JUN-2015 1441
乘客和货物:(为节省空间而删除了过多的数据)
MISSION | B | ONL|OFFL| E | F | G | H | I | J | K | L | M | N |PAX|CAR|LIFT ID
--------------------------------------------------------------------------------
ABC155894 | | 1 | 2 | | | | | | | | | | | 2 |100| E
ABC155894 | | 3 | 4 | | | | | | | | | | | 2 |155| A
ABC155894 | | 4 | 5 | | | | | | | | | | | 2 |155| B
ABC155894 | | 5 | 6 | | | | | | | | | | | 2 |155| C
ABC155894 | | 6 | 7 | | | | | | | | | | | 2 |155| D
ABC156469 | | 2 | 3 | | | | | | | | | | | 2 |220| A
ABC156469 | | 3 | 4 | | | | | | | | | | | 2 |220| B
ABC156469 | | 4 | 5 | | | | | | | | | | | 2 |220| C
ABC156733 | | 2 | 3 | | | | | | | | | | | 2 |0 | A
ABC156773 | | 2 | 3 | | | | | | | | | | | 2 |0 | A
答案 0 :(得分:0)
通常要快得多
根据数据的复杂程度,创建具有所需属性的用户定义对象(类),然后将这些对象收集到Collection中作为Results数组的源可能是有益的。
有关用户定义对象的详细信息,请参阅Chip Pearson's "Introduction to Classes"。
使用这种方法的一个例子,虽然只有一个数据表,但可以在Combine Rows with duplicate values, merge cells if different
的答案中找到这种方法通常至少比在工作表中来回快一个数量级。
以下是一些代码示例,可帮助您入门。检查一下速度。
重命名类模块cLegCargoAndPassengers
将工作表添加到工作簿并将其命名为Combined
Option Explicit
Private pMission As String
Private pLeg As Long
Private pMissionData As Variant
Private pPassengers As Long
Private pCargo As Long
Private pLiftCode As String
Private pLiftCodes As Collection
Private Sub Class_Initialize()
Set pLiftCodes = New Collection
End Sub
Public Property Get Mission() As String
Mission = pMission
End Property
Public Property Let Mission(Value As String)
pMission = Value
End Property
Public Property Get Leg() As Long
Leg = pLeg
End Property
Public Property Let Leg(Value As Long)
pLeg = Value
End Property
Public Property Get MissionData() As Variant
MissionData = pMissionData
End Property
Public Property Let MissionData(Value As Variant)
pMissionData = Value
End Property
Public Property Get Passengers() As Long
Passengers = pPassengers
End Property
Public Property Let Passengers(Value As Long)
pPassengers = Value
End Property
Public Property Get Cargo() As Long
Cargo = pCargo
End Property
Public Property Let Cargo(Value As Long)
pCargo = Value
End Property
Public Property Get LiftCode() As String
LiftCode = pLiftCode
End Property
Public Property Let LiftCode(Value As String)
pLiftCode = Value
End Property
Public Property Get LiftCodes() As Collection
Set LiftCodes = pLiftCodes
End Property
Function Add(Value As String)
LiftCodes.Add Value
End Function
Option Explicit
Sub CombineData()
Dim cLCP As cLegCargoAndPassengers, colLCP As Collection
Dim I As Long, J As Long, K As Long, L As Long, S As String, V() As Variant
Dim wsFM As Worksheet, wsPAC As Worksheet, wsCOMB As Worksheet
Dim vFM As Variant, vPAC As Variant, vCOMB() As Variant
Dim lFirstKey As Long, lLastKey As Long, sKeys() As String
Set wsFM = Worksheets("Full Missions")
Set wsPAC = Worksheets("Passengers and Cargo")
Set wsCOMB = Worksheets("Combined")
'read data into arrays
'could calculate the last column, and/or some of the leg columns,but I hard coded them for now
With wsFM
vFM = .Range("A1", .Cells(.Rows.Count, "A").End(xlUp)).Resize(columnsize:=7)
End With
With wsPAC
vPAC = .Range("A1", .Cells(.Rows.Count, "A").End(xlUp)).Resize(columnsize:=17)
End With
'Collect and combine the data
'First get the full missions and tease out the important data
Set colLCP = New Collection
For I = 2 To UBound(vFM, 1)
Set cLCP = New cLegCargoAndPassengers
'Get the whole row
'Could get each component separately, if needed
ReDim V(1 To UBound(vFM, 2))
For J = 1 To UBound(V)
V(J) = vFM(I, J)
Next J
With cLCP
.MissionData = V
.Mission = Trim(Left(vFM(I, 4), InStr(1, vFM(I, 4), "_") - 1))
.Leg = vFM(I, 5)
colLCP.Add Item:=cLCP, Key:=.Mission & "|" & .Leg
End With
Next I
'Now combine the Passenger and cargo data
For I = 2 To UBound(vPAC, 1)
'Generate all possible keys
'allows for possibility of passengers being on for more than two legs
lFirstKey = vPAC(I, 3)
lLastKey = vPAC(I, 4)
ReDim sKeys(1 To lLastKey - lFirstKey)
K = 0
For J = lFirstKey To lLastKey - 1
K = K + 1
'Trim may be superfluous, but trailing space present in your sample data
sKeys(K) = Trim(vPAC(I, 1)) & "|" & J
Next J
'Add the data for each leg
For K = 1 To UBound(sKeys)
With colLCP(sKeys(K))
.LiftCode = vPAC(I, 17)
.Add (.LiftCode)
.Passengers = .Passengers + vPAC(I, 15)
.Cargo = .Cargo + vPAC(I, 16)
End With
Next K
Next I
'Now Combine the data
'Row 0 for the headers
K = UBound(vFM, 2)
ReDim vCOMB(0 To colLCP.Count, 1 To K + 3)
'Populate headers
For I = 1 To K
vCOMB(0, I) = vFM(1, I)
Next I
vCOMB(0, K + 1) = "LIFT CODE"
vCOMB(0, K + 2) = "LIFT PASSENGERS"
vCOMB(0, K + 3) = "LIFT CARGO"
'Populate data
For I = 1 To colLCP.Count
With colLCP(I)
V = .MissionData
For J = 1 To UBound(V)
vCOMB(I, J) = V(J)
Next J
S = ""
For L = 1 To .LiftCodes.Count
S = S & "," & .LiftCodes(L)
Next L
S = Mid(S, 2)
vCOMB(I, K + 1) = S
vCOMB(I, K + 2) = .Passengers
vCOMB(I, K + 3) = .Cargo
End With
Next I
'Write the results
With wsCOMB.Range("A1").Resize(UBound(vCOMB, 1) + 1, UBound(vCOMB, 2))
.EntireColumn.Clear
.Value = vCOMB
With .Rows(1)
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
.EntireColumn.AutoFit
End With
End Sub