みんなに優しく、解りやすくをモットーに開設しています。 以下のルールを守りみんなで助け合いましょう。
1.ファイルメーカーで解らない事があればここで質問して下さい。 何方でも、ご質問・ご回答お願いします。 (優しく回答しましょう)
You are not logged in.
FileMakerで来訪管理(クロス集計?)
■概要
MS Accessで、会員制の教室の来訪管理を、横に会員名、縦に日付というクロス集計(?)の形で実現していたのですが、それをFile Maker Pro 12に移植したいと考えております。
まだ不慣れな状態で、どの様な形で実現したらよいのか、殆ど分らない状態なので、皆様のお力をお貸しください。
■詳細な説明
会員制の教室の来訪管理をしたいと思っています。
入口に入退室用のカードリーダーがあって、通常、会員は入室時にはそれ用の、退室時にはそれ用のカードリーダーにタッチすることになっており、どのカードリーダーに、誰が、いつタッチしたかが記録されます。
ただし、時々、タッチし忘れる会員がいて、それについては後から手動で、その日に来たという記録を付けたいということがあります。
基本テーブルは以下の通り。
【会員】
会員番号
氏名
生年月日
退会区分
退会日
グループ
※退会者は退会区分に1以上の数値が入っている。
※退会日は退会処理をした日。この日までは会員資格があったものと考える。
※グループは、「特定のグループの人だけ表示したい」といった場合に使う。
【入退室】
会員番号
来訪日
来訪番号
入室日時
退室日時
※このデータは、各カードリーダーに記録された「誰がいつタッチしたか」のデータを、この形式に変換したもの。
※同一人物が同一日に複数回来訪した場合は複数のレコードとして記録される。
※来訪番号には、その日一回目の来訪であれば1が、それ以降は何回目の来訪かに応じて2、3、4といった数字が入る。
※手動でその日の来訪を記録する場合は、会員番号、来訪日、そして来訪番号に0を入れたレコードを追加することにしている。
【閉鎖日】
閉鎖日
※教室を閉めていた日を記録します。
それで、やりたいことは、これらのデータを元に、各会員の来訪状況を以下のような表示にしたいということです。
番号 氏名 年齢 グループ名 01 02 03 04 05 06 07 08 09 10 11…31 ↓期間中の各人の来訪回数
0001 Yamada Taro 28 グループA ○ ○ ○ ● ○ □ ○ □ ○ □ □… □ 25
0002 Suzuki Hana 31 グループA ○ □ ○ ○ □ □ ○ □ ○ □ □… □ 15
0003 Sato Jiro 21 グループB ○ ● ○ ○ □ ○ □ ○ □ □ □… □ 10
0004 Tanaka Koji 35 グループB ○ ○ ○ □ ○ □ ● ○ ○ ○ □… ○ 28
---------------------------------------------------------------------------------
日毎の来訪人数→ 81 101 98 88 102 10 106 52 112 42 78 86←期間中の平均来訪人数※表中の●は手動で入力したデータがあること、つまり、その人のその日の入退室記録に来訪番号が0のデータがあることを示す。
※表中の○は手動で入力したデータが無く、かつカードリーダーから取得したデータが(来訪番号が1以上のレコードが一つ以上)あることを示す。
※表中の□は、その日の入退室データが無いことを示す。
※期間中の平均来訪人数は、その期間の日毎の来訪人数の総和を閉鎖日を除いた有効日数で割った数字です。
※期間は最大31日で、主に月毎の来訪状況を把握するために使うことを想定しています。
■クリックによるレコードの追加や削除
表中のクリックによって以下の仕組みを入れたいと考えています。
□クリックしたら、入退室テーブルに以下のレコードを追加する
会員番号←その行に対応した会員番号
来訪日 ←その列に対応した来訪日
来訪番号←0
●をクリックしたら、入退室テーブルから以下の条件のレコードを削除する
会員番号←その行に対応した会員番号
来訪日 ←その列に対応した来訪日
来訪番号←0
○をクリックしたら、入退室テーブルから以下の条件のレコードを削除する
会員番号←その行に対応した会員番号
来訪日 ←その列に対応した来訪日
※それと同時に、この表の表示も適切なものに変えたいです(例えば□→●)。
※ただし、スクロール位置は変えたくないです。
■一覧に表示させる会員の選択
◇会員資格の有無
会員資格関係なし:会員資格に関係なく表示する。
会員資格有り:退会区分が<1。ただし、退会区分が>=1でも、退会日が期間の開始日以降ならこちらに含める。
会員資格無し:退会区分が>=1。かつ、退会日が期間の開始日より前。
◇グループ
グループ関係なし:グループに関係なく表示する。
グループ関係あり:指定したグループだけ表示する。
◇年齢による
年齢関係なし:年齢によらず表示する。
年齢が12歳以上:開始日の時点で12歳以上の人だけ表示する。
年齢が12歳未満:開始日の時点で12歳未満の人だけ表示する。生年月日が空欄の場合はこちらに含める。
※日毎の来訪人数や期間中の平均来訪人数は、表示されている会員に合わせて適切な値を表示したいと思っています。
以上です。
長いから読み切れてないし
同一日に同じ人がタッチ有りとタッチ無しで入った時は
どうなるのか分からなかったので・・・
超手抜きサンプルですけど、こんな事したら何とかなる?
http://pupld.net/21/141101/yivtwl5vxm/index.cgi
来訪記録.fmp12
手動入力は単に時刻入力無しで判定しているだけですけど。
Offline
旅人さん、サンプルありがとうございました。
ただ、正直、私にとっては、リレーションが複雑すぎて、何のために何をやっているのかを読み解くのが困難でした。
そこで、お願いなのですが、まずは個々のレコードから、表を作ってそれを表示するところまでに絞ったサンプルを作って頂けないでしょうか。
つまり、合計やら件数やらは抜きにした状態のものです。
あと、最初に投稿した内容は少々込み入っていましたので、今回の仕様を改めて示します。
-----------------------------------
各テーブルの決まっているフィールド
-----------------------------------
【入退室】テーブル
会員番号
来訪日
来訪番号
※最初に投稿した内容には入室日時と退室日時が入っていましたが、これらは無視してもらって結構です。
※これら三つのフィールドについては自動計算で何かをする必要はなく、もともと全て値として与えられると考えてください。
※日毎に対応するレコードを判定して●か○か□かになります。
※その日のレコードが無い場合は□です。
※その日のレコードがあり、かつ来訪番号に0のあるレコードがある場合は●です。
※その日のレコードがあり、かつ来訪番号に0のあるレコードがない場合は○です。
【表示】テーブル
開始日
終了日
-----------------------------------
サンプルデータ
-----------------------------------
【入退室】テーブル
001,2014/11/1,0 ←来訪番号に0のレコードがあるのでこの日は●
001,2014/11/2,1 ←来訪番号に0のレコードがないのでこの日は○
001,2014/11/2,2
001,2014/11/3,0 ←来訪番号に0のレコードがあるのでこの日は●
001,2014/11/3,1
001,2014/11/3,2
001,2014/11/4,0 ←来訪番号に0のレコードがあるのでこの日は●
001,2014/11/4,1
001,2014/11/5,1 ←来訪番号に0のレコードがないのでこの日は○
001,2014/11/5,2
002,2014/11/1,1 ←来訪番号に0のレコードがないのでこの日は○
002,2014/11/2,1 ←来訪番号に0のレコードがないのでこの日は○
002,2014/11/2,2
002,2014/11/3,0 ←来訪番号に0のレコードがあるのでこの日は●
002,2014/11/5,1 ←来訪番号に0のレコードがないのでこの日は○
002,2014/11/5,2
【表示】テーブル
2014/11/2,2014/11/5
※敢えて2014/11/1を外しています。
-----------------------------------
サンプルから得たい結果
-----------------------------------
02 03 04 05
001 ○ ● ● ○
002 ○ ● □ ○以上。よろしくお願いします。
検証不十分手抜きサンプル2
http://pupld.net/28/141102/kqym12fpk6/index.cgi
来訪記録_2.fmp12
同じ人が同一日に
1
0
2
となった場合が分からなかったので0が有ると必ず●にしてます。
来訪番号は手入力に変更しました。
日付範囲は10日分しか表示しません。
今から出かけないといけないので、急いで作りましたが消し忘れや
必要な物も消しているかも知れません。
私はログアウトしないので常時オンライン表示ですが、追加質問が
あっても答えられる状況とは限りません。
Offline
旅人さん、ありがとございます。
繰り返しフィールドの計算式に慣れていないため、読み解くのに時間がかかってしまいました。
例えば、「表示」テーブルの「状態」フィールドの計算式
Let ( 変数=開始G[1]+Get ( 計算式繰り返し位置番号 )-1; Case ( 変数 ≤ 終了G[1] ; Lookup ( D::状態計算;"□" )))これを見て、最初は「なぜ開始Gは繰り返しフィールドでは無いのに[]をくっつけるのだろう?」と思ったんですが、
逆に[]がくっついていないフィールドは
フィールド名[Get ( 計算式繰り返し位置番号 )]が参照されていると考えれば良いのですよね?
例えば"状態[3]"を参照した場合、
Get ( 計算式繰り返し位置番号 )は3で、「D::状態計算」の3番目の値を参照しようとするということで。
ただ、それなら
Let ( 変数=開始G[1]+Get ( 計算式繰り返し位置番号 )-1; Case ( 変数 ≤ 終了G[1] ; Lookup ( D::状態[1];"□" )))でも良いような気がして試してみたんですが、正しく表示されませんでした。
これはなぜなのでしょうか?
ややこしいリレーションを使わない方法です。フィールド定義とレイアウトの作成だけですので、簡単かも。
https://dl.dropboxusercontent.com/u/926 … 00.fp7.zip
Offline
開始Gが繰り返しではないので繰り返しになっている日付フィールドとの、繰り返しごとの計算
には[1]を付ける必要があります。
Offline
Let ( 変数=開始G[1]+Get ( 計算式繰り返し位置番号 )-1; Case ( 変数 ≤ 終了G[1] ; Lookup ( D::状態[1];"□" )))
でも良いような気がして試してみたんですが、正しく表示されませんでした。 これはなぜなのでしょうか?
繰り返しフィールドでのLookup関数の仕様で、[n]小間指定はサポートされていないからです。
そこでやむなく参照フィールド(D::状態)の方を繰り返しフィールドへ持ち替えているのです。
なお、従来のフィールド設定のルックアップ機能ではそのような持ち替えの手間が要りません。
が、あえてLookup関数を使うことの利点は、
Lookupを式の一部に使ってより複雑な計算が立てられる事もありますが、
何より計算結果の非保存指定でルックアップの自動更新が可能に成ることです。
目的が集計である場合、自動更新は集計処理自動化の大きなアドバンテージと思います。
旅人さんサンプルの繰り返し[]+Lookup()によるクロス集計法は最新の手法です。
従来の集計レイアウト法は拡張性がないので、どうせ覚えるなら、繰り返しLookup集計法がおすすめ!
Last edited by Hiro (2014-11-04 16:23:56)
Offline
皆さん、色々とご教授頂きありがとうございました。
おかげで少しずつ理解が深まりつつあります。
さて、旅人さんの二つ目のサンプルを元に、「表示」テーブルに、横向きの件数を表示するフィールド「期間来訪数」を以下の計算式で作りました。
PatternCount(List ( 状態 ); "●" ) + PatternCount (List( 状態) ; "○" )他にも色々実現方法はあるでしょうが、よりベターな方法があったら教えてください。
次に、縦向きの件数のフィールド「日毎来訪数」を作りたいと思いますが、どのようにしたら良いでしょうか?
旅人さんの一つ目のサンプルでは、「入退室」(サンプルではD)テーブル同士を「来訪日」でリレーションして、関連レコードの「会員番号」の数を数えていますが、この方法だと、同じ日に同じ会員が2回以上来訪した場合、その数まで含まれてしまいます。
希望としては、その日に来た延べ人数ではなく、回数によらない実質的な人数を求めたいのですが。
入退室テーブルの日付の自己リレーションの動的値一覧を作ると
ValueCount ( ValueListItems ( Get ( ファイル名 ) ; "その値一覧名" ) )
という計算フィールド(非保存)にその日の重複しない入室数が出ます。
これを表示テーブルから日付でリレーションしてLookupかな。
Offline
あ、横合計もあった。
横は会員ごとに●か○の日付を数えればいいので
「状態 = "○" or 状態 = "●"」という繰り返し10の計算フィールドを作れば
来訪した日は1、しなかった日は0になるので、それをSumしたらいいですね。
Offline
会員番号の検索表示があるかも知れないので、縦も縦行ごとに合計する
集計フィールドの方がいいかも知れない。
Offline
旅人さん、すいませんが、先の二つ目のサンプルに上記のことを加えたサンプルを作って頂くことはできるでしょうか。
自分なりに色々試してみるのですが、正解に到達できません。
表示用のテーブルで○と●を数字に変換する計算フィールド、式は
状態 = "○" or 状態 = "●"
にすると
横合計はSum(このフィールド)
縦は集計フィールドにして、このフィールドの合計で、繰り返しの集計は個別
ではないかなと。
Offline
横は会員ごとに●か○の日付を数えればいいので
「状態 = "○" or 状態 = "●"」という繰り返し10の計算フィールドを作れば
来訪した日は1、しなかった日は0になるので、それをSumしたらいいですね。
違いますよ、来訪延日数ではなく来訪延回数の合計ですので、元データから数えないとダメ。
どっちにしても最後には集計作業が多く入るので、私のサンプルを使えば。
全部の計算が終わっていますよ。
集計機能は古い手法だけど、FM独自の基本的な機能で、是非習得しておくべきで、最新の機能にこだわる必要は無いでしょう。その上で、リレーションを使ったクロス集計を覚えると、活用範囲が非常に広がります。
Last edited by Shin (2014-11-06 16:30:19)
Offline
カウント集計するのに、カウント対象外の無効データをワザワザ「☐」として集計対象にしていますが、
本来の空欄のままにして単純Count計算で済むようにはできませんか?
Offline
>来訪延日数ではなく来訪延回数の合計ですので
同じ人が1日に何回来訪しても1と数えたいということでした。
>カウント対象外の無効データをワザワザ「☐」として集計対象にしていますが
確かに。○と□も分かりにくいですし、□は無い方が・・・
Offline
来訪延べ日数でしたか、読み間違いしたようで。申し訳ないです。
論理的に、1フィールドは3値持てるので、それに合わせて値を持たせれば、□も邪魔ではないですが。具体的には上のサンプルを参照。
Offline
皆様、お世話になっております。
既にご承知の様ですが、縦の件数、横の件数とも延べではない人数を表示したいと思っております。
また、カウント対象外の無効データは空欄でも構いません。ただ、その空欄をクリックした時に、その日に来訪したというレコードを追加する機能は持たせたいと考えております。
論理的に、1フィールドは3値持てるので、それに合わせて値を持たせれば、□も邪魔ではないですが。具体的には上のサンプルを参照。
「1フィールドは3値持てる」といのはどういう意味でしょう?
サンプルを元に、延べ人数ではない人数を求める方法を、もう少し具体的かつ詳細に教えて頂けると助かります。
□欄をクリックすれば、●に変わるように変更してあります。
https://dl.dropboxusercontent.com/u/926 … 00.fp7.zip
論理値で3値持てるとは、サンプルを見ればわかるように、内部の繰り返しフィールドは、論理値で処理していますが、実際には、●○□の3個の値が表現されていますね。という意味です。厳密に言うとおかしいのですが、処理系としては都合良く処理できています。
人数の数え方は、単に繰り返しフィールドの中の実繰り返しフィールドをカウントしているだけです。
開講日数(参加者が居た日数)も、その集計した繰り返しをカウントしているだけです。
繰り返しフィールドと集計機能を使ったクロス集計は、複雑な事は実現するのが難しくなりますが、このレベルでしたら、シンプルで良い手法です。ただ、集計機能に少し癖があって、取り付きにくいのが難点でしょうか。
Offline
Shinさん、サンプルありがとうございます。
色々と参考になりました。
サンプルを見れば、「ああ、なるほど」と思うのですが、思いつきを形にできるようになるまではもう少しかかりそうです。
ところで、このサンプルの中に会員というテーブルを作って、会員番号から氏名を引っ張ってきたりしたいのですが、それと共に、ある期間まったく来訪していなかった人についても、一覧に加えたいという要望があるのですが、それは可能でしょうか?
例えば、送って頂いたサンプルの中には会員番号が1~3までのデータがあるのですが、会員が5人居た場合、4と5の人についても、一覧に加えたいということです。
理由としては、会員の来訪状況を確認することが目的なので、来訪の多い人、少ない人、そして全く来ていない人も状況を知りたいということがあるからです。
横合計や縦合計は単純な計算では期間や会員を絞ったときにダメだったので・・・
うっ、これもダメだったのでサンプル削除。
ウインドウ再表示を入れないと縦が計算されない時があった。
Dテーブルでの再計算が必要なようで画面がちらついてしまう・・・
Last edited by 旅人 (2014-11-08 11:03:10)
Offline
来訪_ の計算式を変更し、次の条件を追加します。
IsEmpty ( 来訪番号[1] ) ; "" ;
来訪番号を空白にしたダミーレコードを作れば良いです。日付は、その月内の適当な日付で。
運用上、月初めに月初日で全会員のダミーレコードを作っておけば良いかもしれませんね。会員テーブルからインポートで簡単に作成できます。
Last edited by Shin (2014-11-08 12:39:01)
Offline
#1の最初の質問で希望されたフルスペックの内容で、サンプルを作りアップしましたので参考ください。
入退テーブル側のデータを会員テーブルのポータルでクロス集計結果を動的に自動表示します。
全ての処理は集計条件の指定だけであとは自動更新・自動集計します。
関連レコード削除の後戻って来たときに、元のスクロール位置を保持する希望実現のため、画面が多少ブリンクしますが了解ください。
年齢計算は非索引計算のため一覧表示は重くて不向きのためあえて表示せず、軽い生年月日の一覧表示に止めています。
●サンプル「会員来訪管理.fmp12」 → http://yahoo.jp/box/JGs16o
繰り返しLookup集計法のこのサンプルを見てもらえば、こう云った要件にも、
後々厄介な空枠レコードを作るような無駄手間も無く、自在でシンプル手法な事を判って貰えるかと…。
Last edited by Hiro (2014-11-09 06:15:15)
Offline
Hiroさん、サンプルで勉強させていただいています。
初歩的な質問だと思いますが、
1)会員テーブルの「縦集計配列」の計算式、
Case(日付配列<>""; 縦集計)
の「日付配列<>""」はどういう条件・論理になっているんでしょうか。
2)会員テーブルの「日付配列」の計算式、
Let(
[#dt=開始日[1]+(Get(計算式繰り返し位置番号)-1)];
Case(#dt<=終了日[1] and FilterValues(#dt; ValueListItems(Get(ファイル名);"閉鎖日値一覧"))=""; #dt)
)
開始日[1]の[1]はどういう意味ですか?開始日は繰り返しフィールドでないのに
繰り返し位置番号ですか?
教えていただけるとありがたいです。
Offline
[ Generated in 0.008 seconds, 9 queries executed - Memory usage: 660.52 KiB (Peak: 693.42 KiB) ]