Excel VBAの覚え書(クリップボード編)~Microsoft FormsのDataObjectによるClipboard操作
Excelでクリップボード操作を行う場合、Microsoft Formsで提供されている、DataObjectを使用するのが便利です。
もともとクリップボードはWindowsが提供している機能ですので、Excel VBAでクリップボードを取扱う場合も、Windows APIを使用すればきめ細かな操作が可能ですが、使用方法が煩雑なので、通常はDataObjectで充分だと思います。
■Microsoft Formsの概要
Excelのワークシート上で使用できる標準的なフォーム(ユーザ・フォーム、コマンド・ボタン、テキスト・ボックス等の各種コントロール)には、フォーム・コントロールとActveXコントロールの2種類があり、ActiveXコントロールを提供しているのがMicrosoft Formsです。
[開発]タブで[挿入]をクリックすると、下図のようなコントロールの一覧が表示されますが、下半分にある「ActiveX コントロール」がMicrosoft Formsに対応しており、1段目には「コマンド・ボタン」「コンボ・ボックス」「チェック・ボックス」「リスト・ボックス」「テキスト・ボックス」「スクロール・バー」、2段目に「スピン・ボタン」「オプション・ボタン」「ラベル」「イメージ」「トグル・ボタン」「コントロールの選択」といったボタンが並んでいます。
DataObjectはコントロールではありませんので、この一覧には表示されておらず、プログラムの中でインスタンス化して使用します。
■DataObjectの詳細
DataObjectで提供されている機能と使用方法を説明します。
DataObjectのメソッド
DataObjectで提供されているメソッドは、下表の通りです(プロパティはありません)。
⇒詳細はMicrosoftのサイト(Microsoft Forms)を参照して下さい。
(DataObjectのメソッド)
Clearメソッド | |||||||||||
説明 | DataObject上にある全てのデータを削除する | ||||||||||
定義 | Sub Clear() | ||||||||||
GetFormatメソッド | |||||||||||
説明 | DataObject上にあるデータの形式を示す整数値を取得する
(※)Formatで指定したデータが存在する場合、Trueを返す |
||||||||||
定義 | Function GetFormat(Format As Variant) As Boolean | ||||||||||
GetFromClipboardメソッド | |||||||||||
説明 | クリップボードからDataObjectにデータをコピーする | ||||||||||
定義 | Sub GetFromClipboard() | ||||||||||
GetTextメソッド | |||||||||||
説明 | 指定した形式を使用して、DataObjectからテキスト文字列を取得する | ||||||||||
定義 | Function GetText([Format As Variant]) As String | ||||||||||
PutInClipboardメソッド | |||||||||||
説明 | DataObjectからクリップボードにデータを移動する | ||||||||||
定義 | Sub PutInClipboard() | ||||||||||
SetTextメソッド | |||||||||||
説明 | 指定した形式を使用して、テキスト文字列をDataObjectにコピーする | ||||||||||
定義 | Sub SetText(Text As String, [Format As Variant]) | ||||||||||
StartDragメソッド | |||||||||||
説明 | DataObjectのドラッグ・アンド・ドロップ操作を開始する
(※)fmDropEffect列挙体の値は、以下の通り。 |
||||||||||
定義 | Function StartDrag(OKEffect As Variant) As fmDropEffect |
(※)Formatの値は、以下の通り。
1:テキスト形式
文字列または1以外の整数:ユーザー定義のDataObject形式(SetTextメソッドで設定した値)
DataObjectを使用するための事前準備
DataObjectを使用するための事前準備は、以下の3ステップです。
⇒オブジェクトを使用するための事前準備とオブジェクトブラウザによる調査方法については、Excel VBAでオブジェクト指向プログラミング(事前準備編)を参照して下さい。
①ライブラリの参照設定
Visual Basic Editor(VBE)のファイルメニューから[ツール]-[参照設定]を選択し、
参照設定ダイアログで[参照]ボタンを押下し、使用する「FM20.DLL(※)」を指定し、
Microsoft Forms 2.0 Object Libraryのチェックボックスにチェックを入れ、[OK]ボタンを押下。
(※)64ビット版は「C:\Windows\SysWOW64\FM20.DLL」、32ビット版は「C:\Windows\System32\FM20.DLL」を選択します。
なお、ActiveXコントロールを使用すると、自動的に参照設定されます。
②オブジェクト変数の定義
プログラムの宣言部でオブジェクト変数を定義。
- Dim cb As DataObject
③インスタンスの生成
プログラムの処理部でインスタンスを生成。
- Set cb = New DataObject
- 'ここにオブジェクトを使用した処理を記述
- Set cb = Nothing
■DataObjectの使用方法
基本的な使用法は、以下の通りです。
クリップボードにテキストを設定
SetTextメソッドでDataObjectにテキストをコピーし、PutInClipboardメソッドでクリップボードに移動します。
- cb.SetText 文字列
- cb.PutInClipboard
Format引数を省略した場合は『1(テキスト)』が仮定されますので、「cb.SetText 文字列」は「cb.SetText 文字列, 1」と同義です。
クリップボードからテキストを取得
GetFromClipboardメソッドでクリップボードからDataObjectにデータをコピーし、GetTextメソッドでDataObjectからテキストを取得します。
- cb.GetFromClipboard
- 文字列 = cb.GetText
DataObjectにテキストデータが入っていることを確認し、データがある場合だけテキストを取得したい場合は、以下のようにコーディングします。
- cb.GetFromClipboard
- If cb.GetFormat(1) = True Then
- 文字列 = cb.GetText
- End If
Formatを明示したい場合は、「文字列 = cb.GetText」を「文字列 = cb.GetText(1)」のようにコーディングします。
■クリップボード関連のデータ形式
クリップボード関連データの形式については、DataObject、Excel、Windowsでそれぞれ取扱いが異なりますので、順に説明します。
DataObjectのデータ形式~GetFormatメソッド
DataObjectで扱えるデータはテキストのみですが、SetTextメソッドのFormat引数に1以外の値を指定することにより、DataObjectに複数のデータを登録することが可能です。
- cb.SetText 文字列, 2
- cb.SetText 文字列, 3
- 文字列 = cb.GetText(2)
- 文字列 = cb.GetText(3)
SetTextメソッドのFormat引数に指定した値がデータ形式を表しますので、GetTextメソッドのFormat引数でデータ形式を指定すれば、該当するデータを取出すことができますが、PutInClipboardメソッドでクリップボードに登録すると、データ形式を表す値が別の値に変換されてしまいます(詳細は次項を参照して下さい)。
DataObjectに登録されているデータ形式を確認するためには、GetFormatメソッドを使用しますが、Format引数を省略できないため、「実行結果がTrueであれば、そのデータ形式が登録されている」と判断するしかありません。
Excelにおけるクリップボードのデータ形式~ClipboardFormatsプロパティ
Excelでクリップボード操作を行う際、通常はRangeオブジェクト等のCopyメソッドやCutメソッドを使用しますが、この場合、セルに入力された値(Valueプロパティ)だけではなく、さまざまな形式のデータがクリップボードに格納されます。
ApplicationオブジェクトのClipboardFormatsプロパティを参照すると、クリップボードに登録された全データの形式を参照することができます。
以下のサンプル・プログラムを実行すると、ExcelシートのA列にクリップボードに登録されているデータ形式が一覧で表示されます。
- Dim Tbl As Variant
- Dim cnt As Integer
- Dim i As Integer
- Private Sub Sample1()
- Set sht = ActiveSheet
- Tbl = Application.ClipboardFormats
- cnt = 0
- For i = LBound(Tbl) To UBound(Tbl)
- cnt = cnt + 1
- sht.Cells(cnt, 1) = Tbl(i)
- Next i
- End Sub
Excelの標準データ形式については、下表の通りXlClipboardFormat列挙体で定義されています。
(XlClipboardFormat列挙体)
名前 | 値 | |
---|---|---|
XlClipboardFormat列挙体 | ||
xlClipboardFormatText | 0 | |
xlClipboardFormatVALU | 1 | |
xlClipboardFormatPICT | 2 | |
xlClipboardFormatPrintPICT | 3 | |
xlClipboardFormatDIF | 4 | |
xlClipboardFormatCSV | 5 | |
xlClipboardFormatSYLK | 6 | |
xlClipboardFormatRTF | 7 | |
xlClipboardFormatBIFF | 8 | |
xlClipboardFormatBitmap | 9 | |
xlClipboardFormatWK1 | 10 | |
xlClipboardFormatLink | 11 | |
xlClipboardFormatDspText | 12 | |
xlClipboardFormatCGM | 13 | |
xlClipboardFormatNative | 14 | |
xlClipboardFormatBinary | 15 | |
xlClipboardFormatTable | 16 | |
xlClipboardFormatOwnerLink | 17 | |
xlClipboardFormatBIFF2 | 18 | |
xlClipboardFormatObjectLink | 19 | |
xlClipboardFormatBIFF3 | 20 | |
xlClipboardFormatEmbeddedObject | 21 | |
xlClipboardFormatEmbedSource | 22 | |
xlClipboardFormatLinkSource | 23 | |
xlClipboardFormatMovie | 24 | |
xlClipboardFormatToolFace | 25 | |
xlClipboardFormatToolFacePICT | 26 | |
xlClipboardFormatStandardScale | 27 | |
xlClipboardFormatStandardFont | 28 | |
xlClipboardFormatScreenPICT | 29 | |
xlClipboardFormatBIFF4 | 30 | |
xlClipboardFormatObjectDesc | 31 | |
xlClipboardFormatLinkSourceDesc | 32 | |
xlClipboardFormatBIFF12 | 63 |
Windowsにおけるクリップボードのデータ形式~EnumClipboardFormats関数、GetClipboardFormatName関数
WindowsのAPIを使用してクリップボード操作を行う場合は、user32.dllで提供されているAPIを使用します。
EnumClipboardFormats関数を使用すると、クリップボードに登録された全データの形式を参照することができます。
Windows標準のデータ形式については、下表の通り定義されています(Excelの標準データ形式とは、値が異なります)が、これ以外のデータ形式については、GetClipboardFormatName関数でデータ形式の名前を取得することができます。
(Windows標準のデータ形式)
名前 | 値 | |
---|---|---|
Windows標準のデータ形式 | ||
CF_TEXT | 1 | |
CF_BITMAP | 2 | |
CF_METAFILEPICT | 3 | |
CF_SYLK | 4 | |
CF_DIF | 5 | |
CF_TIFF | 6 | |
CF_OEMTEXT | 7 | |
CF_DIB | 8 | |
CF_PALETTE | 9 | |
CF_PENDATA | 10 | |
CF_RIFF | 11 | |
CF_WAVE | 12 | |
CF_UNICODETEXT | 13 | |
CF_ENHMETAFILE | 14 | |
CF_HDROP | 15 | |
CF_LOCALE | 16 | |
CF_DIBV5 | 17 | |
CF_OWNERDISPLAY | &H80 | |
CF_DSPTEXT | &H81 | |
CF_DSPBITMAP | &H82 | |
CF_DSPMETAFILEPICT | &H83 | |
CF_DSPENHMETAFILE | &H8E | |
CF_PRIVATEFIRST | &H200 | |
CF_PRIVATELAST | &H2FF | |
CF_GDIOBJFIRST | &H300 | |
CF_GDIOBJLAST | H3FF |
■サンプル・プログラム~クリップボード関連のデータ形式を一覧表示する処理
DataObject経由でクリップボードにデータを登録したうえ、A列にDataObjectのデータ形式、B列にExcelにおけるクリップボードのデータ形式、C列にWindowsにおけるクリップボードのデータ形式を表示するExcelツールです。
メイン・プロシジャ
行番号10~11で文字列をDataObjectとクリップボードに登録した後、行番号13~19でDataObjectのデータ形式、行番号21~26でExcelにおけるクリップボードのデータ形式、行番号28~33でWindowsにおけるクリップボードのデータ形式を表示しています。
行番号28~33の処理の中では、行番号28でGetFormat関数(※)を呼び出し、戻って来たvbLf区切りの文字列をSplit関数で配列に格納したうえ、行番号30~33で配列の各要素をExcelシートに転記しています。
(※)GetFormat関数は自作の関数ですが、Windows APIを使用しているため、標準モジュール内に記述する必要があります。
- Dim sht As Worksheet
- Dim cb As DataObject
- Dim Tbl As Variant
- Dim cnt As Integer
- Dim i As Integer
- Private Sub Sample2()
- Set sht = ActiveSheet
- Set cb = New DataObject
- cb.SetText “test"
- cb.PutInClipboard
- 'DataObjectのデータ形式を表示
- cnt = 0
- For i = 0 To 255
- If cb.GetFormat(i) = True Then
- cnt = cnt + 1
- sht.Cells(cnt, 1) = i
- End If
- Next i
- 'Excelにおけるクリップボードのデータ形式を表示
- Tbl = Application.ClipboardFormats
- cnt = 0
- For i = LBound(Tbl) To UBound(Tbl)
- cnt = cnt + 1
- sht.Cells(cnt, 2) = Tbl(i)
- Next i
- 'Windowsにおけるクリップボードのデータ形式を表示
- Tbl = Split(GetFormat, vbLf)
- cnt = 0
- For i = LBound(Tbl) To UBound(Tbl)
- cnt = cnt + 1
- sht.Cells(cnt, 3) = Tbl(i)
- Next i
- Set cb = Nothing
- Set sht = Nothing
- End Sub
GetFormat関数
GetFormat関数はWindows APIを使用して、Windowsにおけるクリップボードのデータ形式を全て取得し、vbLf区切りの文字列にして返す関数です。
行番号14でクリップボードをオープンし、行番号18~56の繰返し処理を行い、行番号57でクリップボードをクローズしています。
繰返し処理の中は、行番号19でデータ形式を取得し、行番号22~47でWindows標準のデータ形式、行番号50でWindows標準でないデータ形式の名称を取得しています。
- Option Explicit
- Declare Function OpenClipboard Lib “user32.dll" _
- (ByVal hWndNewOwner As Long) As Long
- Declare Function EnumClipboardFormats Lib “user32.dll" _
- (ByVal format As Long) As Long
- Declare Function GetClipboardFormatName Lib “user32.dll" Alias “GetClipboardFormatNameA" _
- (ByVal format As Long, ByVal lpszFormatName As String, ByVal cchMaxCount As Long) As Long
- Declare Function CloseClipboard Lib “user32.dll" () As Long
- Dim rc As Long
- Dim fc As Long
- Dim buf As String
- Function GetFormat() As String
- rc = OpenClipboard(Application.Hwnd)
- If rc <> 0 Then
- GetFormat = “"
- fc = 0
- Do
- fc = EnumClipboardFormats(fc)
- If fc <> 0 Then
- Select Case fc
- Case 1: buf = “CF_TEXT"
- Case 2: buf = “CF_BITMAP"
- Case 3: buf = “CF_METAFILEPICT"
- Case 4: buf = “CF_SYLK"
- Case 5: buf = “CF_DIF"
- Case 6: buf = “CF_TIFF"
- Case 7: buf = “CF_OEMTEXT"
- Case 8: buf = “CF_DIB"
- Case 9: buf = “CF_PALETTE"
- Case 10: buf = “CF_PENDATA"
- Case 11: buf = “CF_RIFF"
- Case 12: buf = “CF_WAVE"
- Case 13: buf = “CF_UNICODETEXT"
- Case 14: buf = “CF_ENHMETAFILE"
- Case 15: buf = “CF_HDROP"
- Case 16: buf = “CF_LOCALE"
- Case 17: buf = “CF_DIBV5"
- Case &H80: buf = “CF_OWNERDISPLAY"
- Case &H81: buf = “CF_DSPTEXT"
- Case &H82: buf = “CF_DSPBITMAP"
- Case &H83: buf = “CF_DSPMETAFILEPICT"
- Case &H8E: buf = “CF_DSPENHMETAFILE"
- Case &H200: buf = “CF_PRIVATEFIRST"
- Case &H2FF: buf = “CF_PRIVATELAST"
- Case &H300: buf = “CF_GDIOBJFIRST"
- Case &H3FF: buf = “CF_GDIOBJLAST"
- Case Else
- buf = String(255, vbNullChar)
- rc = GetClipboardFormatName(fc, buf, 254&)
- buf = Left(buf, rc)
- End Select
- GetFormat = GetFormat & fc & “:" & buf & vbLf
- End If
- DoEvents
- Loop Until fc = 0
- rc = CloseClipboard()
- End If
- End Function
実行結果(1)~DataObject経由でクリップボードに登録した場合のデータ形式
前掲のサンプル・プログラムを実行すると、以下のような結果が表示されます。
1 | 0 | 49161:DataObject |
13 | 44 | 1:CF_TEXT |
13:CF_UNICODETEXT | ||
49171:Ole Private Data | ||
16:CF_LOCALE | ||
7:CF_OEMTEXT |
実行結果(2)~直接クリップボードに登録した場合のデータ形式
前掲のサンプル・プログラム中、行番号10~11のDataObjectに登録する処理をコメント・アウトしたうえ、Excelシートの任意のセルをCtrl+Cで直接クリップボードに登録してプログラムを実行すると、以下のような結果が表示されます。
0 | 49161:DataObject | |
2 | 14:CF_ENHMETAFILE | |
4 | 3:CF_METAFILEPICT | |
5 | 2:CF_BITMAP | |
6 | 49627:Biff12 | |
7 | 49604:Biff8 | |
8 | 49606:Biff5 | |
9 | 4:CF_SYLK | |
11 | 5:CF_DIF | |
12 | 49625:XML Spreadsheet | |
14 | 49322:HTML Format | |
17 | 13:CF_UNICODETEXT | |
19 | 1:CF_TEXT | |
22 | 49607:Csv | |
23 | 49624:Hyperlink | |
31 | 49450:Rich Text Format | |
32 | 49163:Embed Source | |
33 | 49156:Native | |
42 | 49155:OwnerLink | |
44 | 49166:Object Descriptor | |
45 | 49165:Link Source | |
50 | 49167:Link Source Descriptor | |
58 | 49603:Link | |
63 | 129:CF_DSPTEXT | |
49154:ObjectLink | ||
49171:Ole Private Data | ||
16:CF_LOCALE | ||
7:CF_OEMTEXT | ||
8:CF_DIB | ||
17:CF_DIBV5 |
出版社:インプレス
発売日:2022/3/23
単行本(ソフトカバー):A5判/912ページ
出版社:技術評論社
発売日:2021/1/9
単行本(ソフトカバー):A5判/800ページ
出版社:技術評論社
発売日:2019/11/25
単行本(ソフトカバー):B5変形判/576ページ
ディスカッション
コメント一覧
まだ、コメントがありません