Office関連

Office クリップボードをマクロで操作する(MSAA)

MSDNフォーラムに質問がありましたが、Office クリップボードをマクロで操作するのは一定の需要があるので、以前書いたマクロ(下記参照)を書き直してみました。

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 クリップボードを操作するためだけに処理を複雑にするのも問題ですので、この機能がどうしても必要でない場合は、実装しない方向で調整しても良いのではないかと思います。

関連記事

関連記事

  1. Office関連

    すべてのテーブルの結合を解除するWordマクロ

    すべてのテーブルのセル結合を解除するWordマクロを考えてみました(W…

  2. Office関連

    Microsoft Graph SDK for PHPを使ったAPIの呼び出しサンプル

    知らない間に(恐らくBuild 2017のタイミングに合わせて)Mic…

  3. Office関連

    ExcelのWebクエリからのアクセス情報

    mougに面白い質問がありました。・Querytables.a…

  4. Office関連

    Officeのヘルプを単独で開く。

    Officeアプリケーションのヘルプが見たいとき、いちいちアプリケーシ…

コメント

  • コメント (0)

  • トラックバックは利用できません。

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

Time limit is exhausted. Please reload CAPTCHA.

最近の記事

アーカイブ

RapidSSL_SEAL-90x50
PAGE TOP