Excel VBA数字的正确datetypes?

我有一个logging员工工作时间的模板。 第5列显示了一周的合同小时数,第14列显示了他们工作的额外小时数。 兼职工作人员(不到37.5小时/周)工作时间以标准价格支付。 但是一旦他们一周超过37.50小时,他们就会被支付一次半(这是logging在一个单独的专栏中)。

下面的代码提取了本周的总小时数(第18列),如果超过37.5,它将提示用户在一个半时间内logging一些小时数。 这是确保人们获得正确报酬的一种安全的方式。

下面的代码几乎可以完美地工作,但是如果签约时间小于10,消息框不pipepopup。 我认为这是因为我有一个string数据types在代码中的小时数是作为一个string,但我似乎无法得到它与其他数据types的工作。 任何援助将不胜感激。

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 

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

 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,但是您真正想要的是发生select更改的工作表。 在这种情况下,它们碰巧是一样的,但是对于其他事件,它们可能不是。
  • 检查string的长度比检查<>“”更快。
  • 你的FTvariables永远不会改变,根本不可变。 常数可能是更好的select。
  • 我使用一个数组来存储一个长消息的所有元素,然后使用Join来创build最终的string。 更易于阅读和维护。
  • 我是一个键盘的家伙,所以最接近我的家,但是每次select改变时都会出现一个消息框? 这意味着,如果我尝试使用箭头键到达我将修复错误的单元格,我将得到常量消息框。 野蛮。 也许_Change事件或_BeforeSave事件值得考虑。

尝试声明为“单一”而不是“string”

我们被告知在uni时宣布十进制数字为单数。 它可以解决你的问题。

或者我注意到另一件事情,但不知道是否会影响它,你没有与您的IF声明ELSE

下面的代码可能需要一些调整,但它应该接近你所需要的。 它在你的问题的意见中实施了几个build议。 你的困难的来源是使用stringvariables来处理数值。

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

您可以通过从VBA编辑器的菜单栏中selectTools / Options,然后在Editor选项卡上勾选“需要variables声明”选项来设置“Option Explicit” – 要求声明variables – 作为代码的默认值。

 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