C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[13]: カレンダーツール


(過去ログ 42 を表示中)

[トピック内 18 記事 (1 - 18 表示)]  << 0 >>

■22155 / inTopicNo.1)  カレンダーツール
  
□投稿者/ えるも (6回)-(2008/07/16(Wed) 11:41:22)

分類:[C#] 

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        
        int year = new int();
        int month = new int();
        int day = new int();
        int dayOfWeek = 0;
        int count = 0;
        Label[] label_ptr = new Label[42];

        /*今日の日付を取得*/
        DateTime dt = DateTime.Now;

        private void Form1_Load(object sender, EventArgs e)
        {
            int Month = DateTime.Today.Month;
            label100.Text = Month.ToString() + "月";
            MakeCarender(dt.Year,dt.Month,dt.Day);
        }

        /*カレンダー設定*/
        private void MakeCarender(int year, int month, int day)
        {
            //アプリケーション起動時のみ
            if (count == 0)
            {
                /*日付をセットする*/
                year = dt.Year;
                month = dt.Month;
                day = dt.Day;
                //dayOfWeek = dt.DayOfWeek.ToString();//曜日の取得
                //Console.WriteLine("\n"+year+"年"+month+"月"+day+"日"+dayOfWeek+"\n");            

            }

            /*月の日数を取得*/
            int MaxDay = GetDays(year, month);
            
            /*指定月の1日の曜日取得*/
            int firstDayOfWeek = getDayOfWeek(year,month,1);

            /*ラベルに日付の割り当て*/
            /*一日までの空白の挿入*/
            for (int i = 0; i < firstDayOfWeek; i++)
            {
                (label_ptr[i]).Text = i.ToString();
                 dayOfWeek++;

            }

            for (int i = 1; i <= MaxDay; i++)
            {
                (label_ptr[i]).Text = i.ToString();
                dayOfWeek++;
                if (dayOfWeek == 7)
                {
                    //System.out.println();
                    dayOfWeek = 0;
                }
            }
            
        }

        /*日数計算*/
        private int GetDays(int year, int month)
        {
            int days = 0;
            switch (month)
            {
                case 2:
                    if (DateTime.IsLeapYear(year))
                        days = 29;
                    else
                        days = 28;
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    days = 30;
                    break;
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    days = 31;
                    break;
            }
            
            //carender_make(year, month, days);
            return days;
        }


        /*
        * 指定した年月日の曜日を求める。戻り値と曜日の関係は
        * 日曜日:0〜土曜日:6
        */
        public static int getDayOfWeek(int year, int month, int day)
        {

            if (month <= 2)
            {
                month += 12;
                year--;
            }
            int h = year / 100, y = year % 100;

            // ツェラーの公式
            int dayOfWeek = y + y / 4 + h / 4 - 2 * h + 13 * (month + 1) / 5 + day;
            return (dayOfWeek + 6) % 7;

        }

        //先月ボタンを押したとき
        private void button1_Click_1(object sender, EventArgs e)
        {
            int year3 = new int();
            int month3 = new int();
            if (month == 1)
            {
                year3 = year - 1;
                month3 = 12;
            }
            else
            {
                year3 = year;
                month3 = month - 1;
            }

            count++;
            MakeCarender(year3, month3, day);
        }

        //来月ボタンを押したとき
        private void button2_Click_1(object sender, EventArgs e)
        {
            int year4 = new int();
            int month4 = new int();
            if (month == 12)
            {
                year4 = year + 1;
                month4 = 1;
            }
            else
            {
                year4 = year;
                month4 = month + 1;
            }

            count++;
            MakeCarender(year4, month4, day);
        }


このようなソースのカレンダーツールを作ったのですが、
先月、来月はボタンで表示させ、
ラベルを42個用いて、そこに日にちを入れて表示させようとおもいました。
月初め(1日が入る)ラベルまでの前のラベルには空白を入れようとしたのですが
(label_ptr[i]).Text = i.ToString();の部分で
デバッガに引っかかりNullReferenceExceptionはハンドルされませんでしたというエラーが出ます…
対処方法がお分かりになる方はよろしくお願いします。

他にもカレンダーツールがおかしいというご指摘があればそこもよろしくお願いします。

引用返信 編集キー/
■22156 / inTopicNo.2)  Re[1]: カレンダーツール
□投稿者/ επιστημη (1155回)-(2008/07/16(Wed) 11:57:06)
επιστημη さんの Web サイト
label_ptr[i] には Label が入っていますか?

Label[] label_ptr = new Label[42];
これはLabelを納める(42個分の)ハコを作っただけで
中身カラッポです。

label_ptr[n] = new Label(); (n=0..41)
しておかないと空き箱にアクセスし、NullReferenceExceptionって怒られます。

引用返信 編集キー/
■22157 / inTopicNo.3)  Re[2]: カレンダーツール
□投稿者/ 特攻隊長まるるう (137回)-(2008/07/16(Wed) 12:02:56)
label_ptr の中が空っぽなのは επιστημη さんの指摘通りだと思います。

実際に用意されているラベルコントロールは
> label100
のみのようですが、他のラベルコントロールは
どこにあるものを使おうと考えていますか?

画面に label1 〜 label99 とかあるのであれば、
それと配列 label_ptr に何の関連も無いわけ
ですから、1つ1つ
 label_ptr[0] = label1
 label_ptr[1] = label2
のように結び付けてやる必要があるのでは?

もしくは実行時にラベルコントロールを動的に
作成するのであれば、今度はその作成したラベル
コントロールを画面に表示するようなプログラムを
書かないといけませんよね?
引用返信 編集キー/
■22172 / inTopicNo.4)  Re[3]: カレンダーツール
□投稿者/ えるも (8回)-(2008/07/16(Wed) 13:38:22)
επιστημηさん、特攻隊長まるるうさん
ありがとうございます。

visual studioを使って作成しているので、表示に関しては大丈夫だと思います。
言われてみると、値の結び付けするのを忘れていました。

結び付けを行って値はちゃんと入るようになりました。
しかし、来月と先月のボタンを押してもちゃんと反応しないのですが
どのようにしたらいいでしょうか?


引用返信 編集キー/
■22175 / inTopicNo.5)  Re[4]: カレンダーツール
□投稿者/ επιστημη (1157回)-(2008/07/16(Wed) 13:49:35)
επιστημη さんの Web サイト
> しかし、来月と先月のボタンを押してもちゃんと反応しないのですが
> どのようにしたらいいでしょうか?

説明不足。
「ちゃんと反応しない」だけで原因が特定できる
霊能者は生憎ここにはおりません。

引用返信 編集キー/
■22176 / inTopicNo.6)  Re[4]: カレンダーツール
□投稿者/ シャノン (541回)-(2008/07/16(Wed) 13:53:14)
No22172 (えるも さん) に返信
> επιστημηさん、特攻隊長まるるうさん
> ありがとうございます。
>
> visual studioを使って作成しているので、表示に関しては大丈夫だと思います。
> 言われてみると、値の結び付けするのを忘れていました。
>
> 結び付けを行って値はちゃんと入るようになりました。
> しかし、来月と先月のボタンを押してもちゃんと反応しないのですが
> どのようにしたらいいでしょうか?

button1_Click_1 みたいに、末尾に _1 がついてるメソッドは、既に button1_Click というメソッドがあるのに、それが button1.Click に結び付けられていない状態で、デザイナから button1.Click を生成したときに作られます。
従って、思うに、イベントとイベントハンドラの関連付けがうまく行ってない(いちど関連付けられたものが無理やり解除されたか?)気がします。
引用返信 編集キー/
■22179 / inTopicNo.7)  Re[5]: カレンダーツール
□投稿者/ えるも (9回)-(2008/07/16(Wed) 14:16:18)
 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        
        public int year;
        public int month;
        public int day;
        int dayOfWeek = 0;
        int count = 0;
        Label[] label_ptr = new Label[42];


        /*今日の日付を取得*/
        DateTime dt = DateTime.Now;

        /*カレンダー本体*/
        private void Form1_Load(object sender, EventArgs e)
        {
            MakeCarender(dt.Year,dt.Month,dt.Day);

            //アプリケーション起動時のみ
            if (count == 0)
            {
                /*日付をセットする*/
                year = dt.Year;
                month = dt.Month;
                day = dt.Day;
                label100.Text = dt.Year.ToString() + "年" + dt.Month.ToString() + "月";
                //dayOfWeek = dt.DayOfWeek.ToString();//曜日の取得
                //Console.WriteLine("\n"+year+"年"+month+"月"+day+"日"+dayOfWeek+"\n");            

            }
        }

        /*カレンダー設定*/
        private void MakeCarender(int year, int month, int day)
        {

            label100.Text = year.ToString()+"年" + month.ToString() + "月";

            /*月の日数を取得*/
            int MaxDay = GetDays(year, month);

            /*指定月の1日の曜日取得*/
            int firstDayOfWeek = getDayOfWeek(year,month,1);

            label_ptr[0] = label1;
            label_ptr[1] = label2;
            label_ptr[2] = label3;
            label_ptr[3] = label4;
            label_ptr[4] = label5;
            label_ptr[5] = label6;
            label_ptr[6] = label7;
            label_ptr[7] = label8;
            label_ptr[8] = label9;
            label_ptr[9] = label10;
            label_ptr[10] = label11;
            label_ptr[11] = label12;
            label_ptr[12] = label13;
            label_ptr[13] = label14;
            label_ptr[14] = label15;
            label_ptr[15] = label16;
            label_ptr[16] = label17;
            label_ptr[17] = label18;
            label_ptr[18] = label19;
            label_ptr[19] = label20;
            label_ptr[20] = label21;
            label_ptr[21] = label22;
            label_ptr[22] = label23;
            label_ptr[23] = label24;
            label_ptr[24] = label25;
            label_ptr[25] = label26;
            label_ptr[26] = label27;
            label_ptr[27] = label28;
            label_ptr[28] = label29;
            label_ptr[29] = label30;
            label_ptr[30] = label31;
            label_ptr[31] = label32;
            label_ptr[32] = label33;
            label_ptr[33] = label34;
            label_ptr[34] = label35;
            label_ptr[35] = label36;
            label_ptr[36] = label37;
            label_ptr[37] = label38;
            label_ptr[38] = label39;
            label_ptr[39] = label40;
            label_ptr[40] = label41;
            label_ptr[41] = label42;

            
            /*ラベルに日付の割り当て*/
            /*一日までの空白の挿入*/
            for (int i = 0; i < firstDayOfWeek; i++)
            {
                (label_ptr[i]).Text = "";
                 dayOfWeek++;

            }

            for (int i = 1; i <= MaxDay; i++)
            {
                (label_ptr[i]).Text = i.ToString();
                dayOfWeek++;
                if (dayOfWeek == 7)
                {
                    //System.out.println();
                    dayOfWeek = 0;
                }
            }

            for (int i = MaxDay+1 ; i <=41 ; i++)
            {
                (label_ptr[i]).Text = "";
                dayOfWeek++;

            }

        }

        /*日数計算*/
        private int GetDays(int year, int month)
        {
            int days = 0;
            switch (month)
            {
                case 2:
                    if (DateTime.IsLeapYear(year))
                        days = 29;
                    else
                        days = 28;
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    days = 30;
                    break;
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    days = 31;
                    break;
            }
            
            //carender_make(year, month, days);
            return days;
        }


        /*
        * 指定した年月日の曜日を求める。戻り値と曜日の関係は
        * 日曜日:0〜土曜日:6
        */
        public static int getDayOfWeek(int year, int month, int day)
        {

            if (month <= 2)
            {
                month += 12;
                year--;
            }
            int h = year / 100, y = year % 100;

            // ツェラーの公式
            int dayOfWeek = y + y / 4 + h / 4 - 2 * h + 13 * (month + 1) / 5 + day;
            return (dayOfWeek + 6) % 7;

        }

        //先月ボタンを押したとき
        private void button1_Click_1(object sender, EventArgs e)
        {

            if (month == 1)
            {
                year = year - 1;
                month = 12;
            }
            else
            {
                //year = year;
                month = month - 1;
            }

            count++;
            MakeCarender(year, month, day);
        }

        //来月ボタンを押したとき
        private void button2_Click_1(object sender, EventArgs e)
        {

            if (month == 12)
            {
                year = year + 1;
                month = 1;
            }
            else
            {
                //year = year;
                month = month + 1;
            }

            count++;
            MakeCarender(year, month, day);
        }
    }

というように少し変更しました。

επιστημηさん、すみません。
かなりの説明不足でした。
先月来月ボタンを押しても、1日の場所が7月(2008年7月)の火曜から変化しません。
月末の表示は、ちゃんと変更されているのになぜでしょうか?

シャノンさんありがとうございます。
上記のように変更したところ、ボタンを押したときに動作は行われました。
しかし、曜日や日付が7月のまま、月に合わせて日数が減ったり増えたりしています・・・

質問している立場なのにかなり至らない点が多く申し訳ないのですが、よろしくお願いします。

引用返信 編集キー/
■22182 / inTopicNo.8)  Re[6]: カレンダーツール
□投稿者/ επιστημη (1158回)-(2008/07/16(Wed) 14:29:56)
επιστημη さんの Web サイト
2008/07/16(Wed) 14:48:40 編集(投稿者)
> 先月来月ボタンを押しても、1日の場所が7月(2008年7月)の火曜から変化しません。

>             /*ラベルに日付の割り当て*/
>             /*一日までの空白の挿入*/
>             for (int i = 0; i < firstDayOfWeek; i++)
>             {
>                 (label_ptr[i]).Text = "";
>                  dayOfWeek++;
>             }

おそらく、firstDayOfWeekは0〜6の値を取り、
最大 label_ptr[5]までを""で埋めますよね。
にもかかわらず
 
>             for (int i = 1; i <= MaxDay; i++)
>             {
>                 (label_ptr[i]).Text = i.ToString();
>                 ...

してんだから label_ptr[1]以降を書き換えてます。
さっき""で埋めたとこを書き潰しますね。

第1日を表示すべきラベルは label_ptr[1] では"ない"はずです。

引用返信 編集キー/
■22234 / inTopicNo.9)  Re[7]: カレンダーツール
□投稿者/ えるも (10回)-(2008/07/17(Thu) 11:30:06)
No22182 (επιστημη さん) に返信
> 2008/07/16(Wed) 14:48:40 編集(投稿者)
> 
> > 先月来月ボタンを押しても、1日の場所が7月(2008年7月)の火曜から変化しません。
> 
>>            /*ラベルに日付の割り当て*/
>>            /*一日までの空白の挿入*/
>>            for (int i = 0; i < firstDayOfWeek; i++)
>>            {
>>                (label_ptr[i]).Text = "";
>>                 dayOfWeek++;
>>            }
> 
> おそらく、firstDayOfWeekは0〜6の値を取り、
> 最大 label_ptr[5]までを""で埋めますよね。
> にもかかわらず
>  
>>            for (int i = 1; i <= MaxDay; i++)
>>            {
>>                (label_ptr[i]).Text = i.ToString();
>>                ...
> 
> してんだから label_ptr[1]以降を書き換えてます。
> さっき""で埋めたとこを書き潰しますね。
> 
> 第1日を表示すべきラベルは label_ptr[1] では"ない"はずです。
> 

遅くなってすみません。
ありがとうございます。
まさにそのとおりでした。全く気づきませんでした。
そこで、

int j = 1;
/*日付部分*/
for (int i = firstDayOfWeek ; i <= MaxDay+1; i++)
    {
     (label_ptr[i]).Text = j.ToString();
      dayOfWeek++;
      j++;
     if (dayOfWeek == 7)
      {
         //System.out.println();
         dayOfWeek = 0;
      }
    }

というように変更しました。


しかし、これでも問題があって、月末日がちゃんと表示されないのと
2008年6月以前と2009年4月以降(6月と4月)でエラーが
     (label_ptr[i]).Text = j.ToString();
の部分でIndexOutOfRangeExceptionはハンドルされませんとデバッグにひっかかります。

質問ばかりして申し訳ないのですが、お願いします…

引用返信 編集キー/
■22235 / inTopicNo.10)  Re[8]: カレンダーツール
□投稿者/ επιστημη (1165回)-(2008/07/17(Thu) 11:38:57)
επιστημη さんの Web サイト
2008/07/17(Thu) 12:17:06 編集(投稿者)
あのさー、「考えようよ」

> しかし、これでも問題があって、月末日がちゃんと表示されないのと
> for (int i = firstDayOfWeek ; i <= MaxDay+1; i++)

列挙開始を firstDayOfWeek だけズラしたんだから
終了条件も同じだけズラさにゃいかんのじゃないの?

> 2008年6月以前と2009年4月以降(6月と4月)でエラーが
>      (label_ptr[i]).Text = j.ToString();
> の部分でIndexOutOfRangeExceptionはハンドルされませんとデバッグにひっかかります。

そのときiはいくつになってますか? 
41を超えてはいけませんよ? 0を下回ってはいけませんよ?

引用返信 編集キー/
■22236 / inTopicNo.11)  Re[8]: カレンダーツール
□投稿者/ 鶏唐揚 (247回)-(2008/07/17(Thu) 11:40:31)
No22234 (えるも さん) に返信
>質問ばかりして申し訳ないのですが、お願いします…
質問ばかりになってるのは、例外のメッセージが何を意味してるのかを
把握してないからだと思います。せっかくコンパイラが親切に「こんなエラー起きたよ!」って言ってくれてるので
そのあたりも理解するようにすれば自然と明確な質問ができるようになったり、質問自体が減ったりしますので
がんばってください。

>IndexOutOfRangeException
これは「指定された配列インデックス(Index)が配列の範囲(Range)を外れ(Out)ちゃいましたよ」という意味です。
したがって、iの値がlabel_ptrの要素数を超えてしまったか、マイナス値になったかのどちらかだと思います。
で、配列は0から開始して要素数-1が最大要素値となりますので、
for文の「i <= MaxDay+1」が怪しいんじゃないかと。

全体の仕様とかは把握してないので、この「i <= MaxDay+1」が間違っているのか
label_ptrの要素が足りてないのかは判断できません。
引用返信 編集キー/
■22238 / inTopicNo.12)  Re[9]: カレンダーツール
□投稿者/ みきぬ (19回)-(2008/07/17(Thu) 12:02:48)
2008/07/17(Thu) 12:11:32 編集(投稿者)

getDayOfWeek() メソッドにバグがありますな。
本来 0〜6 を返すところを、マイナスの値を返しちゃってる。

以下、思考過程

例外が発生する

iの値をのぞいてみる

-3!? -4!? なんじゃこりゃ

ソースを上にたどっていく

firstDayOfWeek の初期値って、getDayOfWeek() の戻り値を入れているのか ← 今このへん

戻り値を整数にしようとして (dayOfWeek + 6) % 7 しているのか。dayOfWeek が-7以下だったらどうなるんだろ

引用返信 編集キー/
■22239 / inTopicNo.13)  Re[10]: カレンダーツール
□投稿者/ えるも (11回)-(2008/07/17(Thu) 13:21:55)
2008/07/17(Thu) 13:24:38 編集(投稿者)

επιστημηさん、鶏唐揚さん

ありがとうございます。
自分なりに調べてみたのですが、わからなかったので…すみませんでした。

本当に皆さんの言うとおりなので、もう少し自分で考えてから質問するようにします。

みきぬさん

ありがとうございます。
dayOfWeekにマイナスの値が入っていたんですね…
公式をそのまま載せていたのでこれで何とかなるだろうと
思っていました。少し考えみます
引用返信 編集キー/
■22240 / inTopicNo.14)  Re[11]: カレンダーツール
□投稿者/ えるも (12回)-(2008/07/17(Thu) 13:53:41)
2008/07/17(Thu) 14:31:08 編集(投稿者)

επιστημηさん、特攻隊長まるるうさん、シャノンさん、鶏唐揚さん、みきぬさん
質問にお答えいただいた皆様のおかげでなんとかカレンダーツールを作成することができました。

本当に質問ばかりしてしまってすみませんでした。
ありがとうございました。
解決済み
引用返信 編集キー/
■22242 / inTopicNo.15)  Re[12]: カレンダーツール
□投稿者/ みきぬ (20回)-(2008/07/17(Thu) 14:10:25)
No22240 (えるも さん) に返信
> επιστημηさん、特攻隊長まるるうさん、シャノンさん、鶏唐揚、みきぬさん
えるもさーん! 1人さんづけ忘れてますよー!

それだけだとアレなのでもう1個だけ。
何となくプログラムの勉強かな? と思ったので書かないでいたのですが、
「指定した月の日数を取得する」「指定した日の曜日を取得する」方法は用意されていまして、
DateTime.DaysInMonth() メソッド、DateTime.DayOfWeek プロパティがそれになります。

これらを使ってプログラムを書き直してみるのもよいと思います。
解決済み
引用返信 編集キー/
■22243 / inTopicNo.16)  Re[12]: カレンダーツール
□投稿者/ えるも (13回)-(2008/07/17(Thu) 14:30:14)
2008/07/17(Thu) 23:45:36 編集(投稿者)
2008/07/17(Thu) 14:33:34 編集(投稿者)
2008/07/17(Thu) 14:30:52 編集(投稿者)

すみません…わすれてました…

みきぬさん
ありがとうございます。
ちゃんとメソッドが用意されてるんですね…知りませんでした。
メソッドがないと思って作っていたのですが、用意されているならそれを使ってみようと思います。
解決済み
引用返信 編集キー/
■22244 / inTopicNo.17)  Re[13]: カレンダーツール
□投稿者/ シャノン (542回)-(2008/07/17(Thu) 15:05:08)
No22243 (えるも さん) に返信
> シャノンさん
えるもさーん! お礼を言う相手を間違えてますよー!
解決済み
引用返信 編集キー/
■22295 / inTopicNo.18)  Re[13]: カレンダーツール
□投稿者/ えるも (14回)-(2008/07/17(Thu) 23:44:50)
2008/07/17(Thu) 23:47:16 編集(投稿者)

シャノンさん
ありがとうございます。

最後の最後までご迷惑をかけてしまいました・・・
皆さん本当にありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -