DOBON.NET DOBON.NETプログラミング掲示板過去ログ

XMLデータで、2項目を書式化した値を、DataGridViewの1列に表示したい

環境/言語:[(WindowsXP,C#, Framework2.0]
分類:[.NET]

いつもお世話になっております。
XMLデータで、分からない点があり、ご教授ください。

今、開発しているシステムは、DBを使用しておらず
データはすべてXMLファイルで保存しております。

そして、XMLから読み込んだデータを、DataGridView に表示するため
DataGridView の DataSource に DataTable/DataView を設定するのですが
XMLでは分割されている2項目のデータを、1列に表示したい箇所があります。

↓このテーブルで言いますと、testテーブルのcolumn1とcolumn2を組み合わせたデータ
"column1 - column2"形式のデータを、DataGridView の1列に表示したい。

<test>
<column1>1</column1>
<column2>2</column2>
</test>
<test>
<column1>1</column1>
<column2>3</column2>
</test>
<test>
<column1>1</column1>
<column2>4</column2>
</test>



(DataGridViewの列)
---------------------
1 - 2
1 - 3
1 - 4


そこで、testテーブルに、結合データ保存用の列(custom_column)を内部で追加し、testのレコード件数分
ループさせ、custom_columnに、column1とcolumn2を書式化した値を放り込み
DataGridView の対象列のDataPropertyNameを"custom_column"に設定し、1列に表示しております。
しかし、testのレコード件数が増える程、当たり前なのですが時間が掛かり、効率的とはいえません。

SQLの一括更新のように、一括でcustom_columnに値を更新できる方法、
または、もっと良い方法はありますでしょうか?

何か不明な点や、説明不足な点がございましたら、ご指摘願います。
宜しくお願い致します。
■No23124に返信(yamaneさんの記事)
> しかし、testのレコード件数が増える程、当たり前なのですが時間が掛かり、効率的とはいえません。
どのように確認したのでしょうか?
メモリ上での文字列編集なら数万件程度あっても0.3秒以内だと思います。
実際のデータ件数と処理時間、理想とする処理時間の具体的な数値を教えてください。
るしぇ様

返信有難うございます。
申し訳ございません。質問上、1項目だけの結合にしておりましたが
実際は、結合したい項目が最も多いテーブルで20項目あります。

テストで行ったレコード件数は350件、結合項目20で、3秒掛かりました。
項目を入れる際に、文字列型への変換や書式化を行っておりますので
それも若干時間を取る要因になっていると思います。
るしぇ様のご指摘通り、さほど時間は掛からないと自分も思っておりましたので
予想外に掛かっており、その変換部辺りも見直してみます。

時間計測は、対象テーブルのレコード毎ループ開始前と後で、計っております。

実データは最大4000件になります。
全データの表示で3秒ならば、まだ許容範囲なのですが
単純に計算して、(4000/350) × 3 = 30秒以上は、さすがに掛かりすぎであると・・。
■No23128に返信(yamaneさんの記事)
>実際は、結合したい項目が最も多いテーブルで20項目あります。
それでもおかしいでしょう?極論を言えば
  Dim Tmp As String
  For i As Integer = 0 To (4000 * 20)
    Tmp = i.ToString("0000000") & ":" & i.ToString("0000000")
  Next
で30秒掛かるくらいの話?

実際にこちらの環境で計測した処理時間は0.2秒
DataTableに格納しても0.5秒で終わりました。

結合するデータの取得方法に問題はないですか?
XML からデータを取り出すのに毎回キーで検索してるとかじゃ
ないよね?
るしぇ様

何度も有難うございます。
ご提示頂きましたコードで試した結果は、1秒も掛かりませんでした。
別のプロジェクトを立ち上げて、下記コードを試してみましたところ
これも1秒以下でした・・・。

DataTable dt = new DataTable( );

// 列追加
for ( int i = 1; i <= 20; i++ ) {
dt.Columns.Add( string.Format( "X{0:00}", i ), typeof( string ) ) ;
dt.Columns.Add( string.Format( "Y{0:00}", i ), typeof( string ) ) ;
}



// テストデータ4000件追加
int buf = 0;
for ( int i = 1; i <= 4000; i++ ) {
List<object> data = new List<object>();
for ( int j = buf; j < buf + 40; j++ ) {
data.Add( j.ToString( ) );
}
dt.Rows.Add( (object[])data.ToArray( ) );
buf += 40;
}

// 書式化した値を格納する列を追加
for ( int i = 1; i <= 20; i++ ) {
dt.Columns.Add( string.Format( "Custom{0:00}", i ), typeof( string ) ) ;
}

// タイムカウントスタート

for ( int i = 0; i < dt.Rows.Count; i++ ) {
DataRow dr = dt.Rows[ i ];
dr[ "Custom01" ] = this.FormatData( dr[ "X01" ], dr[ "Y01" ] );
dr[ "Custom02" ] = this.FormatData( dr[ "X02" ], dr[ "Y02" ] );
dr[ "Custom03" ] = this.FormatData( dr[ "X03" ], dr[ "Y03" ] );
・・・・
dr[ "Custom20" ] = this.FormatData( dr[ "X20" ], dr[ "Y20" ] );
}

// タイムカウントエンド

// 書式化した文字列を取得する
private string FormatData( object _obj1, object _obj2 )
{
return string.Format( "{0}-{1}",
Convert.ToInt32( _obj1 ), Convert.ToInt32( _obj2 ) );
}


時間が掛かるコードとの大きな違いは、テーブルの構成だけです。

dtに、プライマリキーを追加した結果、2秒程度掛かるようになりました。
dt.PrimaryKey = new DataColumn[]{ dt.Columns[ 0 ], dt.Columns[ 1 ] };

それでも、開発中システムより、ずいぶんと早く許容範囲なのですが・・・。
他の何が関係しているのか、もう少し調べてみます。

DOBON.NET | プログラミング道 | プログラミング掲示板