1

我有一个记录员工工作时间的模板。第 5 栏显示了他们每周的合同工时,第 14 栏显示了他们的额外工作时间。加班的兼职员工(每周少于 37.5 小时)按标准收费。但是,一旦他们超过一周的 37.50 小时,他们就会按时支付一半(这记录在单独的栏中)。

下面的代码获取一周的总小时数(第 18 列),如果超过 37.5,它将提示用户在一个半小时记录一些小时数。这是确保人们得到正确报酬的一种万无一失的方法。

下面的代码几乎可以完美运行,但是如果约定的小时数少于 10,则无论如何都会弹出消息框。我认为这是因为我有一个字符串数据类型,代码中的小时数是字符串,但我似乎无法让它与其他数据类型一起使用。任何帮助将不胜感激。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

If Target.Column = 14 Then

Dim I As Integer, CheckHours As Boolean
Dim MonthX As Worksheet
I = 6
CheckHours = False
Set MonthX = ThisWorkbook.ActiveSheet

Dim FT As String
FT = 37.5

Application.ScreenUpdating = False

'Use the Employee Number column to perform the check
Do While MonthX.Cells(I, 3) <> ""

    'Declare variables
        Dim ContractHours As String
        Dim HoursPaid As String
        Dim TotalHours As String

        ContractHours = MonthX.Cells(I, 5)     
        HoursPaid = MonthX.Cells(I, 14)
        TotalHours= MonthX.Cells(I, 18)

            'If the contract hours plus the additional hours are greater than 37.50 then display warning
            If TotalHours > FT Then
                MsgBox "WARNING: Check the additional hours entered for " & _
                MonthX.Cells(I, 2).Value & " " & MonthX.Cells(I, 1).Value & _
                " as they will need to be split between Additional Basic and Overtime." & _
                vbNewLine & vbNewLine & _
                "Please refer to the Additional Hours Guidelines tab for more information.", vbOKOnly, "Please Check"

                CheckHours = True

            End If

    I = I + 1
Loop

'Cancel boolean
If CheckHours = True Then
    Cancel = True
    End If

Application.ScreenUpdating = True

End If

End Sub
4

3 回答 3

1

我不知道你的逻辑是否正确,但这是一个与你的代码做同样事情的重写。你的代码中有很多额外的东西似乎没有目的,所以我删除了它。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

   Dim i As Long
   Dim dTotalHours As Double
   Dim aMsg(1 To 5) As String

   Const dFULLTIME As Double = 37.5

   i = 6

   If Target.Column = 14 Then
      Do While Len(Me.Cells(i, 3).Value) > 0
         dTotalHours = Me.Cells(i, 18).Value
         If dTotalHours > dFULLTIME Then
            aMsg(1) = "WARNING: Check the additional hours entered for"
            aMsg(2) = Me.Cells(i, 2).Value
            aMsg(3) = Me.Cells(i, 3).Value
            aMsg(4) = "as they will need to be split between Additional Basic and Overtime." & vbNewLine & vbNewLine
            aMsg(5) = "Please refer to the Additional Hours Guidelines tab for more information."

            MsgBox Join(aMsg, Space(1)), vbOKOnly, "Please Check"
         End If
         i = i + 1
      Loop
   End If

End Sub

一些笔记

  • Excel 将数字单元格值存储为双精度值。如果您正在从单元格中读取数字,那么除了 Double 之外,真的没有理由使用任何东西。
  • 当您在工作表的类模块(事件所在的位置)中时,您可以使用 Me 关键字来引用工作表。您指的是 Activesheet,但您真正想要的是发生选择更改的工作表。在这种情况下,它们恰好是相同的,但对于其他事件,它们可能不同。
  • 检查字符串的长度比检查 if <>"" 更快。
  • 您的 FT 变量永远不会改变,使其根本不可变。常数可能是更好的选择。
  • 我使用一个数组来存储长消息的所有元素,然后使用 Join 来制作最终的字符串。更易于阅读和维护。
  • 我是一名键盘手,所以这对我来说最接近我的家,但是每次选择更改时都会出现一个消息框?这意味着如果我尝试使用箭头键进入我将修复错误的单元格,我将得到持续的消息框。野蛮。也许 _Change 事件或 _BeforeSave 事件值得考虑。
于 2013-04-04T12:54:48.293 回答
0

尝试声明为“单个”而不是“字符串”

我们被告知在大学时将十进制数字声明为单数。它可能会解决您的问题。

或者我注意到但不知道是否会影响它的另一件事,您的 IF 语句中没有 ELSE

于 2013-04-03T14:28:26.587 回答
0

以下代码可能需要进行一些调整,但它应该接近您的需要。它实现了对您问题的评论中的一些建议。您的困难的根源是使用字符串变量来处理数值。

我已将 FT、ContractHours、HoursPaid 和 SumHours 声明为单个变量,并将 Cancel 声明为布尔值(尽管您不在子例程中使用它)。

您可以通过从 VBA 编辑器的菜单栏中选择工具/选项,然后选中编辑器选项卡上的“需要变量声明”选项,将“选项显式”(需要声明变量)设置为代码的默认值.

Option Explicit

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
   Dim i As Integer, CheckHours As Boolean, Cancel As Boolean
   Dim MonthX As Worksheet
   Dim FT As Single
   Dim ContractHours As Single
   Dim HoursPaid As Single
   Dim SumHours As Single
   Set MonthX = ThisWorkbook.ActiveSheet
   i = 6
   FT = 37.5
   If Target.Column = 14 Then
      Application.ScreenUpdating = False
      'Use the Employee Number column to perform the check
      Do While MonthX.Cells(i, 3).Value <> ""
         'Assign variables
         ContractHours = MonthX.Cells(i, 5).Value
         HoursPaid = MonthX.Cells(i, 14).Value
         SumHours = MonthX.Cells(i, 18).Value
         'When the contract hours plus the additional hours are greater than 37.50 
         '   display warning
         If SumHours > FT Then
            MsgBox "WARNING: Check the additional hours entered for " & _
               MonthX.Cells(i, 2).Value & " " & MonthX.Cells(i, 1).Value & _
               " as they will need to be split between Additional Basic and Overtime." & _
               vbNewLine & vbNewLine & _
               "Please refer to the Additional Hours Guidelines tab for more information.", vbOKOnly, "Please Check"
            CheckHours = True
         End If
         i = i + 1
      Loop
      'Cancel boolean
      If CheckHours = True Then
        Cancel = True
      End If
      Application.ScreenUpdating = True
   End If
End Sub
于 2013-04-04T04:35:12.463 回答