8

単一のレガシーMSAccessアプリケーションで苦労しているときに、この奇妙なエラーに直面しました。

Cannot open any more databases.

アプリケーションはUNIONSQLステートメントを広範囲に使用します。したがって、これにより、アクセスが2048のオープンテーブルの制限に達するように見えます。これらの組合を取り除く以外のチャンスはありますか?

4

6 に答える 6

4

リンクされた外部テーブルを使用すると、この問題が発生しました。さまざまなクエリで約10個のExcelファイルが何度も使用されたため、制限に達しました。したがって、開いているテーブルの数は、多かれ少なかれクエリとテーブルの積でした。

ユニオンを使用すると、この問題も倍増すると思います。

私にとっての解決策は、最初にリンクされたExcelテーブルをAccessネイティブテーブルにコピーすることでした。次に、ネイティブテーブルを使用してまったく同じクエリを実行します。

于 2012-09-25T13:40:46.107 に答える
3

多くの場合、これは、多くのサブフォームやコンボボックス/リストボックスを含む大きな/複雑なフォームで発生します。

Saurabhが言うことをやってみてください。とにかく良いことです。しかし、これらの変更はあなたの問題を解決しないと思います。

最近、私は同じ問題を解決します。特定のフォームが開かれたときに常に発生することを確認しました。このフォームには多くのサブフォームとコンボがありました。

初め。1つまたは複数のフォームを単純化してみてください。本当にすべてのサブフォームが必要ですか?すべてのサブフォームは常にロードする必要がありますか?

タブコントロールのさまざまなページにサブフォームを配布する際の問題を解決します。次に、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

この変更には他にも利点があります。フォームの読み込みが速くなり、レコードのナビゲーションが速くなります。

于 2012-09-25T10:50:21.113 に答える
2

UNIONクエリの各セクション、およびそれが依存するその他のクエリを評価する必要があります。多くの結合テーブルを含むクエリを表す一時テーブルを作成し、代わりに一時テーブルを使用することで、改善が得られる場合があります。

Accessで開発を始めたとき、私は大きな非正規化スノーフレーククエリを作成し、それらをレポートとリストボックスのソースとして使用する習慣がありました。100,000を超えるレコードを持つテーブルがなく、データベースは高速に実行されました。その後、「これ以上データベースを開くことができません」という厄介なエラーが発生し始め、自分のやり方のエラーを発見しました。

使用したデータベース接続の数と残りのデータベース接続の数を追跡するのに役立つフォームを作成しました。このフォームをデータベースに追加し、クエリやその他のオブジェクトを開いた後で[再クエリ]をクリックする、多数の接続を使用しているオブジェクトを見つけることができます。

ここに画像の説明を入力してください

ローカルテーブルまたはクエリオブジェクトへのすべての参照は1つの接続を使用することに注意してください。リンクされたテーブルへの参照は2つの接続を使用します。2つのリンクされたテーブルを結合するクエリは、5つの接続を使用します。そのクエリがユニオン内の他の多くのクエリによって呼び出されている場合、その数は急速に増加します。サブクエリで結合されたテーブルのフィールドは必要ないかもしれません。その場合、新しいクエリを作成できます。

私はこれについてオンラインでたくさん読んでおり、Access / Jetには約2,000のTableIDがあると考える人もいますが、その数は私のフォームのレポートと一致しません。私のフォームによって報告された数値は、エラーと完全に一致しています。TableIDとは異なるものをカウントしている可能性がありますが、新しいオブジェクトを開くときに使用されている接続の量を測定するための正確なゲージを提供します。

あなたはもっと読んで、ここからそれをダウンロードすることができます:

https://access.wordpress.com/2014/04/01/how-many-database-connections-are-still-available-in-an-access-database/

于 2018-11-02T19:53:03.817 に答える
1

この問題を回避する唯一の実際の方法は、テーブルの一時的なセットを使用することです。ユニオンからの結果を一時テーブルに挿入し、それらを使用してクエリごとのテーブルの数を制限します。私は通常、一時テーブルの前にアンダースコア(_tmpCustomers)を付け、完了したらそれらを破棄します。

于 2012-09-25T09:02:40.947 に答える
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

サブ終了

于 2015-03-10T18:17:44.957 に答える
0

アプリケーションがAccessデータベースへの接続を開きすぎています。合計で2048になるSQLステートメントのテーブルだけでなく、フォーム、レポート、コンボボックス、閉じられていないレコードセットなどでさえ、アプリケーションで使用される接続の数になります。ここで試すことができるいくつかのこと:
1。実際に使用していないリソース(レコードセットなど)を閉じます。
2.ドメインアガーゲート機能(DLookupなど)を使用している場合は、Elookupを使用して変更します。これは、それ自体が明示的にクリーンアップされるためです。
3.一時テーブルを利用するようにSQLコードを変更できます。
それが役に立てば幸い。

于 2012-09-25T09:07:55.653 に答える