在添加到计数器之前如何检查行中之前的单元格是否相同

How to check if cell before in the row is the same before adding to the counter

我正在研究一个时间 sheet,它计算每个员工每周视图中的小时数。我已经实施了一些代码来确定员工是否是公司的一部分,休无薪假,正在离开公司,还是已经离开。

我想做的是创建一个 table,它告诉我每周加入者、离职者和无薪休假者的数量。

应用代码对我的数据进行排序后,它看起来像这样:

我用更有意义的描述替换了之前存在的随机值。

我想创建一个 table,它在该行中第一次将值添加到连接器计数器,该值是“未连接”,因此我不会重复计数。例如ID 1,我不想把那个人算作第2-5周的加入者,只在第2周。

到目前为止,这是我的代码,我在查看下一列之前查看每列的行数:

Dim LastCol As Long
Dim LastRow As Long
Dim I As Long
Dim Z As Long
Dim Q As Long
Dim Joined As Integer
Dim ws As Worksheet

'set worksheet to use
Set ws = Sheets("Sheet1")

With ws
  'Find last col and row for range
   LastCol = ws.Cells(3, Columns.Count).End(xlToLeft).Column
   LastRow = ws.Cells(Rows.Count, D).End(xlUp).Row

For I = 3 To LastCol
    NotJoined = 0
        For Z = 4 To LastRow
            'check if cell is > 0
            If ws.Cells(Z, I).Value > 0 Then
                Joined = Joined + 1
            End If
        Next Z
    'Find last row and add value to row below
    Q = ws.Cells(Rows.Count, I).End(xlUp).Row
    ws.Cells(Q + 1, I).Value = Joined
Next I
End With

我将如何添加一种方法来在任何给定的行中只对加入者(从未加入到任何其他值)/离开者(从任何值到 x)计数一次,但每周找到这些值。我正在努力实现如下所示的 table:

提前致谢!

我已经完成了一半的工作。请完成剩下的工作。据我所知。将代码粘贴到标准代码模块中,并将作品 sheet 的名称从 "Tony" 更改为您正在测试的名称。

Option Explicit

Enum Nst                            ' Status
    ' 15 Oct 2017
    NstNone = -3
    NstNotJoined
    NstOnLeave
    NstLeft
    NstPresent
End Enum

Enum Nix                            ' Array index
    ' 15 Oct 2017
    NixPresent = 1
    NixJoined
    NixLeft
    NixUnpaid
End Enum

Sub HeadCount()
    ' 15 Oct 2017

    Dim Arr() As Integer                ' Result
    Dim Wk As Long, Ix As Nix           ' Arr() indices
    Dim Ws As Worksheet
    Dim LastCol As Long
    Dim LastRow As Long
    Dim StatusArr As Variant
    Dim R As Long, C As Long            ' Row / Column
    Dim Stat As Nst, NewStat As Nst     ' status

    'set worksheet to use
    Set Ws = Sheets("Tony")
    StatusArr = Array(NstNotJoined, NstOnLeave, NstLeft, NstPresent)

    With Ws
        ' prefix a period to refer to object in With statement
        LastCol = .Cells(3, .Columns.Count).End(xlToLeft).Column
        LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
        ReDim Arr(1 To (LastCol - 3), 1 To NixUnpaid)

        For R = 4 To LastRow
            Stat = NstNone                  ' unable to determine changes in Wk 1
            For C = 4 To LastCol
                Wk = C - 3
                NewStat = StatusArr(Application.Match(Val(.Cells(R, C).Value), StatusArr, 1) - 1)
                If NewStat <> Stat Then     ' count changes
                    ' Count joiners
                    If (Stat = NstNotJoined) And (NewStat = NstPresent) Then
                        Arr(Wk, NixJoined) = Arr(Wk, NixJoined) + 1
                    End If
                    ' count leavers
                    If (Stat <> NstLeft) And (NewStat = NstLeft) Then
                        Arr(Wk, NixLeft) = Arr(Wk, NixLeft) + 1
                    End If
                End If

                Stat = NewStat
                If Stat = NstOnLeave Then Arr(Wk, NixUnpaid) = Arr(Wk, NixUnpaid) + 1
                If Stat = NstPresent Then Arr(Wk, NixPresent) = Arr(Wk, NixPresent) + 1
            Next C
        Next R

        .Cells(20, "D").Resize(UBound(Arr, 2), UBound(Arr, 1)).Value = Application.Transpose(Arr)
    End With
End Sub

我在你的记录中引入了以下逻辑。

  1. -2 表示 "Not yet joined"
  2. -1 表示 "On leave"(大概是未付的)
  3. 0 或空白表示 "not working"(大概是左)
  4. 任何其他正数表示工作时间(假定正在工作)

请在作品中使用这些数字sheet,而不是您目前拥有的文本。如果需要,可以编写代码来翻译它们。在代码中,这些数字在 Enum Nst 中表示。 NstNone 用于一周的开始。我认为您的系统在这一点上存在缺陷,因为您无法在不知道以前状态的情况下判断有多少人加入或离开。 NstNone 弥合差距。

最后一行代码确定输出将写入找到数据的 sheet 范围内的 D20:H23 范围内。现有数据将为 over-written。请务必在员工 ID 下方的 A 列中不写任何内容,因为宏使用 A 列来确定要评估的员工人数。

结果的列数将与上面的周数一样多。它将有 4 行,由 Enum Nix 确定,这意味着员工在场、加入、离职和休无薪假。这个想法是,您可以将此列表粘贴到 table 中,您可以在其中获得所需的标题和格式。您可以通过修改 Enum Nix 来更改序列。请务必将值 = 1 分配给名字。 (并且不要随机播放 Enum Nst!)

我的数字与您的结果不符。那是因为我不明白你的结果。但是,我认为数字已经存在,如果您需要额外的数字,它们将很容易集成到已建立的系统中。