我无法完全迭代自定义对象的Excel VBA集合。我在第三个对象上收到Invalid procedure call or argument
错误。
当检查每个对象并逐行逐步执行该过程时,它对前两个对象起作用,然后在第三个对象上失败。我已经尝试单独执行代码,手动调用第三个对象实例,没有错误。
为什么程序会执行计算并正确设置前两个对象实例的属性,然后第三次失败?
我是VBA的新手 - 我错过了哪些明显的东西?
程序:
Sub calculateMaintenancePlan()
'Calculates next x maintenance cycles for a number aircraft
'Assumes the spreadsheet defines a named range containing the following columns:
'1 2 3 4 5 6
'Tail Number Current Hours Next Cycle Next Cycle DUE In Heavy Week Id Cycle Start
'6004 11265.0 4 11333.7 FALSE [Integer or -10 if not in heavy]
'debugging/utility variables
Dim temp As Variant
Dim i As Integer, j As Integer
'Assumes the spreadsheet defines a named range containing the following columns:
'Cycle ID Cycle Type Duration Text ID
'1 200 hour 1 HMT1
ReDim mx_cycles(1 To Worksheets("Matrix Inputs").Range("maintenance_cycles").Rows.Count, 1 To 3)
For i = 1 To Worksheets("Matrix Inputs").Range("maintenance_cycles").Rows.Count
mx_cycles(i, 1) = Worksheets("Matrix Inputs").Range("maintenance_cycles").Cells(i, 2)
mx_cycles(i, 2) = CInt(Worksheets("Matrix Inputs").Range("maintenance_cycles").Cells(i, 3))
mx_cycles(i, 3) = Worksheets("Matrix Inputs").Range("maintenance_cycles").Cells(i, 4)
'Debug.Print i & " : " & mx_cycles(i, 1) & " : " & mx_cycles(i, 2) & " : " & mx_cycles(i, 3)
Next i
'an array containing each aircraft tail number, assume spreadsheet
'contains named range called "aircraft"
Dim aircraft As Collection, s_Aircraft As Collection
Dim acft As c_Aircraft
Set aircraft = New Collection
Set s_Aircraft = New Collection
'Set the Collection size to the total number of aircraft on station
'and create a c_Aircraft instance representing each airframe
For i = 1 To Range("aircraft").Count
Set acft = New c_Aircraft
acft.init_aircraft Worksheets("Matrix Inputs").Range("inputs"), i, mx_cycles
aircraft.Add acft, CStr(acft.tailNumber)
Next i
'Sort the aircraft
Set s_Aircraft = sortedAircraft(aircraft)
End Sub
'Sort a Collection of c_aircraft objects
Private Function sortedAircraft(unsortedAircraft As Collection) As Collection
Set sortedAircraft = New Collection
Dim acft As c_Aircraft
Dim temp_acft As c_Aircraft
Dim i As Long, j As Long
Dim next_acft_cycle_start_week_id As Integer
Dim previous_acft As String
Dim t_tailNum
'copy the Collection to a new collection
For Each acft In unsortedAircraft
sortedAircraft.Add acft
Next acft
'Sort the aircraft
For i = 1 To sortedAircraft.Count
For j = i + 1 To sortedAircraft.Count
If sortedAircraft.Item(i).hoursToDUE > sortedAircraft.Item(j).hoursToDUE Then
Set temp_acft = sortedAircraft.Item(j)
sortedAircraft.Remove j
t_tailNum = CStr(temp_acft.tailNumber)
sortedAircraft.Add temp_acft, t_tailNum, i
End If
Next j
Next i
previous_acft = CStr(sortedAircraft.Item(1).tailNumber)
For Each acft In sortedAircraft
If acft.inHeavy = False Then
'******* FAILS here on the third item of six items in the collection
Debug.Print sortedAircraft.Item(previous_acft).weekIdCycleStart + sortedAircraft.Item(previous_acft).nextCycleDuration + 1
previous_acft = CStr(acft.tailNumber)
Else
previous_acft = CStr(acft.tailNumber)
End If
Next acft
End Function
对象:代表具有各种属性的飞机
Option Explicit
'Class c_Aircraft
'Requires call to init_aircraft() with the Range and "row" of the aircraft instance to be created.
'Assumes the Range contains the following columns:
'1 2 3 4 5 6
'Tail Number Current Hours Next Cycle Next Cycle DUE In Heavy Week Id Cycle Start
'6004 11265.0 4 11333.7 FALSE 0
'Attributes
Private p_tailNumber As Long
Private p_tailNumStr As String
Private p_initialAircraftHours As Double
Private p_currentAircraftHours As Double
Private p_initialNextCycleType As Integer
Private p_nextCycleType As Integer
Private p_initialNextCycleDuration As Integer
Private p_nextCycleDuration As Integer
Private p_initialHoursNextCycleDue As Double
Private p_hoursNextCycleDue As Double
Private p_initialInHeavy As Boolean
Private p_inHeavy As Boolean
'An integer representing the Week Id the current cycle
'started, if in heavy maintenance
Private p_initialWeekIdCycleStart As Integer
Private p_weekIdCycleStart As Integer
Private p_initialHoursToDUE As Double
Private p_hoursToDUE As Double
Private p_initialHoursToDNE As Double
Private p_hoursToDNE As Double
'General Methods
'Custom Initialize
Public Sub init_aircraft(data_range As Range, asset_number As Integer, mxCycles() As Variant)
p_tailNumber = data_range(asset_number, 1)
p_tailNumStr = CStr(data_range(asset_number, 1))
p_initialAircraftHours = data_range(asset_number, 2)
p_currentAircraftHours = p_initialAircraftHours
p_initialNextCycleType = data_range(asset_number, 3)
p_nextCycleType = p_initialNextCycleType
p_initialNextCycleDuration = mxCycles(p_nextCycleType, 2)
p_nextCycleDuration = p_initialNextCycleDuration
p_initialHoursNextCycleDue = data_range(asset_number, 4)
p_hoursNextCycleDue = p_initialHoursNextCycleDue
p_initialInHeavy = data_range(asset_number, 5)
p_inHeavy = p_initialInHeavy
If p_inHeavy Then
p_initialWeekIdCycleStart = data_range(asset_number, 6)
p_weekIdCycleStart = p_initialWeekIdCycleStart
Else
'set to a week prior more than the longest cycle duration
p_initialWeekIdCycleStart = -10
p_weekIdCycleStart = -10
End If
p_initialHoursToDUE = Round(p_hoursNextCycleDue - p_currentAircraftHours, 1)
p_hoursToDUE = p_initialHoursToDUE
p_initialHoursToDNE = Round(p_hoursNextCycleDue - p_currentAircraftHours + 15, 1)
p_hoursToDNE = p_initialHoursToDNE
End Sub
'Return the aircraft objects properties as String
Public Function print_aircraft() As String
print_aircraft = p_tailNumber & vbCrLf & _
"Current Hours: " & p_currentAircraftHours & vbCrLf & _
"Next Cycle: " & p_nextCycleType & vbCrLf & _
"Next Cycle Duration: " & p_nextCycleDuration & vbCrLf & _
"Hours Next Cycle Due: " & p_hoursNextCycleDue & vbCrLf & _
"In Heavy: " & p_inHeavy & vbCrLf & _
"Week Id Cycle Start: " & p_weekIdCycleStart & vbCrLf & _
"DUE: " & p_hoursToDUE & vbCrLf & _
"DNE: " & p_hoursToDNE
End Function
'Get/Let Methods
' Hours Remaining to the DNE
Public Property Get hoursToDNE() As Double
hoursToDNE = p_hoursToDNE
End Property
Public Property Let hoursToDNE(HoursDNE As Double)
p_hoursToDNE = HoursDNE
End Property
'Hours Remaining to the DUE
Public Property Get hoursToDUE() As Double
hoursToDUE = p_hoursToDUE
End Property
Public Property Let hoursToDUE(HoursDUE As Double)
p_hoursToDUE = HoursDUE
End Property
' Aircraft in Heavy Property
Public Property Get inHeavy() As Boolean
inHeavy = p_inHeavy
End Property
Public Sub setInHeavy(Value As Boolean, weekIdCycleStarted As Integer)
p_inHeavy = Value
p_weekIdCycleStart = weekIdCycleStarted
End Sub
'p_weekIdCycleStart
Public Property Get weekIdCycleStart() As Integer
weekIdCycleStart = p_weekIdCycleStart
End Property
'p_weekIdCycleStart
Public Property Let weekIdCycleStart(weekId As Integer)
p_weekIdCycleStart = weekId
End Property
' Aircraft Hours at Next Maintenance Cycle Due Property
Public Property Get hoursNextCycleDue() As Double
hoursNextCycleDue = p_hoursNextCycleDue
End Property
Public Property Let hoursNextCycleDue(Value As Double)
p_hoursNextCycleDue = Value
End Property
' Next Maintenance Cycle Due Property
Public Property Get nextCycleType() As Integer
nextCycleType = p_nextCycleType
End Property
Public Property Let nextCycleType(cycleType As Integer)
p_nextCycleType = cycleType
End Property
' Next Maintenance Cycle Duration Property
Public Property Get nextCycleDuration() As Integer
nextCycleDuration = p_nextCycleDuration
End Property
Public Property Let nextCycleDuration(cycleDuration As Integer)
p_nextCycleDuration = cycleDuration
End Property
' Current Aircraft Hours Property
Public Property Get currentAircraftHours() As Double
currentAircraftHours = p_currentAircraftHours
End Property
Public Property Let currentAircraftHours(Value As Double)
p_currentAircraftHours = Value
End Property
' Tail Number Property
Public Property Get tailNumber() As Long
tailNumber = p_tailNumber
End Property
Public Property Let tailNumber(Value As Long)
p_tailNumber = Value
End Property