
何かと年を感じるなと思っている柴犬です。
今回の概要
レコードを選択できるようにしました。

レコードの選択はレコードセレクターをクリックします。
するとチェックボックスにチェックが入ります。

ボタン「一覧プレ」をクリックしてプレビューを表示しました。

つづいて、ボタン「タックシールプレ」をクリックしてプレビューを表示しました。

表題の「全選択」をクリックしてみます。
すると、全レコードのチェックボックスにチェックが入り選択状態になります。
また、表題の「全選択」は「選択解除」になります。

表題の「選択解除」をクリックしてみます。
すると、全レコードのチェックボックスにチェックが外れ未選択状態になります。
また、表題の「選択解除」は「全選択」になります。

ACCESSのフォームの修正
テキストボックスなどオブジェクトの配置
テキストボックス「selected」「ID」とチェックボックス「チェック1」を配置します。

「チェック1」のプロパティ
「チェック1」のプロパティを変更します。
コントロールソースに式を書く加えます。
規定値を False にします。

コントロールソースがちょっと見にくいため、次にコードを載せました。
=IIf(InStr(selected.Value & ",","," & ID.Value & ",")>0,True,False)
テキストボックス「selected」のプロパティ
テキストボックス「selected」のプロパティの可視を「いいえ」にします。

テキストボックス「ID」のプロパティ
テキストボックス「ID」のプロパティの可視を「いいえ」にします。
コントロールソースを「ID」にします。

コード
フォーム「 フォーム1 」
すべて新しく追加しています。
説明は、後で自分が困らない程度にコードの中で行っています。
Option Compare Database
Option Explicit
Private myList As String
Private myParent As String
Private AllList As String
Private TargetList As String
'---------------------------------------
'
Private Sub Form_Open(Cancel As Integer)
Dim UF As Object
'------親フォーム名
myParent = Me.OpenArgs
'------親フォームを探査します。
For Each UF In Forms
With UF
If .Name = myParent Then
'------全IDのリストを取得します。
AllList = .AllList
TargetList = .TargetList
End If
End With
Next UF
End Sub
'---------------------------------------
'
Private Sub Form_Load()
'------TargetList に既選択がある場合
If TargetList <> "" Then
Me.selected.Value = "," & TargetList
End If
End Sub
'---------------------------------------
'
Private Sub Form_Click()
Dim BUF As String
Dim UF As Object
Dim AddFLG As Long
If Me.SelHeight > 0 Then
If InStr(Me.selected.Value & ",", _
"," & Me.ID.Value & ",") = 0 Then
'------クリックしたレコードのIDを追加します。
Me.selected.Value = Me.selected.Value & "," & Me.ID.Value
'------選択のフラッグ
AddFLG = 1
Else
'------検索文字列の調整
BUF = Me.selected.Value & ","
'------クリックしたレコードのIDを削除します。
BUF = Replace(BUF, _
"," & Me.ID.Value & ",", _
",")
'------最後尾のカンマを削除します。
Me.selected.Value = Left(BUF, Len(BUF) - 1)
'------削除のフラッグ
AddFLG = -1
End If
Me.Recalc
For Each UF In Forms
If UF.Name = myParent Then
'------先頭のカンマを削除します。
TargetList = Mid(Me.selected.Value, 2)
UF.TargetList = TargetList
End If
Next UF
'------全選択・選択解除のキャプション
Call AllCheck(AddFLG)
End If
End Sub
'---------------------------------------
'
Private Sub AllCheck(ByVal AddFLG As Long)
Dim TargetDict As Dictionary
Dim ArrayBUF As Variant
Dim I As Long
Dim Check As Boolean
'------選択がない状態
If TargetList = "" Then
Me.ラベル選択.Caption = "全選択"
Exit Sub
End If
'------初期値
Check = True
'------選択がある ID ハッシュテーブルを作成します。
ArrayBUF = Split(TargetList, ",")
Set TargetDict = New Dictionary
With TargetDict
For I = 0 To UBound(ArrayBUF)
If Not TargetDict.Exists(ArrayBUF(I)) And ArrayBUF(I) <> "" Then
.Add ArrayBUF(I), 1
End If
Next I
End With
'------全 ID とハッシュテーブルと照合します。
ArrayBUF = Split(AllList, ",")
For I = 0 To UBound(ArrayBUF)
If Not TargetDict.Exists(ArrayBUF(I)) Then
'------全て選択されていない。
Check = False
I = UBound(ArrayBUF)
End If
Next I
'------全て選択されていれば選択解除とします。
If Check Then
Me.ラベル選択.Caption = "選択解除"
'------一部が選択されている。
Else
Select Case AddFLG
Case 1
'------選択を追加した場合
Me.ラベル選択.Caption = "全選択"
Case -1
'------選択を削除した場合
Me.ラベル選択.Caption = "選択解除"
End Select
End If
End Sub
'---------------------------------------
'
Private Sub ラベル選択_Click()
Dim UF As Object
Select Case Me.ラベル選択.Caption
Case "全選択"
Me.ラベル選択.Caption = "選択解除"
Me.selected.Value = "," & AllList
TargetList = AllList
Case "選択解除"
Me.ラベル選択.Caption = "全選択"
Me.selected.Value = ""
TargetList = ""
End Select
Me.Recalc
For Each UF In Forms
If UF.Name = myParent Then
UF.TargetList = TargetList
End If
Next UF
End Sub
レポート「 レポート1 」「 レポート2 」
レポート1・レポート2とも同じです。
Option Compare Database
Option Explicit
Private myList As String
Private myParent As String
Private Sub Report_Open(Cancel As Integer)
Dim UF As Object
Dim mySQL As String
myParent = Me.OpenArgs
For Each UF In Forms
If UF.Name = myParent Then
myList = UF.TargetList
End If
Next UF
mySQL = "SELECT * "
mySQL = mySQL & "FROM テーブル1 AS A "
mySQL = mySQL & "WHERE A.ID IN (" & myList & ");"
Me.RecordSource = ""
Me.RecordSource = mySQL
End Sub
フォーム「 ベース 」
修正・追加は次の3カ所あります。
レポートから参照するためのプロパティを新しく追加しました。
Private memTargetList As String
Private memAllList As String
'---------------------------------------
'
Public Property Let TargetList(ByVal myList As String)
memTargetList = myList
End Property
Public Property Get TargetList() As String
TargetList = memTargetList
End Property
Public Property Let AllList(ByVal myAllList As String)
memAllList = myAllList
End Property
Public Property Get AllList() As String
AllList = memAllList
End Property
プロシージャ「 ChangeObj 」の修正
全「 ID 」を取得した分を作成する「 Call getAllList 」の実行を追加します。
また、選択がない場合レポートを開かないようにIf文「If TargetList = “” Then」を追加します。
Private Sub ChangeObj(ByVal strCap As String)
Dim OpenObj As Variant
OpenObj = Split(strCap, ":")
If OpenObj(0) = "F" Then
'------全レコードのIDを取得します。(追加)
Call getAllList
SetForm = OpenObj(1)
Else
'------選択がない場合レポートを開かないようにしています。(追加)
If TargetList = "" Then
MsgBox "選択がありません。"
Exit Sub
End If
SetReport = OpenObj(1)
End If
End Sub
getAllList プロシージャを新規に作成
プロシージャ「 ChangeObj 」から使っています。
このプロシージャの仕事は、名簿の「テーブル1」のフィール「 ID 」をカンマ区切りの一つの文を作成します。
そして、作成した文をプロパティ「 AllList 」を経由して変数「memAllList」に代入します。
Private Sub getAllList()
Dim Db As DAO.Database
Dim Rs As DAO.Recordset
Set Db = CurrentDb()
Set Rs = Db.OpenRecordset("SELECT A.ID FROM テーブル1 AS A;", _
dbOpenSnapshot)
If Not Rs.EOF Then
Do Until Rs.EOF
If AllList = "" Then
AllList = Rs.Fields("ID")
Else
AllList = AllList & "," & Rs.Fields("ID")
End If
Rs.MoveNext
Loop
End If
Rs.Close
Db.Close
End Sub
まとめ
最後なりましたので、フォーム「ベース」のすべてのコードを記載しています。
Option Compare Database
Option Explicit
Private TP As Long
Private X As Long
Private Y As Long
Private cx As Long
Private cy As Long
Private curReportName As String
Private curFormName As String
Private CapRepo As Dictionary
Private CmdBL As Variant
Private Const Margin As Long = 56
Private memTargetList As String
Private memAllList As String
'---------------------------------------
'
Public Property Let TargetList(ByVal myList As String)
memTargetList = myList
End Property
Public Property Get TargetList() As String
TargetList = memTargetList
End Property
Public Property Let AllList(ByVal myAllList As String)
memAllList = myAllList
End Property
Public Property Get AllList() As String
AllList = memAllList
End Property
'---------------------------------------
'
Public Property Let SetReport(ByVal NewName As String)
Dim Ret As Variant
On Error Resume Next
'------表示しているフォーム・レポートを閉じる
Call ObjClose
'------新しいレポートを開く
DoCmd.OpenReport NewName, acViewPreview, OpenArgs:=Me.Name
curReportName = NewName
'------ベースに表示するレポート・フォームの位置とサイズを調整
Call MWindow
'------新しいレポートの子ウィンドウを親ウィンドウのフォームに設定
SetParent Reports(curReportName).hWnd, Me.hWnd
DoCmd.SelectObject acReport, curReportName
End Property
'---------------------------------------
'
Public Property Get SetReport() As String
SetReport = curReportName
End Property
'---------------------------------------
'
Public Property Let SetForm(ByVal NewName As String)
Dim Ret As Variant
On Error Resume Next
'------表示しているフォーム・レポートを閉じる
Call ObjClose
'------新しいフォームを開く
DoCmd.OpenForm NewName, acNormal, OpenArgs:=Me.Name
curFormName = NewName
'------ベースに表示するレポート・フォームの位置とサイズを調整
Call MWindow
'------新しいフォームの子ウィンドウを親ウィンドウのフォームに設定
SetParent Forms(curFormName).hWnd, Me.hWnd
DoCmd.SelectObject acForm, curFormName
End Property
'---------------------------------------
'
Public Property Get SetForm() As String
SetForm = curFormName
End Property
'---------------------------------------
'
Private Sub ObjClose()
Dim Rpt As Report
Dim Frm As Form
On Error Resume Next
'------表示しているレポートを閉じる
If Len(curReportName) > 0 Then
For Each Rpt In Reports
If Rpt.Name = curReportName Then
DoCmd.Close acReport, Rpt.Name
curReportName = ""
End If
Next Rpt
End If
'------表示しているフォームを閉じる
If Len(curFormName) > 0 Then
For Each Frm In Forms
If Frm.Name = curFormName Then
DoCmd.Close acForm, Frm.Name
curFormName = ""
End If
Next Frm
End If
End Sub
'---------------------------------------
'
Private Sub Form_Load()
Dim Ret As Variant
Dim SetValue As Long
Dim OpenObj As Variant
Dim I As Long
On Error Resume Next
'------Win32API関数を使ってアクセスを最小化します
CloseWindow Application.hWndAccessApp
'------現在の設定値を取得
SetValue = GetWindowLong(Me.hWnd, GWL_STYLE)
'------最小化ボタンを無効
SetValue = SetValue And Not WS_MINIMIZEBOX
'------設定値をセット
SetWindowLong Me.hWnd, GWL_STYLE, SetValue
'------単位変換の変換率の計算
TP = TwipPixel
'------ボタンのキャプションリスト
CmdBL = Array("一覧プレ", "タックシールプレ", "選択フォーム")
'------ボタンのキャプションをセット
For I = 0 To UBound(CmdBL)
Me("bu" & I).Caption = CmdBL(I)
Next I
'------ボタンのキャプション名とレポート名・フォーム名の
' ハッシュテーブル
Set CapRepo = New Dictionary
With CapRepo
.Add CmdBL(0), "R:レポート1"
.Add CmdBL(1), "R:レポート2"
.Add CmdBL(2), "F:フォーム1"
End With
'------初期値
curReportName = ""
curFormName = ""
TargetList = ""
AllList = ""
'------子フォームの原点
X = 0
Y = Me.bu閉じる.Height + Me.bu閉じる.Top * 2
'------子フォームの大きさ
Call ChildFormSize
'------フォームの OpenArgs プロパティを使用します
If IsNull(Me.OpenArgs) Then
Call ChangeObj(CapRepo("選択フォーム"))
Else
Call ChangeObj(Me.OpenArgs)
End If
End Sub
'---------------------------------------
'
Private Sub Form_Close()
Call ObjClose
Set CapRepo = Nothing
End Sub
'---------------------------------------
'
Private Sub Form_Resize()
Dim Ret As Variant
On Error Resume Next
'------リサイズ後のレポート・フォームのサイズ
Call ChildFormSize
'------ベースに表示するレポート・フォームの位置とサイズを調整
Call MWindow
'------ボタンの配置
Call BuPosiSet
End Sub
'---------------------------------------
'
Private Sub bu印刷_Click()
On Error Resume Next
If Len(curReportName) = 0 Then
Exit Sub
End If
DoCmd.SelectObject acReport, curReportName, False
DoCmd.RunCommand acCmdPrint
End Sub
'---------------------------------------
'
Private Sub bu閉じる_Click()
DoCmd.Quit acQuitSaveNone
End Sub
'---------------------------------------
'
Private Sub bu0_Click()
Call ChangeObj(CapRepo(Me.bu0.Caption))
End Sub
'---------------------------------------
'
Private Sub bu1_Click()
Call ChangeObj(CapRepo(Me.bu1.Caption))
End Sub
'---------------------------------------
'
Private Sub bu2_Click()
Call ChangeObj(CapRepo(Me.bu2.Caption))
End Sub
'---------------------------------------
'
Private Sub ChangeObj(ByVal strCap As String)
Dim OpenObj As Variant
OpenObj = Split(strCap, ":")
If OpenObj(0) = "F" Then
'------全レコードのIDを取得します。(追加)
Call getAllList
SetForm = OpenObj(1)
Else
'------選択がない場合レポートを開かないようにしています。(追加)
If TargetList = "" Then
MsgBox "選択がありません。"
Exit Sub
End If
SetReport = OpenObj(1)
End If
End Sub
'---------------------------------------
'
Public Function TwipPixel() As Long
Dim DskhWnd As Long
Dim nhDc As Long
Dim Bit As Long
Dim nWidth As Long
Dim nHeight As Long
'------デスクトップのハンドル
DskhWnd = GetDesktopWindow
'------デスクトップのデバイスコンテキストハンドル
nhDc = GetDC(DskhWnd)
'------画面の横幅
nWidth = GetDeviceCaps(nhDc, HORZRES)
'------画面の縦幅
nHeight = GetDeviceCaps(nhDc, VERTRES)
'------ピクセル当たりのビット数
Bit = GetDeviceCaps(nhDc, BITSPIXEL)
TwipPixel = CLng(1440 / GetDeviceCaps(nhDc, LOGPIXELSX))
End Function
'---------------------------------------
'
Private Sub MWindow()
Dim Ret As Variant
If Len(curReportName) > 0 Then
Ret = MoveWindow(Reports(curReportName).hWnd, _
X / TP, _
Y / TP, _
cx / TP, _
cy / TP, _
SWP_SHOWWINDOW)
End If
If Len(curFormName) > 0 Then
Ret = MoveWindow(Forms(curFormName).hWnd, _
X / TP, _
Y / TP, _
cx / TP, _
cy / TP, _
SWP_SHOWWINDOW)
End If
End Sub
'---------------------------------------
'
Private Sub BuPosiSet()
Dim buStart As Long
Dim buAreaLen As Long
Dim I As Long
buStart = Me.bu閉じる.Width + _
Me.bu印刷.Width + _
Margin * 2
For I = 0 To UBound(CmdBL)
buAreaLen = buAreaLen + _
Me("bu" & I).Width + Margin
Next I
If buStart < _
cx - buAreaLen Then
Me("bu0").Left = buStart + _
((cx - buStart - buAreaLen) / 2)
Else
Me("bu0").Left = buStart
End If
For I = 1 To UBound(CmdBL)
Me("bu" & I).Left = Me("bu" & (I - 1)).Left + _
Me("bu" & (I - 1)).Width + Margin
Next I
End Sub
'---------------------------------------
'
Private Sub ChildFormSize()
cx = Me.InsideWidth
cy = Me.InsideHeight - Y
End Sub
'---------------------------------------
'
Private Sub getAllList()
Dim Db As DAO.Database
Dim Rs As DAO.Recordset
Set Db = CurrentDb()
Set Rs = Db.OpenRecordset("SELECT A.ID FROM テーブル1 AS A;", _
dbOpenSnapshot)
If Not Rs.EOF Then
Do Until Rs.EOF
If AllList = "" Then
AllList = Rs.Fields("ID")
Else
AllList = AllList & "," & Rs.Fields("ID")
End If
Rs.MoveNext
Loop
End If
Rs.Close
Db.Close
End Sub