If Me.CurrentRecord < 1 Then
'//抽出でレコードが見つからなかったので新規登録画面を表示する
Me.AllowAdditions = True
'//抽出内容を設定する
Me!日付.DefaultValue = Me!検索用日付
Me!氏名.DefaultValue = Me!検索用氏名
End If
Option Compare Database
Option Explicit
Private preValue As String
Private Sub グループヘッダー1_Format(Cancel As Integer, FormatCount As Integer)
If preValue = "" Or preValue = Me.名前.Value & " " & Me.性別.Value Then
Cancel = True
End If
preValue = Me.名前.Value & " " & Me.性別.Value
End Sub
Private Sub ページヘッダーセクション_Format(Cancel As Integer, FormatCount As Integer)
preValue = ""
End Sub
Dim lastID As String
Dim newNo As Long
lastID = Nz(DMax("発行番号", "発行簿", "コード='" & Me!コード & "' AND 区分='" & Me!区分 & "'"))
If lastID = "" Then
'//新規(条件グループの連番が見つからなかった時)なので初期値を設定する
If Me!区分 = "後" Then
newNo = 501
Else
newNo = 1
End If
Else
'//連番部分を取り出して1増やす
newNo = Val(Right(lastID, 3)) + 1
End If
Me!発行番号 = Me!コード & "-" & Me!区分 & "-" & Format(newNo, "000")
Dim tempLastNo As Long '//条件により連番の初期値を変えたい
Dim lastNo
Dim newNo As Long
'//新規(条件グループの連番が見つからなかった時)の仮の連番を設定する
If Me!区分 = "後" Then
tempLastNo = 500
Else
tempLastNo = 0
End If
'//発行番号は「[コード]-[区分]-[連番(3桁0詰め)]」形式の文字列なのでうまいことなんやかんやする
lastNo = Nz(DMax("発行番号", "発行簿", "コード='" & Me!コード & "' AND 区分='" & Me!区分 & "'"), tempLastNo)
newNo = Val(Right(lastNo, 3)) + 1
Me!発行番号 = Me!コード & "-" & Me!区分 & "-" & Format(newNo, "000")
データの更新問題につきまして、あちこちで更新されない状況が起きています…
コンボボックスには下記コードにてrequeryをつけたりしているのですが、
'''
private sub cbo更新したい_afterUpdate()
me.cbo更新したい.requery
end sub
'''
あっているでしょうか?
また、同期したいところがちょこちょこみつかるのですが、
テキストボックスやチェックボックスについても
全てにrequeryをつけるという対処方法になりますでしょうか?
気に入っていただけて良かったです。
簡単に解説をしておきます。
フィルター関係のコードは下記のものとほぼ同じで、最後の Filter、FilterOn を設定するところを、サブフォームのものに変更しただけです。
複数条件の抽出フォームの設計 その1 - hatena chips
非連結のメインフォームの詳細セクションに、上記のフォームヘッダーのコントロール群を配置します。
その下に、データシートビュー表示のサブフォームを配置します。
サブフォームコントロールの幅は詳細セクションの幅と同じにします。
また、「水平アンカー」「垂直アンカー」プロパティをどちらも「両方」に設定します。
これでメインフォームをリサイズしても、それにあわせて拡大/縮小します。
フォームを開く時に、サブフォームの最上部へ移動、高さもフィルターのコントロール群を覆える高さにします。
また、詳細セクションの高さもそれに合わせます。
フォームヘッダーに「フィルターを開く」ボタンを配置して、それで、
サブフォームの位置、詳細セクションの高さを変更して、フィルターのコントロール群をサブフォームの裏に隠したり、見えるようしています。
もし、ご不明な点がありましたら、追加質問してください。
データを確認させていただきました!素晴らしいですね!この方式で作ってみたいと思います。
ありがとうございました!!
データシートビュー表示がいいのなら、サブフォームにデータシートフォームを埋め込んで、
フィルター用のテキストボックスやコマンドボタンは普段は閉じておいて、ボタンクリックで開くようにするというのはどうでしょうか。
言葉では分かりにくいと思いますので、サンプルを作成しましたので、参考にしてみてください。
FrmFilter_1_1.accdb
ボタンについても調べたり実行していましたが、
帳票のためロックをかけても
全てのレコードにかかってしまうという問題があるのですね・・・
やはりこちらを参考に作成するしかないのですよね。
帳票フォームでレコード毎にテキストボックスの表示/非表示を切り換えたい
なるほど、そういう手もありますね。
右クリック、コンボボックス、データシートビュー、
3つの可能性から検討していきたいと思います。
ありがとうございました!
構想だけ
フォームヘッダーの部分って列のラベル表示とかしていますか?
この部分にコントロールを2つ重ねて
下:テキストボックス(コンボボックス)でフィルタ用
上:テキストボックスでラベル表示用
両方ともタブストップを「しない」
ラベル用コントロールでフォーカス取得時にフィルタ用にSetFocus
コントロールソースは「
="ラベル名"&IIf([フィルタ用]<>"","▼","▽")
」これで少しはそれっぽい見た目になるんじゃないかと思います
以前教えていただき、ありがとうございました。
こちらの件、やはり重たいので悩んでいます。
ある条件を満たした際、チェックボックス(やボタン)を「使えない」とわかるようにしたいのですが、軽く対処できる方法はありませんでしょうか。
※ボタンはまだあまり調べていないのですが、チェックボックスは調べても方法が見つからず…
>テキストボックス上で右クリックすれば、並べ替えとかフィルターのメニューが出ますが
本当ですね!知りませんでした。ありがとうございます。
>VBAでフィルター処理を作りこめば
ページの上の領域を結構使ってしまうのが気になっております。
別ウィンドウのポップアップで検索するフォームも別のところで作ってみたのですが
やはりいまいち使い勝手がいいとは言えなくて、あれもこれも欲張るのは難しいですね・・
>エクセルに移行するのはもったいないと
そうですよね。エクセルに移行しようとは思っていないのですが、
アクセスの「データシートビュー」のが、エクセルライクでユーザーにもわかりやすいので悩んでおりました。
ただ、見栄えがあまりよくなくて…
テキストボックスの右クリックをユーザーにわかりやすく告知できないか考えてみようかと思います。
テキストボックス上で右クリックすれば、並べ替えとかフィルターのメニューが出ますがそれでは不足ですか。
あるいは、リボンの「並べ替えとフィルター」セクションの「詳細設定」の「フォームフィルター」だと複数のフィールドの条件をまとめて設定できます。
あとは、VBAでフィルター処理を作りこめば自由に思い通りのUIが構築できます。
例えば、下記のような感じです。
複数条件の抽出フォームの設計 その1 - hatena chips
フィルタリングに関してはエクセルよりデータベースであるアクセスの方が高機能、高速ですので、それが目的でエクセルに移行するのはもったいないと思います。
いまやっていることよりも、やっていて手間や不満に思うことがあるか?という目線で考えるといいです
メリットはないことはないと思いますが、ACCESSが覚えられる(ゴールが明確なので挫折しにくい)のが一番のメリットで、ACCESSを知らないというだけで忌避される(特に引き継ぎ)という問題を回避できるのか?が一番のデメリットになりそうです
EXCELからACCESSに乗り換えるときは
・データ的に誤りのないインプットをしたい(させたい)
・データ量が多く、作業ごとに必要な内容だけで表示したい
・集計したデータに合わせて書式を整えた印刷をしたい
といった、大量のデータを操作する必要があるかどうかが焦点でしょうか。現状の「記録だけでいい」状態からだとメリットは感じられないと思います
仰る通り、別名をつけてあげればよかったんですね。きれいにまとまりました。ありがとうございました。
前の質問と同じで抽出フォームを使えば既存レコードの表示はできます
「日付」「氏名」の項目固定で抽出になるのでその辺は調整してあげるといいと思います
検索結果でレコードが無ければ新規として登録できるようにしてあげればいいので抽出処理の後に追加の条件判定をして追加の処理を入れます
※「検索用日付」、「検索用氏名」は抽出用のそれぞれのフィールドです。適宜置き換えてください
※フォームを開いたときに新規登録ができるとまずいので開くときイベントでレコードの追加を「しない」にする処理を追加しておきましょう
基本はフォームでやるそれと変わりません
複数条件の抽出フォームの設計 その1
フィルターの設定先をレポートを参照するように変更する必要はあります
Me.Filter
↓
Reports!レポート名.Filter
など
レポートに直接編集できる検索窓を設置する方法はちょっとわかりません
抽出フォームをポップアップで表示し、レポートの上に被せるように表示させておくというのが妥協点かと思います
「Q取引先.宛先2」自体がフィールド名になってるので[Q取引先.宛先2]としてあげればいいです
こういうフィールド名はやっかいなので、クエリ作成の段階で、クエリデザインなら「取引先の宛先2:Q取引先.宛先2」のようにして、使いやすい形にフィールドに別名をつけてあげるといいと思います
上記は新スレッドをたてるつもりがレスになってました
スルーしてください
書き直します
まず、入力フォームの日付フィールドと氏名フィールドに入力します
他には出勤時間などのフィールドがあります
日付と氏名どちらもが一致するレコードがすでにある場合にはその他のフィールドには既存のレコードを表示
日付と氏名が一致するものがなければ新規レコードとして作成
というのはどのようにしたらよいですか?
ありがとうございました!思い通りの印刷が出来ました。
フームのレコードソースを、レポートのレコードソースと同じにしてみてください。
VBAが必要になりますね。
まずは、グループ化/並べ替えは、[番号]フィールドのみグループ化して、下記のように設定します。
昇順 ヘッダーセクション付き フッターセクションなし
リボンの[コードの表示]をクリックしてVBAウィンドウを表示させます。
そこに下記のコードをコピーして貼り付けてください。
これでご希望の結果になると思います。
やっていることは、
モジュールレベル変数 preValue に直前のレコードの値を格納しておいて、
現在のレコードの値と比較して同じたったら、Cancel = True でヘッダーを出力しない。
異なっていたらそのまま出力とするということです。
ページヘッダーセクションで preValue = "" としているのは、
ページの先頭にレコードの前に空白行が出力されるのを防ぐためです。
3つ目のブロックに回答っぽいものがありますが1行で書くなら
Me!発行番号 = Me!コード & "-" & Me!区分 & "-" & Format(Val(Right(Nz(DMax("発行番号", "発行簿","コード='" & Me!コード & "' AND 区分='" & Me!区分 & "'" )),3)) + 1, "000")
↓
Me!発行番号 = Me!コード & "-" & Me!区分 & "-" & Format(Val(Right(Nz(DMax("発行番号", "発行簿","コード='" & Me!コード & "' AND 区分='" & Me!区分 & "'" ),IIf(Me!区分 = "後", 500, 0)),3)) + 1, "000")
フォーム上のテキストボックスだとか、レポートで一発表示だけしたいとか、どうしても計算式1行で済ませなければいけないという要件がでることもままあります。どっちも同じことをやっているのでどっちが基本ということもないですがVBAで記述するなら柔軟性を活用すべしということですね
自分でも見直したコードを追記してみた(やっていることは変わらない)ので見比べてみてください
後から見直したらもっといいコードがあったんじゃないかなと思うことはよくあること。なので
先のコードよりわかりやすくなってると思います
区分で設定を変えたいということでそこだけ条件分岐にしましたが、元々の「連番+1の処理」をそのまま残して初期値側を「後でプラス1されるからマイナス1しておく」ように弄ったところも条件分岐させてあげたほうが直感的に書けますね
ついでに
lastID
もAs String
指定できるので変な使い方ができないよう(バグのもとにならないよう)に制限できるのも良い点かなと余談
変数名も「lastNo」と「newNo」だとそっくりなのに中身別物じゃないかってなるので手を加えてみました
hiroton様
回答頂きましてありがとうございます。
簡単に、どこかに条件分岐を入れるといいのかな~、などと考えていました。
式を分解して考える事が基本に繋がるのですね。
マネだけせずに、考えていきたいと思います。
ありがとうございます。
おかげさまで、上記の質問の内容は出来ましたが、追加がありました。
| 番号 | 名前 | 性別 |
| 1 | 猫 | オス |
| 6 | 猫 | メス |
| 2 | 猫 | メス |
| 5 | 犬 | オス |
| 4 | 犬 | オス |
| 3 | 犬 | メス |
このデータの場合、最優先は番号だとしたら、
| 番号 | 名前 | 性別 |
| 1 | 猫 | オス |
| 空白 | | |
| 2 | 猫 | メス |
| 空白 | | |
| 3 | 犬 | メス |
| 空白 | | |
| 4 | 犬 | オス |
| 5 | 犬 | オス |
| 空白 | | |
| 6 | 猫 | メス |
このようにしたいです。
グループで番号を優先にしても名前を優先にしても
うまくいかなかったので、大変申し訳ございませんが、
ご教授願います。
印刷はレポートでするのですよね。
まずは、
に関しては、下記を参考にしてください。
レコードがない場合も用紙の最後まで罫線を出力する - hatena chips
レポートの「グループ化/並べ替え」の機能で、
並べ替えの追加で「名前」フィールドを追加。
その後、グループの追加で「性別」フィールドを追加。
「ヘッダーセクションなし、フッターセクション付き」に設定。
以上です。
詳しく書いて説明して頂き、ありがとうございます。
出先のため、後日じっくりと勉強させていただきます。
フォームにレコードを表示していて、別のところ(別フォームや更新クエリ、VBAなど)で同じレコードを更新したときに、その更新が反映されないという意味でしたら、反映させたいフォームに対して Refresh すれば反映されます。
自分自身なら
Me.Refresh
、別フォームならForms!フォーム名.Refresh
ということになります。これはカレントレコードのみの更新です。
もし、帳票フォームで複数レコードの更新を反映させたいなら、フォームに対して Requery です。フォームに対してRequeryすると先頭レコードへ
前の回答のコンボボックスの Requery はValueの更新ではなく、コンボボックスのリストの更新になります。
Form.Refresh メソッド (Access) | Microsoft Docs
Requery メソッド (Access) | Microsoft Docs
式をバラバラにしてみましょう
処理は一番内側の括弧から順に処理されます。
バラバラにするなら下から順に処理を書けばいいということですね。
気を付ける点は、DMax関数は「値かNULL」が返ってくるところです。今回の場合、発行番号を対象にしているので「文字列かNULL」ですね。
条件に一致する発行番号がないとき(項目が新規の組み合わせの場合)、DMax関数がNULLを返すわけですが、この時の動きを調べてみてください。
結果を言うと項目が新規の組み合わせの場合、最新の番号として0(になる値)がとれるため、最新の番号+1で連番を作るということになっています。
この部分に条件分岐をいれてあげればいいですね。
ここまで何でもかんでも変数にして、とする必要はないですが、VBAで記述するなら適宜変数を置くと理解しやすくなります。
「Not(A and B and C and D)」は「(Not A) or (Not B) or (Not C) or (Not D)」と等価です。
クエリのデザインビューなら条件を横一列に設定すればANDですが、行を変えるとORになりますね。
データの更新問題につきまして、あちこちで更新されない状況が起きています…
コンボボックスには下記コードにてrequeryをつけたりしているのですが、
'''
private sub cbo更新したい_afterUpdate()
me.cbo更新したい.requery
end sub
'''
あっているでしょうか?
また、同期したいところがちょこちょこみつかるのですが、
テキストボックスやチェックボックスについても
全てにrequeryをつけるという対処方法になりますでしょうか?
マクロの選択の中に、「最新の情報に更新する」というものがあり
ページの頭にボタンを置いて更新をかけたりしますが、
それでも更新されないことがあり困っています。
教えていただきありがとうございます!連休中にじっくり読みます。
検索しても解決法に届かなかったため、大変助かりました。
ありがとうございました。
テキストボックスの印刷時縮小をはいに設定して下さい。
知識が幅広く必要なためか、あまりうまいこと解説しているところはないですね。
VBAとSQL
VBAはプログラミング言語です。
SQLは構造化照会言語(データベースを扱うための所定の書式)です。
VBAにはSQLを実行する機能がありますが、実行そのものはデータベースエンジンに丸投げします。なので、「SQL構文を文字列で指示する」までがVBAで出来ることです。そして、この文字列がSQLの文法として正しいかどうかすらチェックしません。ダメだったらダメだったときにエラーだと返ってくるだけです
SQL構文の例
VBAでSQLを実行する例
入力ミスをしてみましょう
VBAでSQLを実行する例(入力ミス)
実行しようとするSQL構文
単独の文字列としか見ないVBAではわかりにくいですが、SQL構文を色を付けてくれるエディタでみると間違っていることが分かりやすいですね。
実際には様々な部分を変数にしたいとなると思うので、ワンステップ置いて内容を確認するようにするといいです
&もあちこちに出ていますが、VBAでもSQLでも前後の文字列を連結するという役割をします。SQL構文を作るためのVBAの&なのか、SQLとして処理されるときの&(VBA上ではただの文字)なのか、これもコードの色分けがあるとわかりやすいと思います。
もちろん、SQLで処理するときでもただの文字として見たいということもあり得ます。
#
や'
リテラルのデータ型を表す文字です。
リテラルとはコード内に直打ちされた値のことです。
VBAではリテラルのデータ型によって
数値型 => 数値をそのまま
文字型 => 「"」で囲む ※「'」は使えない
日付型 => 「#」で囲む
(ACCESS)SQLではリテラルのデータ型によって
数値型 => 数値をそのまま
文字型 => 「"」または「'」で囲む
日付型 => 「#」で囲む
というように決まっています。
そしてこの(ACCESS)SQLでの「#」はかなりローカルな仕様です。
SQLとは単にそういった場合、本来、国際規格で決まっているモノで、それには日付型に「#」を使うルールはありません。そのため、SQLを勉強しようとしてもこの「#」についての解説はACCESSに言及しているようなところでしか見ることができません。
SQL構文を確認する
VBAならDebug.Printで実行直前の文字列を取得できます。フォームのテキストボックスなんかの場合はとりあえず「
="購入日=#" & [最新購入日] & "#"
」のように確認したい部分だけの式にするといいでしょう後はそれで表示された文字列をコピーして色分け表示すればいいです。
この掲示板ならコードブロックを使うと色分け表示できます。(上の誤りなSQLの表示を見ると今一歩な感じ)
Webサービスを探してもいいでしょう(SQL Fiddle(sqlfiddle.com)とか)
※ローカルルールな「#」にどのように対応しているのかは気に掛ける必要があります
そもそものもとになるSQL構文はクエリデザインから作成するのも手です。
適当な抽出条件を設定したクエリを作って、表示できることを確認したあとSQLビューを確認すればもとになるSQLが作れます。あとは「適当な抽出条件」としたところを変数に置き換えていけば動的に変化するSQL文が作れます。
デザインビューからの表示を通すことによって、データ型による囲み文字の補完、型不一致のエラーのチェックなんかができます
2つの主キーの片方と連結しているテーブルも削除できることを確認しました。
削除問題について、考え方が理解できておりません。
(削除できない=新規登録できない状況と理解しています)
フォームでレコードを削除しようとした場合、クエリで複数のテーブルのフィールドを持っているときは、何を削除することになるのでしょうか。
クエリで取り込まれている主キーのテーブルデータということで間違ってないでしょうか。
レコードを削除できなかった原因がわかりました。
2つの主キーを持っているテーブル(別々に2個)とクエリで連結していたのですが、
そこを取り除いたら削除できるようになりました。
主キーではない項目を使用して連結しているとダメという記事を読んだのですが、
2つの主キーの片方と繋ぐとダメなのでしょうか・・
また、一対一の関係性を持つテーブルを元にしたフォームも削除がきかなかったため
重複ありに変更しました。
BuildCriteriaは引数に決まった書式の文字列を要求するので1度通すと書式が不適切になってしまいます
あとは、例えば、「チーフ、、リーダー」のような誤入力(「、」が2回連続している)なんかも決まった書式を満たせずエラーになるので注意が必要ですね
文字列を区切り文字でsplitして配列に~な処理は今回はあまり適していない(hatenaさんの回答のほうが適切)なので、そういう関数もあるなぁくらいで大丈夫です
hiroton 様
迅速な回答いただき誠にありがとうございます。
hatena 様が教え得て頂いた>レス4で実装できました。
BuildCriteriaを2回重ねる事は出来ないのですね。
配列にして処理すること、加えて勉強させて頂きます。
hatena 様
迅速な回答いただき誠にありがとうございます。
句点、部分一致の文中の間違いご指摘ありがとうございます。
>あと、読点 と 句点 が混在する可能性はありますか。
>「チーフ。リーダー、ボス」とか。
読点 と 句点 が混在する可能性はありません。
どちらかでしか検索出来ないようにしたいとおもっています。
たたき台を使用させて頂きましたところ、
思っていたように検索が出来ました。
本当にありがとうございます。
教えて頂いたこと、勉強させて頂きます。
2は解決いたしました。クエリの中での、主キーとのつなぎ方の問題でした。失礼いたしました。
ありがとうございます!所持している本にも理屈が載ってなかったので、すごく助かります。熟読します。