2009/06/08(Mon) 16:00:51 編集(投稿者)
■No36860 (魔界の仮面弁士 さん) に返信
> ■No36852 (hito さん) に返信
> ここは、jin さんが投稿されたスレッドのはずですが。。。
> とりあえずは、文脈から同一人物と仮定しておきますね。
すみません、同一人物です。
元々、jinという名に統一しようと注意していたのですが、
間違えて昔の名を使用してしまいました。
混乱させてしまい申し訳ありません。
>>以下のようなソースを書いてみたところ、うまく書き込むことができました。
>>'ループでDataGridViewの指定した範囲の値を書き込む
> あれ? DataGridView ではなく、DataTable ですよね。
以前書いていたDataGridViewの書き込みを元に書いていたので、
その時のメッセージだけが残ったままでした。
> また、この部分での If 文は不要なはずです。外しておいた方がよいでしょう。というのも、
> 最初の発言で、『ちなみにテーブルデータは10列までのなので』と書いておられましたよね。
> ループ中の colIndex の最大値というのは、For ループの To 句で指定されていますから、
> この場合の colIndex 変数は 必ず 0〜10 という範囲をとります。11 以上にはなりません。
>
> もし、DataTable の列数がもっと多くて、その場合でも最大 10 列までしか
> 出力したくないのだとしても、ループ内で If 判定させる必要はなく、
> For colIndex As Integer = 0 To 10
> あるいは、
> For colIndex As Integer = 0 To Math.Min(10, dt.Columns.Count - 1)
> のようにしておくだけで済むかと思います。
For colIndex As Integer = 0 To 10
の書き方でIf句を用いずに書き込めました。
考えてみれば、自分で列数を知っているのだから、
こういう指定の仕方も出来たんですよね、
今までのソースを元にしてたりして、
要領のいい書き方というものを
考えておりませんでした・・・。
>>ループ処理内で、dtRowの変数に、SQLで取得したデータを格納するという仕様にしたところ、
> 考え方は良いと思いますが、dtRow を取得する場所が適切では無いようです。
> 行位置は、外側のループ時点では変化しないので、内側のループで毎回取得しなおすのは
> 意味がありません。この場合には dtRow の取得位置を
>
> For rowIndex As Integer = 0 To dt.Rows.Count - 1
> dtRow = dt.Rows(rowIndex) '本来あるべき位置
> For colIndex As Integer = 0 To dt.Columns.Count - 1
> 'dtRow = dt.Rows(rowIndex) '元の位置
> :
> :
> Next
> Next
>
> のようにした方が良いでしょう。
For rowIndex As Integer = 0 To dt.Rows.Count - 1
dtRow = dt.Rows(rowIndex)
For colIndex As Integer = 0 To 10
という書き方にしたところ、無事うまくいきました。
ありがとうございます。
> ついでに、No36846 の「二次元配列」を使った方法を紹介しておきます。
> jin さん(hito さん?)の方法は、データを 1 つずつ置いていくので、コードが分かりやすいのが
> メリットですが、たとえばデータが 1000 件あると、おそらくは出力完了までに
> 数十秒かかってしまうかと思います。
>
> 配列を使って一度に渡すと、Value プロパティへの書き込みが一度で済むので、
> 1000 件のデータでも一瞬で表示させることができます。
>
>
> Dim values(dt.Rows.Count, dt.Columns.Count) As Object
>
> ' No36843 で、「項目名(列名)を先頭に書き込みたい」と書かれていたので…。
> For Each col As DataColumn In dt.Columns
> values(0, col.Ordinal) = col.ColumnName
> Next
>
> '1行目からはデータ
> For rowIndex As Integer = 1 To dt.Rows.Count
> Dim dtRow As DataRow = dt.Rows(rowIndex - 1)
> For colIndex As Integer = 0 To dt.Columns.Count - 1
> values(rowIndex, colIndex) = dtRow(colIndex)
> Next
> Next
>
> '出力先となるセル範囲を 変数 rng に取得
> Dim cells As Excel.Range = xlSheet.Cells
> Dim rngEnd As Excel.Range = cells(dt.Rows.Count, dt.Columns.Count - 1)
> Dim rng As Excel.Range = xlSheet.Range("$A$1:" & rngEnd.Address)
> MRComObject(rngEnd)
>
> '★複数データを、2次元配列で一度に渡す★
> rng.Value = values 'Excel へデータを渡す回数が、この1回だけで済む。
>
> '後始末
> MRComObject(rng)
> MRComObject(cells)
ここまで分かりやすい説明をしていただいて、本当に感謝です。
今回の質問と同じような仕様をいくつか作成する予定ですので、今回ご教授していただいた内容を
活かしたソースを書こうと思います。
ありがとうございます。