我需要以编程方式检查Excel中到SQL表和视图的许多OLEDB数据连接的刷新日期。它们都以相同的方式配置并使用相同的连接字符串,而我正在VBA中使用以下命令对其进行检查:
Connections.OLEDBConnection.RefreshDate
但是,其中的少数几个连接没有刷新日期,并且我并不是说RefreshDate属性返回NULL,甚至不存在。 VBA抛出并显示“应用程序定义的错误或对象定义的错误”,当我检查连接属性时,“上次刷新”字段为空白:
与那些特定的SQL表和视图的连接一致,无论我如何建立连接或刷新多少次。我一直使用OLEDB,我们的某些机器在Power Query方面存在兼容性问题。有谁知道会导致这种情况或我需要更改的内容(无论是Excel还是SQL)?
答案 0 :(得分:5)
我还没有找到令人满意的解决方案,但是如果您非常需要知道连接已更新,这可能会对您有所帮助。这也可能取决于您拥有的连接类型。免责声明:此解决方案比专业解决方案更像是骇客,但似乎可以使用到现在。这是计划:
在工作表中显示来自您的连接的数据。该工作表Sheet1
可以是Hidden
或VeryHidden
。没关系。
修改Worksheet_Change
事件如下:
Private Sub Worksheet_Change(ByVal Target As Range)
RefreshDate (Now())
End Sub
最重要的是,您需要一个模块,该模块提供用于存储和访问另一张纸上的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
您现在需要对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。