2012-09-25 425 views
8

Mientras lucha con una aplicación de MS Access único legado que enfrenté este error extraño:MS Access 2010: "No se pueden abrir más bases de datos".

Cannot open any more databases. 

La aplicación hace uso extensivo de UNION sentencias SQL. Esto parece causar acceso al límite de 2048 tablas abiertas. ¿Alguna otra oportunidad que no sea deshacerse de estas uniones?

+3

Wow, 2048 mesas .. por interés cómo las cosas se ponen tan mal? –

+0

No hay tantas tablas en el DB, por supuesto. Hay menos de 50 tablas y aproximadamente 100 consultas. – Christian

+0

A pesar de lo destacado de Kieren, estoy sorprendido de que ninguna de las respuestas proporcionadas se oriente más hacia una seria revisión del UNION sql; si la estructura de datos está optimizada, entonces nunca debería tener que terminar con una consulta tan grande. Especialmente malo en el acceso ya que todo se ejecuta localmente y podría llevar toda la vida. –

Respuesta

4

Tuve este problema al usar tablas externas vinculadas. El límite fue alcanzado porque aproximadamente 10 archivos de Excel fueron utilizados por diferentes consultas una y otra vez. Entonces, el número de tablas abiertas era más o menos producto de consultas y tablas.

Imagino que el uso de uniones multiplica este problema también.

La solución para mí fue copiar primero las tablas vinculadas de Excel en tablas nativas de Access. A continuación, ejecute las mismas consultas con las tablas nativas.

+0

El mensaje en alemán es 'Fehler 3048: Mehr Datenbanken können nicht geöffnet werden' btw. – msjav

+0

Wow, y obtiene las magnitudes más rápido para editar y ejecutar las consultas de esta manera. Es un poco desagradable que Access no se encargue de esto por sí mismo. Pero para mi caso, esta solución está bien. – Christian

1

La única forma real de solucionar este problema es utilizar un conjunto temporal de tablas. Inserte los resultados de sus uniones en tablas temporales y luego utilícelas para limitar el número de tablas por consulta. Normalmente prefijo mis tablas temporales con un guión bajo (_tmpCustomers) y luego las destruyo cuando termine.

+0

Uh, no entendí esta respuesta antes. Supongo que querías decir lo mismo que msjav. – Christian

+0

Sí, pero mi respuesta no era muy clara ... debería haber usado ejemplos realmente, incluiré ejemplos en el futuro para ayudar :) – twoleggedhorse

0

Su aplicación está tratando de abrir demasiadas conexiones a la base de datos de Access. No son sólo las tablas en su declaración sql las que suman hasta 2048, incluso los formularios, informes, cuadros combinados, registros no cerrados, etc. se suman a la cantidad de conexiones utilizadas por su aplicación. Pocas cosas que puede probar aquí:
1. Cierre los recursos (p. Ej. Juegos de registros) que realmente no está usando.
2. Si está haciendo uso de funciones de agregado de dominio (por ejemplo, DBookup), cámbielo con Elookup ya que se limpia explícitamente.
3. Puede modificar su código sql para hacer uso de tablas temporales.
Espero que ayude.

+0

Cerrar recursos no ayudará, supongo. Puedo iniciar la aplicación, ejecutar una consulta (no vba) y se produce el error. ¿Cómo pueden ayudar las tablas temporales aquí? ¿Puedes hacer un ejemplo? – Christian

2

A menudo, esto ocurre con formularios grandes/complejos con muchos subformularios y/o cuadros combinados/cuadros de lista.

Intenta hacer lo que dice Saurabh. Son cosas buenas de todos modos. Pero creo que estos cambios no resolverán tu problema.

Recientemente, resuelvo el mismo problema. Identifiqué que siempre ocurre cuando se abre una forma determinada. Esta forma tenía muchos subformularios y combos.

Primero. Intenta simplificar tu forma o formularios: ¿realmente necesitas todos los subformularios? Todos los subformularios deben estar cargados siempre?

Resuelvo mi problema al distribuir subformularios en diferentes páginas de un control de pestañas. A continuación, cargue y descargue subformularios dinámicamente en el evento Change.

Inicialmente, solo los subformularios en la primera página deben tener asignada la propiedad "SourceObject". El resto, tiene esta propiedad vacía.

En caso de cambio, trata de hacer algo como esto:

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 

Ésta es una función genérica para iterar sobre todos los controles de subformulario. Si no está en la página activa, descárguelo. En otro caso, tome el objeto fuente de la propiedad de la etiqueta.

Tendrá que evitar las referencias a subformularios descargadas, es decir, si "Subform1" se descarga obtendrá un error con algo como esto: Me.Subform1.Form.InvoiceId

Este cambio ha otra beneficios. Su formulario se cargará más rápido y la navegación de registros será más rápida.

+0

No hay formularios o código vba involucrados, en realidad. La apertura de accdb y la ejecución de una consulta (específica) es suficiente para que aparezca el mensaje de error. Si pongo los resultados de las consultas dependientes en una tabla y los uso mediante una versión de consulta modificada, funciona. – Christian

+0

Su consulta puede llamar funciones agregadas o VBA. ¿Puedes publicar el sql de esta consulta? Usted menciona una consulta específica. Solo con esta consulta? ¿También con otras consultas? – ricardohzsz

+0

El código de la consulta es como SELECCIONAR * DESDE UN SINDICATO TODO SELECCIONADO * DESDE B ... - pero la respuesta de msjav resolvió muy bien el problema real. – Christian

1

Quiero agradecer a ricardohzsz por su maravilloso código! Realmente me ayudó a mejorar el rendimiento de mi base de datos y eliminar el error 3048.

Yo votaría la publicación pero no tengo suficiente reputación aquí para votar.

Tuve que hacer algunas modificaciones para que funcionara para mis necesidades (necesitaba los subformularios para permitir adiciones y ediciones y el uso de este código los hacía de solo lectura). He colgado las alteraciones aquí por si puede ayudar a alguien más, también:

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 

End Sub

Cuestiones relacionadas