【问题标题】:OLEDB Connection has no refresh dateOLEDB 连接没有刷新日期
【发布时间】:2021-12-27 19:12:55
【问题描述】:

我需要以编程方式检查 Excel 中多个 OLEDB 数据连接到 SQL 表和视图的刷新日期。它们都以相同的方式配置并使用相同的连接字符串,我在 VBA 中使用以下命令检查它们:

Connections.OLEDBConnection.RefreshDate

但是,其中一些连接没有刷新日期,我并不是说 RefreshDate 属性返回 NULL,该属性甚至不存在。 VBA 抛出“应用程序定义或对象定义错误”,当我检查连接属性时,“上次刷新”字段为空白:

与那些特定 SQL 表和视图的连接是一致的,无论我如何构建连接或刷新它多少次。我被困在使用 OLEDB 上,而且我们的一些机器与 Power Query 存在兼容性问题。有谁知道在 Excel 或 SQL 中会导致这种情况或我需要更改什么?

【问题讨论】:

  • 未显示此内容的连接有什么共同点?我能够复制该行为,因此它可能不是您的具体问题。

标签: sql excel vba oledb


【解决方案1】:

如果refreshDate 没有填写,可能你运气不好。

作为一种解决方法,您可以自己跟踪刷新。起点是表的afterRefresh-Event。为此,您必须将以下代码添加到Workbook-Module(不适用于常规模块,因为With Events 需要class

Option Explicit
Private WithEvents table As Excel.QueryTable

Private Sub table_AfterRefresh(ByVal Success As Boolean)
    Debug.Print table.WorkbookConnection.name & " refreshed. (success: " & Success & ")"
    If Success Then
        Call trackRefreshDate(table.WorkbookConnection.name, Now)
    End If
End Sub

现在您只需要一个逻辑来保存刷新事件。在我的示例中,我将其保存为工作簿级别的名称,当然您也可以将其保存在(隐藏的)工作表中。将其放入常规模块中:

Sub trackRefreshDate(tableName As String)

    Dim nameObj As Name, nName As String
    Set nameObj = Nothing
    nName = "Refresh_" & tableName
    On Error Resume Next
    ' Check if name already exists
    Set nameObj = ThisWorkbook.Names(nName)
    On Error GoTo 0
    Dim v
    v = Format(Now, "dd.mm.yyyy hh:MM:ss")
    If nameObj Is Nothing Then
        ' No: Create new
        Call ThisWorkbook.Names.Add(nName, v)
    Else
        nameObj.Value = v
    End If
End Sub

Function getRefreshDate(tableName As String)
    Dim nName As String
    nName = "Refresh_" & tableName
    On Error Resume Next
    getRefreshDate = Replace(Mid(ThisWorkbook.Names(nName), 2), """", "")
    On Error GoTo 0        
End Function

【讨论】:

    【解决方案2】:

    为什么不简单地在您连接的 SQL 源中添加一列(无论是视图还是过程)?在此处添加列RefreshTime=GETDATE()。每次用户从 SQL 中提取数据时,他们在返回的结果中都有RefreshTime

    如果您需要在用户刷新 SQL 源时存储信息,也可以在 SQL 数据库中执行此操作。制作存储过程:

    create stored procedure ShareMySource as
    -- part one, prepare data
    select * from MySQLTable;
    
    -- part two, get user data
    insert into dbo.LogBook
    select 
    RefreshTime=getdate(), 
    User = ORIGINAL_LOGIN()
    

    必须先创建表 LogBook。

    【讨论】:

    • 如果他可以访问他的来源,那肯定是可能的。有时您没有权利或访问源代码。例如,如果您使用外部资源。
    • 但是如果你无权访问外部源,则无法刷新。但是您仍然可以看到具有访问权限的人上次为您刷新该源的时间。
    【解决方案3】:

    我还没有找到令人满意的解决方案,但如果您迫切需要知道连接是否已更新,这可能会对您有所帮助。这也可能取决于您拥有的连接类型。免责声明此解决方案与其说是专业解决方案,不如说是一种 hack,但似乎直到现在才有效。这是计划:

    1 虚拟显示器

    在工作表中显示来自您的连接的一段数据。此工作表Sheet1 可能是HiddenVeryHidden。真的没关系。

    2 事件

    修改Worksheet_Change事件如下:

    Private Sub Worksheet_Change(ByVal Target As Range)
    RefreshDate (Now())
    End Sub
    

    3 模块

    除此之外,您还需要一个模块,该模块提供了在另一张纸上存储和访问RefreshDate 属性的功能。您可能希望使用存储在 Thisworkbook 属性中的对象来执行此操作,但据我所知,这并不能免于破坏。

    这里是代码:

    Sub RefreshDate(D As Date)
    Sheet2.Range("A1").Value = D
    End Sub
    
    Public Function GetRefreshDate() As Date
    GetRefreshDate = Sheet2.Range("A1").Value
    End Function
    

    4 冲洗并重复所有连接

    您现在需要对所有不适用于RefreshDate 的连接执行此操作。您可能希望将所有日期保存在一个工作表中,并为每个连接创建一个工作表。

    这个解决方案难看吗?是的。它有效吗?是的,它确实。

    基本思路如下:每次刷新连接时,工作表都会发生变化,这将触发事件:Worksheet_Change 现在您可以保存日期以便以后访问它。

    如果您在刷新连接时找到其他方法来访问事件,这也应该可以解决问题。如果您找到其他方法来保存RefreshDate,它会成功。

    【讨论】:

      猜你喜欢
      • 2016-07-28
      • 2018-01-01
      • 1970-01-01
      • 2013-03-24
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      相关资源
      最近更新 更多