echo("備忘録");

IT技術やプログラミング関連など、技術系の事を備忘録的にまとめています。

【VBA】ファイルをクリップボードにコピーする(Win32API不使用)

超久しぶりの記事&超久しぶりにVBAの記事。
(てか、VBAって時点でネタ切れ感が…)

「(何かの)ファイルをクリップボードにコピーする」という場合の処理。
(要はファイルのコピー)

VBAクリップボードにコピー...という場合、よくあるのは「MSForms.DataObject」を使用する方法。

ただこれだと「テキスト」や「bitmap画像」はうまくいくけど「ファイルそのもの」のコピーはうまくいかない。
(VBAだから、Excel上でやり取りするデータ、という前提なのかも)

あと、Win32API関数を使用しても出来るけど、何個も関数を呼ぶ必要があるので、できればもっと単純にしたい。
(OpenClipboard()→EmptyClipboard()→SetClipboardData()→closeClipBoard()という流れ)

ということで、色々調べてたら、こんな感じで実装できた。
※簡略化のため、エラー処理とかはかなり端折ってます。
※dir_pathは対象ファイルの格納フォルダパス、file_nameはファイル名です。

Dim objShell As object
Dim objDir As object

Set objShell = CreateObject("Shell.Application")
Set objDir = objShell.Namespace(CVar(dir_path))
If (Not objDir Is Nothing) Then

    Dim objFile As object
    Set objFile = objDir.ParseName(file_name)

    For Each verb In objFile.Verbs
        If verb.Name = "コピー(&C)" Then
            verb.doit
            Exit For
       End If
    Next

    Set objFile = Nothing
End If

Set objDir = Nothing
Set objShell = Nothing

※参考:『ファイルをコピーしクリップボードに格納した状態』(田吾作) エクセル Excel [エクセルの学校]

処理の流れとしては

  1. Shell.Applicationオブジェクトを作成して
  2. 1のNameSpaceメソッドでFolderオブジェクト、またそのParseNameメソッドでFolderItemオブジェクトを取得して
  3. 2のVerbsコレクションからファイルのメニュー一覧を取得して「コピー(&C)」なら、それを実行する

という感じ。

ただ、2の「NameSpaceメソッド」で、フォルダパスをVariant型で渡さないとエラーになるので注意。
(まあ、公式ドキュメントにはちゃんと書いてあるけど...)

ただ、今回はコピーのみが必要だったから「貼り付け」の処理は実施してない。
機会があったら、調べてみようと思います。

てか、次はXamarinとかPythonとか、あとReact、Vue.js、Ionicなんかの触りの部分もやってみたいな。