通过VBA Excel从数字中删除十进制

时间:2018-01-17 18:31:36

标签: excel vba excel-vba

我在Excel中编写了一些VBA代码,用于删除包含数字的文本框中的小数点分隔符。代码如下:

Private Sub TextBox1_Change()

TextBox1 = Format(TextBox1, "Standard")

End Sub

但它没有正常运作。最终结果有千位分隔符,也有小数位。

此TextBox不是输入数据入口,实际上它是隐藏单元格的输出显示。它与一个单元格(" B15")有关,单元格设置在Separator Thousand Group(On)和No Decimal Place(Off)上。但TextBox1显示带有分隔符T.Group(On)和带小数位(On)的数字。我需要VB代码的语法来保持Separator T.Group没有Decimal Place。 欢迎任何删除小数分隔符的想法!

4 个答案:

答案 0 :(得分:5)

假设用户正在提供输入,这是一个X-Y问题IMO:您的目标是确保您的用户只能在该文本框中键入数字字符,而不是截断小数

问题是文本框“Change事件的触发太晚了。相反,处理KeyDown - 我会做这样的事情:

Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    If Not KeyCodeValidator.IsValidDigitInput(KeyCode.value) Then KeyCode.value = 0
End Sub

拥有KeyCodeValidator标准模块:

Option Explicit
Option Private Module

Public Function IsValidAlphaInput(ByVal keyAscii As Long, Optional ByVal allowDeletion As Boolean = True, Optional ByVal allowNav As Boolean = True) As Boolean
    IsValidAlphaInput = (keyAscii >= vbKeyA And keyAscii <= vbKeyZ) Or (allowDeletion And IsDeletion(keyAscii)) Or (allowNav And IsNavKey(keyAscii))
End Function

Public Function IsValidDigitInput(ByVal keyAscii As Long, Optional ByVal allowDeletion As Boolean = True, Optional ByVal allowNav As Boolean = True) As Boolean
    IsValidDigitInput = (keyAscii >= vbKey0 And keyAscii <= vbKey9) Or (keyAscii >= vbKeyNumpad0 And keyAscii <= vbKeyNumpad9) Or (allowDeletion And IsDeletion(keyAscii)) Or (allowNav And IsNavKey(keyAscii))
End Function

Public Function IsValidAlphanumericInput(ByVal keyAscii As Long, Optional ByVal allowDeletion As Boolean = True, Optional ByVal allowNav As Boolean = True) As Boolean
    IsValidAlphanumericInput = IsValidAlphaInput(keyAscii) Or IsValidDigitInput(keyAscii) Or (allowDeletion And IsDeletion(keyAscii)) Or (allowNav And IsNavKey(keyAscii))
End Function

Public Function IsValidDecimalInput(ByVal keyAscii As Long, ByVal contents As String) As Boolean
    If IsValidDigitInput(keyAscii) Or keyAscii = Asc(".") Then
        IsValidDecimalInput = IsNumeric(contents & Chr$(keyAscii))
    End If
End Function

Private Function IsDeletion(ByVal keyAscii As Long) As Boolean
    IsDeletion = keyAscii = vbKeyDelete Or keyAscii = vbKeyBack
End Function

Private Function IsNavKey(ByVal keyAscii As Long) As Boolean
    IsNavKey = keyAscii = vbKeyTab Or keyAscii = vbKeyLeft Or keyAscii = vbKeyRight
End Function

如果你想支持小数,你可以将文本框的当前内容传递给IsValidDecimalInput(需要进行微调以支持国际小数分隔符)。

我实际上将该模块作为一个类,但是标准模块也很合适。

重点是,不要在文本框中修改用户的输入 - 阻止用户的无效输入,即使是在第一个位置输入。

答案 1 :(得分:3)

请注意,两个方法(来自OP评论的Format和来自@Gary的学生的Split有效地阻止用户输入小数,但它们不会截断或舍入(大概是(数值)值,因此,如果用户尝试输入123.54,则可能需要12354(轮次)或124(截断)时,结果值为123

依赖_Change事件进行验证有一些限制:D和该值可能会被其他任何使用它作为输入的过程验证/操作。

示例:

Option Explicit
Private Sub CommandButton1_Click()
    Call ValidateMe(TextBox1)
    MsgBox (TextBox1.Value)

End Sub

Private Sub TextBox1_Change()
    ' do nothing
End Sub

Private Sub ValidateMe(obj As MSForms.TextBox)
    obj.Value = Format(obj, "0")
End Sub

答案 2 :(得分:2)

如果TextBox1是String之类的:

1,234.56

然后使用类似的东西:

TextBox1 = Split(TextBox1,".")(0)

修改#1:

根据评论,应该使用:

TextBox1 = Split(TextBox1 & Application.DecimalSeparator, Application.DecimalSeparator)(0)

这将:

  1. 返回给定空字符串的空字符串
  2. 如果没有整数部分,则返回空字符串
  3. 以独立于区域设置的方式返回整数部分

答案 3 :(得分:0)

braX 发送了此代码:

TextBox1.Text = Format(TextBox1.Text, "#,###,###,##0")

做得好 braX ,谢谢,它运作正常...... :)