VBA强制字符串变量为英国日期格式

时间:2013-04-30 13:52:20

标签: excel-vba vba excel

编辑:经过一些阅读后,我遇到了一个我在下面发布的答案。

好的,所以我一直在寻找可通过www.contextures.com获得的VBA。有问题的代码使用户能够将多个条目添加到由逗号分隔的数据验证列表中。该列表允许用户从日期列表中选择,以及一小组文本条目。它的工作方式是用户可以自由键入日期,或使用选择列表选择日期或文本条目。有时两个日期可能需要进入单元格,因此下面的VBA允许用户选择/键入一个日期,按Enter键,然后在同一单元格中键入另一个日期。一旦他们按Enter键,上一个日期就会出现在单元格中,新日期后面会用逗号分隔。到目前为止一切都很好。

这是VBA的原创作品。

Option Explicit
' Developed by Contextures Inc.
' www.contextures.com
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
If Target.Count > 1 Then GoTo exitHandler

On Error Resume Next
Set rngDV = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitHandler

If rngDV Is Nothing Then GoTo exitHandler

If Intersect(Target, rngDV) Is Nothing Then
   'do nothing
Else
  Application.EnableEvents = False
  newVal = Target.Value
  Application.Undo
  oldVal = Target.Value
  Target.Value = newVal
  If Target.Column = 3 Then
    If oldVal = "" Then
      'do nothing
      Else
      If newVal = "" Then
      'do nothing
      Else
      Target.Value = oldVal _
        & ", " & newVal
      End If
    End If
  End If
End If

exitHandler:
  Application.EnableEvents = True
End Sub

现在,我遇到的问题是VBA有效,但是,因为我是英国人,只要我在VBA适用的单元格中输入英国日期(例如01/06/2013即dd / mm / yyyy),VBA正在介入并将日期恢复为06/01/2013(mm / dd / yyyy)。我的控制面板设置都设置为uk格式,所以我认为它与VBA的存储方式有关,然后返回日期。我已经尝试修改dims oldval和newval(到日期)但是然后VBA不允许我像以前一样在一个单元格中有多个条目(我猜vba不喜欢连接日期?)。

我已经修改了VBA到一个hacky work(下面),它将日期格式化为非标准dd.mm.yyyy(dd / mm / yyyy不起作用)但这需要我告诉用户以这种格式输入日期,我宁愿不这样做(我宁愿允许更标准的01/01/2013或01-01-2013,这两者都被excel认可为日期):

Option Explicit
' Developed by Contextures Inc.
' www.contextures.com
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
If Target.Count > 1 Then GoTo exitHandler

On Error Resume Next
Set rngDV = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitHandler

If rngDV Is Nothing Then GoTo exitHandler

If Intersect(Target, rngDV) Is Nothing Then
   'do nothing
Else
  Application.EnableEvents = False
  newVal = Format(Target.Value, "dd.mm.yyyy") 'amendment
  Application.Undo
  oldVal = Format(Target.Value, "dd.mm.yyyy") 'amendment
  Target.Value = newVal
  If Target.Column > 1 Then 'amendment
    If oldVal = "" Then
      'do nothing
      Else
      If newVal = "" Then
      'do nothing
      Else
      Target.Value = oldVal _
        & ", " & newVal
      End If
    End If
  End If
End If

exitHandler:
  Application.EnableEvents = True
End Sub

无论如何,任何建议/指针将不胜感激!我正在使用Excel 2007,但电子表格需要与2003兼容。

编辑:数据的显示方式如下:Excel 2003 - How to count dates in row, including multiple dates in cell

编辑:我还应该提一下,如果我将01/07/2013输入一个单元格两次,它会出现如下:

07/01 / 2013,01 / 07/2013

这很奇怪。就像第一次填充单元格一样,它将其切换为美国日期格式,但之后的任何内容都可以。我将尝试在同事的机器上测试,并在家用PC上查看结果。

4 个答案:

答案 0 :(得分:2)

好的,所以在这里阅读这篇文章之后:http://allenbrowne.com/ser-36.html 我对代码做了一些调整:

 Option Explicit
' Developed by Contextures Inc.
' www.contextures.com
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
If Target.Count > 1 Then GoTo exitHandler

On Error Resume Next
Set rngDV = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitHandler

If rngDV Is Nothing Then GoTo exitHandler

If Intersect(Target, rngDV) Is Nothing Then
   'do nothing
Else
  Application.EnableEvents = False
  'newVal = Target.Value 'amendment
  newVal = Format(Target.Value, "\ dd\/mm\/yyyy\")

  Application.Undo
  'oldVal = Target.Value 'amendment
  oldVal = Format(Target.Value, "\ dd\/mm\/yyyy\")
  Target.Value = newVal
  If Target.Column > 1 Then 'amendment
    If oldVal = "" Then
      'do nothing
      Else
      If newVal = "" Then
      'do nothing
      Else
      Target.Value = oldVal _
        & ", " & newVal
      End If
    End If
  End If
End If

exitHandler:       Application.EnableEvents = True     结束子

重要的一点似乎是格式:

oldVal = Format(Target.Value, "\ dd\/mm\/yyyy\")

艾伦建议的代码是:

Format$(varDate, "\#mm\/dd\/yyyy\#")

我将它更改为dd / mm并将#替换为空格,嘿presto - 它似乎正在工作!这是一个非常令人沮丧的问题,我现在必须确保在其他用户机器上工作!感谢@ sous2817和@GSerg的意见/建议。

答案 1 :(得分:0)

这似乎对我有用......除非我想念你的问题......

newVal = Format(Sheet1.Range("A1"), "dd/mm/yyyy;@")

完整的代码:

Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngDV As Range
Dim oldVal As String
Dim newVal As String
If Target.Count > 1 Then GoTo exitHandler

On Error Resume Next
Set rngDV = Cells.SpecialCells(xlCellTypeAllValidation)
On Error GoTo exitHandler

If rngDV Is Nothing Then GoTo exitHandler

If Intersect(Target, rngDV) Is Nothing Then
   'do nothing
Else
  Application.EnableEvents = False
  newVal = Format(Target.Value, "dd/mm/yyyy;@") 'amendment
  Application.Undo
  oldVal = Format(Target.Value, "dd/mm/yyyy;@") 'amendment
  Target.Value = newVal
  If Target.Column > 1 Then 'amendment
    If oldVal = "" Then
      'do nothing
      Else
      If newVal = "" Then
      'do nothing
      Else
      Target.Value = oldVal _
        & ", " & newVal
      End If
    End If
  End If
End If

exitHandler:
  Application.EnableEvents = True
End Sub

答案 2 :(得分:0)

我遇到了类似的问题 - 我的 VBA 代码将一个单元格值作为英国格式“DD/MM/YYYY”的字符串写入本地日期格式设置为 DD/MM/YYYY 的单元格中,但日期以美国格式出现月/日/年。

上述讨论非常有助于将其识别为 VBA 正在做的事情而不是我的代码。为了解决这个问题,我编写了一个函数将我的英国日期字符串转换为美国格式日期字符串,并将美国格式日期字符串写入单元格。 VBA 然后在工作表中将美国日期处理成英国日期,这正是我想要的!

公共函数MM_DD_YYYY(DD_MM_YYYY As String) As String ' 函数将日期格式从 DD/MM/YYYY 切换为 MM/DD/YYYY Dim DD 作为字符串 将 MM 调暗为字符串 将 YYYY 调暗为字符串 DD = 左(DD_MM_YYYY,2) MM = Mid(DD_MM_YYYY, 4, 2) YYYY = 右(DD_MM_YYYY, 4) MM_DD_YYYY = MM & "/" & DD & "/" & YYYY 结束函数

答案 3 :(得分:-1)

这个小小的变化对我来说非常合适。

newVal = Format(Sheet1.Range(“ A1”),“ mm-dd -yyyy; @”)

我的VBA选择的日期是美国格式(mm-dd-yyyy)。我想要英国格式(dd-mm-yyyy)

我只是使用上面的代码读取了美国格式本身的值,所以VBA会正确选择日期和月份。 最终,因为我的系统设置基于英国,所以最终结果是英国格式。