こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

アクセスのフォームで連動したコンボボックスの絞りこみ速度を速める方法はないでしょうか?

Access2003を使用しています。
フォームでユーザーNOコントロールボックスでユーザを選ぶと、商品番号コントロールボックスにはそのユーザーが所有する商品番号だけを絞り込んで表示するように設定しました。(QNo.3477730で質問)
ですが、商品番号コントロールボックスのプルダウンをクリックしてから、商品番号が表示されるまでに5秒近くかかってしまいます。
これは、妥当な所要時間でしょうか?
私としては、1秒ぐらいに縮めたいのですが方法はないでしょうか?
他のユーザの商品も含めて商品数は1600件あります。
PCのメモリは260MB RAMです。
テーブルの商品番号のプロパティのインデックスは、はい(重複あり)になっております。
こうすればもう少し時間を短く出来る方法がありましたら教えていただけないでしょうか。

投稿日時 - 2007-11-01 16:01:23

QNo.3480383

困ってます

質問者が選んだベストアンサー

先の回答の際に私が作成したテストテーブルは次のようです。
少し、長くなりますが、問題解決のヒントにはなるかと思います。

顧客マスター:

ユーザーNo___氏名
_____________1___鈴木 一郎
_____________2___中村 主水

商品マスター:

商品番号____品名
___________1___商品A
___________2___商品B

顧客商品管理:

ID___ユーザーNo_____商品番号
1____鈴木 一郎_______商品A
2____鈴木 一郎_______商品B
3____中村 主水_______商品A

もちろん、<顧客商品管理>の実際のデータは次のようです。

1_______________1__________________________1
2_______________1__________________________2
3_______________2__________________________1

次にテストしたのは、<ユーザーNo=1>が所有する商品の品名のリストを検索すること。

[イミディエイトウインドウ]
? DBSelect("SELECT 商品マスター.品名
               FROM 顧客商品管理
               INNER JOIN 商品マスター
               ON 顧客商品管理.[商品番号]=商品マスター.商品番号
               WHERE 顧客商品管理.[ユーザーNo]=1;")
商品A;商品B

確かに、<商品A;商品B>をセミコロン(;)で区切って抜き出しています。
ならば、 ユーザ番号_AfterUpdate() で次のように書けば、目的は達成します。

Private Sub ユーザ番号_AfterUpdate()
  Dim strQuerySQL As String

  strQuerySQL = "SELECT 商品マスター.品名
             FROM 顧客商品管理
             INNER JOIN 商品マスター
             ON 顧客商品管理.[商品番号]=商品マスター.商品番号
             WHERE 顧客商品管理.[ユーザーNo]=" & Me.ユーザ番号
  Me.コンボ_ユーザ所有商品名一覧.RowSource = DBSelect(strQuerySQL)
  Me.コンボ_ユーザ所有商品名一覧.Value = Me.コンボ_ユーザ所有商品名一覧.ItemData(0)
End Sub

先の回答では、このテスト内容は一切示していません。
しかし、質問文から、上述のようなテーブル構造になっているのか一抹の不安を覚えていました。

また、クエリにフォームを条件として組み込めば実行速度が大幅に低下するとも思っていました。
確かに、それは簡単に実現できる手法かも知れません。
が、クエリも所詮は SQL文。
ならば、VBA で直接に値リストを設定するのが手っ取り早いと思います。
SQL文自体は、クエリで作成すればいいです。
実際、上述のSQL文もクエリで作成しています。

もちろん、DBSelect関数は最速ではありません。
DAOでINDEXとSEEKを使えば、もっと、高速化します。
が、いずれにしろ 0.01秒以下の世界の話で、どっちでもいいのじゃないですかね。

Public Function DBSelect(ByVal strQuerySQL As String, _
             Optional ByVal strSeparator As String = ";") As String
On Error GoTo Err_DBSelect
  Dim I   As Integer
  Dim J   As Integer
  Dim R   As Integer
  Dim C   As Integer
  Dim M   As Integer
  Dim N   As Integer
  Dim rst  As ADODB.Recordset
  Dim fld  As ADODB.Field
  Dim Datas As String
  
  Set rst = New ADODB.Recordset
  ' =================
  ' Begin With: rst
  ' -----------------
  With rst
     .Open strQuerySQL, _
        CurrentProject.Connection, _
        adOpenStatic, _
        adLockReadOnly
     If Not .BOF Then
      M = .RecordCount - 1
      N = .Fields.Count - 1
      .MoveFirst
      For R = 0 To M
        For C = 0 To N
          Datas = Datas & .Fields(C) & strSeparator
        Next C
        .MoveNext
      Next R
     End If
  End With
  ' ---------------
  ' End With: rst
  ' ===============
Exit_DBSelect:
  DBSelect = Left(Datas, Len(Datas) + (Len(Datas) > 0))
  Exit Function
Err_DBSelect:
  MsgBox "SELECT 文の実行時にエラーが発生しました。(DBSelect)" & Chr$(13) & Chr$(13) & _
      "・Err.Description=" & Err.Description & Chr$(13) & _
      "・SQL Text=" & strQuerySQL, _
      vbExclamation, " 関数エラーメッセージ"
  Resume Exit_DBSelect
End Function

投稿日時 - 2007-11-02 09:50:11

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

たかがレコード数1600で5秒は考えられないです
1秒でも長すぎます

PCのスペックなんかの問題ではなく作り方に問題があるのでしょうね
それを詳しく説明してみれば

投稿日時 - 2007-11-01 19:08:44

ANo.1

>ユーザーが所有している商品番号は、商品リストと顧客名簿というテーブルを連結させたクエリで出来上がっています。

これから推測すると、顧客名簿に商品番号を入れるところがあるようですね。 1ユーザーが複数商品を保有する場合のデータの登録方法がどうなっているのかわかりませんが、顧客名簿の商品番号も、インデックスは、はい(重複あり)にすると良いと思います。 あとは最適化を行ってみること。 それで改善しなければ、他のスペックのPCで動かしてみて、改善があるか調べてみることくらいかな。

投稿日時 - 2007-11-01 19:00:41

あなたにオススメの質問