Excel VBA クリップボードに値を設定

 https://qiita.com/Q11Q/items/c688646dfdb5923c0ebd


今使っているアプリに組み込んでテストをするために転記。

ExcelのSelection.Copyだと改行が含まれてしまうので改行が含まれないようにするためにクリップボードへ直接値を設定してみる。

やっぱりすごい人がいっぱいいるんだなぁ。



標準モジュール

' https://msdn.microsoft.com/ja-jp/vba/access-vba/articles/retrieve-information-from-the-clipboard

' http://keirivba.hateblo.jp/entry/2017/11/03/234832

' [Docs/Windows/Desktop/Data Exchange/Clipboard/Clipboard Overviews](https://docs.microsoft.com/en-us/windows/desktop/dataxchg/clipboard-overviews)

'''''''''''''''''''''''''''''''''''''

' Class Module

' ClipBoardClass

' Win 64/32

''''''''''''''''''''''''''''''''''''''''

#If VBA7 Then

Private Declare PtrSafe Function OpenClipboard Lib "User32" (ByVal hWnd As LongPtr) As Long

Private Declare PtrSafe Function CloseClipboard Lib "User32" () As Long

Private Declare PtrSafe Function GetClipboardData Lib "User32" (ByVal wFormat As _

LongPtr) As Long

Private Declare PtrSafe Function EmptyClipboard Lib "User32" () As LongPtr

Private Declare PtrSafe Function GlobalSize Lib "kernel32" (ByVal hMem As LongPtr) As LongPtr

'クリップボードにデータを渡す

Private Declare PtrSafe Function SetClipboardData Lib "User32" ( _

ByVal wFormat As Long, _

ByVal hMem As LongPtr) As LongPtr


'指定したサイズ分のメモリを割り当て

Private Declare PtrSafe Function GlobalAlloc Lib "kernel32" ( _

ByVal wFlags As Long, _

ByVal dwBytes As LongPtr) As LongPtr


'メモリブロックをロックして最初の1バイトへのポインタを返す

Private Declare PtrSafe Function GlobalLock Lib "kernel32" ( _

ByVal hMem As LongPtr) As LongPtr


'メモリのロックを解除

Private Declare PtrSafe Function GlobalUnlock Lib "kernel32" ( _

ByVal hMem As LongPtr) As Long

'バッファに文字列をコピー

Private Declare PtrSafe Function lstrcpy Lib "kernel32" ( _

ByVal lpString1 As Any, _

ByVal lpString2 As Any) As LongPtr

#Else

'Open close get globalalloc GlobalLock GloablUnlock GlobalSize lstcpy Empty

Private Declare Function OpenClipboard Lib "User32" (ByVal hWnd As Long) _

As Long

Private Declare Function CloseClipboard 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, 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" (ByVal lpString1 As Any, _

ByVal lpString2 As Any) As Long

#End If

'GlobalALock

Private Const GHND = &H42

' SetClipboadData

Private Const CF_TEXT = &H1

Private Const CF_LINK = &HBF00

Private Const CF_BITMAP = 2

Private Const CF_METAFILE = 3

Private Const CF_DIB = 8

Private Const CF_PALETTE = 9

Private Const MAXSIZE = 4096

Public Sub ClsClipBoardClass_Err()

OpenClipboard (0)

EmptyClipboard

CloseClipboard

End Sub


Public Function SetClipBoard(MyString As String)

#If VBA7 Then

Dim hGlobalMemory As LongPtr

Dim lpGlobalMemory As LongPtr

Dim hClipMemory As LongPtr

Dim X As LongPtr

#Else

Dim hGlobalMemory As Long

Dim lpGlobalMemory As Long

Dim hClipMemory As Long

Dim X As Long

#End If

'移動可能なグローバルメモリを割り当て

hGlobalMemory = GlobalAlloc(GHND, LenB(MyString) + 1)

'ブロックをロックして、メモリへのfarポインタを取得

lpGlobalMemory = GlobalLock(hGlobalMemory)

'文字列をグローバルメモリへコピー

lpGlobalMemory = lstrcpy(lpGlobalMemory, MyString)

'メモリのロックを解除します。

If GlobalUnlock(hGlobalMemory) <> 0 Then

MsgBox "メモリのロックを解除できません" & vbCrLf & _

"処理が失敗しました"

GoTo OutOfHere2

End If


'データをコピーするクリップボードを開く

If OpenClipboard(0&) = 0 Then

MsgBox "クリップボードを開くことができません" & vbCrLf & _

"処理が失敗しました"

Exit Function

End If


' クリップボードの内容を消去

X = EmptyClipboard()


' データをクリップボードへコピー

hClipMemory = SetClipboardData(CF_TEXT, hGlobalMemory)


OutOfHere2:

'クリップボードの状態チェック

If CloseClipboard() = 0 Then

MsgBox "クリップボードを閉じることができません"

End If

End Function


Public Function ClipBoard_GetData()

#If VBA7 Then

Dim hClipMemory As LongPtr

Dim lpClipMemory As LongPtr

#Else

Dim hClipMemory As Long

Dim lpClipMemory As Long

#End If

Dim MyString As String

Dim RetVal As Long


If OpenClipboard(0&) = 0 Then

MsgBox "Cannot open Clipboard. Another app. may have it open"

Exit Function

End If


' 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


' Lock Clipboard memory so we can reference

' the actual data string.

lpClipMemory = GlobalLock(hClipMemory)


If Not IsNull(lpClipMemory) Then

MyString = Space$(MAXSIZE)

RetVal = lstrcpy(MyString, lpClipMemory)

RetVal = GlobalUnlock(hClipMemory)

' Peel off the null terminating character.

MyString = Mid(MyString, 1, InStr(1, MyString, Chr$(0), 0) - 1)

Else

MsgBox "Could not lock memory to copy string from."

End If


OutOfHere:

RetVal = CloseClipboard()

ClipBoard_GetData = MyString

End Function


''''SampleCode For Module

' 標準モジュール用のコードです

' Classモジュールでは動きません。かならず標準モジュールに記述してください。


'Sub ClipBoardClassTest()

'' 標準モジュール用のコードです

'On Error GoTo Clip_Error

'' Dim and New For ClipBoadClass

'Dim clsClip As ClipBoardClass: Set clsClip = New ClipBoardClass

'clsClip.SetClipBoard ("test1")

'Debug.Print clsClip.ClipBoard_GetData

'Clip_Error:

'Call clsClip.ClsClipBoardClass_Err

'End Sub



利用例

Sub ClipBoardClassTest()

' 標準モジュール用のコードです

On Error GoTo Clip_Error

' Dim and New For ClipBoadClass

Dim clsClip As ClipBoardClass: Set clsClip = New ClipBoardClass

clsClip.SetClipBoard ("test1")

Debug.Print clsClip.ClipBoard_GetData

Clip_Error:

Call clsClip.ClsClipBoardClass_Err

End Sub

0 件のコメント:

コメントを投稿

PowerShellでEdgeを自動化(インストール不要。参考:郵便追跡サービス自動操作)

1.経緯について  RPAのソフトをインストールできないので、これまでVBSでCreateObjectでブラウザの自動操作をすることがたまにあった。 ※いざというときの手札として持っているだけで安心感が段違い  見た目上IEがインストールされていなくても、CreateObject...