10

データシートを含むフォームがあります。ユーザーが複数の行を選択し、ボタンをクリックしてSQLクエリを実行し、それらの行に対していくつかの作業を実行できるようにしたいと思います。

VBAコードを見ると、CurrentRecordプロパティを使用して最後に選択したレコードにアクセスする方法がわかります。しかし、複数選択でどの行が選択されたかを知る方法がわかりません。(私ははっきりしているといいのですが...)

これを行うための標準的な方法は何ですか?Access VBAのドキュメントは、ネット上ではややわかりにくいです...

ありがとう!

4

9 に答える 9

10

JohnFx に似た手法を使用しました

Selection の高さが消える前にトラップするには、メイン フォームのサブフォーム コントロールの Exit イベントを使用しました。

したがって、メイン フォームでは次のようになります。

Private Sub MySubForm_Exit(Cancel As Integer)

  With MySubForm.Form
    m_SelNumRecs = .SelHeight
    m_SelTopRec = .SelTop
    m_CurrentRec = .CurrentRecord
  End With

End Sub
于 2009-11-03T22:32:32.763 に答える
10

これを行うコードは次のとおりですが、キャッチがあります。

Private Sub Command1_Click()
     Dim i As Long
     Dim RS As Recordset
     Dim F As Form

     Set F = Me.sf.Form
     Set RS = F.RecordsetClone

     If F.SelHeight = 0 Then Exit Sub

     ' Move to the first selected record.
     RS.Move F.SelTop - 1

     For i = 1 To F.SelHeight
       MsgBox RS![myfield]
       RS.MoveNext
     Next i

End Sub

問題は次のとおりです。 コードがボタンに追加された場合、ユーザーがそのボタンをクリックするとすぐに、グリッドで選択が失われます (selheight はゼロになります)。したがって、その情報をキャプチャし、タイマーまたはフォーム上の他のイベントを使用して、モジュール レベルの変数に保存する必要があります。

これは、キャッチを回避する方法を詳細に説明する記事です。
http://www.mvps.org/access/forms/frm0033.htm

キャッチ 2:これは、連続した選択でのみ機能します。グリッド内の複数の連続していない行を選択することはできません。

更新:
これをトラップするためのより良いイベントがあるかもしれませんが、これは私がテストした form.timerinterval プロパティを使用した実用的な実装です (少なくとも Access 2k3 では、2k7 は問題なく動作するはずです)。

このコードは SUBFORM に入り、プロパティを使用してマスター フォームの selheight 値を取得します。

Public m_save_selheight As Integer

Public Property Get save_selheight() As Integer
    save_selheight = m_save_selheight
End Property

Private Sub Form_Open(Cancel As Integer)
    Me.TimerInterval = 500
End Sub

Private Sub Form_Timer()
    m_save_selheight = Me.selheight
End Sub
于 2009-11-03T21:02:12.917 に答える
2

サブフォームがフォーカスを失ったときの選択の喪失に対する回避策は、Exit イベントで選択を保存することです (他の人が既に述べたように)。

良い追加は、タイマーを使用してすぐに復元することです。これにより、ユーザーは自分が行った選択を引き続き確認できます。

注: ボタン ハンドラーで選択を使用する場合、実行時に選択が復元されていない可能性があります。変数から保存された値を使用するか、ボタン ハンドラーの先頭に DoEvents を追加して、タイマー ハンドラーが最初に実行されるようにしてください。

Dim m_iOperSelLeft As Integer
Dim m_iSelTop As Integer
Dim m_iSelWidth As Integer
Dim m_iSelHeight As Integer

Private Sub MySubForm_Exit(Cancel As Integer)

    m_iSelLeft = MySubForm.Form.SelLeft
    m_iSelTop = MySubForm.Form.SelTop
    m_iSelWidth = MySubForm.Form.SelWidth
    m_iSelHeight = MySubForm.Form.SelHeight

    TimerInterval = 1

End Sub

Private Sub Form_Timer()

    TimerInterval = 0

    MySubForm.Form.SelLeft = m_iSelLeft - 1
    MySubForm.Form.SelTop = m_iSelTop
    MySubForm.Form.SelWidth = m_iSelWidth
    MySubForm.Form.SelHeight = m_iSelHeight

End Sub
于 2011-09-11T22:32:47.227 に答える
2

以前にそのようなことを試みたことがありますが、ユーザーが Windows ファイル ダイアログ ボックスと同じスタイル (Ctrl、Shift などを押す) で複数の行を選択する必要がある方法を使用して成功したことはありません。

私が使用した 1 つの方法は、2 つのリスト ボックスを使用することです。左側のリスト ボックスの項目をダブルクリックするか、項目が選択されているときにボタンをクリックすると、右側のリスト ボックスに移動します。

もう 1 つのオプションは、ソース データと、サブフォームのチェックボックスとして表されるブール値が取り込まれたローカル テーブルを使用することです。ユーザーがチェックボックスをクリックして必要なデータを選択した後、ユーザーはボタン (またはその他のイベント) を押します。その時点で、基になるデータのテーブルに直接移動し、チェックされた行のみをクエリします。適切に動作させるには少しコードが必要ですが、このオプションが最適だと思います。

Access でも、Access フォームの組み込みツールを使用するよりも、テーブルやクエリを直接操作する方が簡単な場合があります。組み込みツールでは、必要な機能が正確に実行されないことがあります。

于 2009-11-03T20:43:33.347 に答える
2

別の解決策があります。

以下のコードは、マウス ボタンを離すとすぐに、選択された行の数を表示します。この値を保存するとうまくいきます。

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)

        MsgBox Me.SelHeight

End Sub
于 2013-09-13T18:40:09.357 に答える
1

フォームでグローバル変数を使用し、ボタン コードでそれを参照します。

Dim g_numSelectedRecords as long

Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
   g_numSelectedRecords = Me.SelHeight
End Sub


Dim formRecords As DAO.Recordset
Dim i As Long

Set formRecords = Me.RecordsetClone

' Move to the first record in the recordset.
formRecords.MoveFirst

' Move to the first selected record.
formRecords.Move Me.SelTop - 1

For i = 1 To numSelectedRecords
    formRecords.Edit
    formRecords.Fields("Archived") = True
    formRecords.Update
    formRecords.MoveNext
Next i
于 2012-01-06T16:47:17.133 に答える
0

配列またはレコードセットを使用してから、ユーザーが行をクリックするたびに (連続しているかどうかにかかわらず、その行またはいくつかの識別子をレコードセットに保存します。次に、親フォームのボタンをクリックすると、単純にレコードセットを繰り返します)ボタンをクリックした後、配列またはレコードセットをクリアすることを忘れないでください。

于 2014-12-03T13:40:58.390 に答える
0

プロシージャの実行中に選択を保持する別の回避策 - データシートを離れてボタンをアクティブにする代わりに、OnKeyDown イベントを使用して特定のキーコードとシフトの組み合わせを定義し、コードを実行します。

于 2015-05-05T16:22:12.397 に答える