OLEDB连接没有刷新日期

时间:2018-12-11 15:29:54

标签: sql excel vba oledb

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

Connections.OLEDBConnection.RefreshDate

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

enter image description here

与那些特定的SQL表和视图的连接一致,无论我如何建立连接或刷新多少次。我一直使用OLEDB,我们的某些机器在Power Query方面存在兼容性问题。有谁知道会导致这种情况或我需要更改的内容(无论是Excel还是SQL)?

3 个答案:

答案 0 :(得分:5)

我还没有找到令人满意的解决方案,但是如果您非常需要知道连接已更新,这可能会对您有所帮助。这也可能取决于您拥有的连接类型。免责声明:此解决方案比专业解决方案更像是骇客,但似乎可以使用到现在。这是计划:

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的方法,它将可以解决问题。

答案 1 :(得分:3)

如果refreshDate未满,则可能是您不走运。

作为一种解决方法,您可以自己跟踪刷新。起点是表的afterRefresh-事件。为此,您必须将以下代码添加到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 :(得分:0)

为什么不直接在您要连接的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。