- ベストアンサー
MonthCalendarで選択範囲の日数を表示する方法
- MonthCalendarとDataGridViewを使用して、ユーザーが選択した範囲の日数を一行に表示する方法を教えてください。
- 選択した範囲の日数を一行に表示するために、1/1から31日までの列を作成し、列の名前に日付を表示させたいです。
- 最終的には、選択した範囲内の社員の勤怠表を表示したいため、社員データと日勤データのテーブルを組み合わせて表示する方法を教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>テーブル1・・・勤務表 >日付 | 社員ID | 勤怠 の3列です。 >テーブル2・・・社員名簿です。 >社員ID | 氏名 の2列(抜粋です) この場合だと、以下のようなSQL文を実行すれば、良いと思います。 Access2003では、このSQL文は動作しました。 SELECT テーブル1.社員ID,テーブル2.氏名, MAX(IIF(テーブル1.日付=#2006/10/01#, テーブル1.勤怠, '')) AS [2006/10/01], MAX(IIF(テーブル1.日付=#2006/10/02#, テーブル1.勤怠, '')) AS [2006/10/02], MAX(IIF(テーブル1.日付=#2006/10/03#, テーブル1.勤怠, '')) AS [2006/10/03] FROM テーブル1 INNER JOIN テーブル2 ON テーブル1.社員ID=テーブル2.社員ID WHERE テーブル1.日付 BETWEEN #2006/10/01# AND #2006/10/03# GROUP BY テーブル1.社員ID,テーブル2.氏名 ORDER BY テーブル1.社員ID で、このSQL文を選択した日付で動作するように、コーディングしてます。 Dim sql As String sql = "SELECT テーブル1.社員ID,テーブル2.氏名" While wkdate <= MonthCalendar1.SelectionRange.End sql &= String.Format( _ ",MAX(IIF(テーブル1.日付=#{0:yyyy/MM/dd}#, テーブル1.勤怠, '')) AS [{0:yyyy/MM/dd}]", wkdate) wkdate = wkdate.AddDays(1) End While sql &= " FROM テーブル1 " sql &= " INNER JOIN テーブル2 " sql &= " ON テーブル1.社員ID=テーブル2.社員ID " sql &= String.Format(" WHERE テーブル1.日付 BETWEEN #{0:yyyy/MM/dd}# AND #{1:yyyy/MM/dd}# ", _ MonthCalendar1.SelectionRange.Start, MonthCalendar1.SelectionRange.End) sql &= " GROUP BY テーブル1.社員ID,テーブル2.氏名" sql &= " ORDER BY テーブル1.社員ID" こんな感じ。 あと、補足?ですが、 >sql = "SELECT テーブル1.社員ID,テーブル2.氏名" _ >& "FROM テーブル1 INNER JOIN テーブル2" _ >& "ON テーブル1.社員ID = テーブル2.社員ID" この場合、展開すると、「氏名FROM」のようになり、エラーとなっていまします。 前側の「"」の後にスペースを入れるか、後側の「"」の前にスペースを入れましょう。 上のSQL文だと、下記の○の位置にスペースを入れてください。 sql = "SELECT テーブル1.社員ID,テーブル2.氏名" _ & "○FROM テーブル1 INNER JOIN テーブル2" _ & "○ON テーブル1.社員ID = テーブル2.社員ID" または、 sql = "SELECT テーブル1.社員ID,テーブル2.氏名○" _ & "FROM テーブル1 INNER JOIN テーブル2○" _ & "ON テーブル1.社員ID = テーブル2.社員ID"
その他の回答 (3)
- qtea
- ベストアンサー率77% (38/49)
SQL文初挑戦ということなので、参考になる(かもしれない)サイトを紹介します。 http://www11.plala.or.jp/studyhall/access/index.html http://www.rasweb.co.jp/reference/index.html http://homepage2.nifty.com/inform/vbdb/ No.3のSQL文を理解できようになるまでは、ちょっとたいへんかもしれません…。 #あと、考えてみれば、アクセスのクロス集計クエリーを使って実現する方法もありますね。 #こちらのほうが楽なのかも。
お礼
回答ありがとうございました。 サイトのリンクを貼っていただいてありがとうございました。 覚えることが沢山あって大変そうですが、使いこなせるととても便利だと思うので頑張って勉強します。 アクセスの「クロス集計クエリー」というのをはじめて聞いたのでネットで調べて作ってみました。まだプログラムに組み込んでないのでどちらが良いのかわかりませんが、色々と試して見たいと思います。 この度はお世話になって本当にありがとうございました。
- qtea
- ベストアンサー率77% (38/49)
>←ここ!の部分でエラーになり、「集計関数の一部として指定された式 '社員ID' を含んでいないクエリを実行しようとしました。」と表示されます。実際のテーブルには他にも項目があるのですが、それが原因でしょうか? SQL文がどこかで間違えてるのだと思います。 No1のサンプルコードは、以下のようなSQLを作っています。 SELECT テーブル1.社員ID, MAX(IIF(テーブル1.日付=#2006/10/01#, テーブル1.勤務形態, '')) AS [2006/10/01], MAX(IIF(テーブル1.日付=#2006/10/02#, テーブル1.勤務形態, '')) AS [2006/10/02], MAX(IIF(テーブル1.日付=#2006/10/03#, テーブル1.勤務形態, '')) AS [2006/10/03] FROM テーブル1 WHERE テーブル1.日付 BETWEEN #2006/10/01# AND #2006/10/03# GROUP BY テーブル1.社員ID ORDER BY テーブル1.社員ID 「集計関数の一部として指定された式 '社員ID' を含んでいないクエリを実行しようとしました。」というエラーは、 GROUP BY テーブル1.社員ID がない場合に出力されることが多いです。 もしかしたら、社員名をだすのに、社員一覧と結合してたりしますか? 例えば、 SELECT テーブル1.社員ID FROM テーブル1 INNER JOIN 社員一覧 ON テーブル1.社員ID=社員一覧.社員ID GROUP BY 社員一覧.社員ID のようにしてたりしませんか?この場合は、 GROUP BY 社員一覧.社員ID を GROUP BY テーブル1.社員ID とするか SELECT テーブル1.社員ID を SELECT 社員一覧.社員ID としないとエラーになります。(ORDER BY あたりも見てください) あとデバッグするときには、 dbadpt.Fill(ds) あたりで一時停止して、変数 sqlの値を見て、SQL文の確認をしてみださい。
お礼
こんにちは。丁寧な回答をしていただきましてありがとうございました。 ご指摘どおり、社員名を出すのに名簿と結合しておりました。 何度かやったのですが、SQL文初挑戦でして、どこに埋め込んだらよいのかわからず試行錯誤しており、うまくいかないのでお時間のある時に下記のコードを見て、どこに入れたら良いのか教えていただけますか? テーブル1・・・勤務表 日付 | 社員ID | 勤怠 の3列です。 テーブル2・・・社員名簿です。 社員ID | 氏名 の2列(抜粋です) sql = "SELECT テーブル1.社員ID,テーブル2.氏名" _ & "FROM テーブル1 INNER JOIN テーブル2" _ & "ON テーブル1.社員ID = テーブル2.社員ID" Dim mdb As String = "C:\テスト.mdb" Dim dbcon As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=""" & mdb & """") dbcon.Open() Try Dim wkdate As Date = MonthCalendar1.SelectionRange.Start Dim sql As String sql = "SELECT テーブル1.社員ID" ←ここに上のSQL文を追加してました。 While wkdate <= MonthCalendar1.SelectionRange.End sql &= String.Format( _ ",MAX(IIF(テーブル1.日付=#{0:yyyy/MM/dd}#, テーブル1.勤務形態, '')) AS [{0:yyyy/MM/dd}]", wkdate) wkdate = wkdate.AddDays(1) End While sql &= " FROM テーブル1 " sql &= String.Format(" WHERE テーブル1.日付 BETWEEN #{0:yyyy/MM/dd}# AND #{1:yyyy/MM/dd}# ", _ MonthCalendar1.SelectionRange.Start, MonthCalendar1.SelectionRange.End) sql &= " GROUP BY テーブル1.社員ID" sql &= " ORDER BY テーブル1.社員ID" Dim dbadpt As New OleDb.OleDbDataAdapter(sql, dbcon) Dim ds As New DataSet dbadpt.Fill(ds) DataGridView1.DataSource = ds.Tables(0) Finally dbcon.Close() End Try 埋め込む場所が他にもあるのでしょうか?上記の結合のSQL文をいれずに実行したらきちんと動作します。
- qtea
- ベストアンサー率77% (38/49)
MonthCalendar1,DataGridView1があるとして… >ユーザーが選択した日数の取得の仕方 MonthCalendar1.SelectionRange.End.Subtract(MonthCalendar1.SelectionRange.Start) または、 MonthCalendar1.SelectionRange.End - MonthCalendar1.SelectionRange.Start で日数は取得できます。 >取得した範囲内の個別の日付を列の名前に指定するやり方 いろいろやり方は考えられますが、下記を参考にしてみてください。 http://www.atmarkit.co.jp/fdotnet/vblab/gridlab_01/gridlab_01_01.html http://www.atmarkit.co.jp/fdotnet/vblab/gridlab_02/gridlab_02_01.html 単純に選択日付の列をつくるだけなら… DataGridView1.Columns.Clear() Dim wkdate As Date = MonthCalendar1.SelectionRange.Start While wkdate <= MonthCalendar1.SelectionRange.End DataGridView1.Columns.Add(wkdate.ToString("yyyy/MM/dd"), wkdate.ToString("MM/dd")) wkdate = wkdate.AddDays(1) End While でいけますけど、DBの内容を設定するのが、ちょっと面倒そうです。 他には、テーブル1があって、項目が以下のようだとします。 社員ID (KEY) 日付 (KEY) 勤務形態 で、動的にSQLをつくってあげて、むりやり(?)表示させる方法もあります。 Dim mdb As String = "C:\テスト.mdb" Dim dbcon As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=""" & mdb & """") dbcon.Open() Try Dim wkdate As Date = MonthCalendar1.SelectionRange.Start Dim sql As String sql = "SELECT テーブル1.社員ID" While wkdate <= MonthCalendar1.SelectionRange.End sql &= String.Format( _ ",MAX(IIF(テーブル1.日付=#{0:yyyy/MM/dd}#, テーブル1.勤務形態, '')) AS [{0:yyyy/MM/dd}]", wkdate) wkdate = wkdate.AddDays(1) End While sql &= " FROM テーブル1 " sql &= String.Format(" WHERE テーブル1.日付 BETWEEN #{0:yyyy/MM/dd}# AND #{1:yyyy/MM/dd}# ", _ MonthCalendar1.SelectionRange.Start, MonthCalendar1.SelectionRange.End) sql &= " GROUP BY テーブル1.社員ID" sql &= " ORDER BY テーブル1.社員ID" Dim dbadpt As New OleDb.OleDbDataAdapter(sql, dbcon) Dim ds As New DataSet dbadpt.Fill(ds) DataGridView1.DataSource = ds.Tables(0) Finally dbcon.Close() End Try あまりほめられたやり方ではないかもしれませんが…
お礼
回答ありがとうございます。 SQLを作って表示させる、というコードをコピーしてデバッグしてみたのですが、後半部分の Dim dbadpt As New OleDb.OleDbDataAdapter(sql, dbcon) Dim ds As New DataSet dbadpt.Fill(ds) ←ここ! DataGridView1.DataSource = ds.Tables(0) Finally dbcon.Close() End Try ←ここ!の部分でエラーになり、「集計関数の一部として指定された式 '社員ID' を含んでいないクエリを実行しようとしました。」と表示されます。実際のテーブルには他にも項目があるのですが、それが原因でしょうか?
お礼
この度もわかりやすい回答をいただきましてありがとうございました。 おかげさまで、きちんと動作させることができました。 SQL文の書き方は、スペースの位置でエラーになることがあるんですね。 大変勉強になりました。 まだ試行錯誤しつつ勉強中ですので、また質問を見かけた際にはどうぞよろしくお願いします。 この度は本当にありがとうございました。