在 Options Explicit 下的多列中自动插入冒号 (:)

Posted

技术标签:

【中文标题】在 Options Explicit 下的多列中自动插入冒号 (:)【英文标题】:Automatically inserting Colon (:) in multiple columns under the Options Explicit 【发布时间】:2022-01-21 08:53:39 【问题描述】:

我一直在寻找一种代码来自动将“:”(冒号)插入到列 R 和 S、W 和 X 中,并找到了我认为可以根据自己的需要进行自定义的代码,但我面临两个问题:

    代码可以在 R 和 S 中运行,但也需要代码在 W 和 X 列中运行

    我收到一个错误

    变量未定义 - 停在 TLen 我猜它也会停在 TimeV

程序员不使用Option Explicit,(没有Option Explicit 也可以正常工作)。但是我所有的代码都是Option Explicit,但是我不确定如何为这两个变量写Dim

此代码在一个特定的工作表中,在 Worksheet_Change 子中,其中我还有其他代码用于其他事情,例如人们从 B 列进行选择时的时间戳,当出现在 B 列中进行选择。

我在另一个工作簿中尝试了冒号代码,没有Option Explicit,它可以正常工作而不会出现错误。

代码来源来自

Excel VBA tips n tricks #12 no more colons when typing time of day, type 123 instead of 01colon23 AM

我已经修改了代码以引用下面代码中的列 R 和 S。

Private Sub Worksheet_Change(ByVal Target As Range)

    ' This code will ADD the COLON for TIME automatically
    ' The code is from: https://www.youtube.com/watch?v=ATxaNbTV2d0 (Excel is Fun -
    ' Excel VBA Tips n Tricks #12 NO MORE COLONS When Typing Time of Day, Type 123 instead of 01colon23 AM

    ' To avoid an error if you select more than 1 cell, this next line of code will exit the sub

    If Selection.Count > 1 Then
        Exit Sub
    End If

    If Not Intersect(Range("R4:S1200"), Target) Is Nothing Then

        TLen = Len(Target)
        [![Layout of Worksheet and sample of the columns that need automatic insertion of colons ][1]][1]
        If TLen = 1 Then
            TimeV = TimeValue(Target & ":00")

        ElseIf TLen = 2 Then
            TimeV = TimeValue(Target & ":00")

        ElseIf TLen = 3 Then
            TimeV = TimeValue(Left(Target, 1) & ":" & Right(Target, 2))

        ElseIf TLen = 4 Then
            TimeV = TimeValue(Left(Target, 2) & ":" & Right(Target, 2))

        ElseIf TLen > 4 Then
            'Do nothing

        End If

        'Target.NumberFormat = "HH:MM"
        Application.EnableEvents = False

        Target = TimeV
        Application.EnableEvents = True

    End If
End Sub

【问题讨论】:

1. 我可以告诉你数据类型,但我希望你自己去发现它。删除Option Explicit,然后在TimeV 上添加Watch。看看它是哪种类型;) 2. "R4:S1200" 控制是否发生更改。您认为您应该在此处进行哪些更改以使其也可以与WX 一起使用? :) 我知道您正在“伸展和教导”我为自己解决问题,我很感激(我肯定已经学会了如何看待类型 (1.))。但在这种情况下,“类型”作为变体/日期出现,即使它是时间(也许我误解了语法)。 2.但没有一个例子我该如何学习,我显然已经用尽了我的搜索来解决这个问题,但什么也没找到..我发布这个问题的原因。感谢您鼓励我继续自己解决问题:) 干得好! :) 发布了一个答案,因为 cmets 将无法支持我想说的话。我的回答仅供参考。 代码中的“[![Layout of Worksheet and sample of the columns that need automatic insertion of colons ][1]][1]”是什么意思? 【参考方案1】:

扩大相交Intersect(Range("R:S,W:X"),Target)的范围。

Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)

    If Target.Cells.Count > 1 Then Exit Sub
    If IsNumeric(Target) = False Then
        MsgBox Target & " is not a number", vbExclamation
        Exit Sub
    ElseIf Intersect(Range("R:S,W:X"), Target) Is Nothing Then
        Exit Sub
    End If
    
    Dim n As Long
    n = Len(Target)
    If n >= 1 And n <= 4 Then
        Application.EnableEvents = False
        Target.NumberFormat = "hh:mm"
        If n <= 2 Then
            Target.Value2 = TimeSerial(Target, 0, 0)
        Else
            Target.Value2 = TimeSerial(Int(Target / 100), Target Mod 100, 0)
        End If
        Application.EnableEvents = True
     End If
End Sub

【讨论】:

BRILLIANT - 实现梦想,非常感谢 CDP1802,对于延迟反馈表示歉意。不幸的是,我遇到了代码故障,在午夜到凌晨 1 点之间的任何时间(例如 0001 或 0059)输入时,它会出现一个 whacko 日期或数字。我检查了设置为 [HH]:mm 的列格式,并且在午夜和凌晨 0001 之间以外的任何时间都可以正常工作。我已经警告用户这个故障,但是,我不知道为什么或如何自己修复它。我在 Winodws 10 上使用 Excel 365(以防这些版本存在已知问题)。你能帮忙吗?怀着感激之情,TheShyButterfly @theshybutterfly 试试n = Len(Cstr(Val(Target)))。这将删除前导零,因此 0001 的 n=1 和 0059 的 2 【参考方案2】:

我知道您是在“伸展和教”我自己解决问题,我对此表示赞赏(我肯定已经学会了如何看待类型 (1.))。但在这种情况下,“类型”作为变体/日期出现,即使它是时间(也许我误解了语法)。 – 害羞的蝴蝶

你做得很好!是的,这是查找类型的一种方法。另一种方法是使用VarType function:

Option Explicit

Sub Sample()
    Dim TimeA

    TimeA = TimeValue("01:00 PM")

    MsgBox VarType(TimeA)
End Sub

这将为您提供7,即vbDate

您还可以将时间存储为VariantDouble,如下所示。

Option Explicit

Sub Sample()
    Dim TimeA As Date
    Dim TimeB As Double
    Dim TimeC As Variant

    TimeA = TimeValue("01:00 PM")
    TimeB = TimeValue("01:00 PM")
    TimeC = TimeValue("01:00 PM")

    MsgBox "Time stored as Date : " & TimeA
    MsgBox "Time stored as Double : " & TimeB
    MsgBox "Time stored as Variant : " & TimeC

    MsgBox "TimeA formated as Date : " & Format(TimeA, "hh:mm:ss AM/PM")
    MsgBox "TimeB formated as Date : " & Format(TimeB, "hh:mm:ss AM/PM")
    MsgBox "TimeC formated as Date : " & Format(TimeC, "hh:mm:ss AM/PM")
End Sub

但是没有一个例子我该如何学习,我显然已经用尽了我的搜索来解决这个问题,但什么也没找到......我发布这个问题的原因。感谢您鼓励我继续自己解决问题:) TheShyButterfly

您可以将范围写为他的帖子中显示的CDP1802,也可以使用Application.Union method (Excel)。

例如,

Option Explicit

Sub Sample()
    Dim rngA As Range
    Dim rngB As Range
    Dim rngCombined As Range

    Set rngA = Range("R4:S1200")
    Set rngB = Range("W4:X1200")

    Set rngCombined = Union(rngA, rngB)

    MsgBox rngCombined.Address
End Sub

所以在你的代码中它变成了Intersect(rngCombined, Target) Is Nothing

另外,由于您正在使用Worksheet_ChangeEvents,我建议您查看Working with Worksheet_Change。

【讨论】:

以上是关于在 Options Explicit 下的多列中自动插入冒号 (:)的主要内容,如果未能解决你的问题,请参考以下文章

在vivado中自定义编辑器

一日一技:在Python Selenium + Chromedriver中自定义缓存路径

如何在Kendo UI网格中自定义导出excel

弹出编辑模式下的多列

在 UINavigationController 中自定义 UITabBarItem

virtuoso中自定义快捷键报错unbiund