Excelで外部の実行ファイルと連携する【シンプルなコード例付き】

編集履歴：2024/5/12 ⑤を追加しました。

<h1>■はじめに</h1>
初の記事です！

ExcelVBAが好きなので、最初のネタとして選択しました。

Qiitaとしてはネタかぶりしても問題無いだろうとは思ったけど、一応、ネタかぶりするか500件弱の記事タイトルを確認しました
１．「Excel アドイン」で検索してヒットした約380件
２．「VBA Call Shell」で検索してヒットした約110件

<h1>■注意点</h1>
ExcelVBAが好きなだけで詳しいわけではありません。

使用している用語を鵜呑みにしないで下さい。
「確かにそのように動く」ことを書いています。

また、この記事は、Excelをメイン武器にできる環境を持っている人しか恩恵を受けらません。

<h1>■Excel VBA</h1>
「マクロの記録」を使うと、Excel内でできる操作を、再現性のあるコードに出力することができます。

出力したコードは、とても読み辛いものになっているので、ここでVBAを脱落する人も多いのではないでしょうか。
マクロの記録のやり方は、参考記事の項「mink0212様の記事」参照。

マクロには、ショートカットキーを割り当てることもできる。べんり。
「マクロの記録」だけでは分からないものもありますが、そんなときはネットの力を借ります。べんり。

「マクロの記録」の知識だけでは記載できないコード例：
```vb:sample.bas
Sub sample()
  Dim intRow As Integer '行番号
  '1行目から順にA列が空白が現れるまで、A列の文字数をB列に入力する
  intRow = 1 '1行目から開始
  Do While "" <> Cells(intRow, 1).Value
    '空白ではないため、A列の文字数をB列に入力する
    Cells(intRow, 2).Value = Len(Cells(intRow, 1).Value)
    '次の行へ
    intRow = intRow + 1
  Loop
End Sub
```
変数の宣言・代入・取得、Do While文、Cells(行, 列).value, 関数などの知識は、マクロの記録からは得られません。

<h1>■Excelアドイン</h1>
Excel VBAをアドインとして常駐させることで、Excelマクロ有効ブックを開かずに、また、Excelの見た目を変えずに、マクロを呼び出すことができます。

Excelアドインの作成方法も、参考記事の項「mink0212様の記事」参照。（この人のこの記事、とっても分かりやすいですね！）
Excel VBAと同じく、ショートカットキーを割り当てることもできる。べんり。

<h1>■実行ファイルの起動</h1>
私が気に入っているVBAの関数は、Call Shell関数。

実行ファイルを起動する関数といえば、Runメソッドを連想するかも知れない。
RunメソッドはObjectを宣言してからCreateする必要があるけど、Call Shell関数は1行で済むのでラクチン♪

私が実務で使用しているCall Shell関数によるExcel+外部の実行ファイルでの連携を列挙します。

<h2>①エクスプローラー</h2>
Excelに記載されているファイルを開くとき、どのように開いているでしょうか。

ファイル名を指定して実行しているでしょうか。新規エクスプローラーを開いているでしょうか。
このマクロをExcelアドイン登録すれば、ショートカットキー一発です！
（私は「Ctrl+Shift+F」または「Ctrl+Shift+V」に割り当てています）

メイン処理：

:::note info
  Call Shell("explorer.exe /select, " & ファイルのフルパス, vbNormalFocus)
:::
コード例：
```vb:explorer.bas
'ファイルが選択された状態で、エクスプローラーを開く
Sub OpenFolder()
  'ファイル/フォルダのフルパスが入力されたセルを選択し、実行すること
  Call Shell("explorer.exe /select, " & ActiveCell.Value, vbNormalFocus)
End Sub
```

<h2>②サクラエディタ</h2>
コードレビューで、Excelからファイルを開きたいと思ったことはありませんか？
そんなときはこれで解決！このマクロを使えば、grep結果をExcelに貼り付けて一発！
（私はダブルクリックイベント発生時に割り当てています）

メイン処理：

:::note info
  Call Shell(sakura.exeのフルパス & " -Y:" & 行番号 & " " & ファイルのフルパス)
:::
コード例：
```vb:sakura.bas
'セルに記載されているファイルを、サクラエディタにて指定ラインを選択した状態で開く
Sub OpenLine_sakura()
  Dim iRow As Integer
  Dim sExe As String  'サクラエディタの実行ファイル（フルパス）
  Dim sLine As String '開きたい行番号
  Dim sPath As String '開きたいファイル（フルパス）
  iRow = ActiveCell.Row
  sExe = """" & Cells(iRow, 1).Value & """"
  sLine = Cells(iRow, 3).Value
  sPath = """" & Cells(iRow, 2).Value & """"
  '1つでも入力されていなかったらファイルを開かない
  If "" <> sExe And "" <> sLine And "" <> sPath Then
    'ファイルを開く
    Call Shell(sExe & " -Y:" & sLine & " " & sPath)
  End If
End Sub
```

<h2>③秀丸</h2>
内容はサクラエディタと一緒！

メイン処理：

:::note info
  Call Shell(hidemaru.exeのフルパス & " /m3 /j" & 行番号 & " " & ファイルのフルパス)
:::
コード例：
```vb:hidemaru.bas
'セルに記載されているファイルを、秀丸にて指定ラインを選択した状態で開く
Sub OpenLine_hidemaru()
  Dim iRow As Integer
  Dim sExe As String  '秀丸の実行ファイル（フルパス）
  Dim sLine As String '開きたい行番号
  Dim sPath As String '開きたいファイル（フルパス）
  iRow = ActiveCell.Row
  sExe = """" & Cells(iRow, 1).Value & """"
  sLine = Cells(iRow, 3).Value
  sPath = """" & Cells(iRow, 2).Value & """"
  '1つでも入力されていなかったらファイルを開かない
  If "" <> sExe And "" <> sLine And "" <> sPath Then
    'ファイルを開く
    Call Shell(sExe & " /m3 /j" & sLine & " " & sPath)
  End If
End Sub
```

<h2>④WinMerge</h2>
コードレビューと言えば、比較！

このマクロを使えば、比較したいファイル2つをExcelに貼り付けて一発！

メイン処理：

:::note info
  Call Shell(WinMergeU.exeのフルパス & " " & 比較ファイル①のフルパス & " " & 比較ファイル②のフルパス)
:::
コード例：
```vb:winmerge.bas
'セルに記載されている2ファイルを、WinMergeにて比較する
Sub Compare_winmerge()
  Dim iRow As Integer
  Dim sExe As String   'WinMergeの実行ファイル（フルパス）
  Dim sPath1 As String '比較したいファイル１（フルパス）
  Dim sPath2 As String '比較したいファイル２（フルパス）
  iRow = ActiveCell.Row
  sExe = """" & Cells(iRow, 1).Value & """"
  sPath1 = """" & Cells(iRow, 2).Value & """"
  sPath2 = """" & Cells(iRow, 3).Value & """"
  '1つでも入力されていなかったらファイルを開かない
  If "" <> sExe And "" <> sPath1 And "" <> sPath2 Then
    'ファイルを比較する
    Call Shell(sExe & " " & sPath1 & " " & sPath2)
  End If
End Sub
```


<h2>⑤コマンドプロンプト</h2>
例としてxcopyコマンドで説明します。
指定のファイルだけをコピーしたいときにを使うコマンドです！フォルダの新規作成もしてくれちゃう。

このマクロを使えば、コピーしたいファイルとコピー先のフォルダパスをExcelに貼り付け、コピー先のファイルパスはコピー元のファイルパスをExcelのSUBSUTITUTE関数を使って自動計算！
コピーしたいファイルの取得は、Windowsの「パスのコピー」を使う想定です。
（私が使用するxcopyのオプションは、"echo F | xcopy /R /Y"です）
複数ファイルをコピーしたい場合は、Whileなどで対応しましょう！

メイン処理：

:::note info
  Call Shell("cmd.exe /c " & xcopyコマンド & " " & コピー元のフルパス & " " & コピー先のフルパス)
:::

コード例：
```vb:cmd_xcopy.bas
'セルに記載されているファイルをxcopyコマンドでコピーする
Sub Command_xcopy()
  Dim iRow As Integer
  Dim sCmd As String   'xcopyコマンド
  Dim sPath1 As String 'コピー元（フルパス）
  Dim sPath2 As String 'コピー先（フルパス）
  iRow = ActiveCell.Row
  sCmd = Cells(iRow, 1).Value
  sPath1 = """" & Cells(iRow, 2).Value & """"
  sPath2 = """" & Cells(iRow, 3).Value & """"
  '1つでも入力されていなかったらコマンドを実行しない
  If "" <> sCmd And "" <> sPath1 And "" <> sPath2 Then
    'ファイルを比較する
    Call Shell("cmd.exe /c " & sCmd & " " & sPath1 & " " & sPath2)
  End If
End Sub
```


<h1>■まとめ</h1>
Excel VBAで外部実行ファイルと連携して、誰にも理解されないツールを作ろう！

<h1>■募集</h1>
こんな情報お待ちしております。

・こんなコード使ってるよ！
・その用語は正しくは○○だよ！
・VBAっていいよね！


<h1>■参考記事</h1>
@mink0212様の記事

https://qiita.com/mink0212/items/eef607400c887ecdf16c