『SELECT Q買掛の支払締日と期日.支払締の年月
FROM Q買掛の支払締日と期日
WHERE (((Q買掛の支払締日と期日.買掛先ID)=[Forms]![F買掛仕入一覧]![cb取引先選択]) AND ((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理")) OR (((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理") AND (([Forms]![F買掛仕入一覧]![cb取引先選択]) Is Null))
GROUP BY Q買掛の支払締日と期日.支払締の年月
ORDER BY Q買掛の支払締日と期日.支払締の年月』
下ではNullチェックすることがあるのに上では「=」比較をしているとか
『SELECT Q買掛の支払締日と期日.支払締の年月
FROM Q買掛の支払締日と期日
WHERE (((Q買掛の支払締日と期日.買掛先ID)=[Forms]![F買掛仕入一覧]![cb取引先選択]) AND ((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理")) OR (((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理") AND (([Forms]![F買掛仕入一覧]![cb取引先選択]) Is Null))
GROUP BY Q買掛の支払締日と期日.支払締の年月
ORDER BY Q買掛の支払締日と期日.支払締の年月』
SELECT 支払締の年月
FROM Q買掛の支払締日と期日
WHERE 買掛先ID=Nz([Forms]![F買掛仕入一覧]![cb取引先選択],買掛先ID)
AND 支払締の年月>Nz([Forms]![F買掛仕入一覧]![cb支払締の年月1],"")
AND 支払締の年月<>"支払処理"
GROUP BY 支払締の年月
ORDER BY 支払締の年月
hirotonさんありがとうございました。質問が大きく変わって申しわけないのですが、このコンボで”実行時エラー2766” ”式が正しく入力されていないか、複雑すぎるために評価できません。たとえば、数式に複雑な要素が多すぎます。
変数に式の一部を割り当て、式を簡単にしてください。”が頻繁にでます(毎回ではなく普通に機能することもあります)。コードに問題あるのかなと思ってたのですがそうではなさそうです(すみません)。
コンボのSQLは下記です。
『SELECT Q買掛の支払締日と期日.支払締の年月
FROM Q買掛の支払締日と期日
WHERE (((Q買掛の支払締日と期日.買掛先ID)=[Forms]![F買掛仕入一覧]![cb取引先選択]) AND ((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理")) OR (((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理") AND (([Forms]![F買掛仕入一覧]![cb取引先選択]) Is Null))
GROUP BY Q買掛の支払締日と期日.支払締の年月
ORDER BY Q買掛の支払締日と期日.支払締の年月』
顧客の選択があるときは顧客+年月、選択ないときは年月のみでフィルターしています。
これが全然解決できなくて困っております・・・
Private Sub コンボ_KeyDown(KeyCode As Integer, Shift As Integer)
KeyCode = 0
End Sub
Private Sub コンボ_KeyPress(KeyAscii As Integer)
KeyAscii = 0
End Sub
Private Sub コンボ_KeyUp(KeyCode As Integer, Shift As Integer)
KeyCode = 0
End Sub
Private Sub テキスト0_KeyPress(KeyAscii As Integer)
Select Case KeyAscii
Case 8 To 10, 13, 45
Case 48 To 57
Case Else
MsgBox "数字を入力して下さい", vbExclamation + vbOKOnly, "入力検査"
KeyAscii = 0
End Select
End Sub
フォームフィルタがうまく行かないということですね。
質問を読み違えてました。スルーしてください。
担当者別にレポートを表示するフォームのレコードソースが、なぜか文字数調整のフォームのレコードソースになっているクエリと同じだったので、本来レコードソースにしたかったテーブルに変更したところ表示されるようになりました。
文字数調整用のフォームはレコード数が0だったので表示されないままだったということみたいですね。
このような不具合を出さないようにするにはフォームの構成に一工夫いるということですね。勉強になります。
単純なデータベースを作って試してみましたがそれらしい症状はでないですね
新規にデータベースを作って、同様のコンボボックスを配置してみて、同様にフィルタを実行しても同じ問題が発生しますか?
どちらのフォームも「表示するデータがなかったから表示がなかった」ですかね?(hirotonの回答もそれを想定してのものですが)
ACCESSの基本仕様ではあるんですが、レコードが一切表示されない=ヘッダーに設置した抽出用の非連結のテキストボックスも使えなくなる等、副作用が厄介で、メイン-サブフォームにして抽出機能は親フォームで実装、サブフォームに明細表示だけを実装なんてことをよくやりますね
コードですか?単純にデザインビューから、該当(コンボボックス)のフィールドをドラック&ドロップしているだけなのでわからないです。
担当者別に表示するフォームの方は、レコードソースに誤りがあったので、正しいレコードソースに変更したところフォームを開くときちんとオブジェクトが表示されるようになりました。
文字数を調整するフォームの方ですが、レコードソースのクエリにレコードはありませんでした。
抽出条件で設定している文字数を超えるレコードがなかったためだと思います。
毎回ナビゲーションウィンドウからフォームを開いています。
担当者別にレポートを表示するフォームには、担当者を選択するコンボボックスと、レポートを表示するボタン、それからレポートを閉じるボタンがあり、それぞれのボタンにはVBAのコードがありますが、フォームが開けない原因としては考えにくいと思います。
レコードの文字を別フィールドに振り分けるフォームには、振り分けが終わった後に更新するためのRequeryボタンがあり、そちらにVBAのコードが記述されています。
削除してみましたが、結果は変わらずでした。
私の作成したフォームでは普通に使って正常に動作してます。
設計に問題があるのでしょうね。
どのように実現しているのか、そのコードを提示してください。
フォームのレコードソースのクエリをナビゲーションウインドウから直接開いた場合、レコードは表示されますか。
また、そのクエリでデータの入力や更新はできますか。
ナビゲーションウインドウから直接フォームを開いても同じ症状ですか?
フォームにはVBAのコードが組み込まれていますか?
その場合、一度すべてのコードを削除して開いてみるとどうですか?(フォームそのものをコピーして試すと安全です)
hiroton様
そちらのプロパティを確認しましたが、「いいえ」になっておりました😖😖😖
日付/時刻型のフィールドに対して例えば
Format([年月日],"yyyy/mm")
というような式を設定した演算フィールドがあるということでしょうか。だとしたら演算フィールドに対して抽出条件を設定するとインデックスが利用されないので、データ件数が多い場合は処理が重くなる可能性があります。
式は冗長になりますが、処理を少しでも高速にしたい場合は、演算フィールドにせずに下記のように生のフィールドに条件を設定するようにした方がいいです。(日付/時刻型フィールドにはインデックスを設定)
参考リンク
抽出条件でインデックスが無効になる場合 - hatena chips
フォームのプロパティで読み込み時にフィルターを適用プロパティが「はい」になってるとかかな?
Nz 関数
1つ目のデータが
Null
なら2つ目のデータに置き換える関数です今回の場合
[Forms]![F買掛仕入一覧]![cb取引先選択]が選択済みのとき
[Forms]![F買掛仕入一覧]![cb取引先選択]が未選択(
Null
)のとき上記どちらかが実行されることになります。
買掛先ID=買掛先ID
は自分自身と比較すれば必ずTRUE
になる(※)ので、すなわち全データ。ということになります※買掛先IDが
NULL
の場合、正しく動作しませんデータベースでは「1つのフィールドに複数の情報を持たせない」というのが鉄則です
フィールド名のイメージと合わない情報が含まれるデータ構造は、なにかと厄介な問題を引き起こします
hirotonさんありがとうございました。それにして試してみます。いける時とエラーがでるときがあるので。結果はまた連絡しますね。因みに”Nz([Forms]![F買掛仕入一覧]・・・”のNzはこの場合どういう意味合いになりますでしょうか?
「年月」データに対して「"支払処理"(なにかの文字列)」比較は・・・基クエリにIIFでそうしているのですが年/月と文字を一緒にしない方がいいでしょうか?
元のデータ(テーブル構造)からみないと何ともですが、
『SELECT Q買掛の支払締日と期日.支払締の年月
FROM Q買掛の支払締日と期日
WHERE (((Q買掛の支払締日と期日.買掛先ID)=[Forms]![F買掛仕入一覧]![cb取引先選択]) AND ((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理")) OR (((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理") AND (([Forms]![F買掛仕入一覧]![cb取引先選択]) Is Null))
GROUP BY Q買掛の支払締日と期日.支払締の年月
ORDER BY Q買掛の支払締日と期日.支払締の年月』
下ではNullチェックすることがあるのに上では「=」比較をしているとか
『SELECT Q買掛の支払締日と期日.支払締の年月
FROM Q買掛の支払締日と期日
WHERE (((Q買掛の支払締日と期日.買掛先ID)=[Forms]![F買掛仕入一覧]![cb取引先選択]) AND ((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理")) OR (((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理") AND (([Forms]![F買掛仕入一覧]![cb取引先選択]) Is Null))
GROUP BY Q買掛の支払締日と期日.支払締の年月
ORDER BY Q買掛の支払締日と期日.支払締の年月』
「年月」データに対して「"支払処理"(なにかの文字列)」比較してるとかは首をかしげる部分ですね
とくに、Nullは扱いを間違うと不具合がよく出るので注意が必要です
「選択がない(=Null)ときは全データを対象にする」のはちょっとテクニックが必要ですが、たとえば
とかしてみたらどうでしょう?
hirotonさんありがとうございました。質問が大きく変わって申しわけないのですが、このコンボで”実行時エラー2766” ”式が正しく入力されていないか、複雑すぎるために評価できません。たとえば、数式に複雑な要素が多すぎます。
変数に式の一部を割り当て、式を簡単にしてください。”が頻繁にでます(毎回ではなく普通に機能することもあります)。コードに問題あるのかなと思ってたのですがそうではなさそうです(すみません)。
コンボのSQLは下記です。
『SELECT Q買掛の支払締日と期日.支払締の年月
FROM Q買掛の支払締日と期日
WHERE (((Q買掛の支払締日と期日.買掛先ID)=[Forms]![F買掛仕入一覧]![cb取引先選択]) AND ((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理")) OR (((Q買掛の支払締日と期日.支払締の年月)>[Forms]![F買掛仕入一覧]![cb支払締の年月1] And (Q買掛の支払締日と期日.支払締の年月)<>"支払処理") AND (([Forms]![F買掛仕入一覧]![cb取引先選択]) Is Null))
GROUP BY Q買掛の支払締日と期日.支払締の年月
ORDER BY Q買掛の支払締日と期日.支払締の年月』
顧客の選択があるときは顧客+年月、選択ないときは年月のみでフィルターしています。
これが全然解決できなくて困っております・・・
そのまま右辺の内容を変数1、変数2の位置に記述すればそれでいいと思いますが
ただ、文字列リテラルをわざわざ分割して記述する必要はないので
"'" & " AND " & "年月<= '"
の部分は一つにまとめてもしくは、範囲を抽出するなら
BETWEEN n1 AND n2
を使ってなんていうのもありです
余談ですが、フィルタのコードは複雑化したりするのでバラしておいたほうが(コードを読み解く場合と合わせて)簡素だったりしますね
テンプレート的な記述で、この掲示板でも何度かこのようなコードを書いています
hatenaさん回答ありがとうございます。原因が分かりました!(”ユニークである必要があります”で)。クエリCの基テーブルにオートナンバーIDがあり、そこのインデックス設定が”いいえ”となってました。⇒”はい (重複なし)”に変更しましたら入力可能クエリとなりました。このインデックス設定は何を意味しているのでしょうか? 設定すると検索スピードが速くなるだけの認識しかありませんでした。
クエリA、クエリCのデザインビューのスクショもアップしてもらった方かいいですね。
結合線で結ばれたフィールドの少なくとも片方のフィールドはユニークである必要があります。
つまり一対多の関係になっているか、ということです。
フィールドがユニークであるには、主キーフィールドであるか、インデックスが「はい(重複なし)」に設定されている必要があります。
上記の点を確認ください。
確認方法が分からないのではあれば、入力不可のクエリのデザインビューのスクショをアップロードしてもらえますか。
hatenaさん回答ありがとうございます。トラブルシューティング見ても理解できないこともありますが、どうも
あてはまらいない様です(私の知識不足のせいもありますが)。入力可能とそうでないクエリは共に2つのクエリから作成しており、構成の1つは共通のものでもう1つが異なるだけです⇒入力OKはクエリA-クエリB、入力NGはクエリA-クエリC。クエリA、B、C共に単体では入力可能。クエリAにCを結合させずにクエリデザインに配置させるだけでも入力NGとなります。試しにクエリCの基板のテーブルを配置させるだけでも入力NGとなります。原因が全く分からなくて・・・
とりあえず下記のページを読んで該当するものがないか確認してみてください。
クエリまたはフォームでデータを更新するときのエラーのトラブルシューティング - Microsoft 365 Apps | Microsoft Learn
あと、クエリのデザインビューでテーブル(クエリ)間の結合線が一対多になっているか確認してください。
一対多にならない結合線がある場合は更新できません。
hirotonさん、hatenaさん ありがとうございました。色々勉強になります。
IME 入力モードとの兼ね合いは全く知りませんでした。試してみます。
hatena様、たびたびありがとうございます。
私もそもそも「リンクテーブルを速くする」コツとして見かけたのでピンと来なかったのですが、ブログ主様はそもそもSQLのことを考えていたのであり、そしてhatena様のおっしゃるとおりのように思われます。
同じブログ主様のこちらのページではクエリチューニングのコツの1つとして載っており、
https://euc-access-excel-db.com/tips/ct07_se/ct071701_mini_system_make/qry-tuning
知恵袋には Null だけを許容すると設計ポリシーの方も見かけられ、
Accessについて。 - 超Access初心者なのですが、... - Yahoo!知恵袋
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10190934870
>テキスト型の場合、
>Null と "" は見た目の区別がつかないので、混在する状態だと管理が難しくなるので、
>最初に仕様としてどちらか一方のみ許容するように決めます。
>どちらがいいかは最初は好みでいいと思います。(後で簡単に変更できますので。)
>どちらかしかないと決まっていれば、抽出条件などの式を書く時、それを念頭において書けばいいですので。ちなみに私の場合は、Nullのみ許容するようにしてます。
混在の場合には WHERE に OR や Nz が入って、速度的に悪くなりそうなのもhatena様のおっしゃるとおりです。
今まであまり気にしてこなかったのですが、学びの機会になりました。ありがとうございました。
UIとしては、
数字とマイナス以外の文字が入力されていたらメッセージを出して修正をユーザーに要求するという仕様より、
最初から数字とマイナス以外の文字がキーボードから入力できないようにしておくという仕様のほうがユーザーにやさしいと思います。
ただ貼り付けなどで数値以外の値が入力された場合にそなえて、入力規則も設定しておく、という設計がいいと思います。
さらにIMEがオンだとKeyDownイベントでは検知できないので、「IME 入力モード」を「オフ」に設定しておくいいでしょう。
Accessの内部のコードや処理に関しては原則公開されていないので、MSの中の人以外には分かりません。
前の回答のMSの公式のドキュメント以外の方法は、ユーザーが、特定の設計、特定のデータで試した結果、効果があったという報告でしかありません。
その速度もテーブル設計、クエリ設計、データ構成によって変わることは、いくらでもあります。
また、そのしくみはどうとかいう解説をしている方がいたとしても、それは推測でしかありません。
よって、WEB上で多数、報告されている改善方法をそのまま採用するのではなく、
実際のテーブルとデータと処理で、試してみて効果があればその方法を採用する、ということをたいていの開発者はしていると思います。
あえて推測するならば、
すずやんさんの回答のリンク先にもありますが、「値要求」と「空文字列の許可」の設定の組み合わせは4通りあります。
そのうち、「値要求 いいえ」「空文字列の許可 はい」の設定(既定の設定)にしておくとNullと空文字列の両方が存在しうることになります。
そうなると、Nullの場合と空文字列の場合の両方を考慮した設計(抽出条件など)をする必要があります。
面倒だし、速度的にも悪い方向性を持つことになります。
「Nullのみ存在」あるいは「空文字列のみ存在」の設計にしておけば処理がシンプルにできます。
そこで既定の「値要求 いいえ」「空文字列の許可 はい」から、「空文字列の許可 いいえ」にしてNullのみ存在するというシンプルな状態にしておいた方が速度的にいいということかもしれません。
私の場合は、逆に「値要求 いいえ」「空文字列の許可 はい」から、「値要求 はい」にして空文字列のみ存在するという設計をよくします。
申し訳ありません、タイプミスです・・・<haneta様→hatena様
haneta様、お返事ありがとうございます。
「空文字列の許可」について私も初見であり、そちらのブログ主様も多くの経験値と発信力(興味深い話題をいろいろと書いていらっしゃいます)をお持ちのようだったので、気になってしまった次第です。
そちらのブログ主様は別のページ複数でも空文字列の許可に言及しており、「クエリやデータベースを速くする方法」「クエリが遅い場合の対処方法」という見出しの下にその一文があります。そして残念ながら、解説がありません。
ちなみに「空文字列の許可=いいえ」については、こちらのベテランエンジニアの方が「実際に便利だったこと」として書き残して下さっている中に見つかるには見つかりました。ただ、狙いは違っています。
http://www.kitagawa-hanga.com/se/s_acchint.html
仕様や経験則でそういうものがある(あり得る)、ということで承知しておこうと思います。
私もいろいろAccess関係の情報をチェックしてますが、「空文字の許可」の設定で速度が変わるという情報は初見でした。
MSの公式が、速度についての「動作が改善するしくみ」について提示することはほとんどないと思います。
例えば、下記でも速度改善の方法の提示はありますが、「改善するしくみ」についてまでは言及していません。
Access のパフォーマンスを向上させる - Microsoft サポート
WEB上でよくある速度改善の情報はたいていは経験則によるものだ思います。
内部動作については、Accessの開発者にしか分からないし、ほとんど公開されていないので。
私自身は、管理しやすいので「空文字の許可=はい」「値要求=はい」の設計(Null値の排除)にすることが多いですが、いままで遅くなるという経験はないです。(体感できるほどの規模のデータベースを扱っていないということかもしれませんが)
キー入力に関するイベントで全部リセットしてしまえばいいんじゃないですかね
hirotonさんskさん、ありがとうございました。コード使わずにシンプルに可能ですね。頭がカチカチになってました。色々試してみます。
hatenaさん、ありがとうございました。確かにそれで機能しました。私の方でごちゃごちゃしている内に混乱してた様です。(すみません・・・)
あと入力制御の事でお聞きしたいのですがコンボボックスが同フォームにあり、そこはマウスで選択する以外キー入力が一切受付ない様にするには、どうすればいいでしょうか?
すずやん様、レスありがとうございます
ただ、あいにく、そちらのブログにはコメント欄もBBSもメールアドレス記載も無いようです。
一応英語でも検索しましたが、「テーブルデザインで「空文字の許可」をしないと速くなる」という情報は、
私の英語力等が拙いのもあって見つけられませんでした。
もしかすれば、すずやん様のおっしゃるとおりただそういう仕様があるのかもしれないし、
Nullと""が両方入力できることから生じる混乱や手間を避けるための一般則を書かれただけなのかもしれません。
ベテラン社内SEの方の知見のようですが、同じくベテランの方の意見から何か伺えれば幸いです。
テキストボックスのキー入力時に下記のコードを設定して試してみましたが、「-」キーを問題なく入力できました。
入力する数値の桁数に一定の上限があるのであれば、そのテキストボックスの[定型入力]プロパティを設定なさればよいでしょう。
(設定例)
「整数である」の判定はいくつか手法があると思いますが、たとえば
とかですかね
数値であることのチェックは前述とおりやっておいて、文字列としてみたときに小数点が含まれていなければいいというチェックを追加でやります
まずそもそも論で申し訳ないのですが、御本人に確認されるのが良いと思われます。
こちらのブログはいまも更新されているようですので。
以下、単なる予測ですが、おそらく「そのような設定を行うとAccessの動作が早くなる」という仕様上の理由なのではないかな、と感じます。
https://qiita.com/Masataka_Sugia/items/90be563842813d7d2393
デメリットは「なにかしらのデータを必ず入れなければならない」ということでしょうか。
ちょっとめんどくさいですね。
hirotonさん、ありがとうございます。確かにそうですね。ただ>0 Or <1だと小数も入力可能になってしまいます(例えば2.5)。整数と負の分だけ入力の場合はどうすればいいでしょうか? すみません。
複雑な制限でなければ入力規則プロパティで対応すると簡単です
入力規則を使ってデータ入力を制限する
数値に限るなら
等、指定すればいいです
hatenaさん、ありがとうございました。
updateできました。
AOBのSQL文とは、扱いが少し違っていたのですね。
解決した時の、解決ボタンらしきものが見当たりませんでしたが、
このままでよろしかったでしょうか