MSDNフォーラムに質問がありましたが、Office クリップボードをマクロで操作するのは一定の需要があるので、以前書いたマクロ(下記参照)を書き直してみました。
- Office クリップボードをマクロで操作する(Office 2003)
- http://www.ka-net.org/office/of55.html
- Office クリップボードをマクロで操作する(Office 2007以降)
- http://www.ka-net.org/office/of56.html
Option Explicit
Private Declare Function AccessibleChildren Lib "oleacc" ( _
ByVal paccContainer As IAccessible, _
ByVal iChildStart As Long, _
ByVal cChildren As Long, _
ByRef rgvarChildren As Any, _
ByRef pcObtained As Long) As Long
Public Sub Sample()
'DoActionOfficeClipboard "すべて貼り付け"
DoActionOfficeClipboard "すべてクリア"
End Sub
Private Sub DoActionOfficeClipboard(ByVal ButtonName As String)
'Officeクリップボードコマンド実行
Dim accClipboard As IAccessible
Dim accCollectPage As IAccessible
Dim accButton As IAccessible
Dim tmp As Boolean
Dim i As Long
Const CommandBarName = "Office Clipboard"
Const ROLE_SYSTEM_PROPERTYPAGE = &H26
Const ROLE_SYSTEM_PUSHBUTTON = &H2B
Const CHILDID_SELF = &H0&
Select Case ButtonName
Case "すべて貼り付け", "すべてクリア"
Case Else
MsgBox "指定したコマンドには対応していません。" & vbNewLine & _
"「すべて貼り付け」か「すべてクリア」のどちらかを指定してください。", _
vbCritical + vbSystemModal
Exit Sub
End Select
With Application.CommandBars(CommandBarName)
tmp = .Visible
.Visible = True
End With
DoEvents
Set accClipboard = Application.CommandBars(CommandBarName)
If accClipboard Is Nothing Then GoTo Fin
'旧バージョンOffice対応
Set accCollectPage = GetAccessibleObject(accClipboard, _
"Collect and Paste 2.0", _
ROLE_SYSTEM_PROPERTYPAGE)
If Not accCollectPage Is Nothing Then
For i = 1 To accCollectPage.accChildCount
If (accCollectPage.accName(i&) = ButtonName) And _
(accCollectPage.accRole(i&) = ROLE_SYSTEM_PUSHBUTTON) Then
accCollectPage.accDoDefaultAction i&
Exit For
End If
Next
Else
'新バージョンOffice対応
Set accCollectPage = GetAccessibleObject(accClipboard, _
"クリップボード", _
ROLE_SYSTEM_PROPERTYPAGE)
If Not accCollectPage Is Nothing Then
Set accButton = GetAccessibleObject(accCollectPage, _
ButtonName, _
ROLE_SYSTEM_PUSHBUTTON)
If accButton Is Nothing Then GoTo Fin
accButton.accDoDefaultAction CHILDID_SELF
Else
MsgBox "クリップボードウィンドウが見つかりませんでした。" & vbNewLine & _
"処理を中止します。 ", vbCritical + vbSystemModal
End If
End If
Fin:
Application.CommandBars(CommandBarName).Visible = tmp
End Sub
Private Function GetAccessibleObject(ByVal SrcAccObj As IAccessible, _
ByVal TgtAccName As String, _
ByVal TgtAccRole As Long) As IAccessible
Dim ret As IAccessible
Dim list() As Variant
Dim cnt As Long, i As Long
Const CHILDID_SELF = &H0&
Set ret = Nothing '初期化
If (SrcAccObj.accName(CHILDID_SELF) = TgtAccName) And _
(SrcAccObj.accRole(CHILDID_SELF) = TgtAccRole) Then
Set ret = SrcAccObj
Else
cnt = SrcAccObj.accChildCount
If cnt > 0 Then
ReDim list(cnt - 1)
If AccessibleChildren(SrcAccObj, 0, cnt, list(0), cnt) = 0 Then
For i = LBound(list) To UBound(list)
If TypeOf list(i) Is IAccessible Then
Set ret = GetAccessibleObject(list(i), TgtAccName, TgtAccRole)
If Not ret Is Nothing Then Exit For
End If
Next
End If
End If
End If
Set GetAccessibleObject = ret
End Function
以前書いたコードは、OfficeやOSのバージョンが変わると動作しませんでしたが、今回はバージョンの差異も一応考慮しています(Excel 2007,2010,2016で確認)。
とはいえ、次期バージョンで動作するかは分かりませんし、Office クリップボードを操作するためだけに処理を複雑にするのも問題ですので、この機能がどうしても必要でない場合は、実装しない方向で調整しても良いのではないかと思います。

















この記事へのコメントはありません。