【问题标题】:VBA - Find date within text containing format 'DDMMYYYY'VBA - 在包含格式“DDMMYYYY”的文本中查找日期
【发布时间】:2015-11-15 05:10:09
【问题描述】:

我已经扫描并找到了许多与我的问题相似的答案,尽管没有一个完全符合要求,所以我将解释我所追求的并希望它有意义:

  • 我已将数据从 TXT 导入到 Excel 电子表格(使用 2007),其中包含各种日期(均采用 DDMMYYYY 格式)。
  • 我要做的是创建一个子例程,它会查找这种格式的任何日期,然后将日期减少 1 年。
  • 日期在导入 TXT 时的范围内(在这种情况下,前 2 个日期出现在范围 A6 下)所以理想情况下我想指定该范围,因为我不一定要减少所有存在的日期在 TXT 中。

例如,这是错误的代码,我确信需要认真调整!

    Cells.Replace What:="Dates", Replacement:="Dates-1", LookAt:=xlPart,    _
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=DDMMYYYY, _
    ReplaceFormat:=False 

我认为在上述代码之类的任何东西都可以工作之前,需要先进行一些定义,但如果有人可以提供帮助,我将不胜感激!

非常感谢,

罗宾。

【问题讨论】:

  • 如果你知道如何定义你的范围以减少一年,你可以简单地使用 cell.Value = Left(cell.Value, 4) & Right(cell.Value, 4) - 1
  • 嗨,Fabrizio,我不知道怎么做,但我想这是我可以扩展的。 - 感谢您提供正确的路径!
  • 请选择这些导入的日期之一,切换到 VB 编辑器,在即时窗口中输入 ? vartype(activecell) 并按 Enter。如果 Excel 认为它是日期,它将显示 7。我希望您会得到 5 或 8,因为我不相信导入的值是日期;它们只是看起来像日期。
  • 我不知道如果答案被修改,您是否会收到消息,所以此评论是为了确保您知道我在答案中添加了更多句子。正如我在之前的评论中所说,我相信这些日期实际上是数字或字符串。新句子解释了如果有数字或字符串我将如何处理。

标签: excel date replace find vba


【解决方案1】:

我认为任何调整都不会让您的代码达到您想要的效果。我不能给出明确的答案,因为我不太相信你的描述。我希望下面的信息能让您调查您的数据并制定适当的解决方案。

据我所知,您没有正确使用SearchFormat。你需要这样的东西:

With Application.FindFormat
  .Font.Bold = True
End With

Set Rng = .Find(. . .  SearchFormat = True  . . .)

Find 的 VBA 编辑器帮助指出:“SearchFormat 可选Variant。搜索格式。”但没有举例说明这意味着什么。我找不到使用不属于上述样式的查找格式工具的示例。即:您使用FindFormat 指定感兴趣的格式并将SearchFormat 设置为True 以指示要搜索这些格式。

你可以试试:

With Application.FindFormat
  .NumberFormat = "DDMMYYYY"
End With

我没有尝试过,也找不到任何说明可以搜索哪些格式类型的文档。如果这行得通,那么根据以下信息,它几乎肯定会比任何事情都更快、更容易。

要让 Excel 将文本文件中的字符串作为日期导入,它必须:

  • 将字符串识别为日期。
  • 将该字符串转换为数字。
  • 以数字格式存储该数字,表明它是一个日期。

Excel 将日期存储为自 1900 年 1 月 1 日以来的天数。例如,“21 August 2015”将存储为 42238,数字格式为“dd mmmm yyyy”。单元格值没有任何内容表明它是日期。您可以将单元格值输入为 42238,然后将数字格式设置为“dd mmm yy”,该值将显示为“21 Aug 15”。

您的描述暗示日期在文本文件中保存为 Excel 识别为日期的八位数值,因此将数字格式设置为“DDMMYYYY”。我从来没有设法让 Excel 将八位数的值识别为日期。如果你成功了,我想知道如何。

我最好的建议是:

For Each CellCrnt in RngImport
  If CellCrnt.NumberFormat = "ddmmyyy" Then
    ' Add year to date
  End If
Next

扩展

如果您针对您的问题执行我在评论中要求的操作,我们应该能够识别您希望查找和修改的值的类型。此扩展说明了您可以如何使用这些信息。

在我之前的代码中,我使用RngImport 来表示导入数据的范围。你的一句话让我想知道:你知道如何初始化那个 Range 吗?

我们是否必须在整个范围内搜索这些“日期”?也就是说,是分散在数据中还是仅限于单列?如果我们不必检查每个单元格,最终的代码会更快。

我的猜测是我们需要类似的东西:

If IsDate(Mid(CellValue,1,2) & "/" & Mid(CellValue,3,2) & "/" & Mid(CellValue,5,4)) Then

将“ddmmyyyy”转换为“dd/mm/yyyy”,然后将新字符串测试为日期。

【讨论】:

  • 除非我错误地使用了你的建议,否则这一次也没有运气! ://
  • 感谢您的所有建议。 - 我似乎仍然无法让它工作。 - 我猜最大的问题是包含 DDMMYYYY 格式的日期的每一行的长度可能会改变,因此定义它不一定有帮助。如果有人有任何进一步的建议,我将不胜感激!
  • 您好,我已经获得了一个解决方案,使用了您的一些建议以及与识别范围相关的初步建议,然后使用“MID”来指定距离。 - 我可以添加一年,然后用更新的年份替换整个字符串......这似乎可行。我的下一个问题是我需要能够通过输入框指定确切的日期,然后替换,但我会在问另一个问题之前深入研究它! - 谢谢你的帮助。 :)
【解决方案2】:

这是我的建议:

Sub OneYearEarlier()
    Dim c As Range
    Dim dt As Date

    For Each c In Selection
        If c.NumberFormatLocal = "TT.MM.JJJJ" Then
            dt = DateAdd("yyyy", -1, c.Value)
            c.Value = dt
        End If
    Next c
End Sub

首先,我认为您必须将单元格值作为 Date 数据类型处理,而不是作为字符串处理。这将避免上溢或下溢,如果不是减少一年而是其他时间间隔(例如一个月。
其次,正如其他人所提到的,您无法可靠地检测到数字是 XL 中的日期。我的代码使用
- 仅限您事先选择的单元格(例如一列)
- 仅具有日期格式的单元格

我在这里使用NumberFormatLocal,以便格式字符串与您在格式对话框/“自定义格式”中看到的相同。但这在这里并不重要,只是为了方便。

我真的不喜欢同时使用“内部”格式字符串“yyyy”和本地化格式字符串“JJJJ”,但这正是DateAdd 想要的方式。

【讨论】:

  • 你好,我试过这个但不幸的是它崩溃了系统! :/ 我得到的最接近的是在使用代码的改编版本时尝试生成一个 msgbox。 - 不幸的是,这一切都证明它没有从文本行中获取日期。
  • 好的,如果你选择一个带有日期的单元格并启动VBA编辑器(ALT-F11),它说的格式是什么(直接窗口,“?selection.numberformatlocal”?在这里测试过它奏效了(德语 XL 2003)
  • 我认为混淆是虽然字符串包含日期信息,它恰好以 DDMMYYYY 格式表示,但字符串包含各种其他数据;因此不能定义为日期? - 我知道如果单元格被分配了“日期”格式,它将获取 numberformat.local,但我无法更改整个单元格的格式,因为这可能会导致剩余数据出现问题。 - 我希望这是有道理的。
  • 您能否编辑您的原始问题以显示示例单元格、内容和格式?如果日期周围的单元格中有其他文本,那么您必须使用字符串操作来获取日期值,减少它并重新构建单元格内容。
【解决方案3】:

您始终可以创建自己的 RegEx 函数来简化:

    Function RegEx(Target As String, RegExpression As String, _
                   Optional ReplaceString As String, Optional xIgnoreCase As Boolean, _
                   Optional xGlobal As Boolean, Optional xMultiLine As Boolean)
    
        Dim regexOne As Object
                
        Set regexOne = New RegExp
        regexOne.Pattern = RegExpression
        If xIgnoreCase Then regexOne.IgnoreCase = xIgnoreCase
        If xGlobal Then regexOne.Global = xGlobal
        If xMultiLine Then regexOne.MultiLine = xMultiLine
        
        If regexOne.Test(Target) Then
            If IsMissing(ReplaceString) Then
                RegEx = regexOne.Execute(Target)
            Else
                RegEx = regexOne.Replace(Target, ReplaceString)
            End If
        End If
            
    End Function

【讨论】:

  • 请不要在不同的问题中添加identical answers。您需要自定义答案以解决问题。在这个 cae 中,解释如何使用你的函数来解决 OPs 问题
猜你喜欢
  • 1970-01-01
  • 2018-01-28
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-10
  • 2016-02-22
  • 1970-01-01
相关资源
最近更新 更多