tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルエクセル間でで値だけのコピー
記事No6708
投稿日: 2007/12/22(Sat) 18:37
投稿者
いつもお世話になります。Kと申します。

環境:WinXP+SP2 VB.net2003 Excel2003+SP3 Access2003+SP3

データベースからVB上のDataGridにデータを取り込み、
それをエクセルで作成された雛型ファイルにデータを書き込むのですが
エクセルの雛型ファイルに直接Range.Valueで書き込むと時間がかかります。
(3000件強のレコード数で1時間以上かかる)
そこで、一旦CSVファイルに書き出し、CSVファイルとエクセルの雛型ファイルを開き
範囲指定でコピーしようとしました。
色々調べて、xlPasteValuesが値のみのコピーだと思い、下記のようにやってみましたが
書式設定までコピーしてしまっています。
値だけをコピーして、書式設定は雛型ファイルで設定しているのを使いたいのです。

csSheetがCSVファイル、xlSheetがエクセルの雛型ファイル
'CSVファイルのデータを雛型エクセルファイルへコピー
csSheet.Range(csSheet.Cells(1, 1), csSheet.Cells(65000, 34)).Copy()
xlSheet.Range(xlSheet.Cells(11, 1), xlSheet.Cells(11, 34)).PasteSpecial(Excel.XlPasteType.xlPasteValues)

2つのエクセルファイル間で、値のみのコピーはできないものなんでしょうか?
どなたか、サンプルや手法をご存知の方がおられましたら、ご教授いただけないでしょうか?

よろしくお願いいたします。

[ツリー表示へ]
タイトルRe: エクセル間でで値だけのコピー
記事No6709
投稿日: 2007/12/23(Sun) 08:58
投稿者花ちゃん
> データベースからVB上のDataGridにデータを取り込み、

なぜ、DataGrid に取り込む必要があるのですか?
http://support.microsoft.com/default.aspx?scid=kb;ja;316934

> エクセルの雛型ファイルに直接Range.Valueで書き込むと時間がかかります。
> (3000件強のレコード数で1時間以上かかる)

どのようなコードを書いておられて、実際のデータの個数は?
3000件=3000行 としても何列かによっても違うしデータの種類にもよるだろうし
通常は1時間以上かかる事はないと思うのですが。

> そこで、一旦CSVファイルに書き出し、CSVファイルとエクセルの雛型ファイルを開き
> 範囲指定でコピーしようとしました。

CSVファイルに書き出すくらいなら、Excelファイル上に書き出した方が早い気がしますが。

> 値だけをコピーして、書式設定は雛型ファイルで設定しているのを使いたいのです。

値だけをコピー は、式の部分に答えを表示した状態ですよね。

> 2つのエクセルファイル間で、値のみのコピーはできないものなんでしょうか?
プログラムに関係なく Excel を手動で扱って貴方の言う 値のみのコピー はできますか?

CSV ファイルに書き出して使うのならCSVファイルに式の部分も書くようにしないと。

雛型ファイルがどのようなものか解らないので確かではないですが、データを入力する
部分だけの範囲を指定して、その範囲事に入力してやれば、少しは早くなるかと。
http://hanatyan.sakura.ne.jp/dotnet/Excel07.htm

[ツリー表示へ]
タイトルRe^2: エクセル間でで値だけのコピー
記事No6710
投稿日: 2007/12/24(Mon) 10:41
投稿者
花ちゃん様、ご返答ありがとうございます。
色々と情報不足があり、申し訳ありません
> なぜ、DataGrid に取り込む必要があるのですか?
一旦データをDataGrid上に表示して、ユーザが必要に応じてエクセルファイルに
DataGrid上のデータを書き出すとう処理を行っています。

> どのようなコードを書いておられて、実際のデータの個数は?
> 3000件=3000行 としても何列かによっても違うしデータの種類にもよるだろうし
> 通常は1時間以上かかる事はないと思うのですが。
1レコードに34列のデータがあり、文字列型・数値型・金額型・日付型と複数の形式が
混ざっています。
きちんと時間を計ったわけではないのですが、エクセルファイルに1レコード書き終わった
時に、書き始めからの経過時間と書き込んだレコード数から1レコードあたりの平均時間を
出し、残りのレコード数からあとどれくらい時間がかかるか表示をしていました。
その時に、1時間以上かかるとわかったのです。

> CSVファイルに書き出すくらいなら、Excelファイル上に書き出した方が早い気がしますが。
今のところ、CSVファイルに書き出しCSVファイルをエクセルで開き範囲指定してコピーした
方が、断然早く処理ができています。

> > 2つのエクセルファイル間で、値のみのコピーはできないものなんでしょうか?
> プログラムに関係なく Excel を手動で扱って貴方の言う 値のみのコピー はできますか?
エクセルでは、貼り付けをする時にマウスの右クリックで「形式を選択して貼り付け」を
選択し、「値」を選択すると値だけのコピーができますよね?

> CSV ファイルに書き出して使うのならCSVファイルに式の部分も書くようにしないと。
'DatGridからCSVファイルへデータを書き込み
For Row_Num = 0 To dTbl.DefaultView.Count - 1
    WriteLine = ""
    For Clm_num = 0 To 33
        Select Case Clm_num
        Case 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 17, 18, 20, 22, 24, 26, 28, 30, 32, 33
            WriteLine = WriteLine & "=" & Chr(34) & DataGridEx1.Item(Row_Num, Clm_num) & Chr(34) & ","
        Case 12, 14, 15, 16, 19, 21, 23, 25, 27, 29, 31
            WriteLine = WriteLine & Chr(34) & DataGridEx1.Item(Row_Num, Clm_num) & Chr(34) & ","
        End Select
    Next
    swFile.WriteLine(WriteLine)
Next
CSVファイルへの書き出し部分です。色々とサイトを参考にし文字列は="文字列"とし
その他は"値"という形でCSVファイルに書き込んでいます。

もう一度、花ちゃん様のご意見を参考にして挑戦してみます。

[ツリー表示へ]
タイトルRe^3: エクセル間でで値だけのコピー
記事No6711
投稿日: 2007/12/24(Mon) 11:32
投稿者GOD
> > CSVファイルに書き出すくらいなら、Excelファイル上に書き出した方が早い気がしますが。
> 今のところ、CSVファイルに書き出しCSVファイルをエクセルで開き範囲指定してコピーした
> 方が、断然早く処理ができています。
>
クリップボードを使用したらどうですか。ただ全データを一気にコピーできるかはメモリ次第に
なってくるので、1000行ずつとか分割でコピー&ペーストできるように作成しておいた方が良い
かも。(データが3000行以上になったときでもメモリを気にせずに対応できだろうから)
アプリを使用するたびにクリップボードの中身が書き換わるのが嫌なら使用前のデータを保存し
ておいて使用後に戻せば問題ないはず。
※ 列間は TAB、改行は LF かな。

[ツリー表示へ]
タイトルRe^3: エクセル間でで値だけのコピー
記事No6712
投稿日: 2007/12/24(Mon) 12:40
投稿者花ちゃん
> 1レコードに34列のデータがあり、文字列型・数値型・金額型・日付型と複数の形式が
> 混ざっています。

この書き込みコードに問題はありませんか?
(CSVファイルを作ってそれを読み込んでからコピーした方が早いって事は???)

> > CSVファイルに書き出すくらいなら、Excelファイル上に書き出した方が早い気がしますが。
> 今のところ、CSVファイルに書き出しCSVファイルをエクセルで開き範囲指定してコピーした
> 方が、断然早く処理ができています。

そもそもデータベースを使っているのなら、下記のようにすれば相当早いと思うのですが。
xlBook.Worksheets(1).Range("A1").CopyFromRecordset mdbRS
上記より必要部分(範囲)を取り出し、xlRange.Value = strDat のように範囲内に1発で
入力すれば、コピーするより数段早くなるのでは。

> エクセルでは、貼り付けをする時にマウスの右クリックで「形式を選択して貼り付け」を
> 選択し、「値」を選択すると値だけのコピーができますよね?

この時の値は計算式が入っているセルには、計算式が入らず、答え が入ってしまいますよね。
それでいいなら、上記の CopyFromRecordset を使用すればいいのでは。

ひな形のファイルがどのようなものかによってどのような方法が早いかは解りませんが、
少なくても今のやり方はベストではない事はたしかです。

[ツリー表示へ]
タイトルRe^4: エクセル間でで値だけのコピー
記事No6713
投稿日: 2007/12/24(Mon) 14:04
投稿者
GOD様、花ちゃん様、ご返答ありがとうございます。
お二方のご返答を参考に、再度検討してみます。

またわからない事がありましたら、ご質問させてください。

[ツリー表示へ]
タイトルRe^4: エクセル間でで値だけのコピー
記事No6717
投稿日: 2007/12/24(Mon) 16:46
投稿者
GOD様、花ちゃん様、お世話になります。

花ちゃん様からご返答を頂いた、CopyFromRecordsetは ADOのみ対応してるものとの事で、
こちらではOLEDBを使用しているため使えないようです。
GOD様からご返答を頂いた、「クリップボードを利用して」では、私の知識不足もありますが、クリップボードへのデータを入れ方はわかったのですが、貼り付け方がわからずに断念しました。

その後、VB.netのヘルプを参考に、2次元配列のオブジェクト変数を宣言してその変数に
DataGrid上のデータを取り込み、それを下記のようにエクセルに貼り付けるようにしました。
Dim WriteLine(dTbl.DefaultView.Count, 2) As Object
    For Row_Num = 0 To dTbl.DefaultView.Count - 1
        For Clm_num = 0 To 33
            WriteLine(Row_Num, Clm_num) = DataGridEx1.Item(Row_Num, Clm_num)
        Next
    Next
    xlSheet.Range("A11").Resize(dTbl.DefaultView.Count, 34).Value = WriteLine
これで思ってた通りの処理ができるようになりました。

GOD様、花ちゃん様、本当にありがとうございました。

[ツリー表示へ]