わいえむねっと

Contents
Categories
Calendar
2026/08
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
Monthly Archives
~2000/01
Recent Entries
RSS1.0
Templates
Information
Processed: 0.093 sec
Chashed: -
2010/04/14 Wed
2時に寝て6時に目が覚めて9時まで仕事して、そろそろ仕事いくかと出社して。
なにかがおかしい。 rbindかと思っていたらbindだった上にrbindがなかった。 HTML→Excelのスペースの扱いについてちょと調べたのでメモ。

<table>
  <tr>
    <td>Narrow</td>
    <td><span>foo   bar</span></td>
    <td><span style="mso-spacerun:yes;">foo   bar</span></td>
  </tr>
  <tr>
    <td>Wide</td>
    <td><span>foo   bar</span></td>
    <td><span style="mso-spacerun:yes;">foo   bar</span></td>
  </tr>
  <tr>
    <td>NBSP</td>
    <td><span>foo&nbsp;&nbsp;&nbsp;bar</span></td>
    <td><span style="mso-spacerun:yes;">foo&nbsp;&nbsp;&nbsp;bar</span></td>
  </tr>
</table>



・mso-spacerun の値に関わらず、半角スペースはまとめられる
・mso-spacerun:yes; では、全角スペースが半角になる
・mso-spacerun:no; では、NBSP が 0x3F になる

Excel上の見た目では0x3Fでも問題ないのだけれど、他アプリケーションとの連携を考えると嬉しくない。
さりとて、全角スペースが半角にされてしまうのも嬉しくない。

ここでスペースを数値文字参照にすると、

<table>
  <tr>
    <td>Narrow</td>
    <td><span>foo&#x20;&#x20;&#x20;bar</span></td>
    <td><span style="mso-spacerun:yes;">foo&#x20;&#x20;&#x20;bar</span></td>
  </tr>
  <tr>
    <td>Wide</td>
    <td><span>foo&#x3000;&#x3000;&#x3000;bar</span></td>
    <td><span style="mso-spacerun:yes;">foo&#x3000;&#x3000;&#x3000;bar</span></td>
  </tr>
</table>



・全角スペースの扱いは同様
・半角スペースは数値文字参照にするとまとめられない

WEBブラウザの場合は数値文字参照であってもまとめられるはずだけど。ExcelはExcelだものということなのか。

というか、Excel→HTMLの場合は連続した半角スペースに対してのみ mso-spacerun を適用するようになっているので、そもそも mso-spacerun の適用範囲に全角スペースが含まれることがないわけであって HTML→Excelの場合もそうすべきだよねとかなんとか。
炭酸せんべいをかじりながら。
2010/04/13 Tue
ベータリリースのスケジュールが確定したので来週は波乱の予感。
まぁ、要件定義から設計、製造、試験およびサポートも含めてピンのプロジェクトなのでどうとでもしていきたい。 入力支援が強力だと生産性が上がった気になるけどそんなこともないんじゃないかと思う。 ここ数年で大量にでた退職者が集まって飲むという話を聞きつけたのでヒャッハー乱入だぜぇぇぇ!と思ったら、思いっきり定例会とバッティングしていたので、なる様にご相談。

飲み会のバッティングは飲む機会の損失であり、ひいては人生の損失であり、というかそんなことばかり言ったりやったり飲んだり飲んだりしているから前歯を損失したりするんだよこのバカと思ったり、今日もシキさんとネット飲み会したりなんだり。
2010/04/12 Mon
DataTable table1 = new DataTable();
table1.Columns.Add("A");
table1.Columns.Add("B");

DataTable table2 = new DataTable();
table2.Columns.Add("A");
table2.Columns.Add("B");

DataSet dataSet = new DataSet();
dataSet.Tables.Add(table1);
dataSet.Tables.Add(table2);

DataRelation relation1 = dataSet.Relations.Add(
    table1.Columns["A"], table2.Columns["A"]);
Debug.Print(dataSet.Relations.Count.ToString());
//1

table1.Rows.Add(1, "foo");
table2.Rows.Add(1, "bar");

Debug.Print(table1.Rows[0].GetChildRows(relation1)[0]["B"].ToString());
//bar

dataSet.Relations.Clear();
Debug.Print(dataSet.Relations.Count.ToString());
//0

try
{
    DataRow[] rows = table1.Rows[0].GetChildRows(relation1);
}
catch (Exception ex)
{
    Debug.Print(ex.Message);
    //この行は、このリレーションシップと同じ DataSet に属していません。
}

try
{
    table1.Clear();
}
catch (Exception ex)
{
    Debug.Print(ex.Message);
    //ForeignKeyConstraint Relation1 によって制約が実行され、Table2 に子行が存在するため、テーブル Table1 を消去できません。
}

table2.Clear();
table1.Clear();

DataRelation relation2 = dataSet.Relations.Add(
    table1.Columns["B"], table2.Columns["B"]);
Debug.Print(dataSet.Relations.Count.ToString());
//1

table1.Rows.Add(1, "foo");
try
{
    table2.Rows.Add(2, "foo");
}
catch (Exception ex)
{
    Debug.Print(ex.Message);
    //ForeignKeyConstraint Relation1 には親テーブルに存在している子キー値 (2) が必要です。
}
try
{
    table2.Rows.Add(1, "bar");
}
catch (Exception ex)
{
    Debug.Print(ex.Message);
    //ForeignKeyConstraint Constraint1 には親テーブルに存在している子キー値 (bar) が必要です。
}
table2.Rows.Add(1, "foo");

DataSet.Relations.Clear()はなんでこんな中途半端なの。

あげだま2袋と紅しょうが2袋を買って帰る。
あげだまはともかく、紅しょうがはほんともう業務用を買いたい。
2010/04/11 Sun
DataTableをFillした後に手動でAddする分のためにDataColumn.AutoIncrementを設定しているけどそれはなんかタイミング的に駄目な気がするよと思ったので検証。

DataTable table1 = new DataTable();
table1.Columns.Add();
table1.Columns[0].AutoIncrement = true;
table1.Rows.Add();
table1.Rows.Add();
table1.Rows.Add();
foreach (DataRow row in table1.Rows)
{
    Debug.Print(row[0].ToString());
}
//0
//1
//2
通常。

DataTable table2 = new DataTable();
table2.Columns.Add();
table2.Columns[0].AutoIncrement = true;
table2.Rows.Add(1);
table2.Rows.Add();
table2.Rows.Add();
foreach (DataRow row in table2.Rows)
{
    Debug.Print(row[0].ToString());
}
//1
//2
//3
事前に追加された値からインクリメント。

DataTable table3 = new DataTable();
table3.Columns.Add();
table3.Columns[0].AutoIncrement = true;
table3.Rows.Add(2);
table3.Rows.Add(1);
table3.Rows.Add();
foreach (DataRow row in table3.Rows)
{
    Debug.Print(row[0].ToString());
}
//2
//1
//3
事前に追加された最大の値からインクリメント。

DataTable table4 = new DataTable();
table4.Columns.Add();
table4.Rows.Add(1);
try
{
    table4.Columns[0].AutoIncrement = true;
}
catch (Exception ex)
{
    Debug.Print(ex.Message);
}
//'String' 型 の DataColumn AutoIncrement は、一度データが設定されたら変更できません。
数値型でないデータが保持されている場合、AutoIncrement設定不可。

DataTable table5 = new DataTable();
table5.Columns.Add();
Debug.Print(table5.Columns[0].DataType.ToString());
//System.String
table5.Columns[0].AutoIncrement = true;
Debug.Print(table5.Columns[0].DataType.ToString());
//System.Int32
AutoIncrement設定でDataColumn.DataTypeが変化。

DataTable table6 = new DataTable();
table6.Columns.Add();
table6.Columns[0].DataType = System.Type.GetType("System.Int32");
table6.Rows.Add(2);
table6.Columns[0].AutoIncrement = true;
table6.Rows.Add(1);
table6.Rows.Add();
foreach (DataRow row in table6.Rows)
{
    Debug.Print(row[0].ToString());
}
//2
//1
//2
AutoIncrementが設定されてから追加された最大の値からインクリメント。

DataTable table7 = new DataTable();
table7.Columns.Add();
table7.Columns[0].DataType = System.Type.GetType("System.Int32");
table7.Rows.Add(2);
table7.Columns[0].AutoIncrement = true;
table7.Columns[0].Unique = true;
table7.Rows.Add(1);
try
{
    table7.Rows.Add();
}
catch (Exception ex)
{
    Debug.Print(ex.Message);
}
//列 'Column1' は一意であるように制約されています。値 '2' は既に存在します。
AutoIncrementはただインクリメントするだけなので、Unique制約は考慮されない。

Fillする前に設定するか、Fillした後であればAutoIncrementSeedも設定するとか。
2010/04/10 Sat
・構造が同一の2つのDataTableが存在
・1対1のデータが格納
・一方をDataGridViewの表示に、一方をRowFilterとSortの条件に使用

しているコードがあって、ぼけと眺めてみたところ、

・2つのDataTableをマージ
・カラム名は重複を避けて識別子を付与
・識別子を適宜切り替えてアクセス

とかいうことをしていたので、マージとかせずにDataSetで管理できないのかなーと思ったので試してみる。
あと、DataViewのRowFilterとSortは即時反映のため、DataGridViewへの入力を確定した瞬間に行が消えたり移動したりするので、これもどうにかしたい。

とりあえず、RowFilterとSortから参照するためだけの管理列を追加してみる。

DataTable table1 = new DataTable();
table1.Columns.Add("A");
table1.Columns.Add("B");
table1.Columns.Add("Z");
table1.Rows.Add(1, "foo", 1);
table1.Rows.Add(2, "bar", 2);
table1.Rows.Add(3, "baz", 3);
table1.AcceptChanges();

DataTable table2 = new DataTable();
table2.Columns.Add("A");
table2.Columns.Add("B");
table2.Rows.Add(1, "FOO");
table2.Rows.Add(2, "BAR");
table2.Rows.Add(3, "BAZ");
table2.AcceptChanges();

DataSet dataSet = new DataSet();
dataSet.Tables.Add(table1);
dataSet.Tables.Add(table2);
dataSet.Relations.Add(new DataRelation("rel",
    table1.Columns["A"],
    table2.Columns["A"]));

DataView dataView = new DataView(
    table1, "Z > 0", "Z", DataViewRowState.CurrentRows);
//DataGridView.DataSource = dataView;
//DataGridView.Columns["Z"].Visible = false;

foreach (DataRowView rowView in dataView)
{
    Debug.Print(rowView.Row["B"].ToString() + " " +
        rowView.Row.RowState.ToString() + " " +
        rowView.Row.GetChildRows("rel")[0]["B"].ToString() + " " +
        rowView.Row.GetChildRows("rel")[0].RowState.ToString());
}
//foo Unchanged FOO Unchanged
//bar Unchanged BAR Unchanged
//baz Unchanged BAZ Unchanged

foreach (DataRow row in table1.Rows)
{
    row["Z"] = 0;
}
int i = 1;
foreach (DataRowView rowView in new DataView(
    table2, "B LIKE 'B*'", "B DESC", DataViewRowState.CurrentRows))
{
    rowView.Row.GetParentRow("rel")["Z"] = i;
    i++;
}

foreach (DataRowView rowView in dataView)
{
    Debug.Print(rowView.Row["B"].ToString() + " " +
        rowView.Row.RowState.ToString() + " " +
        rowView.Row.GetChildRows("rel")[0]["B"].ToString() + " " +
        rowView.Row.GetChildRows("rel")[0].RowState.ToString());
}
//baz Modified BAZ Unchanged
//bar Modified BAR Unchanged

RowFilterとSortの反映タイミングは列Zの更新タイミングで制御可能になったものの、親DataTableのRowStateが軒並みModifiedになってしまうので、DataGridView経由で編集されたかどうかが取得できなくなる。

だったらと、列Zを子側に押し付けて、DataColumn.Expression経由で参照してみる。

DataTable table1 = new DataTable();
table1.Columns.Add("A");
table1.Columns.Add("B");
table1.Rows.Add(1, "foo");
table1.Rows.Add(2, "bar");
table1.Rows.Add(3, "baz");
table1.AcceptChanges();

DataTable table2 = new DataTable();
table2.Columns.Add("A");
table2.Columns.Add("B");
table2.Columns.Add("Z", System.Type.GetType("System.Decimal"));
table2.Rows.Add(1, "FOO", 1);
table2.Rows.Add(2, "BAR", 2);
table2.Rows.Add(3, "BAZ", 3);
table2.AcceptChanges();

DataSet dataSet = new DataSet();
dataSet.Tables.Add(table1);
dataSet.Tables.Add(table2);
dataSet.Relations.Add(new DataRelation("rel",
    table1.Columns["A"],
    table2.Columns["A"]));

table1.Columns.Add("Y");
table1.Columns["Y"].Expression = "Min(Child.Z)";

DataView dataView = new DataView(
    table1, "Y > 0", "Y", DataViewRowState.CurrentRows);
//DataGridView.DataSource = dataView;
//DataGridView.Columns["Y"].Visible = false;

foreach (DataRowView rowView in dataView)
{
    Debug.Print(rowView.Row["B"].ToString() + " " +
        rowView.Row.RowState.ToString() + " " +
        rowView.Row.GetChildRows("rel")[0]["B"].ToString() + " " +
        rowView.Row.GetChildRows("rel")[0].RowState.ToString());
}
//foo Unchanged FOO Unchanged
//bar Unchanged BAR Unchanged
//baz Unchanged BAZ Unchanged

foreach (DataRow row in table2.Rows)
{
    row["Z"] = 0;
}
int i = 1;
foreach (DataRowView rowView in new DataView(
    table2, "B LIKE 'B*'", "B DESC", DataViewRowState.CurrentRows))
{
    rowView.Row["Z"] = i;
    i++;
}

foreach (DataRowView rowView in dataView)
{
    Debug.Print(rowView.Row["B"].ToString() + " " +
        rowView.Row.RowState.ToString() + " " +
        rowView.Row.GetChildRows("rel")[0]["B"].ToString() + " " +
        rowView.Row.GetChildRows("rel")[0].RowState.ToString());
}
//baz Unchanged BAZ Modified
//bar Unchanged BAR Modified

Modifiedにはならないけれど、余計な列がさらに増えたり、Expressionの中身がどうにも直感的にならなかったり。
ままならない。
2010/04/09 Fri
うちの取締役に会いにきていた協力会社のシャチョさんが人の顔を見るなり
「ちゃんとやってるか!」と言ってきたので
「やってますよ!」と答えたら
「飲みながらやってるか!」と言ってきたので
「飲みながらはやってませんよ!昨日さんざん飲んだので!」と答える。

今日も元気。
2010/04/08 Thu
前歯の先がなんか変な気がするんですけど、もしかして欠けた?
つくりなおしたほうがいいんだろうか。
ええ。差し歯のほうですよ。

あれからもう2年半になるのか…
2010/04/07 Wed
体調がよろしくないからと22時に寝たら2時に目が覚めた。
ままならない。

寝ている間に一昨日とりあえずで実装した箇所のパフォーマンス改善案が思い付いていたりしたので、その検証をしたりとか。 いけそうなので適用してみたら、パフォーマンスがはげるほど改善しました。
そしてそれ以上に精神衛生上大変よろしいコードになりました。睡眠て大事!
この場合、なにか違うような気がするけどそれはそれだよ!

あとは昨日湯船につかりながらぼけと考えたクラス再設計を適用する作業を日がな一日。
体調は依然としてよろしくない。
まぁ、今日は仕事はかどったからいいかーと焼酎を一杯飲んで。二杯飲んで。三杯飲んで。
一息ついてコーヒー飲んで。

キリンビバレッジ キリン ファイア ブラック ディープボディ
http://www.bevera​ge.co.jp/product/coffee/black_db.h​tml

ブラックでロング缶て珍しいやね。
2010/04/06 Tue
Excelへのエクスポート時にたまに書式が失われているセルがある気がすると思ったら、数値は部分書式を受け付けないんだった。
保持するには表示形式を文字列にするくらいしかないか?うーん。

<table>
  <tr>
    <td><strike>foofoofoo</strike></td>
    <td><strike>123456789</strike></td>
  </tr>
  <tr>
    <td>foo<strike>foo</strike>foo</td>
    <td>123<strike>456</strike>789</td>
  <tr>
    <td style="mso-number-format:\@">foo<strike>foo</strike>foo</td>
    <td style="mso-number-format:\@">123<strike>456</strike>789</td>
  </tr>
</table>

2010/04/05 Mon
昨日はエアコンをかけてダウンジャケットを着込んだ上でまだ寒くて、なんだよこの気候は!室内なのに!と思っていたらどうも単に自分が衰弱していただけっぽかったりしましたが今日はすこぶる快調でした。
朝ご飯も食べたし総務のおばちゃんにもらったクッキーもサクサク食べてた!

というか、なんで今日はこんなにおなかすいてるんだと思ったら、そういえば昨日はろくなもの食べてなかったような気がしたのでもう少しなんというか生き方をなんとかしたほうがいいんじゃないのかと思ったり思わなかったり残件の実装をしたり不具合を修正したりして一日が終わるのでした。 今日から青海苔ではなく青さ粉ですよー。