いよいよ、CSV分割ツールの解説に入りたいと思います。
今回は、全ソースの掲載と、ファイル選択ダイアログ、フォルダ選択ダイアログを表示する方法に関する部分です。
全体のソースコード
全体のソースコードは以下の通りです。
今は中身が理解できないと思いますので、ここでは全体の雰囲気を把握するという意味で、軽く目をとおしていただければ結構です。
Visual Studio 2019 のプロジェクトファイル一式は、下記からダウンロードできますので、入力が面倒という方はご利用ください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
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.IO; namespace CsvDivider { public partial class MainForm : Form { /// <summary> /// コンストラクタ /// </summary> public MainForm() { InitializeComponent(); } /// <summary> /// 分割実行ボタンのクリックイベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UxExecDivide_Click(object sender, EventArgs e) { //ヘッダ行数を取得する。数値変換できなかったら0を代入 if (int.TryParse(uxHeaderCount.Text, out int head_cnt) == false) { head_cnt = 0; } //ヘッダ格納用変数の確保 string[] headers = new string[head_cnt]; //CSVファイルの読み込み List<string> lines = File.ReadAllLines(uxCsvFile.Text,Encoding.GetEncoding("shift-jis")).ToList(); //ヘッダー行を別変数にコピー for(int i = 0;i < head_cnt; i ++) { headers[i] = lines[i]; } //読み込んだCSVからヘッダー行数だけ削除 for (int i = 0; i < head_cnt; i++) { lines.RemoveAt(0); //先頭行を削除 } //分割行数の取得する。数値に変換できなければ0を代入 if (int.TryParse(uxDivideCount.Text, out int divid_cnt) == false) { divid_cnt = 0; } //分割保存関数の呼び出し DivideSave(uxOutputFolder.Text, uxCsvFile.Text, headers, lines, divid_cnt); } /// <summary> /// 指定行数で分割しながらファイル出力 /// </summary> /// <param name="Folder">出力先フォルダ名</param> /// <param name="fileName">CSVファイル名</param> /// <param name="headers">CSVヘッダ</param> /// <param name="lines">CSVデータ</param> /// <param name="divideCnt"></param> private void DivideSave(string Folder,string fileName,string[] headers,List<string> lines,int divideCnt) { //拡張子を除いたファイル名を取得 string name = Path.GetFileNameWithoutExtension(fileName); //ファイル名から拡張子のみを取得 string ext = Path.GetExtension(fileName); //出力パス(フォルダ名+ファイル名+連番+拡張子)のテンプレートを作成 string template = Path.Combine(Folder, name + "{0}" + ext); int cnt = 0; //行数カウント変数 int file_no = 0; //ファイル連番 List<string> buff = new List<string>(); //一時保存用LIST変数 //全ての行数をループ処理 foreach (string line in lines) { //一時保存用LIST変数に行を追加 buff.Add(line); //行数カウントに1を加算 cnt++; //行数カウント変数が分割行数を超えていないかチェック if (divideCnt <= cnt) { //先頭にヘッダを挿入 buff.InsertRange(0, headers); //出力ファイル名を作成 string path = string.Format(template, file_no); //ファイル保存 File.WriteAllLines(path, buff.ToArray(), Encoding.GetEncoding("shift-jis")); //行数カウント変数をクリア cnt = 0; //ファイル連番に1を加算 file_no++; //一時保存用LIST変数をクリア buff.Clear(); } } //ファイル保存されていないデータがあるかチェック if(cnt > 0) { //先頭にヘッダを挿入 buff.InsertRange(0, headers); //出力ファイル名を作成 string path = string.Format(template, file_no); //ファイル保存 File.WriteAllLines(path, buff.ToArray(), Encoding.GetEncoding("shift-jis")); } } /// <summary> /// CSVファイル選択ボタンのクリックイベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UxSelectFile_Click(object sender, EventArgs e) { //ファイルオープンダイアログのインスタンスを生成 OpenFileDialog dialog = new OpenFileDialog(); //ファイルオープンダイアログのファイル名に画面項目の値を代入 dialog.FileName = uxCsvFile.Text; //ファイルオープンダイアログの表示と戻り値のチェック if(dialog.ShowDialog() == DialogResult.OK) { //ファイルオープンダイアログで指定したファイル名を画面項目に表示 uxCsvFile.Text = dialog.FileName; } } /// <summary> /// 出力フォルダ選択ボタンのクリックイベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UxSelectFolder_Click(object sender, EventArgs e) { //フォルダ選択ダイアログのインスタンスを生成 FolderBrowserDialog folder = new FolderBrowserDialog(); //フォルダ選択ダイアログの選択フォルダに画面項目の値を代入 folder.SelectedPath = uxOutputFolder.Text; //フォルダ選択ダイアログの表示と戻り値のチェック if(folder.ShowDialog() == DialogResult.OK) { //フォルダ選択ダイアログで選択したフォルダを画面項目に表示 uxOutputFolder.Text = folder.SelectedPath; } } } } |
分割実行ボタンの処理は少し大きめなので次回に説明するとして、今回はダイアログの表示について説明していきます。
ダイアログの表示
今回使うダイアログは、ファイル選択とフォルダ選択の2種類です。
ファイルを選択する場合は OpenFileDialogクラスを、フォルダを選択する場合は FolderBrowserDialogクラスを使います。
ダイアログを使うには、あらかじめインスタンスを生成しておく必要がありますが、その方法としてVisual Studioのレイアウトエディタからドラッグ&ドロップする方法と、ソースコード上で直接インスタンスを生成する方法の2通りが存在します。
今回はソースコード上で直接インスタンスを生成することにしました。
ダイアログについて詳しくお知りになりたい方は、こちらをご覧ください。
ダイアログでユーザーが何かを選択し、決定ボタンをクリックした際、戻り値とプロパティに結果が反映されます。
戻り値は押されたボタンの種類が、プロパティには選択された値が格納されますので、それを利用します。
下記はCSV選択ボタンのイベントハンドラです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
private void UxSelectFile_Click(object sender, EventArgs e) { //ファイルオープンダイアログのインスタンスを生成 OpenFileDialog dialog = new OpenFileDialog(); //ファイルオープンダイアログのファイル名に画面項目の値を代入 dialog.FileName = uxCsvFile.Text; //ファイルオープンダイアログの表示と戻り値のチェック if(dialog.ShowDialog() == DialogResult.OK) { //ファイルオープンダイアログで指定したファイル名を画面項目に表示 uxCsvFile.Text = dialog.FileName; } } |
ダイアログのインスタンスを生成し、ShowDialog メソッドでダイアログを表示します。
ダイアログで何らかのボタンが押された場合、その結果が DialogResult 列挙型として返されますので、OKボタンが押されたことを確認しています。
ファイルオープンダイアログで選択された値は、FileNameというプロパティに格納されていますので、OKボタンが押されていたら uxCsvFile という名前を付けたTextBoxに、選択されたファイル名を代入しています。
ちなみに、インスタンスを生成した直後に
1 |
dialog.FileName = uxCsvFile.Text; |
という処理を行っていますが、これはダイアログを表示する前に、 uxCsvFile の内容をダイアログのFileNameプロパティに代入することで、そのファイルが選択された状態を作り出しています。
こうすることで、ダイアログを開いた際、そのファイルがあるフォルダから選択できるようになります。
また、フォルダ選択ダイアログのイベントハンドラも、ファイルオープンダイアログと同様の処理を行っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
private void UxSelectFolder_Click(object sender, EventArgs e) { //フォルダ選択ダイアログのインスタンスを生成 FolderBrowserDialog folder = new FolderBrowserDialog(); //フォルダ選択ダイアログの選択フォルダに画面項目の値を代入 folder.SelectedPath = uxOutputFolder.Text; //フォルダ選択ダイアログの表示と戻り値のチェック if(folder.ShowDialog() == DialogResult.OK) { //フォルダ選択ダイアログで選択したフォルダを画面項目に表示 uxOutputFolder.Text = folder.SelectedPath; } } |
まとめ
いいかがでしたでしょうか。
今回はダイアログの表示と値の取得部分についての解説を行いました。
次回は、分割実行ボタンのクリックイベントについて解説したいと思います。