'indexes of the values stored as an array in the collection object
Private Const USERNAME As Integer = 0
Private Const DATETIME As Integer = 1
'references to where the data is or should be in the workbook
Public Enum DataColumns
DateTimeStamp = 1
UName = 2
Department = 3
LastUpdater = 4 'The information we will be adding!
End Enum
Sub Main()
Dim lastUserByDept As Collection
Set lastUserByDept = GetLastUpdater(2)
AppendLastUserName 2, lastUserByDept
End Sub
'//Builds a collection of department entries, and stores
'//the last date along with the user tied to that date
Private Function GetLastUpdater(dataStartRow As Long) As Collection
Dim currRow As Integer: currRow = dataStartRow
Dim maxDatesByDept As Collection
Set maxDatesByDept = New Collection
Dim deptInfo As Variant
Do While Not IsEmpty(Cells(currRow, DataColumns.DateTimeStamp))
Dim dept As String: dept = Cells(currRow, DataColumns.Department).Value
If DeptExists(maxDatesByDept, dept) Then
If Cells(currRow, DataColumns.DateTimeStamp).Value > maxDatesByDept.Item(dept)(DATETIME) Then
deptInfo = Array(Cells(currRow, DataColumns.UName).Value, Cells(currRow, DataColumns.DateTimeStamp).Value)
UpdateExistingEntry maxDatesByDept, deptInfo, Cells(currRow, DataColumns.Department)
End If
Else
deptInfo = Array(Cells(currRow, DataColumns.UName).Value, Cells(currRow, DataColumns.DateTimeStamp).Value)
maxDatesByDept.Add deptInfo, Cells(currRow, DataColumns.Department).Value
End If
currRow = currRow + 1
Loop
Set GetLastUpdater = maxDatesByDept
Set maxDatesByDept = Nothing
Конечная функция
«// Поскольку мы используем объект коллекции VBA, нет никакого истинного» // теста на наличие элемента; коллекция просто выдаст // ошибку, если вы попросите ее о чем-то, что она не может найти, поэтому просто «// перехватите ошибку и вернете ложь в этом случае, так как это означает, что ни один элемент // не был найден в списке с этим dept как ключ Закрытая функция DeptExists(ByRef deptList As Collection, dept As String) As Boolean On Ошибка GoTo обработчик deptList.Элемент dept DeptExists = True Выход Обработчик функции: Err.Очистить DeptExists = False End Функция
'// Обновляет существующую запись в нашей коллекции пользователей отдела.
«// Примечание: эта реализация позволяет отлавливать неудачные попытки» // но в этой версии не используется для того, чтобы сделать его таким простым, как «// возможный - если было важно знать, когда такие попытки потерпели неудачу, вы» // может перехватить возвращаемое значение этого метода и выполнить соответствующее действие //.
Закрытая функция UpdateExistingEntry(ByRef deptList As Collection, ByVal deptInfo As Variant, ByVal dept As String) В качестве логического значения при ошибке Обработчик GoTo
If DeptExists(deptList, dept) Then
deptList.Remove dept
deptList.Add deptInfo, dept
UpdateExistingEntry = True
Else
UpdateExistingEntry = False
End If
Exit Function
обработчик: Err.Очистить UpdateExistingEntry = False End Function
'// Использует созданную коллекцию dept, username для добавления // необходимого имени пользователя в столбец Private Sub AppendLastUserName(dataStartRow As Long, deptListing As Collection) Dim currRow As Integer: currRow = dataStartRow Делать пока не IsEmpty(Cells(currRow DataColumns.DateTimeStamp)) Dim currDept As String: currDept = Cells(currRow, DataColumns.Отдел) Ячейки (currRow, DataColumns.LastUpdater).Значение = deptListing (currDept) (USERNAME) currRow = currRow + 1 Loop End Sub
Этот код поместит имя пользователя, который последний раз обновлял систему, в контексте отдела.
Обратите внимание, что предполагается, что некоторые вещи, такие как расположение столбцов; Существует перечисление, используемое для ссылки на соответствующие столбцы, поэтому вы можете указать их на соответствующие индексы столбцов, если они отличаются от примера и все должны работать, как ожидалось. Предполагается также, что столбец, содержащий метку даты, не имеет пробелов и всегда является датой.
Скопируйте и вставьте весь набор кода в один модуль в Excel, и он будет работать отлично.