質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

4回答

894閲覧

日付でグループ化されたクエリを、さらに項目別にグループ化したい

sheephuman

総合スコア112

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

1グッド

0クリップ

投稿2018/08/14 07:18

編集2018/08/14 12:56

質問の内容がこれであっているのかどうか疑わしいのですが。
以下のようなCSVデータを使うものとします。

1459,食費,8月6日,さば、豚切り落とし他
970,食費,8月9日,とまと、枝豆
86,娯楽,8月14日,マンガレンタル
324,雑貨,8月14日,ボタン電池、漬物  100円ショップ
172,娯楽,8月14日,中古マンガ
216,食費,8月14日,炭酸水
705,食費,8月14日,
669,食費,8月8日,
172,娯楽,8月8日,マンガレンタル
206,食費,8月8日,
268,食費,8月8日,コンビニ

コードはoledbを使い、以下のようになります。

System.Data.OleDb 名前空間

ソースコードを実行可能なものに書き直します。失礼しました。
それと、プロジェクトファイルを添付しておきます。

https://box.yahoo.co.jp/guest/viewer?sid=box-l-jjsgnkx53gwi3lt2r7nmvpbfvm-1001&uniqid=71f9a0e5-71d4-426e-97d7-215d6b9c3997&viewtype=detail

C#

1 using System; 2using System.Data.OleDb; 3using System.Data; 4using System.IO; 5using System.Windows.Forms; 6 7 8namespace WindowsFormsApp4 9{ 10 public partial class Form1 : Form 11 { 12 public Form1() 13 { 14 InitializeComponent(); 15 } 16 17 private void Form1_Load(object sender, EventArgs e) 18 { 19 20 CSV_to_chart("2018年8月.csv"); 21 } 22 23 private void CSV_to_chart(string ReadFile) 24 { 25 26 27 28 chart1.Series.Clear(); 29 chart1.Series.Add("合計"); 30 31 32 33 34 35 36 37 try 38 { 39 string current = Directory.GetCurrentDirectory(); 40 41 // Full path to the data source file 42 43 string file = ReadFile; 44 string path = current + "\Data\"; 45             //実行ファイル直下に「Data」ファルダを作る          46 47 // Create a connection string. 48 string ConStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + 49 path + ";Extended Properties=\"Text;HDR=No;FMT=Delimited\""; 50 OleDbConnection myConnection = new OleDbConnection(ConStr); 51 52 53 54 string mySelectQuery = ""; 55 56 57 58 mySelectQuery = "SELECT F3, F2, Sum(F1) FROM " + "\" + "[" + file + "]" + " Group by f3, f2 Order by Format(F3,'MMDD'), F2"; 59 //+、-スペース入りファイル名も使えるようにする 60 61 62 63 chart1.Series[0].Label = "#VAL{C}"; 64 //Chartに価格ラベルを表示する 65 66 67 68 OleDbCommand myCommand = new OleDbCommand(mySelectQuery, myConnection); 69 // Open the connection and create the reader 70 myCommand.Connection.Open(); 71 OleDbDataReader myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection); 72 73 74 chart1.ChartAreas[0].InnerPlotPosition.Width = 90; 75 chart1.ChartAreas[0].InnerPlotPosition.Height = 90; 76 chart1.ChartAreas[0].InnerPlotPosition.X = 8; 77 chart1.ChartAreas[0].InnerPlotPosition.Y = 0; 78 79 80 chart1.ChartAreas[0].IsSameFontSizeForAllAxes = true; 81 82 83 chart1.Series[0].Points.DataBindXY(myReader, "0", myReader, "1"); 84 85 myReader.Close(); 86 myConnection.Close(); 87 88 89 } 90 catch (OleDbException OleEx) 91 { //Console.WriteLine(OleEx.ToString()); 92 93 MessageBox.Show(OleEx.Message); 94 } 95 } 96 } 97} 98

表示は以下のようになります。
以上をこのように日付でグループ化しています。

 イメージ説明

 また、クエリを変えることで、項目毎に集計も出来ました。

mySelectQuery = "SELECT F2,Sum(F1) FROM " + "\" + "[" + file + "]" + " Group by F2";

 イメージ説明

 今のところここまでが限界で、
日時
┗項目

のように集計出来るのが理想なんです。
サブクエリというのがあると知り、打ち込んでみましたが、例外を吐くばかりで上手くいきません。

適切なクエリの書き方を教えていただけると助かります。

 念のために
イメージ説明
このように表示させるようなクエリがあれば書きたいということです。

 回答いただいたコードの結果
mySelectQuery = "SELECT F3, F2, Sum(F1) FROM " + "" +"[" + file+"]" + " Group by f3, f2 Order by Format(F3,'MMDD'), F2";

イメージ説明

 ちなみに 自分が試したのは
```ここに言語を入力
mySelectQuery = "SELECT F3, F2, Sum(F1) FROM " + "" +"[" + file+"]" + " Group by f3, f2 Order by Format(F3,'MMDD')"でした。

 他のもの   //mySelectQuery = "SELECT *,Sum(F1) FROM " + "\" + file + " WHERE F2 = (SELECT F2 FROM " + "\" + file + ")";    意味がよくわかってないと思います。  0. さらに試したこと  Quitaの記事からの流用になります。    [【C#】CSV、Excelファイルの内容をDataTableに格納する](https://qiita.com/OneK/items/c3077aea595635f40ee5)     ``` public static DataTable GetDataTableFromCSV(String strFilePath, Boolean isInHeader = true) { dt = new DataTable(); String strInHeader = isInHeader ? "YES" : "NO"; // ヘッダー設定 String strCon = "Provider=Microsoft.ACE.OLEDB.12.0;" // プロバイダ設定 //= "Provider=Microsoft.Jet.OLEDB.4.0;" // Jetでやる場合 + "Data Source=" + Path.GetDirectoryName(strFilePath) + "\; " // ソースファイル指定 + "Extended Properties=\"Text;HDR=" + strInHeader + ";FMT=Delimited\""; OleDbConnection con = new OleDbConnection(strCon); String strCmd = "SELECT * FROM [" + Path.GetFileName(strFilePath) + "]"; // 読み込み OleDbCommand cmd = new OleDbCommand(strCmd, con); OleDbDataAdapter adp = new OleDbDataAdapter(cmd); adp.Fill(dt); // ds.Tables.Add(dt); return dt; }

 さらに

 ```
private void CSV_to_chart(string ReadFile)
{

dt = GetDataTableFromCSV(current + "\2018年8月.csv", false); string[] seriesArray = dt.AsEnumerable().Select(r => r.Field<string>("F2")).Distinct().ToArray(); //"F2"を名前解決する処理 foreach (string s in seriesArray) { chart1.Series.Add(s); } mySelectQuery = "SELECT F3, F2, Sum(F1) FROM " + "\" + "[" + file + "]" + " Group by f3, f2 Order by Format(F3,'MMDD'), F2"; //グラフが表示されない

     

 // 以下略

このようにすることで以下の結果を得ました。  ![イメージ説明](419ecc86b190ba6c11943152c49be992.png)  系列が追加されていないので表示されないのかと思ったんですが、クエリ側との不一致があるのかやはり表示されませんでした。 参考までに自作の記事を添えておきます。 [C# DataTable to Chart Display(家計簿用サンプル) ](https://mojakouinfotaker.blog.fc2.com/blog-entry-1042.html)
milkteas👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2018/08/14 09:33

SQLでファイルに直接アクセスできているところを見るとDBはACCESSぽいですけど、タグを追加して明確にして下さい。
sheephuman

2018/08/14 09:36

ACCESSなんですね。分かりました。
sazi

2018/08/14 09:50

いやいや、それは私には分かりませんので、確認して下さい。
sheephuman

2018/08/14 10:00

一応追記しましたが、どのように確認取ればいいのか分かりませんでした。
退会済みユーザー

退会済みユーザー

2018/08/15 01:18

質問の主眼は (1) Chart に渡すためのデータの作り方、(2) Chart の操作の方法・・・のどっちなのでしょう? (2) であれば、Microsoft からサンプルが提供されていますが、それは持っていますか? すでに持っているなら余計なお世話かも知れませんけど、一応回答欄に紹介しておきます。
sheephuman

2018/08/15 02:11

(1) Chart に渡すためのデータの作り方 の方です。OLEDBに渡すSQLクエリという形で質問しましたが、分かりづらかったようで申し訳ありません。
退会済みユーザー

退会済みユーザー

2018/08/15 03:08

> (1) Chart に渡すためのデータの作り方 の方です。 ← 質問者さんのやりたいことを実現するには、PIVOT 関係演算子を利用して元データからクロス集計表を生成といった操作が必要になりそうですが、CSV + ADO.NET + JET では無理なような気がします。SQL Server は使えないのですか?
退会済みユーザー

退会済みユーザー

2018/08/15 03:30

ちなみに、PIVOT 関係演算子を利用してクロス集計の例はこのようなことです → http://surferonwww.info/BlogEngine/post/2010/08/07/Use-of-PIVOT.aspx この記事の Employee を質問者さんのデータの費目で考えると分かりやすいのではないかと思います。
退会済みユーザー

退会済みユーザー

2018/08/15 11:10

PIVOT 関係演算子を利用してクロス集計と書きましたが SUM 句を使ってできるかもしれません。ただし、CSV + ADO.NET + JET で可能かどうかは分かりませんが。SQL Server を使った場合の例を回答欄に書いておきます。
guest

回答4

0

ベストアンサー

質問へのコメント欄に、Chart のサンプルの紹介を回答欄に紹介しておきますと書きましたが、それを以下に書きます。

以下のページから Windows Forms アプリ用と ASP.NET Web Forms アプリ用のサンプルの両方をダウンロードできます。

Samples Environments for Microsoft Chart Controls
https://code.msdn.microsoft.com/mschart

Windows Forms 用のサンプルは上のページで[C# (5.6MB)]をクリックしてダウンロードしてください。完全な C# の Windows Forms アプリのソリューションが zip されています。

それを適当なフォルダに解凍して Visual Studio(.NET4 なので 2010 以降のバージョン)で開いて実行すれば、基本の解説、いろいろなタイプのサンプルのデモ、それを作るための C# および VB.NET サンプルコード等が満載のアプリが動くはずです。

解説が英語であるのを厭わなければこのサンプルは今後の開発に非常に有益なものになると思います。

このスレッドの質問者さんの問題がサンプルを見ると解決するかどうかは分かりませんが、解決のためのヒントはあるかもしれません。

解決できなくとも、今後の開発に役立つはずですので、ダウンロードして設定する手間をかけても損はないと思います。

一点だけ、以下の記事に書いた通りフォルダ名の問題があって変更が必要と思いますので注意してください。

Chart Samples
http://surferonwww.info/BlogEngine/post/2016/02/14/chart-samples.aspx

【追記】

質問に対する私のコメントで、

PIVOT 関係演算子を利用してクロス集計と書きましたが SUM 句を使ってできるかもしれません。ただし、CSV + ADO.NET + JET で可能かどうかは分かりませんが。SQL Server を使った場合の例を回答欄に書いておきます。

と書きましたが、それを以下に書いておきます。

以下の記事は積み上げ棒グラフ (SeriesChartType.StackedColumn) ですが、それを普通の棒グラフ (SeriesChartType.Column) にしたものが質問者さんが望む形のものになると思います。

[ASP.NET]チャート・コントロールで積み上げ棒グラフを作成するには?[3.5、C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/1004aspchartstack/aspchartstack.html

以下のコードで望む形になると思います。

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Data.SqlClient; using System.Windows.Forms.DataVisualization.Charting; namespace WindowsFormsChart { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private DataTable CreateDataTable() { string connString = @"Data Source=(local)\sqlexpress;Initial Catalog=Database;Integrated Security=True"; string selectQuery = @"SELECT Month, SUM(CASE WHEN Name = N'三吉' THEN Sales ELSE 0 END) AS 三吉, SUM(CASE WHEN Name = N'春日' THEN Sales ELSE 0 END) AS 春日, SUM(CASE WHEN Name = N'東雲' THEN Sales ELSE 0 END) AS 東雲, SUM(CASE WHEN Name = N'府中' THEN Sales ELSE 0 END) AS 府中, SUM(CASE WHEN Name = N'広島' THEN Sales ELSE 0 END) AS 広島 FROM Shop GROUP BY Month"; using (SqlConnection connection = new SqlConnection(connString)) { SqlDataAdapter adapter = new SqlDataAdapter(); adapter.SelectCommand = new SqlCommand(selectQuery, connection); DataTable table = new DataTable(); adapter.Fill(table); return table; } } private void Form2_Load(object sender, EventArgs e) { Chart chart = new Chart() { Name = "chart1", Width = 600, DataSource = CreateDataTable() }; this.Controls.Add(chart); Legend legend = new Legend() { DockedToChartArea = "ChartArea1", IsDockedInsideChartArea = false, Name = "Legend1" }; chart.Legends.Add(legend); Series series = new Series() { Name = "三吉", ChartType = SeriesChartType.Column, Legend = "Legend1", XValueMember = "Month", YValueMembers = "三吉" }; chart.Series.Add(series); series = new Series() { Name = "春日", ChartType = SeriesChartType.Column, Legend = "Legend1", XValueMember = "Month", YValueMembers = "春日" }; chart.Series.Add(series); series = new Series() { Name = "東雲", ChartType = SeriesChartType.Column, Legend = "Legend1", XValueMember = "Month", YValueMembers = "東雲" }; chart.Series.Add(series); series = new Series() { Name = "府中", ChartType = SeriesChartType.Column, Legend = "Legend1", XValueMember = "Month", YValueMembers = "府中" }; chart.Series.Add(series); series = new Series() { Name = "広島", ChartType = SeriesChartType.Column, Legend = "Legend1", XValueMember = "Month", YValueMembers = "広島" }; chart.Series.Add(series); ChartArea chartArea = new ChartArea() { Name = "ChartArea1", AxisY = new Axis() { Title = "売上高" }, AxisX = new Axis() { Title = "売上月" } }; chart.ChartAreas.Add(chartArea); } } }

イメージ説明

投稿2018/08/15 01:30

編集2018/08/15 11:22
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sheephuman

2018/08/15 02:13

ありがとうございます。このサンプルの存在は知っていましたが、量も多く複雑に思われ、それほど査読しておりませんでした。 この機会にじっくり読んでみようと思います。
sheephuman

2018/08/15 12:16

なるほど。試してみようと思います。 そろそろ閉め切ろうかと思った矢先の回答、ありがとうございました。 感謝します。
guest

0

このようなクエリでは要件は満たされますか?

SELECT F3, F2, Sum(F1) FROM " + "\" +"[" + file+"]" + " Group by f3, f2 Order by Format(F3,'MMDD'), F2

投稿2018/08/14 09:31

denzow

総合スコア640

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sheephuman

2018/08/14 09:35

実はそれを真っ先に試しました。忘れてました。 例外は出ないものの、グラフが出力されないという結果になりました。
sheephuman

2018/08/14 09:49

私見なのですが、MicroSoftのChartはどのサンプルでも複数系列を表示させる場合、DataBindするか、for文で回して一つずつSeriesをAddする形になるようです。 クエリが正しくても、Chart側で出力できない仕様なのではと思いました。
guest

0

【C#】Chartにデータバインドして、DataGridViewの内容を表示する

自作の記事です。
あれから自助努力を行いまして、集約するところまで仕上げる事が出来ました。
回答感謝です。

投稿2020/07/09 03:48

編集2020/07/09 03:50
sheephuman

総合スコア112

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

[Chart][Tips] コードから棒グラフを作成する

質問の画像がここからみつかりました。
質問を編集して画像の入手先を明らかにし、このページを参考に作ってください。

投稿2018/08/14 16:47

Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2018/08/15 02:51

返事がない。ただの○○のようだ。
sheephuman

2018/08/15 12:14

URLは載せていませんが、もちろん知っております。 この例ではデータバインディングを使用しており、SUM句で集計といった処理が入る余地がないように思われました。 この作例で集計する方法をご存知でしたら回答をお待ちしております。
Zuishin

2018/08/15 12:19

知っておりますとかじゃなく、画像借りたなら出典示さないとダメでしょ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問