Private Sub cb月_AfterUpdate()
Dim BeginDay As Date
BeginDay = DateSerial(Me.cb年, Me.cb月 - 1, 21)
Me.Filter = "売上日>=#" & BeginDay & "# AND 売上日<#" & DateAdd("m", 1, BeginDay) & "#"
Me.FilterOn = True
End Sub
Private Sub cb月_AfterUpdate()
Dim BeginDay As Date
BeginDay = DateSerial(Me.cb年, Me.cb月, 1)
Me.Filter = "売上日>=#" & BeginDay & "# AND 売上日<#" & DateAdd("m", 1, BeginDay) & "#"
Me.FilterOn = True
End Sub
それぞれのテーブルの意味を簡単に説明しておきます。
T_料理、T_材料 はマスターテーブルと言われるもので、一度入力しためったに変更することのない固定的なデータになります。
T_献立 はトランザクションテーブルと呼ばれるもので、日々入力していってデータとして蓄積していくものになります。
T_献立 と T_献立_料理 の2つのテーブルは、「一対多の関係」といいます。
献立の1レコードに対して、複数の料理があるからです。
例えば、「12月17日の夕食の献立」に対して「カレーライス、サラダ」と2つの料理がある、という関係です。
T_献立が一側、T_献立_料理が多側になります。
T_料理 と T_材料 は「多対多の関係」になります。
例えば、カレーライスは、じゃがいも、人参、玉ねぎ、牛肉、カレールー の複数の材量が必要です。
逆に、じゃがいもは、カレーライスや肉じゃが、ポテトサラダ・・・などに使われます。
このような関係が「多対多」になります。
リレーショナルデータベースでは多対多の関係を実現することはできないので、2つのテーブルの間に入る中間テーブルというのを作成して、2つの「一対多の関係」に分解します。
T_T_料理_材料 というのが中間テーブルになります。
T_料理(一)---(多)T_T_料理_材料
T_材料(一)---(多)T_T_料理_材料
これらのテーブルにリレーションシップを設定すると、下図のようになります。
実はこの料理材料管理という題材は、かなり難易度が高いものになります。
テーブル設計も複雑になりますし、そこから管理用の入力フォームも作成するのも難しいものになります。
Accessで今まで何か作成したことがありますか。
名簿管理とか、家計簿(出納帳)とか、蔵書管理とか、、、この辺が最初に取り組む題材としては適切です。
入門書にのっているようなレベルのものを作成したことがあるのなら、次に取り組む題材として適切だとは思います。
解決したと思ったら、また壁が立ちはだかるのが世の常です。
サーバ内のPDFを漁っていたんですが、なんとPDFが結合されて100ページほどの1つのPDFとして
存在していました。
製品IDが「A001」「B158c」のような、頭はアルファベット、それ以降尾が数字(及び改訂)と
なっており、多くのPDFが「A001.pdf」みたいな都合の良い形をしていたんですが、
一部(というには多い)のデータが「B001~149.pdf」みたいな名前になってしまっていました。
PDFでしか生きていないデータもありますので、できればこの結合されたものを利用したいんですが、
なにかいいアイデアはありますか?
重ね重ね申し訳ありません。
30日分(全て一人前)を一回で買い物に行くとして、必要な材料の一覧を合算して抽出させたいのです。料理数もかなりの数があるので、料理名を入力するのではなく、簡単なコードを入力して抽出させる仕組みを作りたいのです。もちろん、それ以上に効率的に抽出できる仕組みでもいいです。料理の種類、料理名、材料名、個数、これらは必要だと思うんですが、これをどう作り繋げていけばのいいのかわかりません。
テーブルを作っていてわからなくなりました。献立テーブルと献立料理テーブルの必要性が。シンプルに30日分(30品目の料理)から必要な材料を合算して表示させたい。単位も統一して個単位でいいです。説明が下手で申し訳ございません。ご教示お願いいたします。
わかりました。やってみます。非常にわかりやすいです
検索フォームやメインフォームから開くときに、
検索だけなのか、編集等行いたいのかなどで場合分けをして、
開くのは同じフォームだけど、プロパティの設定変更から元データの保護等
ができるような形での実現で問題ないか、社内で相談してみます。
色々な考えの中から、最も適した構成を探すのに苦労しそうですが、
頑張ってみます。
ありがとうございました!
テーブル設計からということですね。
まずは、「正規化」という概念については理解していますか。
データベース設計の基本になります。よく、分からないという場合は、「テーブル 正規化」をキーワードでWEB検索して、解説ページをいくつか読んで、概要を理解しておいてください。(データベース初心者だと完全に理解するのは難しいと思いますので、なんとなくイメージとして掴んでおけばとりあえずOKです。)
例えば、下記のサイトの「正規化」の項目など。
もう一度学ぶMS-Access
そのうえで、最低限、下記のようなテーブルが必要です。
T_料理
料理ID 主キー
料理名
種別(主菜、副菜、汁物など)
T_材料
材料ID 主キー
材料名
単位
T_料理_材料
料理ID 主キー
材料ID 主キー
数量
T_献立
献立ID 主キー オートナンバー型
日付
種別 (朝食、昼食、夕食など)
T_献立_料理
献立ID 主キー
料理ID 主キー
上記のテーブルを作成したら、リレーションシップを設定します。
リレーションシップがよく分からないという場合は、上記で紹介したサイトの「リレーションシップ」の項目を参照してください。
とりあえずここまでやってみてください。それができたら、入力フォームの設計について説明します。
フォームの見た目が同じほうが良いのであれば、プロパティにレコードセットやデータ入力用などの作業を制限する仕組みがあるのでそれらを活用する形でいいかもしれませんね
下記でどうですか。
「F_商品」フォームは開いている必要があります。
Accessからパスの通し方は、一度大学の頃に研究室の部品管理用のQRコードを
Excelのハイパーリンクで一括で作ったことがあるので、なんとなくのイメージはできていました。
(同行内のID等から、文字式結合とかでつくろうかなぁとか)
データ管理に関しましては、PDFデータがてんでバラバラな箇所にしかないので、
今回新たに共通の保存場所を作ることにしようと思っています。
また、少し違う質問になってしまうのですが、
現フォームが、ヘッダに検索用スペース、詳細に検索結果、フッタに分割フォームの表の方
が表示されており、かつ、閲覧・編集兼用フォームなっています。
基本的に、閲覧用(検索用)と、編集用(登録用)は分けた方が良いのはわかりますが
検索だけのフォーム(検索TXTBOXと検索BTNだけ的な)にも分けるかどうかを
考えているところです。
あんまりフォームを分けすぎると、一部のユーザに混乱を与えそうですし、
上記の用に分けた場合のユーザビリティを自分の技量では保てない気がしてしまって。
直接の回答ではありません
デフォルトの設定だとクラスモジュールや別なフォームのモジュールのプロシージャを呼び出して、呼び出し先でエラーが発生すると呼び出し元の行が反転表示されます
オプションからエラートラップをクラスモジュールで中断に変更してエラー発生場所を確認してみてください
VBEのエラートラップオプションの違いについて(T'sWareさん)
ACCESS(データベース)の問題というよりはデータの一元管理の問題って感じです。まぁ、おのずと似たり寄ったりなものになると思いますが
具体的には「データベースの登録情報からPDFの保存パスを作る」感じになります。もっとも単純なのはPDFのファイル名は製品ID(+.pdf)とし、ACCESSファイルの置かれているフォルダに「PDFデータ」フォルダを作ってその中に保存する形
フルパスの保存なんかしなくてもデータベース上の製品IDがあれば
(ACCESSのパス)\PDFデータ\製品ID.pdf
でアクセスできますね。簡単です
データ管理がしっかりしているなら例えば
PDFデータ
└メーカー
_└製品区分
__└製品ID.pdf
なんてツリー構造で保存されていたりするでしょう。データベースでは製品テーブルに「メーカー、製品区分、製品ID」とフィールドを設けてやれば
(サーバーパス)\PDFデータ\メーカー\製品区分\製品ID.pdf
とPDFのパスが生成できます。データがしっかり管理されているのであればフルパスを保存しなくとも、「データベースとして正しい登録」をしてあげればファイルにアクセスすることができるわけです
そして、既にあるデータを活用したいと言われて大口取引先のデータは
「メーカー - プロジェクト名 - 製品シリーズ名 - 製品ID」
小口相手は
「メーカー - 年フォルダ - 製品ID」
のようなデータ管理を見て泣きを見ながらすり合わせをしていくわけです
なにか、フォームでのPDFの管理(パスを通す場合)で、いいアイデアや、基本的な
設計思想等がありましたら、後学のためにもお教えいただけると
幸甚に存じます。
よろしくお願いいたします。
hirotonさん、ありがとうございます。
今は直接埋込ですので、データ数が増えたときの不具合が心配で今回の質問に至りました。
常にフォーム内でPDFを表示したい、との要望でしたので、それを満たしつつ、データを
軽く(できればパスで通す)ような手が思い浮かばなかったのです。
しかしながら、先ほど社内で話し合った結果、フルパス(サーバ管理者との相談によっては相対パス)で
PDFへのリンクを貼り付けることにしました。
フォーム内にミニサイズでの表示はしないことにしました
(ユーザすべての言い分を聞いてられないという判断)
質問文の解釈にお手数おかけしてしまいましたが、今回の質問はこれで終わりにします。
ありがとうございました。
またAccessのDB管理が引き続くと思いますので、その際は以後宜しくお願い致します。
いい案ではないですが
この前提で「埋め込まない」をしようとすると、ACCESSにアクセス権の情報を含めることになります。ACCESSのセキュリティ性能を考えるとやるべきではありません。少なくともACCESS(データベース)のある場所のアクセス権は持っているユーザーを対象とすべきでしょう
そのうえで「埋め込まない」とするならACCESS(データベース)ある場所にサブフォルダを作ってPDF登録時にコピー、相対パスで保存とかでしょうか
これらUIの問題は埋め込みであるかどうかとは別な問題ですね。質問文前半からは「できている」ように見受けられますが問題になっているんでしょうか?
全くです。料理名、材料リストを作ったりしましたがそこからどうしていいかわからずです
全くです。料理名、材料リストを作ったりしましたがそこからどうしていいかわからずです
とかでどうでしょうか。
もっといい方法があるかもしれません。
フィルタにはSQLのWHERE句に相当する文字列を指定します
WHERE句の書き方参考:【SQL入門】WHEREで検索条件の指定方法をわかりやすく解説
組み合わせてどんなデータを表示したいのかによってANDでつないだりORでつないだり、NULLのデータで絞り込みたいのであれば
[フィールド] IS NULL
とする必要がある。あたりを抑えておけば最低限の記述はできるようになります少し加えるだけで出来てしまうのですね。ありがとうございました。
次はオプショングループに挑戦してみたいと思います。
ありがとうございます!!Me.Filterでできました。思っていた通りになりました!!
ありがとうございました。
「月」コンボボックスの更新後処理のイベントプロシージャを下記のように変更すればいいでしょう。
まず、それ自体を表示することが目的なら、フィルタの内容を変えてからボタンを押すまでフォームの表示内容と乖離してしまうのでワンステップ置くような仕組みはオススメしません
別な場所に値をコピーしたいという用途ならそのテキストボックスの値を取得すればいいでしょう(テキストボックスは非表示でもかまいません)
フィルタの実行と同時に取得したい(しかもその処理が結構重い)とかだと、
total = Me!○○フィールドの合計
の処理がうまくいかないこともあるようなので、そういう時ならばDSum関数を使って第三引数でフォームのフィルタと同じ条件を指定すればいいでしょうできましたありがとうございます。これなら年も設定できるので楽になりました。
余談で少し質問なのですが何日から何日までという設定も月の中で設定できるものなのでしょうか
1月というコンボボックスで12/21~1/20までを表示のような。
ご教授ありがとうございます。できました。
が、この機能をボタンを押したときだけ集計するようイベントプロシージャを記述したいのですが、VBAで同じものを記述すると機能してくれません。どうすればよろしいでしょうか。
ご教授ありがとうございます。できました。
が、この機能をボタンを押したときだけ集計するようイベントプロシージャを記述したいのですが、VBAで同じものを記述すると機能してくれません。どうすればよろしいでしょうか。
この手のテーブル設計は、運用実態によって最適な設計は変わりますし、絶対的にこれだと決まるものでもないし、設計者の考えかたによっても設計は千差万別になります。
まずは、現状のテーブル名、フィールド構成、主キー設定を提示してもらえますか。
フォームのFilterプロパティにVBAで抽出条件を設定するようにすればいいでしょう。
UIとしてはコマンドボタンより、コンボボックスで月を選択するようにするか、オプショングループ内にオプションボタンかトグルボタンを配置する設計にした方かいいでしょう。
まずは、コンボボックスの方が簡単なのでコンボボックスで作成してみて、うまくいったら、オプショングループに挑戦するのがいいでしょう。
まずはコンボボックスの方法を提示しておきます。
月間請求書履歴が帳票フォームとして、レコードソースに「売上日」という日付/時刻型のフィールドがあると仮定します。
「年」選択用のコンボボックスと「月」選択用のコンボボックスを配置します。
「年」コンボボックスを下記のように設定します。
名前 cb年
既定値 =Year(Date())
値集合タイプ 値リスト
値集合ソース 2018;2019;2020;2021;2022
「月」コンボボックスを下記のように設定します。
名前 cb月
既定値 =Month(Date())
値集合タイプ 値リスト
値集合ソース 1;2;3;4;5;6;7;8;9;10;11;12
「月」コンボボックスの更新後処理のイベントプロシージャに下記のように記述します。
「年」コンボボックスの更新後処理とフォームの読み込み時のイベントプロシージャを下記のように記述します。
以上です。
単にテキストボックスのコントロールソースを
=Sum([フィールド名])
とすればフォームのフィルターに合わせて自動で計算できますよありがとうございます。勉強になりました。参考にさせていただきます。
現状はどこまでできていますか。
テーブルは作成しましたか。
それとも、まったく手付かずですか。
下記のSQLで組毎の標準偏差と平均を取得できます。
これを Q_標準偏差_平均 と名前を付けて保存します。
次にこのクエリとテーブルを使って下記のSQLで偏差値が求められます。
フォームが最大化されているということではないですか。
それかデザインビューでのフォームの幅と高さが画面サイズより大きいとか。
「作業ウィンドウ固定」「ポップアップ」の設定が関係するとは思えないのですが。
具体的にどのように反映させようとしているのですか。
具体的に説明してください。
返信遅れて申し訳ありません。
テーブル名
MT_テスト
主キー ID オートナンバー型
組 短いテキスト
名前 短いテキスト
点数 数値型
標準偏差 数値型
偏差値 数値型
何卒宜しくお願い致します。
ポップアップをはい、作業ウィンドウ固定をはいにしていたのですが、2つ問題が発生しました。
①上記の条件でもウィンドウが画面いっぱいに広がって、フォームのサイズをマウスで変更できないフォームがある。
②上記の条件だと詳細フォームを閉じたとき、リストフォームに情報が反映されないで困るフォームがある。
以上、対応策があればご教授お願いいたします。
現状のテーブルの名前、フィールド構成、主キー設定を提示してください。
フォームのレコードソースはクエリですか。
クエリなら、そのクエリを開いてそこで更新はできますか。
あとは「最適化と修復」を実行してみて改善しませんか。
SQLをご確認いただき、ありがとうございました。大変お手数をおかけいたしました。
デバッグはまだ行っていないのですが、とりあえずは、サブフォームのヘッダーに更新ボタンを置いて対応することにしました。