何かと年を感じるなと思っている柴犬です。
今回の概要
レコードを選択できるようにしました。
レコードの選択はレコードセレクターをクリックします。
するとチェックボックスにチェックが入ります。
ボタン「一覧プレ」をクリックしてプレビューを表示しました。
つづいて、ボタン「タックシールプレ」をクリックしてプレビューを表示しました。
表題の「全選択」をクリックしてみます。
すると、全レコードのチェックボックスにチェックが入り選択状態になります。
また、表題の「全選択」は「選択解除」になります。
表題の「選択解除」をクリックしてみます。
すると、全レコードのチェックボックスにチェックが外れ未選択状態になります。
また、表題の「選択解除」は「全選択」になります。
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