2009/04/16

[C#]エクセルの列名のようなアルファベットを返す関数

このエントリーをはてなブックマークに追加
エクセルの列名のように、A、B、C、D…で二順目以降はAA、AB、AC…、BA、BB、BC…と続くような関数がほしかったので書いてみました。文字コードをぐるぐる回しているだけです。ちょこっといじれば小文字にできますね。
private string GetColumnName(int index) {
    string str = "";
    do {
        str = Convert.ToChar(index % 26 + 0x41) + str;
    } while ((index = index / 26 - 1) != -1);

    return str;
}

2009/04/07

C#Dictionary<K,V>はXmlにシリアライズできない

このエントリーをはてなブックマークに追加
XmlSerializerというのがあって、クラスを丸ごとXMLにしてしまう強引なやつです。
シリアライズしたXMLをファイル化しておくだけでクラスのプロパティがそのまま保持できるので、設定パラメータなんか専用クラスを作っといて設定の保存/復元とか作るのがものすごく便利。

ただし、List<T>なんてそのままで何も考えなくてもよかったんだけど、Dictionary<K,V>はそうはいかない模様。
派生クラスを作って、IXmlSerializableのReadXmlとWriteXmlを実装しないとダメなんだってさ。
飛んでみて初めて知りました。難儀だなー。面倒だからList<T>に変えちゃえ、と一時しのぎが始まるわけ。

2009/04/02

C#CSVを扱う

このエントリーをはてなブックマークに追加
CSVを扱うのに、以前は自作関数を使ったりしてましたが、C#2.0以降、TextFieldParserというクラスを使用するとものすごいお手軽に実装できます。
以下は、CSVをDataTableとして扱う関数。


//using Microsoft.VisualBasic.FileIO;
public DataTable LoadCsv(string csvFile) {
DataTable dt = new DataTable();
TextFieldParser parser = new TextFieldParser(csvFile);
using (parser) {
parser.TextFieldType = FieldType.Delimited; // FixedWidthを指定すると固定長のcsvを扱える
parser.SetDelimiters(","); // 区切り文字はカンマ

string[] fields = parser.ReadFields(); // 1行目読み込み
foreach (string column in fields) {
dt.Columns.Add(column); // 1行目を列名とする
}

while (!parser.EndOfData) {
dt.Rows.Add(parser.ReadFields()); // 2行目以降
}
}
return dt;
}

お手軽で、重宝してたんだけど…。
CSVの文字列は通常ダブルコーテーション(")で囲まれてます。ダブルコーテーションで囲まれてる文字のなかでは改行やタブスペースなど使い放題なのですが、二つ以上続く改行をTextFieldParserが勝手に一つにまとめてしまうという現象を確認しました。改行全角スペース改行とかしても、まとめられます。意味はともかく、呼び出し先で意図的にやってるとしか思えませんので、ご注意ください。
Microsoft.VisualBasic.FileIO内にあるくらいだから、やっぱり異端なのでしょうか。