简体   繁体   English

SQL表不存在时VBA中的运行时错误

[英]Run-time error in VBA when SQL table doesn't exist

I am trying to refresh some tables in excel that are in an SQL database. 我正在尝试刷新SQL数据库中Excel中的某些表。 The SQL tables get created when there is data to put into them so sometimes those tables are not created. SQL表是在有数据可放入时创建的,因此有时不创建这些表。 I believe I am getting the below error in VBA when it can't find the table in SQL. 我相信当在SQL中找不到表时,VBA中出现以下错误。 How can I avoid this error? 如何避免此错误?

I thought about making the macro "check" if the table exists and if so, refresh it but I don't know how to do this and haven't found similar problems. 我考虑过使宏“检查”表是否存在,如果存在,请刷新它,但我不知道如何执行此操作,也没有发现类似的问题。 Also, I was wondering if the "on error resume next" statement would work because I don't care if there is an error, I only want the macro to pass through every refresh instance (I am trying to refresh 3 tables). 另外,我想知道“在下一个错误时继续执行”语句是否可行,因为我不在乎是否有错误,我只希望宏通过每个刷新实例(我正在尝试刷新3个表)。

Sub RefreshAll()
    Range("Duplicates").ListObject.QueryTable.Refresh BackgroundQuery:=False
    Range("Fatal_Error").ListObject.QueryTable.Refresh BackgroundQuery:=False
    Range("Wrong_MCN").ListObject.QueryTable.Refresh BackgroundQuery:=False

    MsgBox ("Tables have been refreshed")
End Sub

The error message I get is: 我收到的错误消息是:

Run-time error 1004: Method Range of object _Global failed. 运行时错误1004:对象_Global的方法范围失败。

Please note that in my code, the first line runs with no problems and brings all the data. 请注意,在我的代码中,第一行运行没有问题,并带来了所有数据。 The second and third lines of "refresh" give the error because no tables with those names are in the SQL database. “刷新”的第二和第三行给出了错误,因为SQL数据库中没有具有这些名称的表。

It's not the database or its tables; 不是数据库或其表。 method Refresh of QueryTable would have failed if that were the case. 如果是这种情况, QueryTable方法Refresh将失败。

It fails well before that; 在此之前,它就失败了; a call to method Range of (hidden) object _Global happens when you implicitly reference the ActiveSheet , and when the specified range/name doesn't exist on that sheet (whatever sheet is active at that time), it fails. 当您隐式引用ActiveSheet ,对(隐藏的)对象_Global方法Range的调用发生,并且当该工作表上不存在指定的范围/名称(无论当时处于活动状态的工作表)时,它都会失败。

Start with the Worksheet you want to get the Range in: 从要获取RangeWorksheet开始:

Sheet1.Range("named range")...

If the sheet you need to work with exists in ThisWorkbook at compile-time, then you can give it a code name by setting its (Name) property; 如果在编译时ThisWorkbook中存在需要使用的工作表,则可以通过设置其(Name)属性为其指定代码名称 this code name identifier can then be used in code whenever you need to refer to that particular sheet. 每当您需要参考该特定工作表时,都可以在代码中使用该代码名称标识符。

If the names are actually table names, then use the sheet's ListObjects collection to retrieve it: 如果名称实际上是表名称,则使用工作表的ListObjects集合进行检索:

Sheet1.ListObjects("Duplicates").QueryTable.Refresh
Sheet2.ListObjects("Fatal_Error").QueryTable.Refresh
...

As for On Error Resume Next and "I don't care if there is an error"... don't do this. 至于On Error Resume Next和“我不在乎是否有错误”……不要这样做。 You DO care if there's an error. 您一定要注意是否有错误。 In this case the (Excel) table itself isn't even found: an error there means the refresh will never happen. 在这种情况下,甚至没有找到(Excel)表本身:那里的错误意味着永远不会发生刷新。 OERN just shoves errors under the carpet and pretends they didn't happen: it won't magically make the refreshing work for a table that isn't even found. OERN只是将错误推到地毯下,并假装它们没有发生:它不会神奇地使甚至没有找到的桌子都焕然一新。 OERN makes debugging much harder than it needs to be, when there are too many reasons for something to fail. 如果有太多原因导致失败,则OERN会使调试工作变得比原本需要的困难得多。

The trick is to separate getting the table object from the act of refreshing it . 技巧是将获取表对象刷新 对象分开。

OERN is great when you need to run something that might fail, but you need to ignore that error (eg couldn't refresh QueryTable because SQL table doesn't exist) - pull the refresh call into its own scope, and leave it with only a single reason to fail: 当您需要运行可能会失败的东西时,但是您需要忽略该错误(例如,由于SQL表不存在而无法刷新QueryTable),则OERN非常有用-将刷新调用放到自己的作用域中,并仅保留它失败的单一原因:

Private Function TryRefresh(ByVal qt As QueryTable) As Boolean
    On Error Resume Next
    qt.Refresh BackgroundQuery:=False
    TryRefresh = Err.Number = 0
    On Error GoTo 0
End Function

Now you can invoke this specialized procedure whenever you have a valid object reference to a QueryTable object - for example: 现在,只要您具有对QueryTable对象的有效对象引用,就可以调用此专门过程-例如:

If Not TryRefresh(Sheet1.ListObjects(1).QueryTable) Then Debug.Print "table 1 failed to refresh"
If Not TryRefresh(Sheet2.ListObjects(1).QueryTable) Then Debug.Print "table 2 failed to refresh"
If Not TryRefresh(Sheet3.ListObjects(1).QueryTable) Then Debug.Print "table 3 failed to refresh"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM