2013-04-30 31 views
3

编辑:经过一些阅读,我遇到了一个我在下面发布的答案。VBA强制字符串变量为英文日期格式

好的,所以我一直在寻找一块VBA,可通过www.contextures.com。这段代码使用户能够将多个条目添加到由逗号分隔的数据验证列表中。该列表允许用户从日期列表中进行选择,并且还可以选择一小部分文本条目。它的工作方式是用户可以自由输入日期,或使用选择列表选择日期或文本输入。有时两个日期可能需要进入单元格,因此下面的VBA允许用户选择/键入一个日期,按回车键,然后在同一单元格中键入另一个日期。只要他们一进入,前一个日期就会出现在单元格中,新的日期之后用逗号分隔。到现在为止还挺好。

这是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将进行干预并将日期返还为2013年6月1日(年/月/年)。我的控制面板设置都设置为uk格式,所以我认为这与VBA存储方式有关,然后返回日期。我已经尝试修改dims oldval和newval(到日期),但是VBA不允许我像以前一样在一个单元中有多个条目(我猜vba不喜欢连接日期?)。

我已经修改了VBA到周围(下面)将日期格式化为非标准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到单元格的两倍,它出来是这样的:

2013年7月1日,2013年1月7日

这是非常奇怪的。这就像单元格第一次填充它将其切换到美国的日期格式,但之后的任何事情都可以。我将尝试在同事的机器上和我的家用电脑上测试,看看结果如何。

+0

No-repro。 VBA在隐式转换中使用系统设置。请检查应用于单元格的显示格式。 – GSerg 2013-05-01 11:01:48

+0

@GSerg:应用于单元格的格式是Date> type * 14/03/2001,并且语言环境设置为英语(U.K。)。我也试过14/03/2001,但没有区别。试着在不同的机器上测试,看看我是否得到不同的结果。 – bawpie 2013-05-01 11:38:25

回答

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: 应用程序。enableEvents方法=真 结束子

最重要的一点似乎是格式:

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

Allen的建议代码为:

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

我改成了DD/MM和替换#随一个空间,嘿presto - 它似乎工作!尽管这是一个非常令人沮丧的问题,我现在必须确保在其他用户机器上有效!感谢@ sous2817和@GSerg的意见/建议。

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 
+0

谢谢@ sous2817,但使用它,如果我输入一个日期到B2它只是消失完成(Excel 2007)?我已经更新了我的问题,试图让我的想法更清晰一些。 – bawpie 2013-05-01 09:33:21

+0

@bawpie:我编辑了我的帖子以包含整个方法。在我的测试表上,它的工作原理与您的想法完全相同。在B列中输入一个日期:C,你会得到一个以逗号分隔的日期列表,这些列表中的日期已格式化为更“UK”的格式。 – sous2817 2013-05-01 11:03:05

+0

这是非常奇怪的。我建立了一个全新的工作簿,在2013年1月1日至2013年12月31日的k列中列出日期列表,并将其命名为“列表”。我已经进入数据验证并将其应用到列B,告诉它允许列表,并将源设置为=列表。单元格的格式是日期,* 14/03/2001,英国语言环境,但仍然从列表中选择01/07/2013或自由输入时,它将转换为07/01/2013。我将在今晚的家用电脑上试试这个功能,看它是否能够复制。 (这是使用您的发布代码)。感谢你的协助! – bawpie 2013-05-01 11:26:31