tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルクリップボードデータの文字化けについて
記事No8931
投稿日: 2009/05/12(Tue) 16:12
投稿者take
いつもお世話になります。

Windows XP SP3
Visual Basic Express Edition
VB初心者です。

エクセルデータをクリップボードに取り込むところでつまずいてしまいました。
Excel2003で"XML Spreadsheet"という形式で取り込むと文字化けせずに取り込めるのですが、Excel2000にはこの形式がなく、仕方なくHTML形式で取り込むと日本語が文字化けしてしまいます。
罫線情報なども欲しいため、HTML形式で取り込みたいです。
テキストの変換なども調べて試してみたのですが、力不足でわかりませんでした。
どなたかご教示お願いできませんでしょうか。


  Dim Cliphtml As String

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Try
      Dim ClipData As IDataObject = Clipboard.GetDataObject() 'クリップボードデータの取得
      Dim CFTbl() As String = ClipData.GetFormats(False)
      For i As Integer = 0 To CFTbl.Length - 1
        Select Case CFTbl(i)
          Case DataFormats.Html

            Cliphtml = ClipData.GetData(DataFormats.GetFormat(CFTbl(i)).Name, False)

            '************************************************
            '*   ここで適切に変換保存できるのでしょうか?   *
            '************************************************

            'My.Computer.FileSystem.WriteAllText("html.txt", Cliphtml, False)

        End Select
      Next
    Catch ex As Exception
      MsgBox(ex.Message)
    End Try
  End Sub

  Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Try
      Dim SetClipData As New DataObject
      SetClipData.SetData(DataFormats.Html, False, Cliphtml)
      Clipboard.Clear()
      Clipboard.SetDataObject(SetClipData, True)
    Catch ex As Exception
      MsgBox(ex.Message)
    End Try
  End Sub


(エクセル範囲を選択し、Button1でクリップボードに取り込み、エクセルの選択を解除してからButton2でクリップボードにデータを登録し、貼り付けると文字化けしています。)

[ツリー表示へ]
タイトルRe: クリップボードデータの文字化けについて
記事No8940
投稿日: 2009/05/14(Thu) 06:24
投稿者花ちゃん
HTML 形式で取得したいなら、一旦、HTML 形式で保存してから取得するとか?

Excel側で<meta http-equiv=Content-Type content="text/html; charset=shift_jis">
のような設定をしておくとか?
(Excel 2000 の WEB オプション の設定はどのようになっていますか?)

クリップボードから取得したデータには、上記の charset= はどのようになっていますか?
あるいは、取得してから、その部分(charset)を追加したらどうなりますか?

そもそも、取得して、何に表示したいのか?とか詳しい前後のようすや環境を書かないと
他の人が見た場合理解しがたい場合があります。
コードを投稿される場合は、何をしようとしているのか、コメント等を付加しないと
間違っているのか、そのような仕様なのか判断できない場合があります。

レスがつかない場合、質問内容がキチンと見ている人に伝わっていない場合が殆どです。

[ツリー表示へ]
タイトルRe^2: クリップボードデータの文字化けについて
記事No8941
投稿日: 2009/05/14(Thu) 08:48
投稿者take
説明不足で申し訳ありません。

エクセルで作業している時に、後でちょっと使いたい表、関数等をクリップボード経由でファイルに保存しておき、後で再利用するようなものを考えています。なのでエクセルで取得し、エクセルに貼り付けます。

Excel2000のWEBオプションのエンコードでドキュメントを保存する形式は日本語(シフトJIS)になっています。既定のエンコードでWebページを保存するにチェックを入れてもだめでした。

クリップボードから取得したデータは、<meta http-equiv=Content-Type content="text/html; charset=utf-8">になっています。utf-8をshift_jisにしてもだめでした。

文字化けしたデータは、抜粋ですが
    font-family:"・ュ・ウ ・ー譏取悃", serif;
  <td height=16 class=xl26 width=64 style='height:12.0pt;width:48pt'>貂ャ轤ケ</td>
  <td class=xl28 width=64 style='border-left:none;width:48pt'>螳滓命謨ー驥・/td>
  x:fmla="=IF(B2-C2=0,"ツア0",B2-C2)">+25.400</td>
のようになっています。

大変申し訳ありません、ご助力をお願いします。

[ツリー表示へ]
タイトルRe^3: クリップボードデータの文字化けについて
記事No8942
投稿日: 2009/05/14(Thu) 10:31
投稿者花ちゃん
> 説明不足で申し訳ありません。
> エクセルで作業している時に、後でちょっと使いたい表、関数等をクリップボード経由でファイルに保存しておき、後で再利用するようなものを考えています。なのでエクセルで取得し、エクセルに貼り付けます。

先にも言いましたが前後の詳しい情報を教えて頂かないと、貴方のやりたい事(結果)は
何となく理解できますが、その方法がまったく理解できません。

>クリップボード経由でファイルに保存
どのような形式で保存するつもりでしょうか?

>エクセルに貼り付けます。
どのようにして貼り付けるのでしょうか?

文字化けするのがExcelに貼り付けた時に文字化けするなら問題かも知れませんが、
そうでないなら問題ないのでは。

下記を試した限りでは、貴方が考えているような方法ではうまく行かない(役に立たない)
ように思います。

Private myHtm As String
Private Sub Button1_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles Button1.Click
    Dim iData As IDataObject = Clipboard.GetDataObject()
    If iData.GetDataPresent(DataFormats.Html) Then
        myHtm = CType(iData.GetData(DataFormats.Html), String)
    End If
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles Button2.Click
   Clipboard.SetDataObject(New DataObject)
   System.Windows.Forms.Clipboard.SetDataObject(myHtm, True)
End Sub

[ツリー表示へ]
タイトルRe^4: クリップボードデータの文字化けについて
記事No8943
投稿日: 2009/05/14(Thu) 11:40
投稿者take
またまた説明不足で申し訳ありません。

エクセルの作業でクリップボードを監視し、変更された場合にそれを取り込んでいます。
データは Dim obj as Object = ClipData.GetData(DataFormats.Html, False)
で取り出し、バイナリーファイルで保存しています。
貼り付け時はSetData(DataFormats.Html, False, obj)でDataObjectにデータを設定し、クリップボードにSetDataObjectしています。ユーザーはこれをエクセルで右クリックから貼り付けます。
"XML Spreadsheet"という形式で取り込んだ場合は、上記方法で適切に貼り付けられますが、Html形式で取り込んだ場合は文字化けしてしまいます。

このような説明でよろしいでしょうか。
どうかお願いします。

[ツリー表示へ]
タイトルRe^5: クリップボードデータの文字化けについて
記事No8944
投稿日: 2009/05/14(Thu) 12:37
投稿者花ちゃん
文字化けだけを問題にされているなら、英数だけで作ったセルの情報や関数はうまく
取得でき、貼り付けてそのまま使用できますか?
例えば、 =SUM(A1:B1) とかは。 それらを、別の位置のセルに貼り付けた場合は。

[ツリー表示へ]
タイトルRe^6: クリップボードデータの文字化けについて
記事No8945
投稿日: 2009/05/14(Thu) 13:21
投稿者take
ありがとうございます。

> 例えば、 =SUM(A1:B1) とかは。 それらを、別の位置のセルに貼り付けた場合は。
正しく貼り付けでき使用できます。
漢字も全てが化けるのでは無く、末尾に変なものが付いていたり、”合計”の計の”言”は正しくても後ろの”十”が化けていたりです。

[ツリー表示へ]
タイトルRe^7: クリップボードデータの文字化けについて
記事No8952
投稿日: 2009/05/14(Thu) 19:18
投稿者花ちゃん
> 正しく貼り付けでき使用できます。
ヒョットして "XML Spreadsheet"という形式で取り込んだ場合の話ではないですよね。

それは、最初に投稿されたコード(方法)で、できたと言う事ですか?
(HTML 形式で取得して、正しく貼り付けできたと言う事ですよね)


英数だけで作ったセルの情報や関数はうまく取得でき、貼り付けてそのまま使用
できますか?
と私が、言ったのは、英数だけを使用した場合は、HTML形式で取得しても文字化けしない
はずだから、それを使って正しく動作しますかとお尋ねしたのですが。
(勿論使用フォント名も半角の英数名のものを使って)

HTML 形式で取得した場合は、その時点でテキストファイルにフォーマットされているので
文字化けを解消しても、Excelの関数情報等は、削除されていて取得できないと私は
思ったので、=SUM(A1:B1) はどうなりますかと確認して貰ったのですが。

[ツリー表示へ]
タイトルRe^8: クリップボードデータの文字化けについて
記事No8957
投稿日: 2009/05/14(Thu) 22:30
投稿者take
HTML形式で取り込むと、最初に投稿したコードで関数情報も取得でき、そして使用できます。ただし全部ではないですが漢字が化けます。
最初のコードでテキストファイルに書き出しているのは、HTMLがどうなっているか見てみたかったからで、実際はオブジェクトをバイナリーファイルで保存しています。

すみません、よろしくお願いします。

[ツリー表示へ]
タイトルRe^9: クリップボードデータの文字化けについて
記事No8960
投稿日: 2009/05/15(Fri) 06:10
投稿者花ちゃん
> 最初のコードでテキストファイルに書き出しているのは、HTMLがどうなっているか
>見てみたかったからで、実際はオブジェクトをバイナリーファイルで保存しています。

だったら最初からそのように書いておくか、実際に使っているコードを投稿して
頂かないと。

貴方の方法に合うかどうかは、確認はしておりませんが、下記のような方法も。
(私は、前記の理由から出来ないように思うのですが...。)
http://social.msdn.microsoft.com/Forums/ja-JP/vsfeedbackja/thread/d33fde27-d994-4fac-85cf-34ef7159c2cc

[ツリー表示へ]
タイトルRe^10: クリップボードデータの文字化けについて
記事No8963
投稿日: 2009/05/15(Fri) 09:56
投稿者take
ほんとに申し訳ありません。
ご指示のサイトを参考にしてみたのですが、JAVAからの変換が理解できていないのか、やはり文字化けしてうまくいきません。情けない限りです。
下記がなんとかエラーを取ったコードです。ぜんぜん的外れなのでしょうか。


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Try
      Dim ClipData As IDataObject = Clipboard.GetDataObject() 'クリップボードデータの取得
      Dim CFTbl() As String = ClipData.GetFormats(False)
      For i As Integer = 0 To CFTbl.Length - 1
        Select Case CFTbl(i)
          Case DataFormats.Html

            Dim CData As Object = ClipData.GetData(DataFormats.Html)
            Dim b As Byte() = System.Text.Encoding.UTF8.GetBytes(CData)
            Dim ms As New System.IO.MemoryStream()
            ms.Write(b, 0, b.Length)
            Dim buf As Byte() = ms.ToArray

            Me.TextBox1.Text = System.Text.Encoding.UTF8.GetString(buf)

        End Select
      Next
    Catch ex As Exception
      MsgBox(ex.Message)
    End Try
  End Sub

[ツリー表示へ]
タイトルRe^11: クリップボードデータの文字化けについて
記事No8964
投稿日: 2009/05/15(Fri) 11:02
投稿者花ちゃん
>             Dim CData As Object = ClipData.GetData(DataFormats.Html)
   この時点で、string に変換(文字化け)されているので、それをバイナリで
  保存しても意味がないのでは(文字化けしたテキストをエンコードしても元に戻らない)

   Dim CData As Object = ClipData.GetData(DataFormats.Html)
   Debug.WriteLine(TypeName(CData))
   Debug.WriteLine(CData)

  HTML形式のフォーマットを使用する以上エンコードはできない(HTML Format は、
 MemoryStreamオブジェクトとしてデータを取得できない)と思ったので、この方法では
  うまく取得できないのではと申し上げているのです。
  (但し、私が知らないだけかも知れませんが) 

 例えば、ホームページビルダーのようなソフトで取得するとエンコードは正しくされて
 おり文字化けはありませんが、HTML 形式には、書式情報はあっても、Excel の関数の
 ようなものはないので、変換の過程で無視されて取得する事ができませんよね。
 (関数の記入の部分を文字扱いにすれば取得設定する事はできそうですが)

[ツリー表示へ]
タイトルRe^12: クリップボードデータの文字化けについて
記事No8965
投稿日: 2009/05/15(Fri) 11:28
投稿者take
ありがとうございました。

GetDataした時点で、string に変換(文字化け)されているのではだめな気がします。

もう少しだけ考えてみます。

[ツリー表示へ]
タイトルRe: クリップボードデータの文字化けについて
記事No8969
投稿日: 2009/05/15(Fri) 14:06
投稿者魔界の仮面弁士
> Excel2003で"XML Spreadsheet"という形式で取り込むと文字化けせずに取り込めるのですが、
> Excel2000にはこの形式がなく、仕方なくHTML形式で取り込むと日本語が文字化けしてしまいます。

手元に Excel 2007 しか無いので確認できないのですが、クリップボード形式の中に、
バイナリ交換ファイル形式はありませんでしたか? (Biff8 など)

BIFF ならば書式情報も含まれていると思うので…。

[ツリー表示へ]
タイトルRe^2: クリップボードデータの文字化けについて
記事No8970
投稿日: 2009/05/15(Fri) 14:23
投稿者take
ありがとうございます。

Biff8なら書式情報は入っているのですが、関数情報が抜けてしまいます。

ほんとすみません。

[ツリー表示へ]
タイトルRe: クリップボードデータの文字化けについて
記事No8983
投稿日: 2009/05/19(Tue) 09:02
投稿者take
えいるさんのサイトを参考にさせていただきました。

http://d.hatena.ne.jp/nagakura_eil/20071019/1192765159

下のコードはサイトのC#をVBに変換しています。
コードがすべて適切に変換されているか、良くわかりませんが、動作させると文字化けはなくなりました。

ただ、ちょっと疑問点があります。
半角スペースが続くと”?”に変換されます。これは半角スペースに置換して対応しようと思います。
また、DataObjectにSetDataする際に”DataFormats.Text”形式でしないとうまくいきません。”DataFormats.Html”では文字化けします。”DataFormats.Text”でSetDataするとExcelの形式を選択して貼り付けで、HTML形式は出てこないで、UnicodeTextとTextになり、UnicodeTextで貼り付けるとうまくいきます。

えいるさんにはお忙しい中、とても親切に対応していただきました。
また、皆様ありがとうございました。



  Friend ClipD As Object
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Try
      Dim MyClip As New MyClipboard
      ClipD = MyClip.GetHTMLFormatData(Nothing)
    Catch ex As Exception
      MsgBox(ex.Message)
    End Try
  End Sub

  Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Try
      Dim SetClipData As New DataObject
      SetClipData.SetData(DataFormats.Text, False, ClipD) 'Textフォーマットで書くと正しくHtmlが出力される?
      Clipboard.Clear()
      Clipboard.SetDataObject(SetClipData, True)
    Catch ex As Exception
      MsgBox(ex.Message)
    End Try
  End Sub


Public Class MyClipboard

  Declare Function GetClipboardData Lib "user32.dll" (ByVal uFormat As UInt32) As IntPtr
  Declare Function OpenClipboard Lib "user32.dll" (ByVal hWndNewOwner As IntPtr) As Boolean
  Declare Function CloseClipboard Lib "user32.dll" () As Boolean
  Declare Function RegisterClipboardFormatA Lib "user32.dll" (ByVal lpszFormat As String) As UInt32
  Declare Function IsClipboardFormatAvailable Lib "user32.dll" (ByVal format As UInt32) As Boolean
  Declare Function GlobalLock Lib "kernel32.dll" (ByVal hMem As IntPtr) As IntPtr
  Declare Function GlobalSize Lib "kernel32.dll" (ByVal hMem As IntPtr) As UInt32
  Declare Function GlobalUnlock Lib "kernel32.dll" (ByVal hMem As IntPtr) As IntPtr

  Function GetHTMLFormatData(ByVal handle As IntPtr) As String
    GetHTMLFormatData = ""
    Try
      Dim CF_HTML As UInt32 = RegisterClipboardFormatA("HTML Format")

      If IsClipboardFormatAvailable(CF_HTML) = False Then Return ""
      If OpenClipboard(handle) = False Then Return ""
      Dim hGMem As IntPtr = GetClipboardData(CF_HTML)
      Dim pMFP As IntPtr = GlobalLock(hGMem)
      Dim len As UInt32 = GlobalSize(hGMem)
      Dim bytes As Byte()
      ReDim bytes(len)
      Marshal.Copy(pMFP, bytes, 0, len)

      Dim strMFP As String = System.Text.Encoding.UTF8.GetString(bytes) 'UTF8固定
      GlobalUnlock(hGMem)
      CloseClipboard()
      GetHTMLFormatData = strMFP
    Catch ex As Exception
      MsgBox(ex.Message & " GetHTMLFormatData")
    End Try
  End Function

End Class

[ツリー表示へ]