Private Sub cmdプレビュー_Click()
Dim strFilter As String
If Me.txtChkList <> "" Then
strFilter = "得意先コード In(" & Mid(Me.txtChkList, 2) & ")"
Else
MsgBox "選択されたデータはありません。"
Exit Sub
End If
If Me.Filter <> "" And Me.FilterOn Then
strFilter = strFilter & " AND (" & Me.Filter & ")"
End If
DoCmd.OpenReport "R_得意先", acViewPreview, , strFilter
End Sub
'予定表示プロシージャ
Public Sub SetSchedule()
Dim i As integer, rs As DAO.Recordset
For i = 1 To 42
Me("T" & i).Caption = ""
Next
Set rs = CurrentDb.OpenRecordset( _
"SELECT 日付, 件名 FROM Q_予定件数 WHERE " & _
"日付>#" & FirstDay & "# AND 日付<=#" & FirstDay + 42 & "#", _
dbOpenForwardOnly, dbReadOnly)
Do Until rs.EOF
With Me("T" & rs!日付 - FirstDay)
.Caption = rs!件数
End With
rs.MoveNext
Loop
rs.Close: Set rs = Nothing
End Sub
Private Sub M_CMB_AfterUpdate()
Dim strFilter
If Not IsNull(Me!M_CMB) Then
strFilter = "個人ID=" & Me!M_CMB
End If
Me!F_個人別.Form.Filter = strFilter
Me!F_個人別.Form.FilterOn = True
End Sub
Private Sub M_CMB_AfterUpdate()
[Forms]![基礎情報編集]![M-CMB].Requery
sqlstr="SELECT * " &・・・
Me.F_個人別.Form.RecordSource = sqlStr
Me.F_個人別.Form.Requery
end sub
謎の数字「6」はLen(" And ") + 1で求められる数値です。(「And」の前後に空白スペースが入っています)
条件が複数選ばれると前後の条件を" And "でつなぐことになりますが、そのままコードにするならば、条件追加の時にはすでに条件があるかどうかをチェックするということになります
ex)前提条件を考えた検索条件の追加コードの一部
'-------------------------------------分類---------------------
If Not IsNull(大分類) Then
If myStr <> "" Then myStr = myStr & " And " '初めての条件でなければ" And "でつなぐ
myStr = myStr & "大分類 Like '" & 大分類.Value & "'"
End If
If Not IsNull(中分類) Then
If myStr <> "" Then myStr = myStr & " And " '初めての条件でなければ" And "でつなぐ
myStr = myStr & "中分類 Like '" & 中分類.Value & "'"
End If
If Not IsNull(小分類) Then
If myStr <> "" Then myStr = myStr & " And " '初めての条件でなければ" And "でつなぐ
myStr = myStr & "小分類 Like '" & 小分類.Value & "'"
End If
:
DoCmd.OpenForm "F_周知", , , myStr
:
何回も同じことをしているIfが出てきて手間だし読みにくいですね
そこで、最初かどうかにかかわらず、条件にはすべて先頭に" And "をつけておこう、処理の最後に先頭の" And "を削除するようにしようというのがMid(myStr, 6)です
この条件抽出をどのようにしているかによりますが、もし、Filterプロパティに条件を設定して抽出しているのなら、レポートを開くときのWhere条件式引数にFilterの条件を追加すればいいでしょう。
コード例
こんなやり方があるんですね!!勉強になりました。
思った通りの処理になりました。ありがとうございました。
確かにACCESS側でファイルの移動をさせれば間違いがないですね
ところで、これは別ソフト(スマホDB)の問題なのかもしれませんが
エクスポートした後のスマホDBの中のデータはどうするものでしょうか?
エクスポート毎にファイルを分けると、複数のファイルに同じレコードが含まれていることになります
それは仕方ないこととしてhatenaさんのアドバイスのようにACCESS側で重複を省くものでしょうか?
それで、問題ないと思います。
あるいは、
PC_ID、収支履歴ID というような2つのフィールドで複数フィールド主キーにするという方法もあります。
ならば、それをAccessのテーブルでは主キーにするか、重複を許可しないインデックスを設定しておくいいでしょう。
取りこんだ順番を保持しておく必要があるなら、オートナンバー型のフィールドを追加してそれを主キーに、シリアルキーには重複を許可しないインデックスを設定しておくといいでしょう。
そうすると万が一のミスにも自動対処できます。
あとは、hirotonさんの回答のような運用が楽だと私も思います。
並べ替えはレコードソース(のフィールド)に対して行います
レコードソースをクエリにして
というフィールドをつくると条件に一致するレコードには「-1」、そうでないレコードには「0」が入るので、この日付チェックフィールドに対して並べ替えを設定すれば望みの結果になります
別ソフトの要求次第ですがエクスポートごとに別ファイルになっていたほうが楽だとは思います
1つのファイルにしてしまうと同時にアクセスする可能性の処理が手間だし、ACCESS側でインポート後に「処理済み」等別フォルダに移動するように組んでおけば2重取込が防止できます
目的としては車の運転日報のようなものをAndroidで入力してもらい
それをPCのACCESSで管理したいです
Android側では一度PCに取り込まれたデータはなくてもいいです(あってもいい)
ちなみにAndroidのアプリでは+1していくような主キーが設定できず、自動で1レコードごとにシリアルキー用のような半角英数がランダムで記録されるようです
目的、運用次第、ですので、これだけの情報ではなんとも。
一応、Accessのテーブルにインデックスを適切に設定しておけば、ミスで重複してインポートした場合は、重複データは自動ではじいてくれます。
まずは、このメインフォーム/サブフォームの目的、したいことを明確にすることが先決のような気がします。
一見、解決したようにみえても、本当に目的に合致している動作になっているのか、よくよく検証してみてください。
連結フォーム(レコードソースが設定してあるフォーム)、連結コントロール(コントロールソースか設定してあるコントロール)の場合は、テーブルのデータと直結してますので、フォームでの入力がそのままテーブルに反映されます。
連結フォーム、連結コントロールでは当然の動作です。
今回のメインフォームの目的は何かを明確にしましょう。
サブフォームのデータを抽出する(フィルターをかける)だけが目的なら、非連結フォーム、非連結コントロールにすればいいでしょう。
逆にサブフォームの目的はなんでしょうか。「参照元入力ソースのコンボボックスを非連結にして」で本当に目的がかなってますか。
すいません、自己解決しました!(この方法が正しいのかどうかは分かりません。手探りです)
まず、親フォームのコンボボックスの規定値を「=Null」にしました。
その後、リンクフィールドで、親と子でキーIDをリンクさせてやればうまくいきました。
お騒がせしてすいません。
すいません、自己解決しました。
フォーム・サブフォームとも参照元入力ソースのコンボボックスを非連結にして、教えていただいたフィルターをかけたところ、うまく動作してくれました。
なんで、コントロールソースを入れると値が書き換わってしまうのかは不明なままですが・・・
こんばんわ、ろでますです。
先般はありがとうございました。
以降、色々触っているのですが、不可解な事象に遭遇しました。
色々設定を触りはしているのですが、あと一歩(?)のところでうまく動きません。
事象ですがテーブルが以下の様になっています
基礎情報_T - 個人別障害状況_T - 障害種別_T
│
- 等級_T
となっています。
この状態で以前と違い、フォームにレコードソースをセットして、コントロールソースも設定しています。
フォームには、基礎情報_より「個人ID」「名前」、障害種別_Tより「障害種別」、等級_Tより「等級」を表示させて、シンクさせています。(個人IDを変えれば、他も連動して変わります)
個人別障害状況_Tには、個人ID、障害種別ID、障等級IDが格納されて、これが各個人の実データテーブルになっています。
この状態で、フォームを起動して、例えば、個人ID1を参照します。
連動して、個人ID1の人の障害種別・等級が表示されます・・・といった具合にすべて正常に見えます。
ところが、参照後フォームを閉じた瞬間に、個人別障害状況_T内の「個人ID」の値が1レコード、必ず書き換わってしまいます。
何も命令を出していないのに書き換わってしまい、かなり困っています。
すいません、原因など分かればご教授いただけないでしょうか。
よろしくお願い申し上げます。
こんにちわ、ろでますです。
そんな方法があったんですか。
強にでも早速試そうとおもいます。
正直、サブフォームの作成って結構手間がかかってしまって、若干困っていたところです。😄
うまく行ったようで何よりです。
そういえばですが、現状の内容だとメイン・サブにフォームを分ける必要がないですね。
「F_個人別」フォームのフォームヘッダーに「M_CMB」を設置して、フォームのフィルターをいじる部分は自分自身(のフォーム)でいいので
で出来ます。
または、データ(テーブル)は正規化の観点から「T_個人」「T_障害」のように分かれていると思うので、
メインフォーム
既定のビュー:単票フォーム
レコードソース:T_個人
サブフォーム
既定のビュー:帳票フォーム
レコードソース:T_障害
サブフォームコントロール
リンク親フィールド:ID
リンク子フィールド:個人ID
のように、リンク関係を持ったメイン・サブフォームを作成すれば、メインフォーム側のレコード移動に伴って自動でサブフォーム側のレコードを変更することができます。
フォームの表示はたとえば
氏名:Aさん
住所:
電話番号:
<障害一覧>
○○障害
××障害
△△障害
のように作ることができ、共通するAさん(とその個人情報)は単票フォーム部分に1つだけ、Aさんに関連する障害情報は障害の情報だけを帳票フォーム部分に表示するといったようなことができ、Excelとは差別化されたACCESSらしい画面を作ることができます。
サブフォームの基本的な使い方でもあるので、一度調べてみることをオススメします。
なお、この場合の「M_CMB」はメインフォーム側に設置し、メインフォームのレコードを操作することになります。
ありがとうございます。 集計クエリを作るのがコツだったのですね。御指南ありがとうございます。
カレンダー形式のスケジュール管理フォーム作成 その3 - hatena chips
上記のページのテーブル設計、フォーム設計として回答します。
予定テーブル(T_予定)から集計クエリを作成して、件数を表示させます。デザインビューで下記のように設定します。
名前を Q_予定件数 とします。
フォームモジュールの予定表示プロシージャを下記のように修正します。
以上です。
おはようございます、ろでますです。
サブフォームの調整を考えて、きっちりすれば行けました!
というより、サブフォームのレコードソースをきっちりして、連結にすると、わざわざDlookup関数を用いないでも、きっちり連動してくれました。
その後、ご教授いただきましたフィルターをかけると思うように動作してくれました。
ありがとうございました。
ACCESSを扱うなら非常に行儀が悪いですね。危惧している通りいろいろ問題が起きます。
まずはしっかりACCESSの作法を覚えるべきで、応用はその上に成り立つものでしょう
フォーム(サブフォーム)に必要とするすべてのデータを表示することができたら、フィルタープロパティを使ってデータの絞り込みができます。
サブフォームにはレコードソースを設定しておいて、親フォームのM_CMBの更新後イベントを次のようにします
たびたびすいません、もう一点。
レコードソースについてなのですが、少し他の人に以前教えていただいたところ、VBAの中で
Private Sub M_CMB_AfterUpdate()
[Forms]![基礎情報編集]![M-CMB].Requery
sqlstr="SELECT * " &・・・
Me.F_個人別.Form.RecordSource = sqlStr
Me.F_個人別.Form.Requery
end sub
で、サブフォームのレコードセットは適当でも、これで書き換わるからいいと教えられました。
確かにこれでサブフォームのレコードセットは書き換わってうまく動作はするのですが・・・
だったら、最初からマクロに書かないで、レコードセットの所に直接書けば動くのでは?、と思い書くと動きませんでした。
こういう場合、このようなやり方は一般的なのでしょうか?
後からこのDBのフォームを見た人は、レコードセットがないと勘違いしてしまいそうで怖いです。
ちなみに、とりあえずの最終形態として考えているは、
個人別サブフォームを帳票フォームにして、
M_CMBを1に切り替えると、
Aさん ○○障害
Aさん ××障害
Aさん △△障害
そして、2に切り替えると、帳票フィールドの行数も動的に変化し
Bさん ××障害
Bさん △△障害
といった形に持って行きたいと思っています。
今は。帳票フォームの行が全部AさんやBさんになっているので、そこからまた頭を使って考えなければなりません(^^;
早々なご対応、誠にありがとうございます。
一番の問題は私自身の知識不足です。
エクセルからのAccessへの移行なので、その辺の知識が完全に欠落しております。
「関数に間違いない変数を渡してるんだから、計算して当然」
という思い込みがありました。
私もレコードセットは疑って、色々試したんですが、とりあえず、クエリ1でいいのかなと思って当てたものの、うまくいかず(エラーのまま)、であれば、SQL分でSelect・・・で書いたものはどうか、と色々試しては見たんですが結果が同じでしたので、そのまま非連結の状態でお渡ししてしまったという経緯です。
やはり、一番望ましいのは、
>リンクフィールドが設定されていないために、自動で再読み込みが発生しないのが原因だと思われます。
これを回避するために、リンクフィールドをきちんと設定してあげて、自動で再読み込みさせるのが理想です。
もしよろしければ教えていただきたいのですが、このような場合、どのようなレコードソースを設定してあげるのがよろしいのでしょうか。
ご教授いただけると助かります。
送信ありがとうございました。
ファイルは私のところにメールで届いています。
自動でダウンロードできるようにはなってません。
ファイルを見てみました。
原因はメインフォームで個人IDを変更したときに、サブフォームで再クエリか再読み込みか再計算をしないと変更が反映されないようです。
コンボボックス「M_CMB」の更新後処理のイベントプロシージャで再読み込みをしたらエラーなく表示されて、更新するとサブフォームの値も更新されました。
下記が修正済みのファイルです。
ZIPファイル
ただ、サブフォームが非連結(レコードソースが空欄)で、リンクフィールドが設定されていないために、自動で再読み込みが発生しないのが原因だと思われます。
通常、サブフォームはテーブルかクエリに連結させて、リンクフィールドを設定すると思います。そうすれば、リンクフィールドを更新すればサブフォームも再読み込みされます。
現状の非連結のサブフォームは、サブフォームにする必然性があるようには思えません。
最終的にどのようなものを考えているのでしょうか。
こんばんわ、ろでますです。
お手数おかけしますm(_ _)m
ファイルの方送付させていただきました・・・
が、この掲示板ではどこでアップしたファイルがダウンロードできるようになっているのでしょう。
手順を間違えたでしょうか(汗
これで、
フォーム名、コンボボックス名に間違いがないとすると、
外から原因を特定するのは難しそうです。
症状の再現できるなるべくシンプルなファイルを、右カラムのファイル送信フォームから送ってもらえませんか。
そうすれば、現物をみて原因を特定できるかもしれません。
>=[Forms]![基礎情報編集]![M_CMB]
>としたときは、正しい個人IDが表示されますか。
テキストボックスの値は真っ白でした・・・
全く値が取れていないようですね・・・。
>=[Parent]![テキストボックス名]
同じく、
「#エラー」
となりました・・・><
VBAとかで細かく値の受け渡し状況を確認する方法とかあれば・・・
=[Forms]![基礎情報編集]![M_CMB]
としたときは、正しい個人IDが表示されますか。
ということなら、このテキストボックスは非表示で配置しておいて、サブフォームのテキストボックスのコントロールソースを下記のように設定してみたらどうなりますか。
=[Parent]![テキストボックス名]
こんにちわ、ろでますです。
フォーム名が間違っているということはないと思います。
一度フォームを組み立てなおしても、同じエラーが出て、かなり困っています。
・メインフォーム名=基礎情報編集
・コンボボックスの名前=M_CMB
・クエリ名=クエリ1
メインフォーム上で
=DLookUp("氏名","クエリ1","個人ID=" & [M_CMB])
では、テキストボックスに「Aさん」が入ってくれますが
サブフォームに
=DLookUp("氏名","クエリ1","個人ID=" & [Forms]![基礎情報編集]![M_CMB])
と入れると
「#エラー」
となります。
何処がおかしいのか、以下の様にしたら、Aさんが取れました。
=DLookUp("氏名","クエリ1","個人ID=" & 1)
同様に以下の様にしたら、Bさんがとれました。
=DLookUp("氏名","クエリ1","個人ID=" & 2)
つまり、Dlookup関数の構文は間違っていないけども、M_CMBの値がちゃんと取れていないようです。
フォーム名等も、式ビルダーを使って、タブキーを押しながら選んでいったので、間違いはないと思います。
すいません、よろしければ、サブフォームに引き渡されているM_CMBの値を見る方法はありませんか。
よろしくお願い申し上げます。
Mid(myStr, 6)
はMid()関数を使った複数の中からいくつかを選ぶときに使うよくある手法ですね。これをそうだと解説しているのはあまり見ない気がします。謎の数字「6」は
Len(" And ") + 1
で求められる数値です。(「And」の前後に空白スペースが入っています)条件が複数選ばれると前後の条件を" And "でつなぐことになりますが、そのままコードにするならば、条件追加の時にはすでに条件があるかどうかをチェックするということになります
ex)前提条件を考えた検索条件の追加コードの一部
何回も同じことをしているIfが出てきて手間だし読みにくいですね
そこで、最初かどうかにかかわらず、条件にはすべて先頭に" And "をつけておこう、処理の最後に先頭の" And "を削除するようにしようというのが
Mid(myStr, 6)
ですいつもご丁寧ありがとうございます。
ヘルプを熟読します。
ありがとうございました。
コードの意味が分からないときは、まずはヘルプを参照しましょう。
OpenForm をクリックしてカーソルを置いてF1キーを押すとヘルプページが表示されます。下記のページです。
DoCmd.OpenForm メソッド (Access) | Microsoft Docs
上記の構文をみると4番目のパラメータ(引数)は WhereCondition です。
この下のほうにそれぞれのパラメータの役割が説明してあります。WhereConditionの説明は下記です。
ちょっと遠回りな説明ですが、抽出条件式を文字列として設定するということです。
Mid(myStr, 6) の部分は、やはりMidにカーソルを置いてF1キーを押してヘルプを表示させます。「キーワード」というページが表示されました。下の方にスクロールしていくと「Mid 関数」というリンクがありますのでそれをクリックします。下記のページか表示されます。(ダイレクトにこのページにいけないところがちょっち使いづらいですね。)
Mid 関数 (Visual Basic for Applications) | Microsoft Docs
これを読めば、Mid(myStr, 6) は myStrに格納されている文字列の6桁目以降を取り出しているとわかります。
上の方のコードで myStr変数に条件式を格納しているのですが、" And 条件式" というように前に不要な" And "が付いているので、それを削除しているのです。
分からないコードがあったらこんな感じで調べてみてください。F1でのヘルプは結構目的のページにたどり着けない場合もあります。その場合は「VBA 分からないコード」というようなキーワードで調べればたいてい解説ページにたどり着けます。
フォーム名が間違っているくらいしかなさそうですが、「基礎情報編集2」はフォーム名で合ってますか?(フォームのプロパティの「標題」ではないですよね?)
前回のテーブルと今回のテーブルの2つがあるなら、
変更があったレコードの抽出は、クエリウィザードの不一致クエリウィザードを使って作成してみてください。
新たに追加されたレコードの抽出は、
今回のテーブルと前回のテーブルを外部結合して、前回の主キーフィールドがNullのレコードを抽出すればいいでしょう。
hatenaさん
お返事ありがとうございます。
もう少し具体的に整理してから、もう一度ここに書き込みします!
まずは、そのようなことができるのかを知りたかったのです。
整理してきます。
素晴らしいです。
同じ宛名印刷システムでもお歳暮用になると上級編なのですね。自力では挫折していたと思います。
まだ半分位しか理解出来ていないので勉強します。
1から10までありがとうございました。
m(_ _)m
提示のコードだと、構文エラーで実行すらできません。実際のコードを提示してください。
「MT_単価」テーブルのフィールド構成、主キー設定、データ例を提示してください。
これはテーブルにデータ化されているモノですか?
そうですよね。私の記憶でもできたような気がしていたのですが、当方の2019で確認したら反映されないので、動作が変わったのかも知れませんね。
他にも、動作が変わっている部分があるような気がします。
例えば、コンボボックスのフォーカス取得時で、自身を再クエリするというコードで以前は問題なかったとおもったのですが、2019だと▼ボタンをクリックしても1回ではリストが開かないという現象が発生しています。
ご確認ありがとうございます。最大で4人に設定する予定でした。