【问题标题】:Convert month in String format to Number in Word Macros将字符串格式的月份转换为 Word 宏中的数字
【发布时间】:2019-07-31 19:21:36
【问题描述】:

我正在使用一个必须将日期转换为另一种格式的 Word 宏。

输入:2019 年 10 月 10 日

预计输出:2019 年 10 月 3 日

问题是日期的月份是字符串(10 de Marzo de 2019)。 我找不到将该日期转换为 dd/mm/YYYY 的方法。

到目前为止,我发现的所有内容都从 dd-mm-YYYY 转换为文本日期。

上面的代码可以使用字符串月份或其他格式从 dd/mm/yyyy 转换为日期,但它从不进入 isDate() 函数。如果我删除 isDate() 函数,格式不会执行。

这是我目前所拥有的:

Sub ChangeDates()

FoundOne = True ' loop at least once

Do While FoundOne ' loop until no date is found
    With Selection.Find
        .ClearFormatting
        .Replacement.ClearFormatting
        .Text = "([0-9]{1,2}) de (*) de ([0-9]{4})"
        .Format = True
        .Forward = True
        .MatchWildcards = True
    End With

    Selection.Find.Execute replace:=wdReplaceNone

    ' check the find to be sure it's a date
    If IsDate(Selection.Text) Then
        Selection.Text = Format(Selection.Text, "dd-mm-yyyy")
        Selection.Font.Color = wdColorLightOrange
        Selection.Collapse wdCollapseEnd
    Else ' not a date - end loop
        FoundOne = False
    End If
Loop

End Sub

有没有办法做到这一点? 提前致谢!

【问题讨论】:

  • (第 1 部分)我还没有解决这个问题,所以不能将此添加为有用的答案。但是,您的搜索基于三个元素 - 1 位或 2 位数字的日期、希望为一个月的字符串和 4 位数字的年份。如果您可以使用这三个元素(正则表达式?)打破找到的组合,然后您可以将其传递给另一个自定义函数,该函数确认日期部分对有效的月份名称有效,然后将这三个部分缝合在一起以创建一个日期.
  • (第 2 部分)如果我要创建这样的函数,我将传递变量 ByRef 并使用该函数返回一个布尔值,指示它是否是有效日期。用法可以像FoundOne = MyParseDate(selectedString) 一样简单,或者在其下方添加一行(如果TRUE)将现在更改的selectedString 调整为您想要的任何日期格式,因为您的函数会将其更改为Word 可接受的格式.
  • 另一个最后的想法 - 在寻找月份部分时,请考虑 [Jan|Feb|someOtherValidMonthText ...etc ... ] 而不是 (*),它会减少您的误报(如果您目前有任何误报)

标签: vba date ms-word


【解决方案1】:

试试:

Sub Demo()
Application.ScreenUpdating = False
Dim i As Long
With ActiveDocument.Range
  With .Find
    .ClearFormatting
    .Replacement.ClearFormatting
    .Text = "<[0-9]{1,2} de <*> de [0-9]{4}>"
    .Replacement.Text = ""
    .Forward = True
    .Wrap = wdFindStop
    .Format = False
    .MatchCase = False
    .MatchWholeWord = False
    .MatchWildcards = False
    .MatchSoundsLike = False
    .MatchAllWordForms = False
    .Execute
  End With
  Do While .Find.Found
    Select Case LCase(Split(.Text, " de ")(1))
      Case "enero": i = 1
      Case "febrero": i = 2
      Case "marzo": i = 3
      Case "abril": i = 4
      Case "mayo": i = 5
      Case "junio": i = 6
      Case "julio": i = 7
      Case "agosto": i = 8
      Case "septiembre": i = 9
      Case "octubre": i = 10
      Case "noviembre": i = 11
      Case "diciembre": i = 12
      Case Else: i = 0
    End Select
    Select Case i
      Case 0
      Case Else: .Text = Split(.Text, " de ")(0) & "/" & Format(i, "00") & "/" & Split(.Text, " de ")(2)
    End Select
    .Collapse wdCollapseEnd
    .Find.Execute
  Loop
End With
Application.ScreenUpdating = True
End Sub

【讨论】:

    【解决方案2】:

    为了让 Word-VBA 识别日期,数据必须与日期的系统设置相匹配。例如,如果系统设置为美式英语,则问题中的日期不会被识别为有效日期,只会识别美式英语的日期。

    VBA 代码需要包含将文本内容解析为特定语言的日期的逻辑。然后它需要将其转换为与系统日期匹配的日期,以便Format 函数起作用,或者它还需要处理格式转换。

    【讨论】:

      【解决方案3】:

      我已经尝试过@macropod,尽管它对我不起作用,但我知道他的解决方案是有效的(可能是一些与语言有关的 Word 问题),一些更改应该可以使它工作,所以也可以随意使用它。

      我接受了@Cindy Meister 的建议,这就是代码。这种方法的缺点是您必须进行两次搜索而不是一次,但优点是您使用 Word Format 内置功能并且可以随时更改格式。

      Private Sub FechasEnTexto()
      
      'We take the date to english format (dd M, Y)
      With ActiveDocument.Range.Find
           .Text = "([0-9]{1,2}) de (*) de ([0-9]{4})"
           .Replacement.Text = "\1 \2, \3"
           .Forward = True
           .MatchWildcards = True
           .Execute replace:=wdReplaceAll
      End With
      
      
      'Here we look for the english format, and proceed to apply the format desired.   
      Selection.HomeKey Unit:=wdStory, Extend:=wdMove
      FoundOne = True ' loop at least once
      
      
      Do While FoundOne ' loop until no date is found
          With Selection.Find
              .ClearFormatting
              .Replacement.ClearFormatting
              .Text = "([0-9]{1,2}) (*), ([0-9]{4})"
              .Format = True
              .Forward = True
              .MatchWildcards = True
          End With
      
          Selection.Find.Execute replace:=wdReplaceNone
      
      
          ' check the find to be sure it's a date
          If IsDate(Selection.Text) Then
              Selection.Text = Format(Selection.Text, "dd/mm/yyyy")
              Selection.Collapse wdCollapseEnd
          Else ' not a date - end loop
              FoundOne = False
          End If
      Loop
      
      
      End Sub
      

      【讨论】:

      • 您指的是«可能是一些 Word 语言问题»。您的示例文本似乎是西班牙语,所以这就是我编码的目的。但是,很明显,如果不是全部是西班牙语和/或您的日期并非全部按照您的示例进行格式化,则 Find 将不起作用 - 其余代码也不起作用。
      • 确实是西班牙文,示例和我预期的格式一样。
      • 如果日期保存在字段(例如表单字段、日期、创建日期)或 ActiveX 控件中,则查找/替换不会更新它们 - 您需要编辑实际字段和 ActiveX 控件。同样,如果它们在文本框、页眉、页脚、脚注等中,查找/替换宏也不会找到它们,除非它被专门编码。
      【解决方案4】:

      Nicolas,也许在您的 IF 语句之前使用 NumberFormat。这样,您将设置格式以保证 IsDate 表达式将读取为 True,因此您的 IF 条件将得到满足。

      Selection.NumberFormat = "dd-mm-yyyy"
      If IsDate(Selection.Text) Then
          Selection.Text = Format(Selection.Text, "dd-mm-yyyy")
          Selection.Font.Color = wdColorLightOrange
          Selection.Collapse wdCollapseEnd
      Else ' not a date - end loop
          FoundOne = False
      End If
      

      【讨论】:

      • 您的建议与 Word 环境无关 - Word 不是 Excel。它没有Selection.NumberFormat 属性,也不将日期存储为数字。 Word 将日期存储为文字字符串。
      • 谢谢,但我认为这是发给 Nicolas 的帖子...所有 cmets 和答案都应该是尝试以加深他的知识和信心。当我发布一些东西时,我会告诉你;你上面的评论会更适合那里。后来,丹尼。
      • Nicolas 无法使用此信息,因为代码位于 Word VBA 中。所有这一切都会混淆情况,因为该建议在该环境中不起作用。在这种情况下,这只是噪音。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多