private static IEnumerable <Message> GetSchedules(Schedule schedule, Excel.Workbook book) { var messages = new List <Message>(); Excel.Worksheet sheet = book.Worksheets["Trains"] as Excel.Worksheet; var r = 2; Train currentTrain = null; string trainId = null; VehicleSchedule currentLoco = null; Dictionary <string, VehicleSchedule> locoSchedules = new Dictionary <string, VehicleSchedule>(); Dictionary <string, DriverDuty> driverDuties = new Dictionary <string, DriverDuty>(); while (true) { var row = (Array)sheet.get_Range(Cell("A", r), Cell("K", r)).Cells.Value; if (row.GetValue(1, 1) == null) { break; } else { var type = row.Value(9).ToUpperInvariant(); switch (type) { case "TRAINDEF": trainId = row.Value(8); var train = schedule.Timetable.Train(trainId); if (train.IsNone) { messages.Add(Message.Error(CultureInfo.CurrentCulture, $"Train {trainId} cannot be found.")); break; } currentTrain = train.Value; break; case "LOCOMOTIVE": var locoId = row.Value(8); if (locoId != null) { if (!locoSchedules.ContainsKey(locoId)) { locoSchedules.Add(locoId, VehicleSchedule.Loco(locoId)); } currentLoco = locoSchedules[locoId]; if (currentTrain != null) { var locoMessages = new List <Message>(); var fromStationSignature = row.Value(3); var toStationSignature = row.Value(4); var fromTime = Time.Parse(row.Value(5)); var toTime = Time.Parse(row.Value(6)); //if (lt2 < lt1) lt2 = lt2.AddDays(1); // TODO: Handle over midnight times, if necessary var(fromCall, fromIndex) = currentTrain.FindBetweenArrivlAndBeparture(fromStationSignature, fromTime); var(toCall, toIndex) = currentTrain.FindBetweenArrivlAndBeparture(toStationSignature, toTime); if (fromCall.IsNone) { locoMessages.Add(Message.Error(CultureInfo.CurrentCulture, Resources.Strings.LocoAtStationWithDepartureDoNotRefersToAnExistingTimeInTrain, locoId, fromStationSignature, fromTime, currentTrain)); } if (toCall.IsNone) { locoMessages.Add(Message.Error(CultureInfo.CurrentCulture, Resources.Strings.LocoAtStationWithArrivalDoNotRefersToAnExistingTimeInTrain, locoId, fromStationSignature, toTime, currentTrain)); } if (fromIndex >= toIndex) { locoMessages.Add(Message.Error(CultureInfo.CurrentCulture, Resources.Strings.LocoInTrainHasWrongTimingEndStartionIsBeforeStartStation, locoId, currentTrain, fromTime, toTime)); } messages.AddRange(locoMessages); if (locoMessages.CanContinue()) { TrainPart trainPart = new TrainPart(currentTrain, fromIndex, toIndex); currentLoco.Add(trainPart); } } } break; case "TRAINSET": var trainsetId = row.Value(8); break; case "JOB": var jobId = row.Value(8); if (jobId != null) { var jobMessages = new List <Message>(); if (currentTrain is null) { messages.Add(Message.Error(CultureInfo.CurrentCulture, $"There is not a current train for job {jobId}.")); break; } if (currentLoco is null) { messages.Add(Message.Error(CultureInfo.CurrentCulture, $"There is not a current loco for job {jobId}.")); break; } if (!driverDuties.ContainsKey(jobId)) { driverDuties.Add(jobId, new DriverDuty(jobId)); } var currentLocoSchedule = locoSchedules.Values.SingleOrDefault(l => l.Identity == currentLoco.Identity); if (currentLocoSchedule is null) { messages.Add(Message.Error(CultureInfo.CurrentCulture, $"Job {jobId} referse no a nonexisting loco schedule {currentLoco}.")); break; } var dt1 = Time.Parse(row.Value(5)); var dt2 = Time.Parse(row.Value(6)); if (dt2 < dt1) { dt2 = dt2.AddDays(1); } var part = currentLocoSchedule.Parts.Select((value, index) => (value, index)).SingleOrDefault(p => p.value.Train.Number == currentTrain.Number && (p.value.From.Arrival == dt1 || p.value.From.Departure == dt1 || dt1 < currentLocoSchedule.Parts.First().From.Arrival) && (p.value.To.Arrival == dt2 || p.value.To.Departure == dt2 || dt2 > currentLocoSchedule.Parts.Last().To.Departure)); if (part.value == null) { jobMessages.Add(Message.Error($"Error in train {currentTrain} for job {jobId}.")); } if (jobMessages.CanContinue()) { driverDuties[jobId].Add(new VehicleSchedulePart(currentLocoSchedule, part.index, part.index)); messages.AddRange(jobMessages); } } break; case "GROUP": if (currentTrain != null) { currentTrain.Category = row.Value(8); } break; default: break; } } r++; } foreach (var loco in locoSchedules.Values) { schedule.AddLocoSchedule(loco); } foreach (var duty in driverDuties.Values) { schedule.AddDriverDuty(duty); } return(messages); }