1

フォームには、ユーザーに追加情報を提供するボタンがいくつかあります。各ボタンは、DCountを使用して、表示する情報があるかどうかを確認し、ある場合は、ポップアップフォームを開いて表示します。すべてが正常に機能していましたが、特定のボタンの場合、ポップアップフォームを開くのに30秒から1分かかりますが、これは明らかに受け入れられません。もともとうまくいった理由がわかりませんが、今ではとても遅くなっています。他のすべてのボタンは、1秒以内にフォームを開きます。VBAは次のとおりです。

Private Sub btnNotes_Click()
  'open the popup notes for the current record, if there are associated records
  If DCount("ID","qlkpIDForNotes") = 0 Then
    MsgBox "There are no notes for this patient", vbOKOnly, "No information"
  Else
    DoCmd.OpenForm "fsubNotes",,,"ID = " & Me.displayID
  End If
End Sub

照会されるテーブルには約40,000行があり、他のボタンについてチェックされる最大のテーブルには約12,000行があります。クエリではなくテーブルで直接DCountを実行しようとしましたが、違いはありません。また、元のテーブルからデータの一部を取り出し、約1100行を新しいテーブルにコピーして、それをテストしてみました。開くのにまだ12秒かかりました。何かアイデアはありますか?

4

1 に答える 1

2

テーブルまたはクエリに行があるDCount()どうかを調べるためだけに使用すると、クエリ全体を実行し、すべてのレコードを調べて合計数を返す必要があるため、それを と比較できるため、かなり非効率的です。DCount()0

そのクエリとその結合の複雑さ、および結合がインデックスを持つフィールドを使用するかどうかに応じて、そのクエリを実行する必要があるコストは、基になるテーブルのレコード数に指数関数的に比例する可能性があります。

問題を解決するには、これを試してください:

  1. クエリ内の基になるテーブルのIDフィールドにインデックスがあり、 or句で使用されるすべてのフィールドにもインデックスがあることを確認してください。qlkpIDForNotesJOINWHERE

  2. メインの基になるテーブルを使用できるかどうかを確認するか、単純なクエリを使用して、によって返される可能性のあるレコードがあるかどうかをテストしますqlkpIDForNotes。要するに、いくつかのレコードがあるかどうかを調べるためだけにそのクエリを完全に実行する必要がない場合があります.

  3. クエリが結果を返すかどうかだけを確認する必要がある場合HasAny()の代わりに、以下のような別の関数を使用してください。DCount()

'-------------------------------------------------------------------------'
' Returns whether the given query returned any result at all.             '
' Returns true if at least one record was returned.                       '
' To call:                                                                '
'   InUse = HasAny("SELECT TOP 1 ID FROM Product WHERE PartID=" & partID) '
'-------------------------------------------------------------------------'
Public Function HasAny(ByVal selectquery As String) As Boolean
    Dim db As DAO.database
    Dim rs As DAO.RecordSet
    Set db = CurrentDb
    Set rs = db.OpenRecordset(selectquery, dbOpenForwardOnly)
    HasAny = (rs.RecordCount > 0)
    rs.Close
    Set rs = Nothing
    Set db = Nothing
End Function

これにより、コードを次のように簡単に書き換えることができます。

Private Sub btnNotes_Click()
  'open the popup notes for the current record, if there are associated records '
  If Not HasAny("qlkpIDForNotes") Then
    MsgBox "There are no notes for this patient", vbOKOnly, "No information"
  Else
    DoCmd.OpenForm "fsubNotes",,,"ID = " & Me.displayID
  End If
End Sub
于 2012-10-15T08:25:24.497 に答える