1

我正在尝试将整个工作表或一系列数据从一个工作簿复制到另一个工作簿。我可以手动成功地做到这一点,方法是选择所有包含数据的单元格并粘贴到新创建的工作表中(保持日期格式)。但是,当我尝试通过 VBA 执行此操作时,任何一天大于 12 的日期都会转换为文本 [美国 (m/dd/yyyy)/澳大利亚 (dd/mm/yyyy) 格式更改]。我已经尝试将单元格首先格式化为美国格式日期,但这没有帮助。有什么建议吗?

仅供参考 - 源数据来自由 VBA 打开的 CSV 文件 - 日期值是在打开时自动转换为日期的文本(例如“2/08/2013”​​或“31/07/2013”​​)(IsNumber = True 和IsText = 假)。

打开的 CSV 看起来像这样(3000 奇数行的样本):请注意,“日期”和“上次更新”字段采用 dd/mm/yyyy hh:mm 格式

Id          Title     Division  Status  Date                Last update
REQ:7619    Job Details ICTIS   InProg  31/07/2013 13:03    6/08/2013 15:51
REQ:7617    Job Details ICTIS   InProg  31/07/2013 12:06    2/08/2013 11:34
REQ:6994    Job Details ICTIS   Open    31/07/2013 12:05    31/07/2013 12:05
REQ:7613    Job Details MNHD    User    31/07/2013 12:01    1/08/2013 15:59
INC:79210   Job Details ICTIS   Open    31/07/2013 12:00    31/07/2013 12:00

代码的简单摘录:

'Select all Data Cells
Sheets(1).Cells(1, 1).Activate
ActiveCell.SpecialCells(xlLastCell).Select
LastRow = ActiveCell.Row

'Format Date Fields to avoid automatic translation issue
'This does not help problem... so commented out
'Columns("M:M").Select
'Selection.NumberFormat = "m/d/yyyy"

'Select all data in sheet and copy
range("A2:" & LastCol & LastRow).Select
selection.Copy

'Rest of code moves to previous sheet and copies into cell A8

运行上述代码后的相同文件。请注意 day>12 的日期与 day<=12 的日期的处理方式不同。2013 年 7 月 31 日添加了“PM”,而 2013 年 6 月 8 日和 2013 年 2 月 8 日则交换了日期和月份!

Id          Title     Division  Status  Date                Last update
REQ:7619    Job Details ICTIS   In Progress 31/07/2013 1:03:49 PM   8/06/2013 15:51
REQ:7617    Job Details ICTIS   In Progress 31/07/2013 12:06:31 PM  8/02/2013 11:34
REQ:6994    Job Details ICTIS   Open    31/07/2013 12:05:50 PM  31/07/2013 12:05:50 PM
REQ:7613    Job Details MNHD    With User   31/07/2013 12:01:46 PM  8/01/2013 15:59
INC:79210   Job Details ICTIS   Open    31/07/2013 12:00:52 PM  31/07/2013 12:00:52 PM

我的快速解决方法是将代码分成两部分 - 由 MsgBox 提示手动复制/粘贴。不是很优雅!!并且容易出错。

4

3 回答 3

3

我过去也遇到过同样的问题。我可以确认使用宏打开 CSV 时会出现问题 - 运行 vba excel 时默认使用美国日期格式打开,而手动打开 CSV 时它使用本地日期格式。不需要任何解决方法的简单解决方法是指示 VBA 使用您的本地日期格式打开 CSV,如下所示。

我损坏的代码的相关行:

Set wbkData = Workbooks.Open(strDataDir & strDataFName)

和固定线路:

Set wbkData = Workbooks.Open(strDataDir & strDataFName, local:=True)
于 2016-04-28T03:13:29.700 回答
0

在这个答案中,我描述了两种实现您描述的错误的方法。如果其中一种方法与您正在执行的操作相匹配,您可以修改代码以避免错误。如果这还不够,那么我需要查看更多代码,然后才能提出补救建议。您可以将完整的代码添加到您的答案中,或者您可以使用我个人资料中的地址将其通过电子邮件发送给我。

我花了很多实验来复制您的错误,但我现在可以通过两种方式将日期损坏为中端格式。(中端似乎是 m/d/y 日期格式的首选学术描述,其中 d/m/y 和 y/m/d 格式称为小端和大端。)

本质上,问题在于 Excel 总是有几种方法可以达到相同的效果。这里的效果是将字符串转换为日期。

方法 1 是使用国家代码来确定本地日期格式。如果您居住在当地日期格式为 d/m/y 的国家/地区,那么使用这种方法,“06/08/2013”​​将转换为“2013 年 8 月 6 日”。

方法 2 是使用 Excel 默认日期格式,在英国、澳大利亚和许多其他国家/地区是“*dd/mm/yyyy”,但如果您向 VBA 询问对应于“*dd/mm/yyyy”的 NumberFormat,您会得到“m /d/yyyy”。方法 2 会将“06/08/2013”​​转换为“2013 年 6 月 8 日”。这在我的问题中有更详细的解释:.NumberFormat 有时会返回错误的值和 dates

如果您导入 CSV 文件并将日期/时间列的格式指定为“常规”,它将使用方法 1。要破坏该日期,您需要使用如下代码移动它:

Dim CopyDate As String
CopyDate = Cell1.Value
Cell2.Value = CopyDate          ' This uses Approach 2

如果您导入 CSV 文件并将日期/时间列的格式指定为“文本”,则会将值保留为文本。如果使用导致 Excel 评估文本的方法移动该文本值,它将使用方法 2 将其转换为日期。

希望这可以帮助。

于 2013-08-10T13:12:01.343 回答
0

Excel 使用默认系统格式来确定在单元格中键入日期时如何解释日期。在美国,如果您输入“2013 年 3 月 2 日”,它会将其解释为 3 月 2 日。在澳大利亚,它将解释与 2 月 3 日相同的击键。更改单元格格式不会产生任何影响,正如您发现的那样。

当您复制与系统格式不兼容的日期时(例如,月份为 20),将发生文本转换。我真的认为问题实际上是在您打开 CSV 文件时发生的。

如果问题出在复制操作中,您可以在使用日期之前将日期转换为文本。=Text(a1, "m/d/yyyy")

编辑:必须是一个工作簿是美国格式,另一个是澳大利亚格式。我对正在发生的事情有一些想法,但我不能肯定地说。确保在同一个 Excel 实例中打开两个工作簿。如果您的代码都打开了两个工作簿,那么这应该不是问题。检查您的任务管理器进程列表以确保 Excel.exe 只出现一次。

此外,我不确定您的代码是否意外导致重新计算,这可能会导致问题。这段代码应该解决这个问题:

'get source worksheet
Dim ws As Worksheet
Set ws = Sheets(1)
ws.Activate

'copy all but first row
Call ws.UsedRange.Offset(1, 0).Resize(rowsize:=ws.UsedRange.Rows.Count - 1).Copy

'activate second sheet
Dim wsDest As Worksheet
Set wsDest = Sheets(2)
wsDest.Activate
wsDest.Paste

'de-activate copy mode
Application.CutCopyMode = False

您也可以使用代码编辑器窗口来单步执行代码(按 F8),以准确查看导致数据更改的行。

于 2013-08-05T08:46:54.030 回答