C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

Excelの指定範囲の内容を表形式で表示 /temaki (20/05/19(Tue) 16:00) #94790
Re[1]: Excelの指定範囲の内容を表形式で表示 /魔界の仮面弁士 (20/05/19(Tue) 16:57) #94791
│└ Re[2]: Excelの指定範囲の内容を表形式で表示 /temaki (20/05/21(Thu) 10:10) #94806
│  └ Re[3]: Excelの指定範囲の内容を表形式で表示 /大谷刑部 (20/05/21(Thu) 11:03) #94808
│    └ Re[4]: Excelの指定範囲の内容を表形式で表示 /temaki (20/05/21(Thu) 11:41) #94809
│      ├ Re[5]: Excelの指定範囲の内容を表形式で表示 /魔界の仮面弁士 (20/05/21(Thu) 12:50) #94810
│      │├ Re[6]: Excelの指定範囲の内容を表形式で表示 /大谷刑部 (20/05/21(Thu) 13:13) #94812
│      ││└ Re[7]: Excelの指定範囲の内容を表形式で表示 /temaki (20/05/21(Thu) 14:32) #94814
│      │└ Re[6]: Excelの指定範囲の内容を表形式で表示 /temaki (20/05/21(Thu) 19:43) #94817 解決済み
│      │  └ Re[7]: Excelの指定範囲の内容を表形式で表示 /魔界の仮面弁士 (20/05/21(Thu) 21:14) #94818 解決済み
│      │    └ Re[8]: Excelの指定範囲の内容を表形式で表示 /temaki (20/05/22(Fri) 09:54) #94830 解決済み
│      └ Re[5]: Excelの指定範囲の内容を表形式で表示 /大谷刑部 (20/05/21(Thu) 12:58) #94811
Re[1]: Excelの指定範囲の内容を表形式で表示 /大谷刑部 (20/05/20(Wed) 11:34) #94798


親記事 / ▼[ 94791 ] ▼[ 94798 ]
■94790 / 親階層)  Excelの指定範囲の内容を表形式で表示
□投稿者/ temaki (1回)-(2020/05/19(Tue) 16:00:16)

分類:[VB.NET/VB2005 以降] 

例えば、Excelの指定範囲をクリップボードにコピーして、
その内容をWinForm上に表形式で表示したいと考えています。
Excelの範囲は10×10程度を想定しています。

セルの書式等はとりあえず無視するとして、何を使うのが手っ取り早いでしょうか?
セルの値も参照するので、やっぱりDataGridViewでしょうか?
他に何かよい方法はないでしょうか?

なお、いつもVB2013(Community)を使用しています。
[ □ Tree ] 返信 編集キー/

▲[ 94790 ] / ▼[ 94806 ]
■94791 / 1階層)  Re[1]: Excelの指定範囲の内容を表形式で表示
□投稿者/ 魔界の仮面弁士 (2721回)-(2020/05/19(Tue) 16:57:26)
No94790 (temaki さん) に返信
> セルの書式等はとりあえず無視するとして、何を使うのが手っ取り早いでしょうか?
> セルの値も参照するので、やっぱりDataGridViewでしょうか?

テキストとして取り出すなら、ListView か DataGridView に展開する手もありますし、
表示だけで良いなら、画像として取り出すという選択肢もあります。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
 Dim d = Clipboard.GetDataObject()
 If d.GetDataPresent(DataFormats.Bitmap) Then
  PictureBox1.BackgroundImageLayout = ImageLayout.Stretch
  PictureBox1.BackgroundImage = DirectCast(d.GetData(DataFormats.Bitmap), Image)
 Else
  PictureBox1.BackgroundImage = Nothing
 End If
End Sub


Excel の見た目を再現したいなら、フリーソフト(MITライセンス)の ReoGrid という手も。
https://reogrid.net/jp/features/
[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94791 ] / ▼[ 94808 ]
■94806 / 2階層)  Re[2]: Excelの指定範囲の内容を表形式で表示
□投稿者/ temaki (2回)-(2020/05/21(Thu) 10:10:19)
No94791 (魔界の仮面弁士 さん) に返信
> テキストとして取り出すなら、ListView か DataGridView に展開する手もありますし、

ありがとうございます。
はい、今回はテキストとして取り出したいです。
Excelの指定範囲をクリップボードにコピーした後、
Dim cliptext As String = Clipboard.GetText()
を見ると、指定範囲のセルの内容がタブ区切りと改行で取得出来ていました。
また、欲しかったのはセルの値そのものではなく、セルの表示内容なので、都合が良かったです。
(セルの実際の値が2.66666666だったとしても、表示が3なら3という値を取得したい。)
また、セル結合については無視しています。

ところで、このデータを直接DataGridViewに貼り付けできるのでしょうか?
データがタブ区切りと改行なので、それで行列に分けた二次元配列のデータを作れるかと思ったのですが、
セル内で改行されているデータを見ると、

"あいうえお
カキクケコ"

のように、改行を含むテキストが二重引用符で囲まれていました。
今回のようなタブ区切りデータを簡単に二次元配列(データテーブル的なものでもよい)に
格納する手っ取り早い方法はありますか?
[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94806 ] / ▼[ 94809 ]
■94808 / 3階層)  Re[3]: Excelの指定範囲の内容を表形式で表示
□投稿者/ 大谷刑部 (80回)-(2020/05/21(Thu) 11:03:32)
No94806 (temaki さん) に返信
> ■No94791 (魔界の仮面弁士 さん) に返信
> また、欲しかったのはセルの値そのものではなく、セルの表示内容なので、都合が良かったです。
> (セルの実際の値が2.66666666だったとしても、表示が3なら3という値を取得したい。)
表示の問題だけなら単にグリッドの該当列の書式設定でいけるでしょう。
画面デザインでも、コード上で記載しても両方できるはずです。

> また、セル結合については無視しています。
>
> ところで、このデータを直接DataGridViewに貼り付けできるのでしょうか?
多分できますよね。聞く前に試してみたらどうですか?
簡単にデバッグできるコードだと思うので。

> データがタブ区切りと改行なので、それで行列に分けた二次元配列のデータを作れるかと思ったのですが、
> セル内で改行されているデータを見ると、
>
> "あいうえお
> カキクケコ"
>
> のように、改行を含むテキストが二重引用符で囲まれていました。
↓データ改行とかが存在しているのなら、TextFieldParserクラスとかで引用符を取り除いてから、クリップボードにコピーした方がその後の処理がしやすいのでは?
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.fileio.textfieldparser?redirectedfrom=MSDN&view=netcore-3.1

> 今回のようなタブ区切りデータを簡単に二次元配列(データテーブル的なものでもよい)に
> 格納する手っ取り早い方法はありますか?
Excelが二次元配列を直接貼り付け(構文的にはレンジへの代入)できるので、探せばなんらか方法はあるかもしれませんが、
DataTableに格納して、バインドする方が、何かと便利な気はしますよ。
簡易ですが、キーやソート、SQLもどきのメソッドでフィルターもかけられますし。

[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94808 ] / ▼[ 94810 ] ▼[ 94811 ]
■94809 / 4階層)  Re[4]: Excelの指定範囲の内容を表形式で表示
□投稿者/ temaki (3回)-(2020/05/21(Thu) 11:41:59)
No94808 (大谷刑部 さん) に返信
>>ところで、このデータを直接DataGridViewに貼り付けできるのでしょうか?
> 多分できますよね。聞く前に試してみたらどうですか?
> 簡単にデバッグできるコードだと思うので。

どうやって?
Ctrl+Vでも貼付けできないんですけど?
「多分できます」ってのは要らないから、
確実にできる方法を書いてもらいたいものです。
[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94809 ] / ▼[ 94812 ] ▼[ 94817 ]
■94810 / 5階層)  Re[5]: Excelの指定範囲の内容を表形式で表示
□投稿者/ 魔界の仮面弁士 (2722回)-(2020/05/21(Thu) 12:50:58)
No94808 (大谷刑部 さん) に返信
> ↓データ改行とかが存在しているのなら、TextFieldParserクラスとかで引用符を取り除いてから、クリップボードにコピーした方がその後の処理がしやすいのでは?
ペースト時ではなく、コピー時に割り込ませるとなると、
Excel 側の操作を見直すことになるので、前提条件から見直しが必要になりそう。


No94809 (temaki さん) に返信
>>>ところで、このデータを直接DataGridViewに貼り付けできるのでしょうか?
>>多分できますよね。聞く前に試してみたらどうですか?
>>簡単にデバッグできるコードだと思うので。
> どうやって?
> Ctrl+Vでも貼付けできないんですけど?
大谷刑部 さんは、「操作」ではなく「コード」と書かれていますね。
『直接貼り付け』というのを、データバインドの意で捉えているかも。


> 「多分できます」ってのは要らないから、
> 確実にできる方法を書いてもらいたいものです。
.NET Framework 4.7.2 以降の「DataGridView の機能強化」にも、
クリップボード操作に関する追加情報は無さそうですね。
https://docs.microsoft.com/ja-jp/dotnet/framework/whats-new/whats-new-in-accessibility


「操作」ではなく「コード」なら、既に提示されていた
TextFieldParser を使って、このように書けます。

Dim tsvData As String = 何某

Dim tbl As New DataTable()
Using reader As New StringReader(tsvData), parser As New TextFieldParser(reader)
  parser.TextFieldType = FieldType.Delimited
  parser.CommentTokens = New String(-1) {}
  parser.Delimiters = New String(0) {vbTab}
  parser.HasFieldsEnclosedInQuotes = True
  parser.TrimWhiteSpace = False

  Do Until parser.EndOfData
    Dim fields = parser.ReadFields()
    For n = tbl.Columns.Count To fields.Count - 1
      tbl.Columns.Add()
    Next
    tbl.Rows.Add(fields)
  Loop
End Using
DataGridView1.AutoGenerateColumns = True
DataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True
DataGridView1.DataSource = tbl
[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94810 ] / ▼[ 94814 ]
■94812 / 6階層)  Re[6]: Excelの指定範囲の内容を表形式で表示
□投稿者/ 大谷刑部 (82回)-(2020/05/21(Thu) 13:13:43)
No94810 (魔界の仮面弁士 さん) に返信
> ■No94808 (大谷刑部 さん) に返信
>>↓データ改行とかが存在しているのなら、TextFieldParserクラスとかで引用符を取り除いてから、クリップボードにコピーした方がその後の処理がしやすいのでは?
> ペースト時ではなく、コピー時に割り込ませるとなると、
> Excel 側の操作を見直すことになるので、前提条件から見直しが必要になりそう。

まあ、そうなりますね。
でも、質問者が現在のクリップボードに保存する方法をどうしてるかがわからないので、何とも言えませんが、
引用符がついてしまった状態ののものを条件分岐して取り除くより、先に取り除いたものを配列に入れるなりなんなりした方が
結果的にコードは簡便にはなると思います。
性能を考慮するとなるとまた話は別ですが。

> ■No94809 (temaki さん) に返信
> >>>ところで、このデータを直接DataGridViewに貼り付けできるのでしょうか?
> >>多分できますよね。聞く前に試してみたらどうですか?
> >>簡単にデバッグできるコードだと思うので。
>>どうやって?
>>Ctrl+Vでも貼付けできないんですけど?
> 大谷刑部 さんは、「操作」ではなく「コード」と書かれていますね。
> 『直接貼り付け』というのを、データバインドの意で捉えているかも。
貼り付け=[ctrl]+[V] またはオブジェクト.Pasteメソッドと考えているなら、質問者の視野が狭いですね。
Excelに貼り付けるときだって、クリップボードコピー→Pasteメソッドより、
Rageオブジェクトに直接代入の方がいいとネット上に書いてる人もいるのですし。
10×10なら問題ないでしょうけど、
ユーザーのキー操作を無効にしておかないと、コピー処理中にユーザーが手操作のコピーをしたら、
不具合が発生するなんてことは、私が関わった現場で実際発生してますしね。


[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94812 ] / 返信無し
■94814 / 7階層)  Re[7]: Excelの指定範囲の内容を表形式で表示
□投稿者/ temaki (4回)-(2020/05/21(Thu) 14:32:37)
2020/05/21(Thu) 14:53:24 編集(投稿者)

No94812 (大谷刑部 さん) に返信

> 貼り付け=[ctrl]+[V] またはオブジェクト.Pasteメソッドと考えているなら、質問者の視野が狭いですね。

あのね、「貼り付け」って言葉は、僕がこのスレで最初に書き込んだ言葉だよ。

「ところで、このデータを直接DataGridViewに貼り付けできるのでしょうか?」

これは、言葉の定義通り、ペーストの意味で使っている。
勝手にこちらの定義を変えないように。

> ↓これくらいの情報自分でググれないの?
> https://effect.hatenablog.com/entry/2018/10/02/030816

コードを書けばできることは分かっているので、そもそも上の情報は役に立たない。
こちらが知りたいのは、もっと簡単にExcelの内容をグリッドに貼り付けできないか、ということ。
(Excelからのコピーされる領域は、行列数が毎回同じとは限らない)

そもそも、こちらは「試してみたら」と言われたから、貼付けを試しただけ。
僕に何を試して欲しかったのでしょうか?意味不明。
そもそも、こちらの質問の意図を理解していないんだろうな。

> でも、質問者が現在のクリップボードに保存する方法をどうしてるかがわからないので、何とも言えませんが、

えっ?マジで分かんないの?
普通の人がExcelのセル領域をクリップボードにコピーする方法って、Ctrl+Cか右クリック等のコピーメニューくらいじゃないの?
ユーザー目線になっていないんじゃないの?


これでは回答者の視野が狭いですね。
波乗り氏レベル。(レベルはそれ以下?)

相手の知りたいことを理解もせずに、いい加減なことしか書けないなら、
もう二度とことスレに書き込まないで欲しい。
(こちらは無視するだけ。)
[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94810 ] / ▼[ 94818 ]
■94817 / 6階層)  Re[6]: Excelの指定範囲の内容を表形式で表示
□投稿者/ temaki (5回)-(2020/05/21(Thu) 19:43:27)
No94810 (魔界の仮面弁士 さん) に返信

TextFieldParserの使い方、誠にありがとうございました。
先程試してみたところ、うまくいきました。
また、Usingって、複数のIDisposableオブジェクトを1行で書けるんですね。
僕はUsingをネストしてしまう所でしたが、これは勉強になりました。

ありがとうございました。
解決済み
[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94817 ] / ▼[ 94830 ]
■94818 / 7階層)  Re[7]: Excelの指定範囲の内容を表形式で表示
□投稿者/ 魔界の仮面弁士 (2723回)-(2020/05/21(Thu) 21:14:36)
No94817 (temaki さん) に返信
> また、Usingって、複数のIDisposableオブジェクトを1行で書けるんですね。

MemoryStream や StringReader のインスタンスに対しては、
Dispose を呼ばなかったとしても問題ないのですけれどね。
もちろん呼んでも OK ですが。

https://docs.microsoft.com/ja-jp/dotnet/api/system.io.stringreader?view=netframework-4.5.1
|
| この型は IDisposable インターフェイスを実装しますが、実際に破棄するリソースはありません。
| つまり、Dispose() を直接呼び出したり、using (C# の場合) または Using (Visual Basic の場合) といった
| 言語構築を行ってリソースを破棄する必要はありません。
|


> 僕はUsingをネストしてしまう所でしたが、これは勉強になりました。

対象オブジェクトが 3 つ 4 つと増えると、構文的に使いにくいですけれどね。
これが C# であれば、
 using (var reader = new StringReader(tsvData))
 using (var parser = new TextFieldParser(reader))
 {
    DoAnything(parser);
 }
の構文が使えるのですが。



とはいえ今回のケースであれば、単一の Using にて、
 Using parser As New TextFieldParser(New StringReader(tsvData))
  DoAnything(parser)
 End Using
という形をとることができます。こっちの方がスマートかもしれません。
あるいは parser.Close() 派の方もおられるようで。
解決済み
[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94818 ] / 返信無し
■94830 / 8階層)  Re[8]: Excelの指定範囲の内容を表形式で表示
□投稿者/ temaki (6回)-(2020/05/22(Fri) 09:54:48)
No94818 (魔界の仮面弁士 さん) に返信

解説誠にありがとうございました。
今回は色々と勉強になりました。
今までは、あんまりプログラミングは好きではなかったのですが、
今回、何だかちょっと好きになりました。
ありがとうございました。

解決済み
[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94809 ] / 返信無し
■94811 / 5階層)  Re[5]: Excelの指定範囲の内容を表形式で表示
□投稿者/ 大谷刑部 (81回)-(2020/05/21(Thu) 12:58:37)
No94809 (temaki さん) に返信
> ■No94808 (大谷刑部 さん) に返信
> >>ところで、このデータを直接DataGridViewに貼り付けできるのでしょうか?
>>多分できますよね。聞く前に試してみたらどうですか?
>>簡単にデバッグできるコードだと思うので。
>
> どうやって?
> Ctrl+Vでも貼付けできないんですけど?
> 「多分できます」ってのは要らないから、
> 確実にできる方法を書いてもらいたいものです。
わからなくて聞いてるのに何逆切れしてんの?
↓これくらいの情報自分でググれないの?
https://effect.hatenablog.com/entry/2018/10/02/030816
[ 親 94790 / □ Tree ] 返信 編集キー/

▲[ 94790 ] / 返信無し
■94798 / 1階層)  Re[1]: Excelの指定範囲の内容を表形式で表示
□投稿者/ 大谷刑部 (79回)-(2020/05/20(Wed) 11:34:21)
No94790 (temaki さん) に返信
> 例えば、Excelの指定範囲をクリップボードにコピーして、
> その内容をWinForm上に表形式で表示したいと考えています。
> Excelの範囲は10×10程度を想定しています。
>
> セルの書式等はとりあえず無視するとして、何を使うのが手っ取り早いでしょうか?
> セルの値も参照するので、やっぱりDataGridViewでしょうか?
ただ表示したいのなら、適合するOLEDBプロバイダーがインストールされてる環境なら、DataGridViewにExcelをバインド可能と思います。
その場合クリップボード経由は不要です。
ただし、Excel2013以降、デフォルトインストールだとOLEプロバイダーがインストールされないとか、64bit/32bit関係で動かないというリスクはあります。
[ 親 94790 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -