Excel/VBA通过从VBA转置/粘贴将日期转换为美式格式
我现在在英国工作。我想我是在区域设置中设置的(企业环境中的Windows 7,Excel 2016,版本1803(我想这也可能是Office 365-?不管是什么)。我试图在VBA中处理日期,并将结果粘贴到Excel。在开始和结束时,日期以英国格式处理。但在中东,Excel坚持把它们转换成美国。粘贴操作:英国->美国->英国Excel/VBA通过从VBA转置/粘贴将日期转换为美式格式,excel,vba,date,format,transpose,Excel,Vba,Date,Format,Transpose,我现在在英国工作。我想我是在区域设置中设置的(企业环境中的Windows 7,Excel 2016,版本1803(我想这也可能是Office 365-?不管是什么)。我试图在VBA中处理日期,并将结果粘贴到Excel。在开始和结束时,日期以英国格式处理。但在中东,Excel坚持把它们转换成美国。粘贴操作:英国->美国->英国 Dim p_dtTermArray() As Date ReDim p_dtTermArray(1 To lgNumTerms) p_dtTermArray(1) = Da
Dim p_dtTermArray() As Date
ReDim p_dtTermArray(1 To lgNumTerms)
p_dtTermArray(1) = DateSerial(2018, 10, 1)
p_dtTermArray(2) = DateSerial(2018, 11, 1)
让我们看看本地窗口:
p_dtTermArray(1) #1/10/2018# Date
p_dtTermArray(2) #1/11/2018# Date
在粘贴之前,我已经清除了工作表,可以手动使用Ctrl-A-A
,Alt-E-A-A
,也可以使用…UsedRange.Clear来清除
当我写这篇文章并尝试一些事情时,情况就发生了变化
如果我这样粘贴:
rgOutput.Offset(0, 0) = p_dtTermArray(1)
rgOutput.Offset(0, 1) = p_dtTermArray(2)
我得到的Excel值为“2018年1月10日”和“2018年1月11日”,相差31天。这是正确的
但如果我这样做(一个列数组,带有转置):
前两个值为“10/01/2018”和“11/01/2018”(减去1)。所以十月和十一月变成了一月和一月,这是错误的。让我们也加入这个(行数组,无转置):
啊!!现在他们来了4337443405(它们又分开了31个)
所以这(部分)是由于转置!让我们试试:
Dim v1, v2, v3, v4, v5
v1 = p_dtTermArray
v2 = Application.Transpose(p_dtTermArray)
v3 = Application.Transpose(v1)
v4 = Application.Transpose(v2)
v5 = Application.Transpose(Application.Transpose(v1))
在v2
到v5
中,日期类型转换为字符串类型。所有字符串都是正确的(“2018年10月1日”,“2018年11月1日”,10月和11月)
因此,出于某种原因,Excel/VBA在这些字符串上使用了错误的区域设置。如果我在两个单元格中输入“1/10/2018”和“1/11/2018”,然后减去它们,我得到31。但当我的转置数组将这两个字符串放入两个单元格时,它们显示为“10/01/2018”和“11/01/2018”(并减去1)。粘贴的字符串读取为美国日期,然后转换为英国日期
我不知道还有什么地方可以找到,在一个非常特定的上下文中,可能会导致这些字符串误读的原因。避免使用日期转置是正确的做法吗(以及,什么?手动转置列向量(当您需要灵活地执行行或列操作时)
(在上面的所有示例中,工作表中的日期都是通用格式。我在粘贴之前和之后都尝试在单元格中使用日期格式,但没有任何改进。在不同的时间和地点,当我进行类似工作时,我的做法是避免在Excel单元格中使用日期,并隐藏字符串是日期这一事实(创建格式为MMM.YY的字符串),以避免Excel对其进行更改。这次,我认为只在该死的Excel中使用该死的日期可能会更好。)如果不指定单元格格式,它似乎会被该国家/地区格式的日期格式所替换。您可能希望对单元格进行适当的格式设置
根据我的测试,当我设置日期值,指定单元格格式为UK或US,然后将值放回变量时,它似乎会自动识别
我们地区的默认日期格式为yyyy-mm-dd
测试代码
Sub test()
Dim p_dtTermArray() As Date
Dim vR() As Long
Dim lgnumterms As Integer
lgnumterms = 2
ReDim p_dtTermArray(1 To lgnumterms)
p_dtTermArray(1) = DateSerial(2018, 10, 1)
p_dtTermArray(2) = DateSerial(2018, 11, 1)
ReDim vR(1 To lgnumterms)
vR(1) = DateSerial(2018, 10, 1)
vR(2) = DateSerial(2018, 11, 1)
With Range("a1").Resize(1, 2)
.Value = p_dtTermArray
.NumberFormatLocal = "dd-mm-yyyy"
End With
With Range("a2").Resize(1, 2)
.Value = vR
.NumberFormatLocal = "mm-dd-yyyy"
End With
Dim vDB, vDB2
vDB = Range("a1").Resize(1, 2)
vDB2 = Range("a2").Resize(1, 2)
End Sub
图纸图像
本地窗口
我发现当我转置日期格式的数组时,它会变成字符格式。防止这种情况的一种方法是将矩阵转换成代码
Sub test()
Dim p_dtTermArray() As Date
Dim vR() As Long
Dim lgnumterms As Integer
Dim r As Long, c As Long, i As Long, c As Long
lgnumterms = 2
ReDim p_dtTermArray(1 To lgnumterms)
p_dtTermArray(1) = DateSerial(2018, 10, 1)
p_dtTermArray(2) = DateSerial(2018, 11, 1)
ReDim vR(1 To lgnumterms)
vR(1) = DateSerial(2018, 10, 1)
vR(2) = DateSerial(2018, 11, 1)
With Range("a1").Resize(1, 2)
.Value = p_dtTermArray
.NumberFormatLocal = "dd-mm-yyyy"
End With
With Range("a2").Resize(1, 2)
.Value = vR
.NumberFormatLocal = "mm-dd-yyyy"
End With
Dim vDB, vDB2, vD() As Long, vD2() As Long
vDB = Range("a1").Resize(1, 2).Value
vDB2 = Range("a2").Resize(1, 2).Value
r = UBound(vDB, 1)
c = UBound(vDB, 2)
ReDim vD(1 To c, 1 To r)
ReDim vD2(1 To c, 1 To r)
For i = 1 To r
For j = 1 To c
vD(j, i) = vDB(i, j)
vD2(j, i) = vDB2(i, j)
Next j
Next i
Range("d1").Resize(2) = vD
Range("f1").Resize(2) = vD2
End Sub
如果未指定单元格格式,则该格式将替换为该国家/地区格式的日期格式。您可能希望适当设置单元格格式
根据我的测试,当我设置日期值,指定单元格格式为UK或US,然后将值放回变量时,它似乎会自动识别
我们地区的默认日期格式为yyyy-mm-dd
测试代码
Sub test()
Dim p_dtTermArray() As Date
Dim vR() As Long
Dim lgnumterms As Integer
lgnumterms = 2
ReDim p_dtTermArray(1 To lgnumterms)
p_dtTermArray(1) = DateSerial(2018, 10, 1)
p_dtTermArray(2) = DateSerial(2018, 11, 1)
ReDim vR(1 To lgnumterms)
vR(1) = DateSerial(2018, 10, 1)
vR(2) = DateSerial(2018, 11, 1)
With Range("a1").Resize(1, 2)
.Value = p_dtTermArray
.NumberFormatLocal = "dd-mm-yyyy"
End With
With Range("a2").Resize(1, 2)
.Value = vR
.NumberFormatLocal = "mm-dd-yyyy"
End With
Dim vDB, vDB2
vDB = Range("a1").Resize(1, 2)
vDB2 = Range("a2").Resize(1, 2)
End Sub
图纸图像
本地窗口
我发现当我转置日期格式的数组时,它会变成字符格式。防止这种情况的一种方法是将矩阵转换成代码
Sub test()
Dim p_dtTermArray() As Date
Dim vR() As Long
Dim lgnumterms As Integer
Dim r As Long, c As Long, i As Long, c As Long
lgnumterms = 2
ReDim p_dtTermArray(1 To lgnumterms)
p_dtTermArray(1) = DateSerial(2018, 10, 1)
p_dtTermArray(2) = DateSerial(2018, 11, 1)
ReDim vR(1 To lgnumterms)
vR(1) = DateSerial(2018, 10, 1)
vR(2) = DateSerial(2018, 11, 1)
With Range("a1").Resize(1, 2)
.Value = p_dtTermArray
.NumberFormatLocal = "dd-mm-yyyy"
End With
With Range("a2").Resize(1, 2)
.Value = vR
.NumberFormatLocal = "mm-dd-yyyy"
End With
Dim vDB, vDB2, vD() As Long, vD2() As Long
vDB = Range("a1").Resize(1, 2).Value
vDB2 = Range("a2").Resize(1, 2).Value
r = UBound(vDB, 1)
c = UBound(vDB, 2)
ReDim vD(1 To c, 1 To r)
ReDim vD2(1 To c, 1 To r)
For i = 1 To r
For j = 1 To c
vD(j, i) = vDB(i, j)
vD2(j, i) = vDB2(i, j)
Next j
Next i
Range("d1").Resize(2) = vD
Range("f1").Resize(2) = vD2
End Sub
谢谢你的评论,蒂姆·威廉姆斯。我没能找到那个。我的可能被称为复制品。到目前为止,我只能略过那个线索,但我的第一反应是坚持我目前的工作,避免日期转换。现在我正在制作(1xnum,1x1)数组。以后如果我遇到更多问题,我将只使用字符串而不是日期。谢谢链接。谢谢你的评论,Tim Williams。我找不到那个。我的可能会被称为重复。到目前为止,我只能略过那个线程,但我的第一反应是坚持我目前的工作方法,简单地避免转置dates.现在我正在制作(1xnum,1x1)数组。以后如果遇到更多问题,我将只使用字符串而不是日期。感谢链接。感谢回复,Dy.Lee。我认为是转置函数使日期的行为出人意料。如果你好奇,也许可以在粘贴到工作表之前尝试转置一个日期数组。(或者,通过您自己的特定设置组合,行为可能看起来很自然。)上面来自@Tim Williams的评论中的链接抓住了确切的问题。@Romniee,你说得对。我发现当我转换日期格式数组时,它会变成字符格式。防止这种情况的一种方法是将矩阵转换为代码。我附上了我的意见。谢谢你的回复,Dy.Lee。我认为这就是转换函数,使日期的行为出乎意料。如果您感到好奇,可以尝试在粘贴到工作表之前转置日期数组。(或者使用您自己的特定设置组合,这种行为可能看起来很自然。)上面@Tim Williams评论中的链接抓住了确切的问题。@Romniee,你是对的。我发现当我转换日期格式数组时,它会变成字符格式。防止这种情况的一种方法是将矩阵转换为代码。我附上了我的意见。