Casio Basic入門26
Casio Basic入門
誤字脱字・記載ミスや分かりにくい表現は随時追記・修正します
最終更新: 2018/11/03
最終更新: 2018/11/03
4. CasioBasicを使ってみる(続き)
Chapter 5
◆ Chapter 5 の目標: サブルーチンを使いこなす
前回: Casio Basic入門25 を見る
[2018/11/03 追記]
▶ ソースコードの誤記を見直しました
▶ CcLinker を使ってfx-5800Pに転送して使えるプログラムファイル(CCLファイル)をダウンロードできます。
前回は、日本時間、ドイツ時間、LA時間のいずれかを入力すると、換算したそれぞれの時間を表示するところまで作りました。
今回は、ドイツ時間を夏時間や標準時間に切り替える機能、それに伴って正しい時間を表示する機能を追加してゆきます。
今回までで完成させるプログラムを一番下に掲載しているので、先にそれを見て分かれば、先に進んでも良いでしょう。
Chapter5-4
少し異なるルーチンを、わかりやすく追加する
具体的には、以下のように 1:CET の右に ドイツ時間の夏時間設定用のメニューを追加表示します。

標準時間を ST、夏時間を DL と表示することにします。
ST は Standard Time (標準時間) の略で、DL は DayLight saving (アメリカでの夏時間の表現) からとりました。
上の画面は、起動時の初期表示で、起動時には標準時間となるようにします。そして、[3] キーを押したら夏時間に切り替わり、もう一度押したら標準時間に戻る...といった動作(トグル動作)にします。
プログラム内部で、現在がドイツの夏時間かどうかがわかるようにするために、新しい変数 S を夏時間フラグとして用い、
S = 0 時は標準時間で、S = 1 の時は夏時間
と決めます。
今回は、[3] キーを押してドイツ時間を夏時間に変更し、ドイツ時間を計算し、その結果を画面表示する機能を追加します。
1.初期化処理
先ず、今回追加する新しい変数 S (ヨーロッパの夏時間フラグ)の初期化を行う。
次に、初期表示の変更を行います。初期表示はサブルーチン TZM で受け持っているので、これを修正する。
2.メニュー番号取得処理
ループの中で Getkey コマンドを使って、[3] キーが押された時、メニュー変数 M に 3 を入れる。
なお、この処理では、何かキーが押されるまでプログラムは先に進まず、入力待ちの状態にする。
3.入力処理
M=3 の時は、入力処理は行なわない。但し、ドイツ時間 G が、夏時間か標準時間に変更されるので、G から「時」と「分」を分離する。
4.時間の計算
M=3 の時、変更されたドイツ時間を計算する。日本時間とロサンゼルス時間には影響が無いので、これらの計算は行わない。
5.時間表示の更新
時間表示サブルーチン TZD を用いて、これまでのように日本時間、ドイツ時間、ロサンゼルス時間の表示を更新する。
6.ループ構造
既にある While 1 ~ WhileEnd ループの中に、上記追加コードを入れる。
メインルーチンの擬似的なプログラムは、以下になります。今回追加・修正するところがはっきりと分かります。
[初期設定]
Prog "TZM" [メイン画面表示]
While 1
[メニュー番号取得処理]
If M=0:Then
[日本時間入力処理] (時間から「時」と「分」の分離も行う)
Else If M=1:Then
[ドイツ時間入力処理] (時間から「時」と「分」の分離も行う)
Else If M=2:Then
[ロサンゼルス時間入力処理] (時間から「時と「分」の分離も行う)
Else If M=3:Then
入力処理は行わず、時間から「時」と「分」の分離のみ行う
IfEnd:IfEnd
IfEnd:IfEnd
If M=0:Then
[時間計算]
Else If M=1:Then
[時差計算]
Else If M=2:Then
[時間計算]
Else If M=3:Then
[時間計算]
IfEnd:IfEnd
IfEnd:IfEnd
Prog "TZD" [時間の再表示]
WhileEnd
(赤文字は追加・修正部分)
1.初期化処理
今回は、ドイツの夏時間フラグ S を追加して、これを 0 で初期化しておきます。
S = 0 は、標準時間であることを示します。
0→S
を追加します。
2.メニュー番号取得処理
[3] キーを押すと、メニュー変数 M に 3 を設定する。
メニュー番号取得処理のプログラム
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M [今回追加]
[3] キーのキーコードは 37 です。
3.入力処理
ドイツ時間を、夏時間 - 標準時間 に切り替えるのみで、キー入力処理は行いません。ドイツ時間が切り替わっても、日本時間やロサンゼルス時間には影響が無いので、この時点での日本時間 J を分離して、「時」を 変数 A に、「分」を変数 B に入れておきます。
Else If M=3
Then
Int(J÷100)→A
J-100A→B
IfEnd
4.時間計算
夏時間になると時差が1時間減り、標準時間に戻る時は時差が1時間増えます。
但し、ドイツ時間が変わるだけで、日本時間やロサンゼルス時間は変化しません。
これを具体的にプログラムにすると、以下のようになります。
Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
IfEnd
この中で、以下の部分は、夏時間フラグの変更と時差の変更を行います。
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
現状が夏時間の時は、S=1 になっています。
If S:Then
は、S が 1 の時の分岐処理なので、
夏時間フラグ:S を 0 にし、時差:P を1時間増やします。
Else 以下は、現状が標準時間の時の処理で、
夏時間フラグ:S を 1 にし、時差:P を1時間減らしています。
この後に続く処理では、ドイツ時間を計算し、時間表示サブルーチン TZM を呼び出します。
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
入力処理のところで、現在の日本時間 J から「時」:A と「分」 B を算出するようにしました。
ドイツ時間は、日本時間の「時」 A と時差 P から計算するので、A - P でドイツ時間の「時」が得られます。
この計算の結果が負の数になる場合は、ドイツはまだ前日と言うことになります。この場合は、得られた負の数に 24 を足せば、24時制の「時」になります。
そこで、A - P を一旦変数 C に入れておき、それが負の数なら 24 を足しておきます。
A-P→C
C<0⇒C+24→C
ドイツ時間:G は、100C + B で計算できます。
100C+B→G
最後に、サブルーチン TZM を呼び出す
Prog "TZM"
さて、画面表示サブルーチン TZM をドイツの夏時間に対応するように変更します。
サブルーチン TZM のプログラム
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 1,4,"<AC>:QUIT"
If S:Then
Locate 5,2,"ST" [1:CET を 1:CEST に表示を切り替える]
Locate 15,2,"DL" [3:ST を 3:DL に表示を切り替える]
Else
Locate 5,2,"T " [1:CEST を 1:CET に表示を切り替える]
Locate 15,2,"ST" [3:DL を 3:ST に表示を切り替える]
IfEnd
(赤文字は追加分)
下から3行目で表示するのは "T " で、 T の後に空白1文字が付加されていることに注意してください。この空白文字があることで、"ST" と表示されている2文字を"T " で上書きして、 表示を 1:CEST から 1:CET に変更できるわけです。
ヨーロッパの標準時間と夏時間の略称は、以下のように標準時間は3文字、夏時間は4文字の表記になっています。
そこで、略称の2文字目以降を T と ST で切り替えると、標準時間と夏時間の略称表示を切り替えられます。
タイムゾーン | 標準時間 | 夏時間 |
西ヨーロッパ時間 | WET | WEST |
中央ヨーロッパ時間 | CET | CEST |
東ヨーロッパ時間 | EET | EEST |
極東ヨーロッパ時間 | FET | FEST |
5.時間の再表示
時間の再表示は、サブルーチン TZD で行います。これまでに作った 時間表示サブルーチン TZD のソースコードを示します。
サブルーチン TZD のプログラム
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U
プログラムを起動した直後は、以下の画面になっています。

先に、ドイツを夏時間に切り替えてから、時間を入力しようとします。つまりこの画面で [3] キーを押すと、以下のような画面になってしまいます。

日本時間が 0000、ドイツ時間が 1700、ロサンゼルス時間が 0000 となっているのは、明かに異常です。
しかし、プログラムを上から順に見ながら確かめると、この状態ではどの地域の時間も入力していないので、当然このような表示になります。では、何が悪いのか?
要するに、この時点で各地域の時間を表示する意味がありません。むしろ表示してはいけない、と考えます。
仮に、どこかの地域に時間を入力すれば、正しい時間が計算される筈です。試しに、日本時間に 20:00 を設定してみます。

正しい時差で、時間が表示されているのが分かります。
どの地域にも時間を入力していない状態、つまりプログラム起動直後の状態では、サブルーチン TZD による時間表示が行われないようにすれば、この問題を解決できます。
このような細かい処理は、メインルーチンを変更するよりも、サブルーチンで対処した方が、プログラムは分かりやすくなるので、TZD をどのように変更すべきかを考えます。
1つの方法として、日本時間の変数 J を -1 で初期化する手があります。プログラムを走らせている時は、J が -1 になることは絶対にありません。と言うのも、INPI は仕様上、負の値を戻すことが無いからです。一回でも、どこかの地域に時間を入力すれば、J は 0 か正の値になるわけで、-1 は初期状態を示すためだけに使えます。敢えて、J を -1 で初期化するのが、今回の作戦です。
言い換えれば、変数 J に、初期状態フラグとしての働きも持たせるわけです。
そこで、サブルーチン TZD では、J の異常値 -1 を検出させて、異常値なら何も動作しないで終了し、メインルーチンに戻るようにします。TZD の最初の行に、以下のコードを追加します。
J=-1⇒Return
Return コマンドは、プログラムを強制終了させます。サブルーチン内では、Return コマンドがあると、そのサブルーチンを直ちに終了させ、メインルーチンに戻ります。
⇒ Casio Basicコマンドリファレンス: Return
サブルーチン TZD を以下のように変更します。
サブルーチン TZD のプログラム
J=-1⇒Return
Locate 8,1,"000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U
これに合わせて、忘れずにメインルーチン TZ の [初期化処理] ブロックでの J の初期化を -1→J に変更しておきます。
では、TZ を起動し、いきなり最初に [3] キーを押して、ドイツを夏時間にしてみます。以下のように、時間が表示されないことを確認してください。次に、日本時間を 20:00 にしてみます。ドイツ時間が 1300、ロサンゼルス時間が 0300 になっていれば正常です。

では、[3] キーをもう一度押して、夏時間から標準時間へ戻してください。日本時間とロサンゼルス時間は、当然変化なしで、ドイツ時間が 1200 と表示され、プログラムが正しく動作していることがわかります。
今回までに作成したプログラムは、以下の通り(今回追加した部分を赤文字で示す):
▶ CcLinkerを使ってfx-5800Pに転送できるCCLファイルのダウンロード
※ CcLinker の紹介
メインルーチン:TZ のプログラム
8→P:17→Q
-1→J:0→G:0→U
0→S
Prog "TZM"
While 1
-1→M
Do
Getkey→K
LpWhile K=0
K=25⇒0→M
K=35⇒1→M
K=36⇒2→M
K=37⇒3→M
If M=0:Then
8→X:1→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→J
Else If M=1
Then
8→X:2→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→G
Else If M=2:
Then
8→X:3→Y:4→D:1→E
Prog "INPI"
Prog "TZC"
X→A:Y→B:Z→U
Else If M=3
Then
Int(J÷100)→A
J-100A→B
IfEnd:IfEnd
IfEnd:IfEnd
If M=0:Then
A≧24⇒A-24→A
100A+B→J
A-P→C
C<0⇒C+24→C
100C+B→G
A-Q→C
C<0⇒C+24→C
100C+B→U
Else If M=1
Then
A≧24⇒A-24→A
100A+B→G
A+P→C
C≧24⇒C-24→C
100C+B→J
A+P-Q→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→U
Else If M=2
Then
A≧24⇒A-24→A
100A+B→U
A+Q→C
C≧24⇒C-24→C
100C+B→J
A+Q-P→C
C<0⇒C+24→C
C≧24⇒C-24→C
100C+B→G
Else If M=3
Then
If S:Then
0→S:P+1→P
Else
1→S:P-1→P
IfEnd
A-P→C
C<0⇒C+24→C
100C+B→G
Prog "TZM"
IfEnd:IfEnd
IfEnd:IfEnd
Prog "TZD"
WhileEnd
サブルーチン:TZM のプログラム (画面表示)
Locate 1,1,"0:JST"
Locate 1,2,"1:CET"
Locate 1,3,"2:PST"
Locate 13,2,"3:"
Locate 1,4,"<AC>:QUIT"
If S:Then
Locate 5,2,"ST"
Locate 15,2,"DL"
Else
Locate 5,2,"T "
Locate 15,2,"ST"
IfEnd
サブルーチン:TZC のプログラム (時間を「時」と「分」に分離):変更なし
If Z<100:Then
Z→X:0→Y
Else
Int(Z÷100)→X
Z-100X→Y
IfEnd
サブルーチン TZD のプログラム (時間の表示)
J=-1⇒Return
Locate 8,1,"0000"
J⇒Locate 11-Int(log(J)),1,J
Locate 8,2,"0000"
G⇒Locate 11-Int(log(G)),2,G
Locate 8,3,"0000"
U⇒Locate 11-Int(log(U)),3,U
今回は、ドイツの夏時間設定機能を追加しました。
次回は、ロサンゼルスの夏時間設定を追加してゆきます。
つづく...
⇒ Casio Basic入門27 / 目次
応援クリックをお願いします。励みになるので...
- 関連記事
-
-
Casio Basic入門28 2018/11/03
-
Casio Basic入門27 2018/11/03
-
Casio Basic入門26 2018/11/03
-
Casio Basic入門25 2018/11/03
-
Casio Basic入門24 2018/11/03
-