Это должно быть VBA.Вы можете использовать «Worksheet_Change» для запуска только в том случае, если в столбец состояния внесено изменение, поэтому количество строк не должно влиять на производительность.
Одним из способов решения этой конкретной проблемы является включение столбцов для каждого из них.этап для даты начала и окончания (AV: AZ для даты начала каждого этапа, например, BA: BE для даты окончания каждого этапа).
Поэтому, когда вы изменяете значение в столбце A, код будетпроверьте новое и старое значение статуса, затем обновите даты начала и окончания этого этапа.
Недостаток этого подхода заключается в том, что при неправильном выборе этапа вам придется вручную изменять время на каждомСтолбцы стадии, поскольку каждая строка получает только один шанс обновить даты начала и окончания.
Другой способ заключается в том, чтобы получить старое значение при изменении ячейки в столбце A, мне пришлось использовать SelectionChange, что означаетчто вы должны изменить, какая ячейка выбрана между изменениями статуса (это не будет проблемой при регулярном использовании, если вы не меняете ту же ячейку дляm CNC, PRESS, PLATING и т. д. без выбора отдельной ячейки между изменениями.
Я поместил дополнительную строку, чтобы сохранить сегодняшнюю дату, чтобы вы могли изменить диапазоны в VBA, чтобы они соответствовали.
Лист изменен таким образом: Макет листа
Формула из ячейки AQ3 и может быть перетащена в AU3 - вы можете легко изменить это, чтобы посчитать правильное числодней на данный момент это «сегодня - дата начала + 1» для этапов, которые все еще активны - возможно, вам придется изменить это.
Вы можете скрыть дополнительные столбцы, BF1 - это просто сегодняшняя дата (= TODAY ()) и столбец BG предназначен только для раскрывающегося списка в столбце A.
Dim oldValue
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
oldValue = Target.Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
Dim startCol As Variant
Dim endCol As Variant
Dim oVal As Variant
Dim nVal As Variant
oVal = oldValue
nVal = Cells(Target.Row, 1).Value
'make no changes if anything other than column A is changed
If Not Target.Column = 1 Then
GoTo continue
End If
'add end date if status is changed to finished
If nVal = "FINISHED" Then
Cells(Target.Row, 57) = Date
GoTo continue
End If
'update end of last stage only if new value is blank
If IsEmpty(nVal) Then
GoTo endDate
End If
'find the column of the stage being changed
startCol = Range("AV2:AZ2").Find(nVal).Column
If Not IsEmpty(oVal) Then
endCol = Range("BA2:BE2").Find(oVal).Column
End If
Set KeyCells = Range("A:A")
'run if something in column A is changed
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
'update the start date of new stage
If IsEmpty(Cells(Target.Row, startCol)) Then
Cells(Target.Row, startCol) = Date
End If
'update the date of the stage just ended
If IsEmpty(endCol) Then
GoTo continue
End If
If IsEmpty(Cells(Target.Row, endCol)) Then
If IsEmpty(oVal) Then
GoTo continue
End If
Cells(Target.Row, endCol) = Date
End If
End If
GoTo continue
endDate:
If oVal = "FINISHED" Then
GoTo continue
End If
Cells(Target.Row, Range("BA2:BE2").Find(oVal).Column) = Date
continue:
End Sub