VBAで System.Windows.Clipboardを使いたい への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 (削除されました)  ()
投稿日時
2018/9/6 19:37:15
(削除されました)
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2018/9/6 18:45:39
>> Word VBA には Clipboard という名のオブジェクトやメンバーも無いはずですし。
> WordにはClipboardが無いのですね。
Word ではなく Word VBA の話をしています…。
VBA エディタ上で [F2] キーを押して表示されるオブジェクト ブラウザー上にも
「Clipboard」という名のオブジェクトは用意されていませんよね、という話。
ちなみに VB2005 には「Clipboard」という名のオブジェクトが用意されていて、
たとえば、現在保持されているデータ形式の一覧を得るといったこともできます。
メモ帳のテキストをコピーしていた場合は、"Text" や "UnicodeText" 形式、
エクスプローラーでファイルを選択してコピーした場合には
"File" や "FileW" 形式などが並んでいることを確認できます。
> WordのVBAでPasteメソッドで貼り付けできるので、
はい。Copy / Cut / Paste メソッドを通じての単純操作程度であれば、
Word VBA からでも行えます。
しかし上記 VB2005 の例のように、クリップボード内に格納されている
データ形式を列挙したり、あるいは特定の形式のみを再加工して
書き戻すためのクラスやメソッドは、「標準では」用意されていません。
(Word 上での列挙や加工が必要な場合は、前々回の回答をご覧ください)
> マイクロソフトのオフィスに共通する、クリップボードに相当するデータ領域が有るのかと想像していました。
クリップボードは、OS が 1 つだけ管理している、データ共有のためのリソースです。
その「Windows 上で単一の共有資源」であるクリップボードを、
VB2005 と Word VBA のそれぞれから読み書きしているだけです。
他のアプリがコピー操作を行うと、前に保持されていた内容が失われるのも
単一の共有資源であるがゆえのことです。
> 「Office クリップボードを使用する」等の表現がネット上でありましたので。
OS からクリップボード変更通知(クリップボード チェイン)を受け取ると、
Office はその内容を履歴として退避する機能があります。
それが Office クリップボード。
Word VBA の Application.ShowClipboard メソッドによって
Word にトグル表示されるペインがこれですね。
しかしこれは、あくまでデータを複製しているだけあり、
「Windows のクリップボード」はあくまでも一つだけです。
また、この履歴データの内容を直接再加工するような機能は
Word VBA には用意されていないと思います。
> WordにはClipboardが無いのですね。
Word ではなく Word VBA の話をしています…。
VBA エディタ上で [F2] キーを押して表示されるオブジェクト ブラウザー上にも
「Clipboard」という名のオブジェクトは用意されていませんよね、という話。
ちなみに VB2005 には「Clipboard」という名のオブジェクトが用意されていて、
たとえば、現在保持されているデータ形式の一覧を得るといったこともできます。
ListBox1.Items.Clear()
For Each fmt As String In Clipboard.GetDataObject().GetFormats()
ListBox1.Items.Add(fmt)
Next
メモ帳のテキストをコピーしていた場合は、"Text" や "UnicodeText" 形式、
エクスプローラーでファイルを選択してコピーした場合には
"File" や "FileW" 形式などが並んでいることを確認できます。
> WordのVBAでPasteメソッドで貼り付けできるので、
はい。Copy / Cut / Paste メソッドを通じての単純操作程度であれば、
Word VBA からでも行えます。
しかし上記 VB2005 の例のように、クリップボード内に格納されている
データ形式を列挙したり、あるいは特定の形式のみを再加工して
書き戻すためのクラスやメソッドは、「標準では」用意されていません。
(Word 上での列挙や加工が必要な場合は、前々回の回答をご覧ください)
> マイクロソフトのオフィスに共通する、クリップボードに相当するデータ領域が有るのかと想像していました。
クリップボードは、OS が 1 つだけ管理している、データ共有のためのリソースです。
その「Windows 上で単一の共有資源」であるクリップボードを、
VB2005 と Word VBA のそれぞれから読み書きしているだけです。
他のアプリがコピー操作を行うと、前に保持されていた内容が失われるのも
単一の共有資源であるがゆえのことです。
> 「Office クリップボードを使用する」等の表現がネット上でありましたので。
OS からクリップボード変更通知(クリップボード チェイン)を受け取ると、
Office はその内容を履歴として退避する機能があります。
それが Office クリップボード。
Word VBA の Application.ShowClipboard メソッドによって
Word にトグル表示されるペインがこれですね。
しかしこれは、あくまでデータを複製しているだけあり、
「Windows のクリップボード」はあくまでも一つだけです。
また、この履歴データの内容を直接再加工するような機能は
Word VBA には用意されていないと思います。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2018/9/6 18:32:17
そういうバージョン情報は、最初に書いておいていただけると助かります。
> クリップボードに代入しているのはVB2005でMy.Computer.Clipboard.SetText() を使用しています。
それは System.Windows.Clipboard クラスではなく
System.Windows.Forms.Clipboard クラスです。紛らわしいですよね…。
(といっても、両者に機能的な差異は無いのですが)
System.Windows.Clipboard という名のクラスも存在しているのですが、
それは、.NET Framework 3.0 以降で利用可能な
WPF (Windows Presentation Foundation) 用のクラスなのです。
VB2005 が対応しているのは .NET Framework 2.0 ですので、
そもそも WPF アプリケーションを作成できません。
また My.Computer の Clipboard プロパティが返すオブジェクトは、
Microsoft.VisualBasic.MyServices 名前空間の ClipboardProxy クラスです。
これの SetText メソッドでは、内部的に、
System.Windows.Forms.Clipboard クラスを呼び出しています。
System.Windows.Clipboard クラスでありません。
> クリップボードの仕組みは良く理解しておりません。
まずは前提知識の確認。
下記の 3 点についてはご存知でしょうか?
(1)クリップボードは、アプリケーションごとに所有されているものではなく、OS 全体で単一のリソースです。
(2)一回のコピー操作では、一つのデータを表すために、同時に複数の形式のデータが書き込まれます。
これについては、Excel シート上で右クリックしたときに「形式を選択して貼り付け」という選択肢を選んでみると分かりやすいでしょう。
(Excel で対応していない形式は表示されないですけど)
(3)貼り付け操作時には、そのアプリが対応している形式が記録されているかどうかを調べ、それを貼り付けます。
対応形式が複数あった場合、どの形式で貼り付けられるのかは、貼り付け先アプリケーションの実装次第です。
たとえば、クリップボード上に画像をコピーしておいても、
それをメモ帳に貼ることができないことはご存知ですよね。
その理由が上記 (3) というわけです。
メモ帳は画像形式は扱えないので、貼り付け操作が行われません。
ただし画像形式と同時に、テキストや Unicode テキスト形式が
保持されている場合は、そのテキストが貼られることになります。
> クリップボードに代入しているのはVB2005でMy.Computer.Clipboard.SetText() を使用しています。
それは System.Windows.Clipboard クラスではなく
System.Windows.Forms.Clipboard クラスです。紛らわしいですよね…。
(といっても、両者に機能的な差異は無いのですが)
System.Windows.Clipboard という名のクラスも存在しているのですが、
それは、.NET Framework 3.0 以降で利用可能な
WPF (Windows Presentation Foundation) 用のクラスなのです。
VB2005 が対応しているのは .NET Framework 2.0 ですので、
そもそも WPF アプリケーションを作成できません。
また My.Computer の Clipboard プロパティが返すオブジェクトは、
Microsoft.VisualBasic.MyServices 名前空間の ClipboardProxy クラスです。
これの SetText メソッドでは、内部的に、
System.Windows.Forms.Clipboard クラスを呼び出しています。
System.Windows.Clipboard クラスでありません。
> クリップボードの仕組みは良く理解しておりません。
まずは前提知識の確認。
下記の 3 点についてはご存知でしょうか?
(1)クリップボードは、アプリケーションごとに所有されているものではなく、OS 全体で単一のリソースです。
(2)一回のコピー操作では、一つのデータを表すために、同時に複数の形式のデータが書き込まれます。
これについては、Excel シート上で右クリックしたときに「形式を選択して貼り付け」という選択肢を選んでみると分かりやすいでしょう。
(Excel で対応していない形式は表示されないですけど)
(3)貼り付け操作時には、そのアプリが対応している形式が記録されているかどうかを調べ、それを貼り付けます。
対応形式が複数あった場合、どの形式で貼り付けられるのかは、貼り付け先アプリケーションの実装次第です。
たとえば、クリップボード上に画像をコピーしておいても、
それをメモ帳に貼ることができないことはご存知ですよね。
その理由が上記 (3) というわけです。
メモ帳は画像形式は扱えないので、貼り付け操作が行われません。
ただし画像形式と同時に、テキストや Unicode テキスト形式が
保持されている場合は、そのテキストが貼られることになります。
投稿者 ひでと  (社会人)
投稿日時
2018/9/6 16:24:51
ありがとうございます。
>まずは、今回扱う予定のクリップボードフォーマットを教えてください。
>CF_TEXT では無いのですよね?
>https://docs.microsoft.com/en-us/windows/desktop/dataxchg/standard-clipboard-formats
>形式が不明な場合は、ツール等で調べておいてください。
>再加工が目的なら、フォーマットがわからないと先に進めませんので。
>https://www.officedaytime.com/clipmm/
>http://www.freeclipboardviewer.com/
クリップボードの仕組みは良く理解しておりません。
クリップボードに代入しているのはVB2005でMy.Computer.Clipboard.SetText() を使用しています。
> そこで、WordのClipboadにVBからデータを送ることも考えるのですが、
>クリップボードは全アプリケーションで共有されるものなので、
>「WordのClipboad」という表現には違和感があります。😅
>Word VBA には Clipboard という名のオブジェクトやメンバーも無いはずですし。
WordにはClipboardが無いのですね。
WordのVBAでPasteメソッドで貼り付けできるので、なにかのデータ領域が有るのだと思い、VB2005から利用できないかと思ったわけです。
>また、ここでいう「VB」とは、どのバージョンの Visual Basic のことでしょうか?
>System.Windows.Clipboard というからには、.NET Framework 3.0 以降のはずなので、
>とりあえず VB2005 以下ということは無さそうですが。
VB2005を未だに使用しています。
> WordのClipboadにデータが転送されているということだと思うのですが
>どういう意味でしょうか?
>(クリップボードの仕組みを、正しく理解されていないような気が…)
マイクロソフトのオフィスに共通する、クリップボードに相当するデータ領域が有るのかと想像していました。
>Range.Paste メソッド
>クリップボードの内容を、指定範囲に挿入します。
と有り、「Office クリップボードを使用する」等の表現がネット上でありましたので。
その領域はVBから参照できるSystem.Windows.Clipboardの領域とは別領域で、
Wordで貼り付けをすると、System.Windows.ClipboardのデータをWordがオフィスのクリップボードにコピーし、さらにその内容をDocumentに貼り付けるという処理がWordで自動で行われるのかと想像していました。
現状、WordのVBA上で、RangeオブジェクトにPastし、RangeオブジェクトをDeleteする、その間にデータを取得してみようと以下のようにしてみました。
Function ClipbordText() As String
Dim objRange As Range
Set objRange = Selection.Range
objRange.Paste
ClipbordText = objRange.Text
objRange.Delete
End Function
これで、VB2005のMy.Computer.Clipboard.SetText()で作成したClipboardの中のテキストが取得できました。今回の目的としては、このテキストを加工して、再びPastすることでしたので、一応目的は達成しているように思います。
ただ、クリップボードの内容(仕組み)については理解していないとのご指摘、ごもっともですので、勘違いを指摘いただければ助かります。
>まずは、今回扱う予定のクリップボードフォーマットを教えてください。
>CF_TEXT では無いのですよね?
>https://docs.microsoft.com/en-us/windows/desktop/dataxchg/standard-clipboard-formats
>形式が不明な場合は、ツール等で調べておいてください。
>再加工が目的なら、フォーマットがわからないと先に進めませんので。
>https://www.officedaytime.com/clipmm/
>http://www.freeclipboardviewer.com/
クリップボードの仕組みは良く理解しておりません。
クリップボードに代入しているのはVB2005でMy.Computer.Clipboard.SetText() を使用しています。
> そこで、WordのClipboadにVBからデータを送ることも考えるのですが、
>クリップボードは全アプリケーションで共有されるものなので、
>「WordのClipboad」という表現には違和感があります。😅
>Word VBA には Clipboard という名のオブジェクトやメンバーも無いはずですし。
WordにはClipboardが無いのですね。
WordのVBAでPasteメソッドで貼り付けできるので、なにかのデータ領域が有るのだと思い、VB2005から利用できないかと思ったわけです。
>また、ここでいう「VB」とは、どのバージョンの Visual Basic のことでしょうか?
>System.Windows.Clipboard というからには、.NET Framework 3.0 以降のはずなので、
>とりあえず VB2005 以下ということは無さそうですが。
VB2005を未だに使用しています。
> WordのClipboadにデータが転送されているということだと思うのですが
>どういう意味でしょうか?
>(クリップボードの仕組みを、正しく理解されていないような気が…)
マイクロソフトのオフィスに共通する、クリップボードに相当するデータ領域が有るのかと想像していました。
>Range.Paste メソッド
>クリップボードの内容を、指定範囲に挿入します。
と有り、「Office クリップボードを使用する」等の表現がネット上でありましたので。
その領域はVBから参照できるSystem.Windows.Clipboardの領域とは別領域で、
Wordで貼り付けをすると、System.Windows.ClipboardのデータをWordがオフィスのクリップボードにコピーし、さらにその内容をDocumentに貼り付けるという処理がWordで自動で行われるのかと想像していました。
現状、WordのVBA上で、RangeオブジェクトにPastし、RangeオブジェクトをDeleteする、その間にデータを取得してみようと以下のようにしてみました。
Function ClipbordText() As String
Dim objRange As Range
Set objRange = Selection.Range
objRange.Paste
ClipbordText = objRange.Text
objRange.Delete
End Function
これで、VB2005のMy.Computer.Clipboard.SetText()で作成したClipboardの中のテキストが取得できました。今回の目的としては、このテキストを加工して、再びPastすることでしたので、一応目的は達成しているように思います。
ただ、クリップボードの内容(仕組み)については理解していないとのご指摘、ごもっともですので、勘違いを指摘いただければ助かります。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2018/9/5 17:00:12
まずは、今回扱う予定のクリップボードフォーマットを教えてください。
CF_TEXT では無いのですよね?
https://docs.microsoft.com/en-us/windows/desktop/dataxchg/standard-clipboard-formats
形式が不明な場合は、ツール等で調べておいてください。
再加工が目的なら、フォーマットがわからないと先に進めませんので。
https://www.officedaytime.com/clipmm/
http://www.freeclipboardviewer.com/
> そこで、WordのClipboadにVBからデータを送ることも考えるのですが、
クリップボードは全アプリケーションで共有されるものなので、
「WordのClipboad」という表現には違和感があります。😅
Word VBA には Clipboard という名のオブジェクトやメンバーも無いはずですし。
また、ここでいう「VB」とは、どのバージョンの Visual Basic のことでしょうか?
System.Windows.Clipboard というからには、.NET Framework 3.0 以降のはずなので、
とりあえず VB2005 以下ということは無さそうですが。
> WordのClipboadにデータが転送されているということだと思うのですが
どういう意味でしょうか?
(クリップボードの仕組みを、正しく理解されていないような気が…)
CF_TEXT では無いのですよね?
https://docs.microsoft.com/en-us/windows/desktop/dataxchg/standard-clipboard-formats
形式が不明な場合は、ツール等で調べておいてください。
再加工が目的なら、フォーマットがわからないと先に進めませんので。
https://www.officedaytime.com/clipmm/
http://www.freeclipboardviewer.com/
> そこで、WordのClipboadにVBからデータを送ることも考えるのですが、
クリップボードは全アプリケーションで共有されるものなので、
「WordのClipboad」という表現には違和感があります。😅
Word VBA には Clipboard という名のオブジェクトやメンバーも無いはずですし。
また、ここでいう「VB」とは、どのバージョンの Visual Basic のことでしょうか?
System.Windows.Clipboard というからには、.NET Framework 3.0 以降のはずなので、
とりあえず VB2005 以下ということは無さそうですが。
> WordのClipboadにデータが転送されているということだと思うのですが
どういう意味でしょうか?
(クリップボードの仕組みを、正しく理解されていないような気が…)
投稿者 ひでと  (社会人)
投稿日時
2018/9/5 16:32:30
>魔界の仮面弁士様、ありがとうございます。
Wordの貼り付けで、クリップボードに保存していたテキストデータが貼り付けできていたので、簡単に出来るかな?と思っていました。
APIまでとなるとハードルが高いです。
そこで、WordのClipboadにVBからデータを送ることも考えるのですが、
この場合、WordのClipboadが開いているBookに固有のものですと、処理が難しくなりそうです。
疑問に思うのは、Wordで貼り付けをするとSystem.Windows.Clipboardの内容が貼り付けできることです。
そうすると、WordのClipboadにデータが転送されているということだと思うのですが、これを利用することは出来ないのでしょうか。
Wordの貼り付けで、クリップボードに保存していたテキストデータが貼り付けできていたので、簡単に出来るかな?と思っていました。
APIまでとなるとハードルが高いです。
そこで、WordのClipboadにVBからデータを送ることも考えるのですが、
この場合、WordのClipboadが開いているBookに固有のものですと、処理が難しくなりそうです。
疑問に思うのは、Wordで貼り付けをするとSystem.Windows.Clipboardの内容が貼り付けできることです。
そうすると、WordのClipboadにデータが転送されているということだと思うのですが、これを利用することは出来ないのでしょうか。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2018/9/5 13:31:04
Word VBA から行えるのは、コピー&ペースト程度に限られますので、
そうした内容の加工は Word VBA だけでは無理ですね。
標準機能から行えるのは、せいぜいテキストの加工ぐらいでしょう。
より高度なやりとりが必要なら、OpenClipboard を始めとする
Win32 API 群を呼び出すことになります。
http://www.geocities.co.jp/SiliconValley-Bay/9960/vb/api/clip.html
CreateObject で InternetExplorer.Application から呼び出せる
IE の .clipboardData オブジェクトも、扱えるのは text 形式と url 形式だけですし。
HTML5 の Clipboard API も、今回の要件を満たせなさそう。
http://officetanaka.net/excel/vba/tips/tips81.htm
それ以外だと、VB6 や .NET 等で、クリップボード操作用の ActiveX DLL 等を
作成して、それを Excel から CreateObject で利用することもできます。
VBA 以外の開発知識と開発環境が必要になりますけれど。
> 検索するとオフィスクリップボード?のことが出てきますが
それは、Word.Application の ShowClipboad メソッドでトグル表示できる
[Office クリップボード] 作業ウィンドウのことではないでしょうか。
> 表題に関する資料が見つけられません。
> VBAで System.Windows.Clipboardを使いたい
System.Windows.Clipboard クラス(System.Windows.Clipboard.dll)や
System.Windows.Forms.Clipboard クラス(System.Windows.Forms.dll)は
.NET から利用するためのものなので、Word からは直接呼び出せません。
そうした内容の加工は Word VBA だけでは無理ですね。
標準機能から行えるのは、せいぜいテキストの加工ぐらいでしょう。
より高度なやりとりが必要なら、OpenClipboard を始めとする
Win32 API 群を呼び出すことになります。
http://www.geocities.co.jp/SiliconValley-Bay/9960/vb/api/clip.html
CreateObject で InternetExplorer.Application から呼び出せる
IE の .clipboardData オブジェクトも、扱えるのは text 形式と url 形式だけですし。
HTML5 の Clipboard API も、今回の要件を満たせなさそう。
http://officetanaka.net/excel/vba/tips/tips81.htm
それ以外だと、VB6 や .NET 等で、クリップボード操作用の ActiveX DLL 等を
作成して、それを Excel から CreateObject で利用することもできます。
VBA 以外の開発知識と開発環境が必要になりますけれど。
> 検索するとオフィスクリップボード?のことが出てきますが
それは、Word.Application の ShowClipboad メソッドでトグル表示できる
[Office クリップボード] 作業ウィンドウのことではないでしょうか。
> 表題に関する資料が見つけられません。
> VBAで System.Windows.Clipboardを使いたい
System.Windows.Clipboard クラス(System.Windows.Clipboard.dll)や
System.Windows.Forms.Clipboard クラス(System.Windows.Forms.dll)は
.NET から利用するためのものなので、Word からは直接呼び出せません。
投稿者 (削除されました)  ()
投稿日時
2018/9/5 13:23:05
(削除されました)
投稿者 ひでと  (社会人)
投稿日時
2018/9/5 09:22:56
お世話になります。
VBで入力したクリップボードの内容を、Wordから使用したいと思います。
検索するとオフィスクリップボード?のことが出てきますが、表題に関する資料が見つけられません。
WordのVBAの使用方法になるのかと思いますが、アドバイスを御願いします。
Wordの文章の中でクリップボードの内容を加工処理して、数式(OMath)として貼り付けしたいのです。
VBで入力したクリップボードの内容を、Wordから使用したいと思います。
検索するとオフィスクリップボード?のことが出てきますが、表題に関する資料が見つけられません。
WordのVBAの使用方法になるのかと思いますが、アドバイスを御願いします。
Wordの文章の中でクリップボードの内容を加工処理して、数式(OMath)として貼り付けしたいのです。
上記だと、文字列データしか受け渡せませんね。
データを文字列としてだけではなく、「複数の形式」でコピーしたい場合は、
下記の構文を使うことができます。
> 数式(OMath)として貼り付けしたいのです。
次は OMath の話。
現行の Word VBA で OMath を書くために、たとえばこんなコードを使えますよね。
Microsoft 数式エディタ時代の Word だとダメですが。
Word 上に書いたこの数式をコピーしてみると、その時のクリップボード内には
MathML 形式、リッチテキスト形式、HTML 形式、Unicode テキスト形式、
メタファイル画像形式などなど、数多くの形式でコピーされていることを確認できるかと思います。
格納されている形式を確認する方法は、既に何通りか紹介しているので
先の回答をご覧いただければと思います。
でもって、Word の数式で扱われるクリップボードデータでは、
主となる形式は MathML 形式となっています。
これは下記のような XML データとして保持されています。
上記をコピーして、Word に貼ってみてください。同じ数式が現れるかと思います。
(この時、先頭の <?xml の前に改行や空白等が入らないように注意してください)
といっても、ブラウザーから直接 Word にコピペすると、
『HTML 形式』が優先されて貼り付けられてしまう可能性がありますので、
一度、ただのテキスト形式に変換しておく必要があります。
ここでは上記を、一度「メモ帳」に貼りつけて、それをメモ帳で全選択してから
テキストしてコピーしなおし、それを Word 上に貼り付けてみてください。
これにより『テキスト形式』に変化しますので、数式が現れるかと思います。
この方法を応用すれば、Word VBA 単体でも のようにして、MathML から 数式(OMath) を貼り付けることが可能となります。
もしもこれを とすれば、HTML 形式で貼り付けられることになりますね。
ただし Word 2007 以降であったとしても、2003 までの旧型式(*.doc)のファイルに対して
呼び出した場合は、数式ではなく XML 文字列のまま貼り付けられてしまうという点と、
WdPasteDataType で指定した形式のデータがクリップボードに無い場合には
実行時エラーになってしまうという点については注意しておいてください。