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

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

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

Re[20]: リッチテキストボックスでカラー情報をコピーする方法


(過去ログ 155 を表示中)

[トピック内 29 記事 (1 - 20 表示)]  << 0 | 1 >>

■89928 / inTopicNo.1)  リッチテキストボックスでカラー情報をコピーする方法
  
□投稿者/ イエメン (1回)-(2019/01/21(Mon) 16:15:06)

分類:[.NET 全般] 

Excel上でセル内の文字列の一部の色を別に変えた状態で
セルをコピーしWord上にペーストすると
その色情報や下線、ボールドなどのフォント情報を保持したまま
貼り付けることができます。

しかし、VBで作成したプログラムの
リッチテキストボックス上で同じことをしようとしても
これらの情報を保持されず、
文字しかペーストされません、

どうすればカラーなどの情報も同時に貼り付けることができますか?


引用返信 編集キー/
■89929 / inTopicNo.2)  Re[1]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ とっちゃん (571回)-(2019/01/21(Mon) 16:29:10)
No89928 (イエメン さん) に返信
> どうすればカラーなどの情報も同時に貼り付けることができますか?
>
Paste( DataFormats.Rtf ) はどうでしょうか?


引用返信 編集キー/
■89930 / inTopicNo.3)  Re[2]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (3回)-(2019/01/21(Mon) 18:26:09)
ご回答ありがとうございます。

しかし、
Paste( DataFormats.Rtf )

というのはどこで使えば良いのでしょうか・・・?
引用返信 編集キー/
■89939 / inTopicNo.4)  Re[3]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (4回)-(2019/01/22(Tue) 18:53:56)
どなたかご回答ください・・・。
引用返信 編集キー/
■89940 / inTopicNo.5)  Re[4]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ Azulean (1027回)-(2019/01/23(Wed) 06:41:42)
2019/01/23(Wed) 06:46:03 編集(投稿者)

No89939 (イエメン さん) に返信
> どなたかご回答ください・・・。

最近、わんくまのサーバーが不安定なようなので回答がつかないのはそういう事情があることも考慮しておいてください。


とっちゃんさんのコメントは、貼り付け処理を自作している・自作に置き換えるケースを想定されているとは思います。(実際には DataFormats.Rtf と単に書くのではなく、DataForamts.GetFormat(DataFormats.Rtf)) のようですが)
もっとも、Excel 2010 をコピー元として様子を見る限り、形式を選択して貼り付けで「リッチテキスト形式」を選んでも色がつかないので、残念ながらこの方法では解決しない模様です。

Word は形式を選択して貼り付けのデフォルトである HTML 形式での貼り付けで実現しているようです。
残念ながら RichTextBox は HTML 形式での貼り付けをサポートしていないようなので、自分でクリップボードの中身を解釈し、RichTextBox.Rtf プロパティに設定する…といった非現実的な作業が必要なので「諦める」が第一選択肢になると思われます。

// https://stackoverflow.com/questions/2627991/how-to-show-html-contents-with-a-richtextbox みたいな力業…?
引用返信 編集キー/
■89941 / inTopicNo.6)  Re[1]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2017回)-(2019/01/23(Wed) 06:59:05)
2019/01/23(Wed) 07:00:41 編集(投稿者)

No89928 (イエメン さん) に返信
> これらの情報を保持されず、
> 文字しかペーストされません、

Excel / Word / RichTextBox それぞれに対して、Ctrl + C で『コピー』を行い、
その直後、下記のコードを実行してみてください。

クリップボード内に、どの形式のデータがどの順番で保持されているかを
DataGridView 上に簡易列挙させるためのコードです。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
 Dim data = Clipboard.GetDataObject()
 DataGridView1.DataSource = data.GetFormats(False).ToDictionary(Function(s) s, Function(s) data.GetData(s)).ToArray()
End Sub


これにより、各アプリケーションが、どのフォーマットを「コピー」するのかを把握したら、
次に、『ペースト』先のアプリケーションが、どの形式のデータをサポートしているかを
調査していきます。(たとえば、メモ帳に画像は貼れないですよね)


RichTextBox の場合、サポート可能な形式かどうかを CanPaste メソッドで判定できます。
そして「形式を指定して貼り付け」のために、引数付の Paste メソッドが用意されています。


先のコードに下記を加えてみます。上記のコードで DataGridView にクリップボード内のデータを
展開したのち、DataGridView のセルをダブルクリックすると、該当行のデータが
RichTextBox の CanPaste / Paste メソッドを通じてペーストされるようにしています。

Private Sub DataGridView1_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentDoubleClick
 Dim fmtName = CStr(DataGridView1("Key", e.RowIndex).Value)
 Dim fmt = DataFormats.GetFormat(fmtName)
 If Not RichTextBox1.CanPaste(fmt) Then
  MessageBox.Show("サポートされていない形式です。:" & fmtName, "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
 Else
  Clipboard.Clear()
  Clipboard.SetData(fmtName, DataGridView1("Value", e.RowIndex).Value)
  Application.DoEvents()
  RichTextBox1.Paste(fmt)
  MessageBox.Show("ペーストしました。", "", MessageBoxButtons.OK, MessageBoxIcon.Information)
 End If
End Sub


> Excel上でセル内の文字列の一部の色を別に変えた状態で
> セルをコピーしWord上にペーストすると

これは、Excel のデータを Word に貼る場合の話ですね。
Excel のバージョンによって、クリップボードに送られるフォーマットに差があります。


> しかし、VBで作成したプログラムの
> リッチテキストボックス上で同じことをしようとしても

「同じこと」が何を指しているのか曖昧ですね。(^^;

RichTextBox のデータを RichTextBox に貼るのでしょうか。
Excel のデータを RichTextBox に貼るのでしょうか。
Word のデータを RichTextBox に貼るのでしょうか。
RichTextBox のデータを Excel に貼るのでしょうか。
RichTextBox のデータを Word に貼るのでしょうか。
それとも…?
引用返信 編集キー/
■89947 / inTopicNo.7)  Re[5]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2018回)-(2019/01/23(Wed) 10:52:43)
2019/01/23(Wed) 12:01:15 編集(投稿者)

No89928 (イエメン さん) に返信
> どうすればカラーなどの情報も同時に貼り付けることができますか?

(案1)Excel からコピーした内容を Word に貼り、それを再コピーして RichTextBox に貼る

(案2)Excel の書式情報(Biff12 等)を解析して Rtf 書式に再構築するコードを自力実装する

(案3)Excel オートメーションで、一文字ずつ書式情報を読み取って処理していく
 http://hanatyan.sakura.ne.jp/vbhlp/Excel13.htm

(案4)有償/無償の RTF コンバーターを探してきて利用する
 https://www.sautinsoft.com/convert-excel-xls-to-pdf/xlsx-to-rtf-dotnet-csharp.php
 https://convertio.co/ja/xlsx-rtf/



No89940 (Azulean さん) に返信
> Excel 2010 をコピー元として様子を見る限り、形式を選択して貼り付けで「リッチテキスト形式」を選んでも色がつかない

こんな情報もあったので、Excel のバージョンを上げれば
マシになるかな…と思いきや、やっぱり駄目でした。無念。

『Excel 2016 でリッチ テキストを使用すると、文字書式設定が失われる』
「この問題は、バージョン 1708 (8431.2109) で修正されています。」
https://support.office.com/ja-jp/article/e0536ed1-b339-45fa-b665-917fe165d957


とりあえず、手持ちの Excel 2016 ver1812 でコピー操作を行ってみて、
その時にクリップボードに送られる形式を調べてみました。
先頭の○×は、RichTextBox に貼ることができるかどうかを示したものです。


クリップボード内容の確認には、フリーソフトの「クリップ見え窓」を利用しました。



《色情報を含むが、OLE 埋め込みや OLE リンクになるもの》
○ "Embed Source" ※ 貼り付け後にダブルクリックすると編集用の Excel が起動する
○ "Link Source" ※ コピー元の Excel ファイルを編集すると RichTextBox 側も自動で書き換わる


《色情報を含むが、画像形式となってしまうもの》
△ "EnhancedMetafile" (CF_ENHMETAFILE = 14) ※ 拡張メタファイル形式。
○ "MetfaFilePict" (CF_METAFILEPICT = 3) ※ メタファイル形式。
× "Bitmap" (CF_BITMAP = 2) ※ ビットマップ形式。System.Drawing.Bitmap として得られた。


《色情報を含められる形式だが、色情報が記録されていなかった物》
○ "Rich Text Format"


《色情報を含む形式で、色情報が記録されていた物》
× "SymblicLink" (CF_SYLK = 4) ※ Microsoft SYLK 形式。
× "Biff12" ※ Excel 2007 形式。
× "Biff8" ※ Excel 97〜2003 形式。
× "Biff5" ※ Excel 95 形式。
× "XML Spreadsheet" ※ Office XML 形式。
× "HTML Format" ※ HTML 形式。


《そもそも色情報を含まない形式の物》
× "DataInterchangeFormat" (CF_DIF = 5) ※ VisiCalc 形式。
○ "UnicodeText" (CF_UNICODETEXT = 13) ※ UTF-16 なタブ区切りテキスト。
○ "Text" (CF_TEXT = 1) ※ 既定のコードページによるタブ区切りテキスト。
× "Csv" ※ ANSI コードページによるカンマ区切りテキスト。


《その他の形式》
× "DataObject"
× "Hyperlink"
× "Object Descriptor"
× "Link Source Descriptor"
× "Link"
引用返信 編集キー/
■89980 / inTopicNo.8)  Re[1]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2021回)-(2019/01/27(Sun) 13:31:51)
No89928 (イエメン さん) に返信
> どうすればカラーなどの情報も同時に貼り付けることができますか?

VB ではなく C# ですが、No78716 に類似のやり取りがあったので紹介しておきます。

> エクセルのセルに設定された文字列の取得で、文字毎の色まで取り込みたいです。
> 最終的にはRichTextBoxに表示できればよいのですが。

http://bbs.wankuma.com/index.cgi?mode=al2&namber=78716&KLOG=133
引用返信 編集キー/
■89981 / inTopicNo.9)  Re[2]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (5回)-(2019/01/27(Sun) 13:49:21)
ありがとうございます。

まだ、他のコードを試すことができていませんが、
とりあえず、このコードなら一発でできそうなので
試してみました

VBに翻訳してみたのですが、


    Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click


        Dim wApp = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application"))
        Dim docs = wApp.Documents
        Dim doc = docs.Add()
        Dim rngWord = doc.Range

        Clipboard.Clear()
        rngExcel.Copy

        rngWord.PasteExcelTable(LinkedToExcel:=False, WordFormatting:=False, RTF:=False)
        rngWord.Copy

        RichTextBox1.Paste(DataFormats.GetFormat(DataFormats.Rtf))

        Marshal.ReleaseComObject(rngWord)
        Marshal.ReleaseComObject(doc)
        Marshal.ReleaseComObject(docs)
        Dim oApp As Object = wApp
        wApp.Quit(SaveChanges:=False)
        Marshal.FinalReleaseComObject(oApp)




    End Sub




        Dim docs = wApp.Documents
        wApp.Quit(SaveChanges:=False)
のところで、Option Strict Onでは遅延バインディングを使用できません
というエラーが出ます。
rngExcel
が宣言されていないので
rngExcel.Copy
でもエラーが出ます

どのように改善したら宜しいでしょうか?


引用返信 編集キー/
■89986 / inTopicNo.10)  Re: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ ユーフォー (1回)-(2019/01/28(Mon) 15:30:06)
2019/01/28(Mon) 16:25:36 編集(投稿者)

メッセージの通りです。
遅延バインディングを使用する場合は、Option Strict Offにする必要があります。
プロジェクトでOption Strict Onにしている場合は対象VBファイルの先頭にOption Strict Offと書けばよいです。
プロジェクトでOption Strict Onにしていない場合は、VBファイル先頭にOption Strict OnがなければOKです。

後、rngExcelについては、恐らく、魔界の仮面弁士様が例示した質問では元からExcelが開いていたのでしょう。
ちょっと僕では今回の例でExcelがどのように使われるか分からないので、仮面様の書き込みを待ちましょうか...
引用返信 編集キー/
■89988 / inTopicNo.11)  Re[3]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2023回)-(2019/01/28(Mon) 17:06:46)
No89981 (イエメン さん) に返信
> VBに翻訳してみたのですが、

これでどうでしょう。


Option Explicit On
Imports System.Runtime.InteropServices
Public Class Form1

 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
  Dim oldCursor = Cursor.Current
  Cursor.Current = Cursors.WaitCursor

  ' クリップボードの内容確認
  Dim cb = Clipboard.GetDataObject()
  Dim fmt = cb.GetFormats(False).FirstOrDefault(Function(f) f Like "Biff#")

  If String.IsNullOrEmpty(fmt) Then
   ' Excel 書式ではないので、そのまま貼り付け
   RichTextBox1.Paste()
  Else
   Dim oldCaption = Text
   Text = "Excel 書式の取得中..."

   ' Excel 書式を維持するため、Word 経由で貼り付け
   Dim wApp As Object = Nothing
   Dim wDocs As Object = Nothing
   Dim wDoc As Object = Nothing
   Dim wRng As Object = Nothing
   Try
    wApp = CreateObject("Word.Application")
    wDocs = CallByName(wApp, "Documents", CallType.Get)
    wDoc = CallByName(wDocs, "Add", CallType.Method)
    wRng = CallByName(wDoc, "Range", CallType.Method)
    CallByName(wRng, "PasteExcelTable", CallType.Method, False, False, False)
    CallByName(wRng, "Copy", CallType.Method)
    Try
     RichTextBox1.Paste(DataFormats.GetFormat(DataFormats.Rtf))
    Catch
     RichTextBox1.Paste()
    End Try
   Catch
   Finally
    If wRng IsNot Nothing AndAlso Marshal.IsComObject(wRng) Then Marshal.ReleaseComObject(wRng)
    If wDoc IsNot Nothing AndAlso Marshal.IsComObject(wDoc) Then Marshal.ReleaseComObject(wDoc)
    If wDocs IsNot Nothing AndAlso Marshal.IsComObject(wDocs) Then Marshal.ReleaseComObject(wDocs)
    If wApp IsNot Nothing AndAlso Marshal.IsComObject(wApp) Then
     CallByName(wApp, "Quit", CallType.Method, False)
     Marshal.FinalReleaseComObject(wApp)
    End If
   End Try
   Text = oldCaption
  End If

  Cursor.Current = oldCursor
 End Sub
End Class
引用返信 編集キー/
■89989 / inTopicNo.12)  Re[4]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (6回)-(2019/01/28(Mon) 17:32:03)
素晴らしいコードをありがとうございます。
ばっちりうまくいきました。

ところで、ExcelのデータをRichTextBoxに貼り付けた後、
そのテキストの一部をCtrl+cでコピーし再度フォーマットを保ったままで
Excelに貼り付けたいのですがフォーマットが維持されません。
Wordには貼り付けられるのですが・・・
この場合もWord経由で貼り付ける必要があるのでしょうか?

できればコードを提示いただけないでしょうか?
引用返信 編集キー/
■89991 / inTopicNo.13)  Re[5]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2025回)-(2019/01/28(Mon) 19:05:20)
No89989 (イエメン さん) に返信
> ばっちりうまくいきました。
残念ながら、条件付き書式は受け継がれないようですけれどね。


> ところで、ExcelのデータをRichTextBoxに貼り付けた後、
> そのテキストの一部をCtrl+cでコピーし再度フォーマットを保ったままで
> Excelに貼り付けたいのですがフォーマットが維持されません。

Excel 側が RTF フォーマットをサポートしていないので、
プレーンテキストで貼りついてしまう模様。

"HTML Format" 形式のデータを設けてやれば、Excel 側に書式情報を届けられましたが、
やはり自前で処理するのは面倒そう……。

Dim htmlBinary As Byte() = 『RichTextBox1 の選択範囲を "HTML Format" 化した UTF-8 バイナリ』
Clipboard.Clear()
Clipboard.SetData(DataFormats.Html, New System.IO.MemoryStream(htmlBinary))



> この場合もWord経由で貼り付ける必要があるのでしょうか?
> できればコードを提示いただけないでしょうか?

ということで、毎度おなじみ Word 経由で。

Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
 Dim oldCursor = Cursor.Current
 Cursor.Current = Cursors.WaitCursor

 Clipboard.Clear()
 RichTextBox1.Copy()

 Dim oldCaption = Text
 Text = "Excel 書式の取得中..."

 ' Excel 書式を維持するため、Word 経由で複写
 Dim wApp As Object = Nothing
 Dim wDocs As Object = Nothing
 Dim wDoc As Object = Nothing
 Dim wRng As Object = Nothing
 Try
  wApp = CreateObject("Word.Application")
  wDocs = CallByName(wApp, "Documents", CallType.Get)
  wDoc = CallByName(wDocs, "Add", CallType.Method)
  wRng = CallByName(wDoc, "Range", CallType.Method)
  CallByName(wRng, "Paste", CallType.Method)
  CallByName(wRng, "Copy", CallType.Method)
 Catch
 Finally
  If wRng IsNot Nothing AndAlso Marshal.IsComObject(wRng) Then Marshal.ReleaseComObject(wRng)
  If wDoc IsNot Nothing AndAlso Marshal.IsComObject(wDoc) Then Marshal.ReleaseComObject(wDoc)
  If wDocs IsNot Nothing AndAlso Marshal.IsComObject(wDocs) Then Marshal.ReleaseComObject(wDocs)
  If wApp IsNot Nothing AndAlso Marshal.IsComObject(wApp) Then
   CallByName(wApp, "Quit", CallType.Method, False)
   Marshal.FinalReleaseComObject(wApp)
  End If
 End Try
 Text = oldCaption
 Cursor.Current = oldCursor
End Sub
引用返信 編集キー/
■89992 / inTopicNo.14)  Re[6]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (7回)-(2019/01/28(Mon) 19:13:43)
ありがとうございます。

試してみたのですが、
なぜか不思議な挙動をします。

Excelのセルをコピー(ABCDEFGH)
RichTextBoxにペースト
RichTextBoxの一部を選択しコピー(CDEF)
そして、Excel上でペーストしても、(CDEF)ではなく(ABCDEFGH)となってしまいます。
再度、RichTextBoxで文字列を選択しなおし、
Excel上にペーストすると2回目だとうまくいきます。

1回目であっても、Excelだとうまくいきませんが、
同じくRichTextBox上だと正常にペーストできます。

これは一体なぜなのでしょうか?




引用返信 編集キー/
■89993 / inTopicNo.15)  Re[7]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2026回)-(2019/01/28(Mon) 19:44:08)
No89992 (イエメン さん) に返信
> 試してみたのですが、
> なぜか不思議な挙動をします。

電車移動中で、手元に試せる環境が無いのですが、
コピー元のエクセルが、コピー中の状態(セルが点滅する破線で囲まれた状態)になっていないでしょうか。
※Excel の 2017/05 月次更新版で仕様変更があった気がしますが、うろ覚え。

もし点滅破線が表示されていたら、Excel データを Word / RichTextBox に貼った後で、Excel 上で Esc キーを押してコピー状態をキャンセルしてみてください。
引用返信 編集キー/
■89994 / inTopicNo.16)  Re[8]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (9回)-(2019/01/28(Mon) 20:16:26)
仰るとおり、Escキーを押すとうまくペーストできました。
ただ、コピーする前に押さないといけないのですね。

できれば、このExcelのコピー状態をキャンセルすることも
プログラム上でできないでしょうか?

引用返信 編集キー/
■89995 / inTopicNo.17)  Re[9]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2027回)-(2019/01/28(Mon) 20:33:17)
No89994 (イエメン さん) に返信
> このExcelのコピー状態をキャンセルすることも
> プログラム上でできないでしょうか?

コピー元 Excel の CutCopyMode プロパティに False を代入してみてください。
引用返信 編集キー/
■89998 / inTopicNo.18)  Re[10]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ イエメン (10回)-(2019/01/29(Tue) 10:54:50)
ありがとうございます。


Dim xlApp = CreateObject("Excel.Application")
CallByName(xlApp, "CutCopyMode", CallType.Method, False)

これをどこかに入れれば良いのでしょうか?

Clipboard.Clear()の前に入れるとエラーが出て実行できず、
Tryの後に入れると、エラーは出ないけれど
コピー状態をキャンセルできないのですが、

どのようにしたら良いですか?

引用返信 編集キー/
■90000 / inTopicNo.19)  Re[11]: リッチテキストボックスでカラー情報をコピーする方法
□投稿者/ 魔界の仮面弁士 (2029回)-(2019/01/29(Tue) 12:24:57)
No89998 (イエメン さん) に返信
> Dim xlApp = CreateObject("Excel.Application")
起動済みのインスタンスを拾うので、
 Dim xlApp = GetObject( , "Excel.Application")
にしておいてください。

GetObject がエラーになる場合は、そもそも Excel が起動していない状態なので
その場合はそもそも、CutCopyMode を操作する必要がありません。


もしも複数の Excel.Application インスタンスが生成されていた場合には、
それらを区別して取得するために、IRunningObjectTable から得る必要が
あるかも知れませんが……大抵は GetObject だけでなんとかなるはず。



> CallByName(xlApp, "CutCopyMode", CallType.Method, False)
それだと
 xlApp.CutCopyMode(False)
相当の意味になってしまいますね。

必要なのは
 xlApp.CutCopyMode = False
に相当する呼び出しなので、Option Strict On で書くなら
 CallByName(xlApp, "CutCopyMode", CallType.Let, False)
です。

処理後は xlApp の COM オブジェクト解放も忘れずに。



> これをどこかに入れれば良いのでしょうか?
「Excel からコピーして Word に貼り付けた後」もしくは
「RichTextBox からコピーして Word に貼り付ける前」のタイミングですかね。
引用返信 編集キー/
■90001 / inTopicNo.20)  Re[12]: リッチテキストボックスでカラー情報をコピーする方法
 
□投稿者/ イエメン (12回)-(2019/01/29(Tue) 12:41:07)
ありがとうございます。


RichTextBox1.Copy()
の後に

Dim xlApp = GetObject(, "Excel.Application")
CallByName(xlApp, "CutCopyMode", CallType.Let, False)
If xlApp IsNot Nothing AndAlso Marshal.IsComObject(xlApp) Then Marshal.ReleaseComObject(xlApp)

を入れたのですが、
コピーすることで、Excel上でセルを選択している表示は解除されることを確認できました。
しかし、Excel上でペーストしてもデータが代入されません、

再度、コピーをやり直すとうまくいくのですが・・・

なぜ1回でうまくいかないのでしょうか?

引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -