クリップボードのテキストデータを取得する関数を書いてみた
コピーした文字列をエクセルのシートのセルA1に書き込んでみる場合
文字をコピーしてから
関数を実行で
書き込めた!
これだけ!
書いたのが
Private Declare Function OpenClipboard Lib "User32" (ByVal hwnd As Long) As Long
Private Declare Function CloseClipboard Lib "User32" () As Long
Private Declare Function EmptyClipboard Lib "User32" () As Long
Private Declare Function GetClipboardData Lib "User32" (ByVal wFormat As Long) As Long
Private Declare Function SetClipboardData Lib "User32" (ByVal wFormat As Long, ByVal hMem As Long) As Long
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalSize Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long
Public Const CF_TEXT As Long = 1
Function クリップボードのテキストを返す2() As String
Dim RetVal As Long
Dim cData As Long
Dim mAddress As Long
Dim gSize As Long
Dim MyString As String
If OpenClipboard(0) = 0 Then
MsgBox "クリップボードを開けない、他のアプリが使っている可能性が巨レ存"
Exit Function
End If
cData = GetClipboardData(CF_TEXT)
If cData = 0 Then
MsgBox "クリップボードにテキストはなかったよ"
RetVal = CloseClipboard()
Exit Function
End If
mAddress = GlobalLock(cData)
If mAddress = 0 Then
MsgBox "メモリをロックできなかったよ"
RetVal = CloseClipboard()
Exit Function
End If
gSize = GlobalSize(mAddress)
MyString = String(gSize, Chr(0))
RetVal = lstrcpy(MyString, mAddress)
GlobalUnlock (cData)
MyString = Left(MyString, InStr(1, MyString, Chr(0)) - 1)
RetVal = CloseClipboard()
クリップボードのテキストを返す2 = MyString
End Function
Sub クリップボードにテキストがあればA1に書き込む()
ActiveSheet.Range("a1").Value = クリップボードのテキストを返す()
End Sub
画像だと
始まりはエクセルのシート上にある図形、グラフ、スマートアートその他を
個別に画像として保存したいってのがあって
これがエクセルだけだとうまくいかない
でも難しいので最初はテキストデータからになった
テキストデータがある場合は動くけれどない場合にエラーになる
画像をコピーして実行すると
エラーになる
赤枠のところが原因
' Obtain the handle to the global memory
' block that is referencing the text.
hClipMemory = GetClipboardData(CF_TEXT)
If IsNull(hClipMemory) Then
MsgBox "Could not allocate memory"
GoTo OutOfHere
End If
クリップボードのテキストデータの有無の判定にIsNullってのを使っていて
これがうまく判定できていないみたい、エクセルだから?
If cData = 0 Then
MsgBox "クリップボードにテキストはなかったよ"
RetVal = CloseClipboard()
Exit Function
End If
エクセル用?に0かそれ以外で判定するように書き換えた結果は
メッセージを表示して終了できた
GetClipboardData 関数
とか見てもデータがなかった場合はNullが返ってくるって書いてあるのは
エクセル用の説明じゃないからかな、難しい…
Nullってのが馴染みがなくてNothingやEmptyとどう違うのか検索すると
これもエクセルではなくてアクセス用だけど、ややこしくてよくわからんw
実際にどんな値が入ってどんな判定になるのがやってみた結果
Dim cData As Long
If cData = Null Then Debug.Print "null"
If cData = 0 Then Debug.Print "0"
If cData = Empty Then Debug.Print "empty"
Debug.Print IsNull(cData)
Debug.Print IsEmpty(cData)
Debug.Print TypeName(cData)
ここまでは何も入っていない状態での判定結果
ここから入れてからの判定
cData = GetClipboardData(CF_TEXT)
If cData = Null Then Debug.Print "null"'→nullではない
If cData = 0 Then Debug.Print "0"
If cData = Empty Then Debug.Print "empty"
Debug.Print IsNull(cData)
Debug.Print IsEmpty(cData)
Debug.Print TypeName(cData)
入れてからの判定でIsNullがTrueを返していればあっているけどFalseだから
IsNullでは判定できないのがわかった
テキストデータがある場合はLong型の値、数値が入るので判定は
0かそれ以外の数値ですることにした
これも解説があるけど
MSForms.DataObjectってのを使ってあるんだけど
これがうまくいかない、特に
クリップボードに書き込むのができなくてググっていたら
【Wordマクロ】
クリップボードへのデータ入力・取得のエラーへの対処|みんなのワードマクロ
説明されているエラーの対処法に
APIが使われている
やっぱり
APIかあ、ハンドルってのがよくわかんないんだよなあ
本当はこんなにカオスなコメント付きの全文画像