マクロを使用して列の最新の日付/時刻を見つける方法


2

以下の表のようなシステムから生成されたデータがあります。最後の列には、各部門からシステムを更新する最後のユーザーであるユーザーを表示する必要があります。

Update Time     User    Department  Last update  
-------------------------------------------------------
1/19/12 7:26    John    A
1/19/12 6:26    Yen     A
1/18/12 9:47    Jefta   B
1/18/12 9:47    Jefta   B
1/18/12 9:47    John    A

2
このデータを表示/編集するためにどのプログラムを使用していますか?
ダニエルベック

これにはPL / Sマクロをお勧めします。Cマクロよりもはるかに強力です。
ダニエルRヒックス

私はExcel 2010を使用しています。私の質問と例が十分に明確であることを願っています!
クリスティン

回答:


2

あなたが求めていることを理解し、これがExcelにある場合、「配列式」を使用できます。

たとえば、データセットが範囲A1:C5のワークシートにある場合、列「D」でこれを使用できます。

{=INDIRECT("B" & MATCH(MAX(IF(C$1:C$5=C1,(A$1:A$5),)),A$1:A$5,0))}

この式は、最大値が見つかった行の行番号を返すことにより、必要なユーザー名を指すセル参照を動的に構築します。ただし、部門の値が列「C」の行の値と一致する行のみです。 (部門の列)、テキスト文字「B」(ユーザー名を含む列)に追加して、「文字+数字」のセル参照全体を作成します。

これは配列関数である必要があることに注意してください。つまり、通常のように入力するのではなく、数式を入力した後にセルを離れるときにCtrl+ Shift+ Enterを押す必要があります。正しく実行すると、上記のように数式は中括弧で囲まれます。数式を囲む中かっこがない場合、配列数式として設定されず、正しく機能しません。

これを行うためのよりシンプルな方法またはよりエレガントな方法があるかもしれませんが、迅速で汚れたソリューションが必要な場合、これは機能します。

さらに説明が必要な場合は、詳細を提供できます。


こんにちはダニエル、私はExcelを使用して、応答していただきありがとうございます
クリスティン

0

戻ってきて、誰もまだVBAソリューションを投稿していないことを確認してください。私はそこに1つを置くだろうと考えました。

'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

End Function

'//Since we are using the VBA collection object, there is no true '//test for if an element exists; the collection will just throw '//an error if you ask it for something it cannot find, so just '//trap the error and return false in that case, as it means no '//item was found in the list with that dept as it's key Private Function DeptExists(ByRef deptList As Collection, dept As String) As Boolean On Error GoTo handler deptList.Item dept DeptExists = True Exit Function handler: Err.Clear DeptExists = False End Function

'//Updates an existing entry in our collection of dept users. '//Note: this implementation allows for the trapping of failed attempts '//but is not used in this version to keep it as straight-forward as '//possible - If it was important to know when such attempts failed, you '//could trap on the return value of this method and take the appropriate '//action. Private Function UpdateExistingEntry(ByRef deptList As Collection, ByVal deptInfo As Variant, ByVal dept As String) As Boolean On Error GoTo handler

If DeptExists(deptList, dept) Then
    deptList.Remove dept
    deptList.Add deptInfo, dept
    UpdateExistingEntry = True
Else
    UpdateExistingEntry = False
End If
Exit Function

handler: Err.Clear UpdateExistingEntry = False End Function

'//Uses the created collection of dept, username to add the '//required username to the column Private Sub AppendLastUserName(dataStartRow As Long, deptListing As Collection) Dim currRow As Integer: currRow = dataStartRow Do While Not IsEmpty(Cells(currRow, DataColumns.DateTimeStamp)) Dim currDept As String: currDept = Cells(currRow, DataColumns.Department) Cells(currRow, DataColumns.LastUpdater).Value = deptListing(currDept)(USERNAME) currRow = currRow + 1 Loop End Sub

このコードは、部門のコンテキスト内でシステムを更新する最後の人のユーザー名を配置します。

列の位置など、いくつかのことを想定していることに注意してください。関連する列を参照するために使用されている列挙があります。したがって、例とは異なり、すべてが期待どおりに動作する場合は、適切な列インデックスを指すことができます。また、日付スタンプを含む列にギャップがなく、常に日付であると想定しています。

コードのセット全体をExcelの1つのモジュールにコピーアンドペーストすると、正常に機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.