2012-09-25 63 views
8

虽然与我面对这个奇怪的错误一个传统MS Access应用程序挣扎:MS Access 2010:“无法打开更多数据库。”

Cannot open any more databases. 

应用广泛使用的UNION SQL语句。所以这似乎导致访问达到2048张开放表的限制。除了摆脱这些工会之外,还有其他的机会吗?

+3

哇,2048表..出于兴趣做事情怎么变得如此糟糕? –

+0

当然,DB中没有那么多表。有少于50个表和大约100个查询。 – Christian

+0

尽管Kieren的亮点是,我惊讶的是没有提供的答案更倾向于认真重新考虑UNION SQL,如果数据结构已经过优化,那么您应该永远不需要结束这么大的查询。特别是在访问方面不好,因为它全部在本地运行并可能需要一生。 –

回答

4

我在使用链接的外部表时遇到了这个问题。由于大约10个excel文件一遍又一遍地被不同的查询使用,因此达到了限制。所以开放表的数量或多或少都是查询和表的结果。

我想象使用工会也会增加这个问题。

我的解决方案是首先将链接的Excel表复制到Access本机表中。然后用本地表运行相同的查询。

+0

德国的消息是“Fehler 3048:Mehr Datenbankenkönnennichtgeöffnetwerden' btw。 – msjav

+0

哇,这样可以更快地编辑和执行查询。 Access无法自行处理这件事有点蹩脚。但对我来说这个解决方案是可以的。 – Christian

1

解决此问题的唯一方法是使用一组临时表。将结果从联合中插入临时表中,然后使用这些来限制每个查询的表的数量。我通常在我的临时表中加一个下划线(_tmpCustomers),然后在完成时销毁它们。

+0

呃,我以前不明白这个答案。我想你的意思是像msjav一样? – Christian

+0

是的,但我的答案不是很清楚......应该已经使用了实例,我将在未来包括示例以帮助:) – twoleggedhorse

0

您的应用程序正试图打开太多连接到Access数据库。它不仅仅是你的sql语句中的表格总计2048,甚至表单,报表,组合框,未关闭的记录集等都会增加你的应用程序使用的连接数。您可以在这里尝试几件事:
1.关闭您并未真正使用的资源(例如记录集)。
2.如果您正在使用域aggergate函数(例如DLookup),请使用Elookup对其进行更改,因为它会在其自身之后明确清除。
3.您可以修改您的sql代码以使用临时表。
希望它有帮助。

+0

关闭资源不会帮助,我想。我可以启动应用程序,执行一个查询(无vba)并发生错误。 临时表如何在这里帮助?你能举个例子吗? – Christian

2

通常,这种情况会发生在具有许多子表单和/或组合框/列表框的大/复杂表单中。

尝试做什么Saurabh说。无论如何,这都是好事。但我认为这些改变不会解决您的问题。

最近,我解决了同样的问题。我发现,当给定的表单被打开时总会发生。这种形式有许多子表单和组合。

首先。尽量让你的表单或表单更简单:你真的需要所有的子表单吗?所有子表单必须始终加载?

我解决了我的问题,在一个选项卡控件的不同页面中分发子窗体。然后在Change事件中动态加载和卸载子窗体。

最初,只有第一页上的子表单必须分配“SourceObject”属性。其余的,这个属性是空的。

在改变事件,试图做这样的事情:

Private Sub TabControl_Change 
    Dim pgn As Access.Page 
... 
    For Each varCtlSubform In Array(Me.Subform1, Me.Subform1, ...) 
     Set pgn = varCtlSubform.Parent 
     If pgn.PageIndex <> Me.TabControl.value Then 
      if varCtlSubform.SourceObject <> "" Then 
       varCtlSubform.SourceObject = "" 
      End if 
     Else 
      If varCtlSubform.SourceObject <> ctlSubform.Tag then 
       varCtlSubform.SourceObject = ctlSubform.Tag 
      End if 
     End If 
    Next 
... 
End sub 

这是一个泛型函数来遍历所有子窗体控件。如果不在活动页面中,请将其卸载。在其他情况下,从标签属性获取源对象。

你需要避免卸载子窗体,即参考值,如果“Subform1”被卸载,你会得到一个错误,像这样的事情: Me.Subform1.Form.InvoiceId

这种变化有其他好处。你的表单加载速度更快,记录导航速度更快。

+0

实际上,没有涉及任何表单或vba代码。打开accdb并执行一个(特定的)查询就足以弹出错误消息。如果我将依赖查询的结果放到一个表中,并使用修改后的查询版本,它就可以工作。 – Christian

+0

您的查询可能会调用聚合或VBA函数。你可以发布这个查询的SQL?你提到具体的查询。只有这个查询?还有其他疑问? – ricardohzsz

+0

查询的代码就像SELECT * FROM A UNION ALL SELECT * FROM B ... - 但msjav的答案很好地解决了实际问题。 – Christian

1

我要感谢ricardohzsz他的精彩代码!它确实帮助我提高了数据库性能以及消除了3048错误。

我会投票发帖,但是我没有足够的信誉来投票。

我不得不做一些修改,以使其满足我的需求(我需要允许添加和编辑的子表单,并使用此代码使它们成为只读)。我在这里张贴的改建情况下,它可以帮助别人,太:

Private Sub TabControlMain_Change() 

Dim pgn As Access.Page 
Dim sbf As SubForm 
Dim strSubForm As String 
Dim VarCtlSubform As Variant 


For Each VarCtlSubform In Array(Me.sf1, Me.sf2, Me.sf3, etc) 
Set pgn = VarCtlSubform.Parent 
    If pgn.PageIndex <> Me.TabControlMain.Value Then 
     If VarCtlSubform.SourceObject <> "" Then 
      VarCtlSubform.SourceObject = "" 
     End If 
    Else 

     If VarCtlSubform.SourceObject <> VarCtlSubform.Tag Then 
      VarCtlSubform.SourceObject = VarCtlSubform.Tag 

      strSubForm = VarCtlSubform.Name 
      Set sbf = Screen.ActiveForm.Controls(strSubForm) 
      sbf.Form.AllowAdditions = True 
      sbf.Form.AllowEdits = True 
     End If 
    End If 
Next 

末次