从日期中删除存储在数组中的整个数据的时间
Posted
技术标签:
【中文标题】从日期中删除存储在数组中的整个数据的时间【英文标题】:Removing time from date for an entire data stored in an array 【发布时间】:2015-11-05 07:14:35 【问题描述】:使用 Excel VBA,我如何将公式 Date(year(A1),Month(A1),Day(A1))
应用于整个列中的所有日期?目前数据采用日期时间格式(例如 1995 年 4 月 30 日上午 9:35:00),但我只想要日期 - 1995 年 4 月 30 日。
目前所有的日期都存储在一个数组中,我试过Columns(data_column).NumberFormat = "[$-1009]d-mmm-yy;@"
,
但我没有成功从日期中删除时间。
【问题讨论】:
您是否有理由要在 VBA 中执行此操作,而不是仅在单元格中输入公式并向下拖动公式?我很困惑,因为第一段说您想将其应用于列中的日期,而第二段说日期存储在数组中。您使用的是预先存在的 VBA 代码吗? 是的,我正在使用一个预先退出的 VBA 代码。否则我只会使用公式,但我无法修改原始数据库。 【参考方案1】:如果您想在保留时间信息的同时更改数据的显示格式,可以在工作表或图表轴的单元格中使用 NumberFormat = "mm/dd/yyyy" 之类的内容。
Excel 将日期/时间信息存储为浮点数。天在小数点的左边,天的小数部分 (hh:mm:ss) 在右边。如果您想从基础数据中剔除时间信息,则转换为 Long,然后再转换回 Date。在 VBA 中(感谢 T.M. 的更正):
DateOnly = CDate(Int(DateTime))
在工作表公式中,只需转换为 Int 并随意格式化
DateOnly = INT(DateTime)
希望有帮助
【讨论】:
(Late) 旁注 :-) 考虑到CLng
函数向上舍入到第二天所有中午之后的下午几个小时,这可能会返回不需要的结果。所以在代码行中使用VBA的Int
或Fix
函数是完全可以的:DateOnly = CDate(Int(DateTime))
@xidgel【参考方案2】:
Excel 中的所有日期都包括时间:datetime。不能仅在单元格中存储日期或时间。原因是 Excel 将它们存储为数字。小数点前为日期,小数点后为时间。因此,即使您将数字 42000 放入单元格(小数点后没有任何内容)并将该单元格的格式更改为日期,该值仍将是 2014 年 12 月 27 日(1899 年 12 月 31 日之后的 42000 天)假定时间为零 = 早上 00:00:00。
由于所有数字都可能有小数点后的内容,因此所有日期在 Excel 中都有时间,所有时间都有日期。
您唯一能做的就是:格式化单元格以仅显示日期部分或时间部分或两者兼而有之。所以,你需要做的就是隐藏时间。
如果要将所有日期更改为小数点后为零,则必须遍历数字并将所有值更改为 INT 值。
For intColumn = 1 to 1000
If Sheet1.Cells(1, intColumn).Value2 = vbNullString then Exit For
Sheet1.Cells(1, intColumn).Value2 = Int(Sheet1.Cells(1, intColumn).Value2) ' Do not use CInt but Int only!
next intColumn
【讨论】:
如何隐藏时间或使其归零? @absundo:使用.NumberFormat
更改单元格的格式。如果您不知道您想要哪种格式,那么只需右键单击一个单元格,将其格式化为日期,单击确定,然后进入 VBA 并写入直接窗口:? Selection.NumberFormat
这就是您要应用的格式。 【参考方案3】:
从日期中删除存储在数组中的整个数据的时间
IMO 这个问题是询问如何直接在包含日期的数组中更改值,包括时间指示。 因此,我将以下示例代码作为对上述有效解决方案的补充,演示如何
从数据列中获取一个从零开始的一维数组(无循环), 使用 VBA 的Fix
函数 * 执行时间删除(在循环中)以删除日期值的小数部分并
(可选择将数组写回任何想要的列)
*) 使用CLng
代替Fix
(或Int
)会将中午之后的下午时间四舍五入到第二天。
示例代码
假设日期值,例如在B:B
列中(省略标题行)。
Sub chngDateArray()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("MySheetName") ' << change to your sheet name string
Dim lastRow&, i&, arr
lastRow = ws.Range("B" & ws.Rows.Count).End(xlUp).Row
' [1a] assign dates to (1-based) 2-dim datafield array
arr = ws.Range("B2:B" & lastRow).Value2 ' get date values as numbers
' [1b] rearrange to (0-based) 1-dim array
arr = Application.Transpose(arr): ReDim Preserve arr(0 To UBound(arr) -1) ' make it a "flat" (zero-based) array
' [2] eliminate time portions and reconvert to date
For i = 0 To UBound(arr)
arr(i) = CDate(Fix(arr(i))) ' cut time portions from entire dates
Next i
' Debug.Print Join(arr, "|") ' check in immediate window
' [3] optional: write back array to any wanted column (e.g. D:D)
ws.Range("D2").Resize(UBound(arr), 1).Value2 = Application.Transpose(arr)
End Sub
补充说明
在[1a]
部分中使用.Value2
允许仅以数字形式获取日期。 [2]
部分中重新转换为日期格式最终允许通过NumberFormat
将数组数据写回[3]
部分中的任何所需列无需事先列格式。
【讨论】:
【参考方案4】:除了上述之外,您还应该能够使用DateValue()
或Format()
从这些字符串中提取日期,如下所示:
DateValue("30/04/1995 9:35:00 AM")
Format("30/04/1995 9:35:00 AM", "dd/mm/yyyy")
【讨论】:
以上是关于从日期中删除存储在数组中的整个数据的时间的主要内容,如果未能解决你的问题,请参考以下文章