ゴミの日トップ手順0|手順1|手順2手順3
手順1.カレンダー作成
まずは、カレンダーを作成しましょう。ここでは、次の2つの作業です
 1.フォームの作成
 2.イベントの作成

 別所に「表(tbl)・フォーム(wfm)・イベント(kev)は、セットで使用する」と書きましたが、今回のカレンダーは途中まで「ゴミの日予備」を使用中は、表(tbl)は使用しません。このようなパターンの典型的な例が、「メニュー」ですね。
 また他には、処理中などのガイド表示なども使用しません。これは、メッセージボックスなど、ユーザーにボタン選択させるときなどのダイアログに、似てますね。



■カレンダーを表示するフォームの作成


フォームの仕様(本当は、色・サイズともに自由ですが、私の作成したものを紹介しておきます)

 その前に、グリッドの設定をします。グリッドは、ある一定幅のグラフ用紙をイメージしてください。
これから作成するものを、サイズや位置を決めるときに役に立ちます。操作は、表示(V)→グリッドの設定(X)
 グリッドの幅(X)10pt ・水平格子数(H)2
 グリッドの高さ(Y)10pt・垂直格子数(V)2



またグリッド操作を行うか否かは、フォーム定義のボタンで選択してください。(赤印)
  
  • ヘッダー部・フッタ部作成(表示)
    • ヘッダー=高さ(H)60pt
    • フッタ=高さ(H)10pt
  • 明細部
    • 高さ(H)240pt
    • 分割数(L)16
    ※明細部の分割はこの時点では直接関係ありませんが、設定しておきます。




画面図(背景はわかりやすいように色を変更しています)
  • 日曜〜土曜までのラベルオブジェクト
    配置する場所は、ヘッダー部です(画面図を参照下さい。1区切り10×10です)
    ちなみに「日」の属性は、
     「始点X:10pt・始点Y40pt・表示幅(W):50pt・高さ(H):20pt・オブジェクト名(N):a日・標題:日」
    ラベルオブジェクトの最後は、「オブジェクト名(N):a土・標題:土」です

  • 日付を表示するテキストオブジェクト
    同様に今度は日付を表示するオブジェクトを作成します。配置する場所は、明細部部です
    ちなみに、一番左上の属性は、
     「始点X:10pt・始点Y0pt・表示幅(W):50pt・高さ(H):40pt・オブジェクト名(N):t1・ソース(S):&日t[1]」
    テキストオブジェクトの最後は、「オブジェクト名(N):t42」
    ソースは37まで、「ソース(S):&日t[37]」まで、入力。38〜42は空白のままです。

     今回、お忙しい方のために、「ゴミの日資料.wfm」を、添付いたしました。複写でも利用できますので、ご利用下さい。
    また、オブジェクト名は、今回「t1」〜「t42」として作成しましたが、複写で作成すると「t_1」みたいになります。
    今回は、カレンダー表示部分名を利用したイベントは組んでないので、どちらでも結構です。

  • 年月を選択する為のボタンオブジェクト
    次はコマンドボタンです(年−・月−・月+・年+・今月・終了)。配置する場所は、ヘッダー部です
    「年−」の属性は、
     「始点X:100pt・始点Y10pt・表示幅(W):30pt・高さ(H):20pt・オブジェクト名(N):b年減・標題:年−」

     ※オブジェクト名と標題の関係:できるだけ同一に作成したいのですが、オブジェクト名には、使用できない文字があります
      通常のファイル名に使用できないような文字です。
      そのため今回は(年−→b年減・月−→b月減・月+→b月増・年+→b年増)というように変更しています

    <コマンドボタンの内容>
    機能(共通) 機能パラメータリスト(年減の場合) 月減 月増 年増 今月
    なし #代入(&作業日付,#年数加算(&作業日付,-1)) A B C D 計算式は下記参照ください
    手続き実行 カレンダー作成 同左 同左 同左 同左 2行目は、全部同じです
    なし 3行目、現在未使用
    なし 4行目、現在未使用

    機能パラメータリストの計算式
    @#代入(&作業日付,#年数加算(&作業日付,-1))
    A#代入(&作業日付,#月数加算(&作業日付,-1,1))
    B#代入(&作業日付,#月数加算(&作業日付,1,1))
    C#代入(&作業日付,#年数加算(&作業日付,1))
    D#代入(&作業日付,#日時値)

    ・#年数加算・・年を動かします
    ・#月数加算・・月を動かします

    ※「&作業日付」を指定した期間増減し、カレンダー表示手続きを実行します

    終了ボタンコマンドリスト
    機能 機能パラメータリスト
    閉じる 確認する
    以下未使用

  • 現在の年月を表示するテキストオブジェクト
    同様にヘッダー部分に現在表示しているカレンダーの年月を表示するオブジェクトを作成します。
    ちなみに、テキストオブジェクトの属性は、
     「始点X:160pt・始点Y10pt・表示幅(W):80pt・高さ(H):20pt・オブジェクト名(N):t作業日付・ソース(S):&作業日付」

注:まだ、イベントを作成・実行してないため、「&作業日付」など使用すると、エラーになりますが、そのまま継続してください
  一度、起動するとエラーは、無くなります。


「一言コーナー」
オブジェクトの名前。これも自由です。わかりやすい名前を付けましょう。ただし、オブジェクト名の前の記号
・月を付ける場合、ラベル「a月」・テキスト「t月」ボタン「b月」このように付けておくとオブジェクトリストでも(イベントなどの中でも)オブジェクトの属性がわかりますね。ちなみに上記設定(a・t)等は、桐フォーム作成時の標準名です。


■変数設定〜カレンダー表示までのイベント作成

  • 今回、カレンダーの日付は、総て変数で持ちます
  • 月々の1日の曜日と最終日付を求め、変数に代入
  • 決まった年月のカレンダー作成(変数代入と表示)
(背景が水色の所は、その上のプログラムの説明です。実行には不要です)

名札 メイン
  変数宣言 整数{&i}
  変数宣言 日付{&作業日付}
  変数宣言 整数{&作業年,&作業月,&作業日,&日t[37],&月初曜,&月末,&元号}
  &元号=0
  &作業日付=#日時値
  データパス名 #一括パス名,固定=する


イベントには必ず先頭に「名札 メイン」があります。特に手入力するわけではありません。おまじない程度に考えてください
変数宣言・・桐では、変数を利用するためには、事前に宣言文を置きます。変数の種類と、変数の型を指定します
変数を配列で使用する時は、[ ]を付加し、要素数を指定します。「0やマイナス」は、指定出来ません。
配列は、1 〜 16384(理論値)の範囲です。

変数の設定・・・別に最初から、上記のように設定するわけではありません。何も宣言しなくてもいいです。
 理由・・変数を使用しない場合。当然ですが、変数は不要ですね
     そのほかに、桐には組み込み変数があります。例:&年・&月・&日・&STR・・・
     それを、利用することも可能です。
逆もあります。集計コマンドを実行すれば、組み込み変数に「合計・平均・件数」等が入ります。
この数値は、次回の集計コマンドを実行するまで保存されますが、後々使用予定がある場合は逆に宣言した変数に代入しておきます
 利用例:数学と英語の合計はどちらが大きいか比較する場合、
 集計[数学]・・・・ここで、&合計に数学の合計がはいります。
 &数学計=&合計 と、代入しておきます。次に、
 集計[英語]・・・・今度は&合計に英語の合計がはいります。(新しい数値に置換されます)
ここで、&合計(英語の合計が入っている)と&数学計の比較が可能になります
(&英語計=&合計 と、代入しておいてもかまいません)
このように、組み込み変数と自分で宣言した変数を組み合わせて利用していきます。

必要になったとき追加してもかまいませんが、くれぐれも名前は気を付けてくださいね

整数と数値の区分・・整数の範囲は、-32768 〜 32767です。従って、月や日などは、範囲内に入りますので整数で宣言します
最初から数値が大きくなるかも知れない場合は、数値で宣言しておいた方が安心ですね。

初期値設定
 プログラムの起動時、最初になにを表示するか。初期値を設定しておきます

>データパス名 #一括パス名,固定=する
この一行は、意味があります。プログラムをあるフォルダーに置いてある場合、途中で他のフォルダーを参照すると、以降そこが基点となってしまいます。ファイルの読み込み等で、フォルダー移動操作を行う場合フルパス(ドライブ名)からの記述の場合は、問題有りませんが、通常ファイル名だけの指定ではエラーになってしまいます。そこで、この一行を入れておくと、次に変更するまで起動フォルダー名が保持されます。これも癖みたいに入れれば安心ですね。
 
手続き定義開始 フォーム::フォーム開始(長整数 &表番号)
  手続き実行 カレンダー作成()
  メソッド呼び出し @b月増.フォーカス設定()
手続き定義終了


>手続き定義開始 フォーム::フォーム開始

フォームが表示されたとき1回だけ実行されます。上記「名札 メイン」の時点では、まだフォームは開かれていませんので、フォームに対する操作は行えません。フォームに対して起動時に処理したい内容や処理はここに記載します。

イベント処理ですので、
>手続き定義開始 フォーム::フォーム開始(長整数 &表番号)
>手続き定義終了
この2行は自動作成可能です。不要の場合は行削除で削除してください

ここでの処理は、カレンダーを作成しフォーカスを「b月増」へ設定しています。(@はオブジェクトの区別用で先頭に必ず付けます)
※ここで、設定が無い場合は、オブジェクトリストの最上段から調べて最初に見つかったフォーカス可能なオブジェクトにフォーカスが設定されます。途中のオブジェクトに設定したいとき記載します。

プログラムは、「手続き定義開始」〜「手続き定義終了」まで実行し、呼び出された次の行へもどります
この手続きは、どこからも呼ばれていませんので、終了後フォームを表示し待機します。(正確にはフォームを開く操作を行った所から呼ばれてますが、意識しなくてけっこうです)
手続き定義開始 カレンダー作成()
  &作業年=#年(&作業日付),&作業月=#月(&作業日付),&作業日=#日(&作業日付)
  &月初曜=#文字位置("日月火水木金土",#曜日(#文字列(#日時値生成(&作業年,&作業月,1))))
  &月末=#日(#月末(#日時値生成(&作業年,&作業月,1)))
  繰り返し &i=1,37
    if(&i+1-&月初曜>=1 .and &i+1-&月初曜<=&月末)
      &日t[&i]=&i+1-&月初曜
    else
      &日t[&i]=#u
    end
  繰り返し終了
手続き定義終了


ここが、カレンダーのエンジンですね

&作業日付に「2002/4/1」のように、日付値が保存されています
起動してなにもボタンをおしてなければ、「&作業日付=#日時値」により、起動日の日付が保存されてます

&作業年=#年(&作業日付)から、年を取り出し、&作業年=2002を代入します。以下(#月・#日も同様です)

&月初曜=#文字位置("日月火水木金土",#曜日(#日時値生成(&作業年,&作業月,1)))
分解すると(一番内側の計算から行われます)  
  #日時値生成(&作業年,&作業月,1)・・・「&作業年&作業月1日」の日付を作成します・・・@
  #曜日(@)・・・その月の1日の曜日を求めます(日月火水木金土)の中から1文字を返します・・・A
  #文字位置("日月火水木金土",A)・・・"日月火水木金土"の中の何番目と一致するかを数値で返します・・・B
  &月初曜=B・・・上記によりその月の1日の曜日を数字で返します
  以上で、曜日を計算できる数値(日=1・月=2・火=3・・・・土=7)に、変更する式です・

&月末=#日(#月末(#日時値生成(&作業年,&作業月,1)))
これも分解すると(一番内側の計算から行われます)  
  #日時値生成(&作業年,&作業月,1)・・・「&作業年&作業月1日」の日付を作成します・・・@
  #月末(@)・・・・月末日を、年月日で返します・・・・A
  #日(A)・・・その中から日の数値を計算します・・・B
  &月末=B・・・月末日が算出されます
以上で、月末最終日が計算できます

繰り返し &i=1,37
  if(&i+1-&月初曜>=1 .and &i+1-&月初曜<=&月末)
    &日t[&i]=&i+1-&月初曜
  else
    &日t[&i]=#u
  end
繰り返し終了
プログラムの説明の前に、なぜ配列変数に37が使用されてるかの説明
1ヶ月の最大日数は31日ですね。カレンダーをイメージしてください。その月が、土曜日から始まったとします。
そのときの31日の場所は・・・6段目の左から2個目ですね。1段が7個ありますので5×7+2です
つまり、カレンダーの最大使用位置です。もちろん1は左上です。

繰り返し &i=1,37 は、&iに1〜37までを代入し、37回(固定して)繰り返し終了まで回すコマンドです

if(計算式の結果が1と同じかそれ以上 かつ 計算式の結果が月末と同じかそれより小さい場合)
 上記条件式の範囲内の場合、配列変数[&i]に、式の結果を代入・・・@
else
 上記条件式の範囲外の場合、配列変数[&i]は、未定義値にする・・・A
end

桐では別記方法としてケース文を書くことも多いです。上記をその書式で記述すると
ケース開始
  ケース(計算式の結果が1と同じかそれ以上 かつ 計算式の結果が月末と同じかそれより小さい場合)
    上記条件式の範囲内の場合、配列変数[&i]に、式の結果を代入・・・@
  ケース(その他)
    上記条件式の範囲外の場合、配列変数[&i]は、未定義値にする・・・A
ケース終了
どちらの方法も結果は同じです。

これで、37個全部の変数に値が代入されます

お断り:私は癖で未定義を「#u」と記載しますが、「#未定義・#U・#UNDEF・#う」などの書き方もあります
手続き定義開始 t作業日付::マウス左ダウン(長整数 &マウス位置[2],長整数 &明細番号,長整数 &フラグ,参照 長整数 &処理中止)
  if(&元号=0)
    &元号=1
  else
    &元号=0
  end
  メソッド呼び出し @フォーム.変数変更()
*  メソッド呼び出し @フォーム.描画更新()
手続き定義終了

これは、イベントです。「t作業日付」(現在の年月日を表示しているオブジェクト)の表示属性を変更します
&元号の値により、西暦表示と元号表示に切り替えています。
切り替え作業はオブジェクトの編集属性式に「#条件選択(&元号=1,"年の表示形式'元号(漢字1文字)'")」のように記載します
通常は西暦年を設定しておき、&元号=1のときだけ元号を漢字1文字形式で表示します。
プログラムは、このイベントが呼ばれた時、&元号の値を変更する処理を行ってます

メソッド呼び出し @フォーム.変数変更()
変数が更新されてますので、フォームに反映させる処理です

* メソッド呼び出し @フォーム.描画更新()
本当は画面の描画更新を、桐任せでなく故意に実行したいときに書くコマンドですが、無くてもほとんど同時に描画されるようです
先頭の「*・*」は、コメント行として扱います。プログラムの説明やメモなど書いておくことも可能です


以外と簡単でしょう!。これで、万年カレンダー完成ですよ。

top