2

在用户输入被提交到单元格之前,是否有与Cell_ChangeEvent inVBA或什至VSTO会触发的东西等效?我需要在单元格中输入新值之前添加一些检查。

WorkSheet_Change事件触发时,Excel 已经修改了用户输入并将其转换为不同的值。我需要获取用户输入的原始输入。

编辑

更具体地说,我想阻止 Excel 将诸如3E9在我的情况下恰好是有效(非数字/非科学)输入的值转换为科学记数法。

用户可以在整个工作表的任何单元格中输入这些值,因此我无法预先应用文本格式,因为这也会阻止 Excel 对有效数字数据执行其正常功能。

所以我打算:

  • 在输入进入单元格并被转换之前以某种方式获取输入。
  • 然后检查它是否符合我正在观察的确切模式,并在该特定单元格上即时应用文本格式。
4

3 回答 3

3

您可以捕获正在应用的科学记数法并将其反转为文本字符串

使用 RegExp 更新以处理解析

  • 将有效值重新格式化回初始文本(即120E399E13
  • 用消息替换损坏的值以租用它们(单元格已格式化为文本,因此下次12E14保留为文本12E14

工作表事件代码

Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng1 As Range
Dim strTmp As String
Dim objRegex As Object
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
    .Pattern = "([1-9]+)(0+)"
    Application.EnableEvents = False
    For Each rng1 In Target.Cells
        If rng1.NumberFormat = "0.00E+00" Then
        rng1.NumberFormat = "@"
        strTmp = Len(.Replace(rng1.Value, "$2"))
            If .Test(rng1.Value) Then
            rng1.Value = "'" & .Replace(rng1.Value, "$1E") & strTmp
                Else
            rng1.Value = "Pls re-enter as text"
            End If
        End If
    Next
End With
Application.EnableEvents = True
End Sub
于 2013-04-09T12:47:46.167 回答
1

我想知道您是否可以使用数据验证来帮助解决这个问题。假设您有 3E9 和 4E7 等有效输入,但没有 5E2 或 7E1 等有效输入。然后让我们进一步假设您很少有超过 10m 的有效数字输入。如果这种非常特殊的情况属实,您可以在用户输入大于 10m 的数字时警告用户。如果它是合法的,他们会忽略警告并继续前进。如果他们打算输入文字字符串,他们可以取消输入并按照您的指示在前面加上撇号。您可以像这样创建 DV:

Allow: Custom
Formula: =OR(ISTEXT(A1),A1<10^7)
Style: Warning
Title: Scientific Notation
Msg: If you enter a string like '9E99' Excel will convert to a number in scientific notation format. If you want the literal string, precede it with an apostrophe.

您的情况是如此具体,这可能会要求很多。也许还有其他一些你可以使用 DV 来避免的特征。就像如果有人输入整数的可能性极小,您可以使用 DV 进行检查。

于 2013-04-09T16:03:03.910 回答
1

撤销功能呢?

Private Sub Worksheet_Change(ByVal Target As Range) 
    Dim OldValue As String, NewValue as string
    If Intersect(Target, Range("B:B")) Is Nothing Then Exit Sub 
    With Application 

        .EnableEvents = False 

        .Undo 
        'this is before
        OldValue = Target.Cells(1).Value 
        .Redo 
        'this is after 
        Newvalue = Target.Cells(1).value

        'do some check to see if you need to reverse the change 
        If oldvalue > newvalue then 
            .undo
            Msgbox "Not valid"
        end if

        .EnableEvents = True 

    End With

End Sub
于 2013-04-09T11:17:46.653 回答