【问题标题】:Incomplete Timestamp using ADODB with VBA for Excel使用 ADODB 和 VBA for Excel 的不完整时间戳
【发布时间】:2013-07-03 01:45:14
【问题描述】:

我正在尝试将一些数据从 SQL Server 提取到 Microsoft Excel 2007。我已经设置了连接,除了时间戳之外,一切似乎都工作正常。我只能得到要通过的日期,而不是相应的小时、分钟或秒。我可以使用 Excel ODBC 查询工具从 SQL 数据库中提取数据,并且在那里列出了小时和分钟。我尝试了各种不同的 CAST() 选项。他们都没有解决我的问题。我正在运行 Windows XP。我不知道服务器上运行的是什么版本的 Microsoft SQL。我的代码如下所示。

 Sub Populate_Sheet(theSheet As Worksheet)

    'Declare variables'
        Dim objMyConn As ADODB.Connection
        Dim objMyCmd As ADODB.Command
        Dim objMyRecordset As ADODB.Recordset
        Set objMyConn = New ADODB.Connection
        Set objMyCmd = New ADODB.Command
        Set objMyRecordset = New ADODB.Recordset

        Dim executeThisSQLStatement As String
        'Dim target As Worksheet
        'Set target = theSheet

        executeThisSQLStatement = "SELECT CAST(DateHour_CPT AS TIMESTAMP) FROM EnergyData_v"

    'Open Connection'
        objMyConn.ConnectionString = "driver={SQLServer};Data Source=DataMart;User ID=acctname.value;Password=mypass.value;"

        objMyConn.Open

    'Set and Excecute SQL Command'
        Set objMyCmd.ActiveConnection = objMyConn
        objMyCmd.CommandText = executeThisSQLStatement
        objMyCmd.CommandType = adCmdText

    'Open Recordset'
        Set objMyRecordset.Source = objMyCmd
        objMyRecordset.Open

    'Copy Data to Excel'
        theSheet.Range("A6").CopyFromRecordset objMyRecordset

End Sub

【问题讨论】:

  • 您的意思是转换为 DATETIME 而不是 TIMESTAMP? SQL Server 在命名 TIMESTAMP 类型时犯了一个大错误 - 虽然它听起来类似于表示与日期和时间有关的东西的 ANSI SQL 类型,但它与任何一个都无关。在查询窗口中尝试此操作,忽略所有这些 VBA 和 Excel 干扰:SELECT CAST(GETDATE() AS TIMESTAMP);
  • 另外,您永远不必说“我不知道我正在运行哪个版本”——使用SELECT @@VERSION; 获得这一点很简单。
  • 这可能是 Excel 格式的问题。尝试将日期列单元格的格式更改为“yyyy-mm-dd hh:mm:ss”
  • 我尝试了 DATETIME 和 TIMESTAMP。 DATETIME 将返回日期,但不返回 hh:mm。 TIMESTAMP 不会返回任何内容。我还尝试了 Excel 中单元格的所有格式选项。所有数据库条目的时间为 00:00:00.000。明天早上我将使用该 Select 语句获取 SQL Server 版本。这个时间戳问题真的让我很恼火。我今天花了很多时间来弄清楚这一点。我现在不能回头。

标签: sql sql-server excel vba ado


【解决方案1】:

尼克,我想我已经为你找到了解决方案:)
让我使用我的示例数据进行演示。
默认情况下,Excel 没有DateTime 单元格格式。这意味着它不能在一个单元格中存储日期和时间。在数据表示方面,Excel 似乎只尝试使用最容易识别的格式——日期。它仍然存储时间,但将单元格格式化为丢失/丢弃时间的日期格式。

看看下面的截图:

你可以看到单元格中显示的数据看起来就像一个正常的日期。但是,如果您查看公式栏 - 时间存在但未显示。

在您的代码末尾,我添加了 Debug.Print 行:
Debug.print Range("B6").Value & vbCrlf & Range("B6").Value2
我得到的结果
25/06/2013 16:00:27
41450.6669791667
因此,我已经确认您在 Excel 中的单元格中看到的内容并不完全是它所指的内容


下一步是编写一个函数来遍历单元格并更改格式和所看到的内容。
为了同时实现:datetime 在一个单元格中我决定将单元格格式化为 Text
Private Sub FormatDateAndTime(ByRef sheet As Worksheet, start As Long, column As String)
    Dim i As Long, rng As Range
    For i = start To sheet.Range(column & Rows.Count).End(xlUp).Row
        Set rng = sheet.Range(column & i)
        Dim str As String
        str = Split(rng.Value, " ")(0) & " " & Split(rng.Value, " ")(1)
        rng.NumberFormat = "@"
        rng = str
        Set rng = Nothing
    Next i
End Sub

FormatDateAndTime() 函数有 3 个参数:
- 活动表
- 起始行
- 日期列
要调用该函数,请在代码中的 End Sub 之前添加这一行

  // Copy Data to Excel
        theSheet.Range("A6").CopyFromRecordset objMyRecordset

  // this is the line you want to add
    FormatDateAndTime sheet:=theSheet, start:=6, column:="A"

End Sub

注意: 我已经在我的样本中发送了其他参数来证明结果,但以上内容适用于您的情况

好的,运行代码后,您应该得到如下结果
注意: 我仅对示例中的列B 运行此代码以显示差异。 em>


注意:我为BC 两列都运行了这个


您的完整解决方案:
Sub Populate_Sheet(theSheet As Worksheet)

'Declare variables'
    Dim objMyConn As ADODB.Connection
    Dim objMyCmd As ADODB.Command
    Dim objMyRecordset As ADODB.Recordset
    Set objMyConn = New ADODB.Connection
    Set objMyCmd = New ADODB.Command
    Set objMyRecordset = New ADODB.Recordset

    Dim executeThisSQLStatement As String
    'Dim target As Worksheet
    'Set target = theSheet

    executeThisSQLStatement = "SELECT CAST(DateHour_CPT AS TIMESTAMP) FROM EnergyData_v"

'Open Connection'
    objMyConn.ConnectionString = "driver={SQLServer};Data Source=DataMart;User ID=acctname.value;Password=mypass.value;"

    objMyConn.Open

'Set and Excecute SQL Command'
    Set objMyCmd.ActiveConnection = objMyConn
    objMyCmd.CommandText = executeThisSQLStatement
    objMyCmd.CommandType = adCmdText

'Open Recordset'
    Set objMyRecordset.Source = objMyCmd
    objMyRecordset.Open

'Copy Data to Excel'
    Range("A6").CopyFromRecordset objMyRecordset

    FormatDateAndTime sheet:=theSheet, start:=6, column:="A"
End Sub

Private Sub FormatDateAndTime(ByRef sheet As Worksheet, start As Long, column As String)
    Dim i As Long, rng As Range
    For i = start To sheet.Range(column & Rows.Count).End(xlUp).Row
        Set rng = sheet.Range(column & i)
        Dim str As String
        str = Split(rng.Value, " ")(0) & " " & Split(rng.Value, " ")(1)
        rng.NumberFormat = "@"
        rng = str
        Set rng = Nothing
    Next i
End Sub


如果此答案对您有所帮助,请接受和/或投票! :) 谢谢,祝你好运

【讨论】:

  • 我复制了你的代码,第一次尝试就完美运行。非常感谢。这真的帮了我很多忙!我无法投票,因为我没有足够的声誉,但这正是我所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-21
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多