Access (VBA)

Access VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10全般 : 指定なし)
フォームフィルターをボタンで再現
投稿日時: 23/08/27 22:32:17
投稿者: おーさん0729

いつもお世話になっております。
 
フォームフィルター機能をボタンで再現したいです。
フォーム上にボタンを配置し、そのボタンを押すと、フォームフィルターと同じように入力画面に移行し、入力できるようにしたいです。
 
また、フィルター時の20/100を表示中に、残り分である80/100を表示できるように切り替えたい。
 
また、20/100を表示中に表示レコードを選択し、表示を除外したい。
 ※20/100を19/100の表示にし、上記切り替えをすると、81/100となるようにです。
 
よろしくお願いします。

回答
投稿日時: 23/08/28 16:59:13
投稿者: Suzu

多くの要望がありますが、ご自身で、どこまでお調べになって、
具体的に何が判らなくてつまづいているのでしょうか?
 
 
一般的なのは、
フィルターの条件を入力する複数のテキストボックス等を設置したフォームを作成し
そのテキストボックスの中身を取得し、SQLの WHERE句を生成し、
Filter プロパティーに設定するなり、
フォームのレコードソースとして設定する
があります。
 
フォームフィルターで良いなら、フォームフィルターを呼び出せば良いのでは?
当方では、直接呼び出す方法が検索しきれませんでした。
 
Form.Filter イベント (Access)
https://learn.microsoft.com/ja-jp/office/vba/api/access.form.filter(even)
辺りで出来るかも知れませんが、確認できていません。
 
ApplyFilter も調べてみてください。
 
 
逆・・・は難しいのですよ。。
他のデータベースソフトだと、実装しているのもある様ですが。
 
 
実装するなら、フィルターで抽出するのではなく、
 
1. WHERE句を取得し、クエリとして保存。
2. このクエリをレコードソースとして、フォームを表示。
3. 逆を選択した際には、元のテーブルと、そのクエリの不一致クエリを作成。
4. 不一致クエリをフォームのレコードソースとして表示
の様な形でしょうか。
 
でも、これだと、編集は出来ない。
 
編集を考慮するなら、不一致クエリ結果の 主キー部分を、ワークテーブルに保存
ワークテーブルと、元テーブルを主キーで連結したクエリを ソースとしてフォーム表示でしょうか。

回答
投稿日時: 23/08/29 00:35:21
投稿者: hatena
投稿者のウェブサイトに移動

引用:
フォームフィルター機能をボタンで再現したいです。
フォーム上にボタンを配置し、そのボタンを押すと、フォームフィルターと同じように入力画面に移行し、入力できるようにしたいです。

 
すでにSuzuさんから回答があるように、フォームフィルターと同じようなフォームを作成することになります。条件を入力するボックスはコンボボックスにするといいでしょう。
 
かなり面倒なことになりそうですので、フォームフィルターを使えばいいと私も思います。
フォームフィルターを呼び出すコマンドは下記ですね。
 
Docmd.RunCommand acCmdFilterByForm

 
ただし、フォームフィルター画面になるとフォーム上のコマンドボタンは無効になるので、フィルター結果を反映させるには、リボンメニューか右クリックメニューで実行させることになります。
 
引用:
また、フィルター時の20/100を表示中に、残り分である80/100を表示できるように切り替えたい。

 
Not (フィールター条件式) で選択を反転できるので、下記のような感じでどうでしょう。
 
Private Sub コマンド1_Click()
    Dim f As String
    f = Me.filter
    If Me.FilterOn And f <> "" Then
        If Me.filter Like "Not (*)" Then
            Me.filter = Mid(f, 6, Len(f) - 6)
        Else
            Me.filter = "Not (" & f & ")"
        End If
    End If
End Sub

回答
投稿日時: 23/08/29 16:29:06
投稿者: Suzu

引用:
また、20/100を表示中に表示レコードを選択し、表示を除外したい。
 ※20/100を19/100の表示にし、上記切り替えをすると、81/100となるようにです。

 
これは、その選択をどの様に行うかに依ります
 
安易に考えれば、レコード 1件1件に、チェックボックスを用意し、そのチェックボックスにより選択を行う
これは、レコードソースに、そのチェックボックスのコントロールソースとなる
フィールドを用意する必要があります。
 
 
 
ちょっと特殊な方法としては
帳票フォーム/データシート内のセル範囲を選択し
リボン/クイックツールバー に配置したボタンを押し、
VBAにて、選択レコードを特定し、選択対象から外す様にします。
 
※一度に選択できるのは、連続したレコードのみで、飛び飛びのレコードを選択する事はできません
※フォームにボタンを配置すると、そのクリック時こ選択範囲が外れるので、
   メイン/サブ形式 として、メイン側に配置
   リボン等に配置
  VBAを実行する様にする必要があります。
 
範囲選択されているレコード数を取得するには?
https://tsware.jp/tips/tips_244.htm
 
 
後者は、特殊ですし、抽出の為の 文字列が長くなりがちになります。
何度も繰り返すと、文字数に制限のある Filter プロパティーに文字列を渡せない事にもなりかねません
前者の方が無難です。

投稿日時: 23/08/29 19:59:30
投稿者: おーさん0729

おーさん0729 さんの引用:
Suzu さんの引用:

逆・・・は難しいのですよ。。
他のデータベースソフトだと、実装しているのもある様ですが。

そうなんです。
要するに、FileMakerでの「現在の対象レコードにないレコードのみを表示」を
Accessで再現したいんです。
 
引用:
安易に考えれば、レコード 1件1件に、チェックボックスを用意し、そのチェックボックスにより選択を行う
これは、レコードソースに、そのチェックボックスのコントロールソースとなる
フィールドを用意する必要があります。

今しているのは、レコード自体にフィールドでチェックを持たせ、検索やフィルターをこのチェックのオンオフを表示して形にしています。
そこで少しでも簡単にできないものかと...。

投稿日時: 23/08/29 20:04:16
投稿者: おーさん0729

hatena さんの引用:

かなり面倒なことになりそうですので、フォームフィルターを使えばいいと私も思います。
フォームフィルターを呼び出すコマンドは下記ですね。
Docmd.RunCommand acCmdFilterByForm

ありがとうございます。これが知りたかったです。コマンドの呼び出し方とお聞きすればよかったのですね。
引用:

Not (フィールター条件式) で選択を反転できるので、下記のような感じでどうでしょう。
Private Sub コマンド1_Click()
    Dim f As String
    f = Me.filter
    If Me.FilterOn And f <> "" Then
        If Me.filter Like "Not (*)" Then
            Me.filter = Mid(f, 6, Len(f) - 6)
        Else
            Me.filter = "Not (" & f & ")"
        End If
    End If
End Sub

ありがとうございます。これで反転はできました。
が、あとは、
引用:
また、20/100を表示中に表示レコードを選択し、表示を除外したい。
 ※20/100を19/100の表示にし、上記切り替えをすると、81/100となるようにです。

ですが、Suzuさんが書いてある方法 もしくは 今している方法くらいしかなさそうですね。

投稿日時: 23/08/29 20:12:36
投稿者: おーさん0729

追記です。
 
したいこととしては、FileMakerの
「現在の対象レコードにないレコードのみを表示」※検索結果の反転
「レコードの対象外」※検索結果からの除外
「複数レコードを対象外に」
になります。これをAccessで再現したいです。
 
今日、調べていたのですが、
FileMakerの「検索」はAccessの「フィルター」でも「検索」でもないので、
少なくとも、Accessの「フィルター」で再現するなら、フィルターをかけた状態からレコードの増減ができないといけないなと思いました。

回答
投稿日時: 23/08/29 20:42:27
投稿者: hatena
投稿者のウェブサイトに移動

引用:
したいこととしては、FileMakerの
「現在の対象レコードにないレコードのみを表示」※検索結果の反転
「レコードの対象外」※検索結果からの除外

 
FileMakerは触ったことがないのでよくわかりませんが、
「レコードの対象外」というのが、
カレントレコードを対象外(非表示)にするということなら、
 
主キーフィールドがIDで数値型と仮定して、下記のようなコードになります。
Private Sub コマンド1_Click()
    Dim f As String
    f = Me.filter
    If Me.FilterOn And f <> "" Then
        If Me.filter Like "Not (*)" Then
            Me.filter = "(" f & ") AND (ID <>" & Me.ID & ")"
        Else
            Me.filter = "ID<>" & Me.ID
            Me.FilterOn = True
        End If
    End If
End Sub

 
引用:
「複数レコードを対象外に」]

 
この場合、複数レコードはどのように指定することを想定してますか。
帳票フォームの場合、連続したレコードは複数選択可能ですが、とびとびのレコードも選択したいですよね。
例えば、チェックボックスを配置してチェックが入ったレコードを対象にするという感じでしょうか。

投稿日時: 23/08/29 22:45:46
投稿者: おーさん0729

[quote="hatena"]

引用:
FileMakerは触ったことがないのでよくわかりませんが、
「レコードの対象外」というのが、
カレントレコードを対象外(非表示)にするということなら、

この認識で合ってます。
20/100を表示中に、カレントレコードを対象外にすると、1件減って19/100を表示することになります。
 
引用:
この場合、複数レコードはどのように指定することを想定してますか。
帳票フォームの場合、連続したレコードは複数選択可能ですが、とびとびのレコードも選択したいですよね。
例えば、チェックボックスを配置してチェックが入ったレコードを対象にするという感じでしょうか。

連続したレコードを選択する形です。
カレントレコードでボタンを押すと、メッセージで「○件対象外にしますか?」と表示して、入力した数字分をカレントレコードから対象外にする感じです。
 
また、反転+対象外の使い方をすることがあります。
具体的には、フィルター→20/100(表示)→反転→80/100(表示)→選択したレコードを対象外→79/100→反転→21/100という感じです。
(フィルターかけた)表示レコードに除外したレコードを足すといった感じですかね。
「フィルター」を使っている以上、両立できないような気がしてます...。

回答
投稿日時: 23/08/30 08:29:56
投稿者: Suzu

1. 抽出条件を元に、更新クエリを発行し、チェックボックスの連結フィールドの値を True へ 更新
2. True の レコードを 表示対象として表示
3. 反転処理で、Not(チェックボックス=True)のレコードを表示
  チェックボックスは False のはず
4. ユーザー操作で、チェックボックス を True へ
5. 反転処理 で、 チェックボックス = True
 
で、希望の動作になるかと。

回答
投稿日時: 23/08/30 08:37:32
投稿者: Suzu

複数人 同時 使用前提の場合
ロックを自前で用意が必要になる事があります。
 
今回の操作でも、ワークテーブルを別に用意した方が無難でしょうね。
 
FileMakerは FileMakerの得意な事があり
そうであれば、FileMaker を使う方が無難でしょう。
 
難しいなら、難しいと言う事も仕事でしょうから。
その辺りの判断は必要と思います。

回答
投稿日時: 23/08/30 09:11:56
投稿者: Suzu

あれ、、、
 
これって、以前、同じ質問をされていませんか?
FileMaker を Access 移植。
 
その時も、マルチユーザー、抽出条件 の反転、の話は出て、
 
 サーバーではなく、ローカルに抽出条件を保存 しないと、
 複数人が同じ抽出結果を表示される様になるよと 話した記憶があります。
 
https://web.archive.org/web/20230326035031/https://www.moug.net/faq/viewtopic.php?t=81858
https://web.archive.org/web/20230531112029/https://www.moug.net/faq/viewtopic.php?t=81959&sid=fedc8c14e58ef87e69008e778bdd9f14
 
何と言うか・・お疲れ様です。

回答
投稿日時: 23/08/30 12:23:40
投稿者: hatena
投稿者のウェブサイトに移動

おーさん0729 さんの引用:

連続したレコードを選択する形です。
カレントレコードでボタンを押すと、メッセージで「○件対象外にしますか?」と表示して、入力した数字分をカレントレコードから対象外にする感じです。

帳票フォームでレコードセレクターをドラッグするあるいはShiftキーでクリックで複数選択して、その選択レコードを対象にするということではなく、
インプットボックスで件数を入力させて、カレントレコード以降その件数分を対象にするということでしょうか。
対象レコードの主キーの値を取得して、それもとに条件式をFilterに追加すれば可能でしょう。
 
前者の場合は、コマンドボタンだと、複数レコード選択が解除されますので、ラベルクリックで代用するなどの対策が必要です。
 
対象の主キーの値を取得する方法はRecorsetプロパティのレコードセットをループさせることで可能です。
 
下記のような条件式をFilterプロパティに追加すればいいでしょう。
 
(Filterプロパティの条件式) And (ID Not In (3,5,7,9))
 
IDが 3,5,7,9 のレコードを除外
 
おーさん0729 さんの引用:

具体的には、フィルター→20/100(表示)→反転→80/100(表示)→選択したレコードを対象外→79/100→反転→21/100という感じです。
(フィルターかけた)表示レコードに除外したレコードを足すといった感じですかね。
「フィルター」を使っている以上、両立できないような気がしてます...。

 
前にも回答した反転方法で可能です。
 
79/100→反転→21/100
なら 79/100 の条件式を Not (条件式) とすることで可能です。

投稿日時: 23/09/03 18:15:51
投稿者: おーさん0729

Suzu さんの引用:
あれ、、、
 
これって、以前、同じ質問をされていませんか?
FileMaker を Access 移植。
 
その時も、マルチユーザー、抽出条件 の反転、の話は出て、
 
 サーバーではなく、ローカルに抽出条件を保存 しないと、
 複数人が同じ抽出結果を表示される様になるよと 話した記憶があります。
 
何と言うか・・お疲れ様です。

覚えてくださり、ありがとうございます。以前の質問時より開発状況はほぼ変わっておりません...
サーバーのテーブルの主キーをローカルに落としこんで、
その主キーにチェックボックスをくっつけたものをテーブルにして、
そのチェックボックスで、表示を操作してました。
 
が、ローカルに落とし込んでるので、サーバーデータが追加削除されると反映されないのです。
(一人ならもちろん問題なし。複数人なら、です)
 
なので、基本に帰って、検索方法(フィルター)を何とかできないかなーが今回の質問につながります。

投稿日時: 23/09/03 19:19:04
投稿者: おーさん0729

hatena さんの引用:

帳票フォームでレコードセレクターをドラッグするあるいはShiftキーでクリックで複数選択して、その選択レコードを対象にするということではなく、
インプットボックスで件数を入力させて、カレントレコード以降その件数分を対象にするということでしょうか。
対象レコードの主キーの値を取得して、それもとに条件式をFilterに追加すれば可能でしょう。
 
前者の場合は、コマンドボタンだと、複数レコード選択が解除されますので、ラベルクリックで代用するなどの対策が必要です。
 
対象の主キーの値を取得する方法はRecorsetプロパティのレコードセットをループさせることで可能です。
 
下記のような条件式をFilterプロパティに追加すればいいでしょう。
 
(Filterプロパティの条件式) And (ID Not In (3,5,7,9))
 
IDが 3,5,7,9 のレコードを除外

一度フィルターをかけて、そこから絞り込み?をするイメージですかね?
今のフィルターの条件に付けたす感じですよね?
 
引用:

前にも回答した反転方法で可能です。
 
79/100→反転→21/100
なら 79/100 の条件式を Not (条件式) とすることで可能です。

上記の反対を行うという理解をしました。
試してみます。
ありがとうございます。

回答
投稿日時: 23/09/04 10:00:35
投稿者: Suzu

引用:
以前の質問時より開発状況はほぼ変わっておりません...

 
以前の話 に立ち戻って 同じ話をしている様にお見受けしますので、その辺は察しています
 
 
引用:
サーバーのテーブルの主キーをローカルに落としこんで、
その主キーにチェックボックスをくっつけたものをテーブルにして、
そのチェックボックスで、表示を操作してました。
 
が、ローカルに落とし込んでるので、サーバーデータが追加削除されると反映されないのです。
(一人ならもちろん問題なし。複数人なら、です)
 
なので、基本に帰って、検索方法(フィルター)を何とかできないかなーが今回の質問につながります

 
自動更新。
 
言葉だけなら、良い様に聞こえます。
 
その画面から、次の業務フローへ続きませんか?
ユーザーは、画面で問題が無い事を確認しました。
 
でも、確認が終わったのに、確認していないデータが現われました。
ユーザーは、確認が終わったつもりで、確認を行っていないレコードを含め次のフローへ進みます。
本当にそれで良いのでしょうか?
 
同じ条件で、レポート印刷しませんか?
確認が終わっていない・終わったレコードを含め 印刷が行われる事になりませんか?
 
 
これを防ぐには、各レコードの状態を示すフラグを持たせる必要があります。
画面の 表示のしかたひとつで、全体フローが変わりえます。
そう言う事も考慮し検討しましょう。
 
 
その場しのぎで、GUIを考えず、
全体を含め業務フロー、各レコードの状態、ユーザーが行うべき処理 をきちんとふまえ
システム設計を行いましょう。

投稿日時: 23/09/10 17:49:50
投稿者: おーさん0729

ありがとうございます。
全部ひとりでしてるので手一杯ですが、少しずつ進めていきます。