Microsoft Copilotを使って業務自動化をやってみた所感~Excelユーザ一覧をAWSへ自動出力するVBAマクロを実装してみて~

## はじめに
本記事は、Microsoft Copilotを使って業務効率化を試みた際の所感についてまとめたものです。

https://www.bing.com/chat?q=Bing+AI&FORM=hpcodx

会社のユーザ管理業務としてよくある、Excelのユーザ一覧が更新された際のシステム（今回はAWSで構築されている想定）への反映作業をVBAマクロを使って自動化してみました。

なお、この取り組みは生成AIを使いこなすための勉強を目的としているため、自身でほぼコーディングは行わずにColilotとの対話のみで実装しています。（VBA初心者だったという理由もありますが…）

## やってみたこと（ユーザ管理業務効率化）
よくある社内のユーザ管理業務を一例に、以下のようなExcelで作られたユーザ一覧に更新が入った場合に、ボタン1つでAWS上にアップロードする仕組みを構築します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740505/cdf7bd04-e789-cfb7-1da9-30a46c7663c4.png)

AWS側はSSMパラメータストア上にユーザ情報を格納するため、ExcelからJson形式に変換しアップロードします。

~~~json:Excelから変換後.json
[
{"A@hogehoge.org":"key_aaaa"},
{"B@hogehoge.org":"key_bbbbbb"},
{"C@hogehoge.org":"key_cc"},
{"D@hogehoge.org":"key_dd"},
{"E@hogehoge.org":"key_dd"},
{"ああ@hogehoge.org":"あああ"}
]
~~~

そして、AWSに構築したLambdaをSSMパラメータストアが参照して各種ユーザ処理を行うという想定です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740505/d87214dd-c0b6-8b8c-b481-0a9785097a32.png)

シンプルですが、結構あるあるな構成かと思います。

上記構成図の赤字部分を、Colilotを使って自動化してみました。

## 実装内容
Colilotとの対話により、以下のようなVBAとBatファイルでの実装としました。

### VBA
~~~visual basic:ExcelからJsonへ変換.vba
Sub ExcelToJSON()
    Dim rng As Range
    Dim cell As Range
    Dim json As String
    Dim rowJson As String
    Dim i As Long
    Dim jsonFile As Variant
    Dim fileNumber As Integer
    Dim lastRow As Long
    Dim jsonList As New Collection
    Dim jsonArray() As String
    
    ' Excelのデータ範囲を設定します。
    With ThisWorkbook.Sheets("Sheet1")
        lastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
        Set rng = .Range("C2:D" & lastRow)
    End With
    
    ' 各行をJSONオブジェクトとして処理します。
    For i = 1 To rng.Rows.Count
        ' "この行より上に記載"という文字列が見つかったらループを抜けます。
        If InStr(rng.Cells(i, 1).Value, "この行より上に記載") > 0 Then Exit For
        
        ' C列がハイフン「-」の場合にjson出力をしないようにします。
        If rng.Cells(i, 1).Value <> "-" Then
            rowJson = "{""" & rng.Cells(i, 1).Value & """:""" & rng.Cells(i, 2).Value & """}"
            jsonList.Add rowJson
        End If
    Next i
    
    ' CollectionをArrayに変換します。
    ReDim jsonArray(1 To jsonList.Count)
    For i = 1 To jsonList.Count
        jsonArray(i) = jsonList(i)
    Next i
    
    ' JSONオブジェクトを結合します。
    json = "[" & vbCrLf & Join(jsonArray, "," & vbCrLf) & vbCrLf & "]"
    
    ' ファイル選択ダイアログを表示します。
    jsonFile = Application.GetSaveAsFilename(InitialFileName:="file.json", FileFilter:="JSON Files (*.json), *.json")
    
    ' ユーザーが「キャンセル」を選択した場合、処理を終了します。
    If jsonFile = False Then Exit Sub
    
    ' JSONファイルに書き込みます。
    fileNumber = FreeFile
    Open jsonFile For Output As #fileNumber
    Print #fileNumber, json
    Close #fileNumber
    
    ' batファイルを実行します。
    RunBatFile
    
End Sub


Sub RunBatFile()
    Dim batFile As String
    Dim cmd As String
    
    ' batファイルのパスを指定します。
    batFile = "C:\hogehoge\AWSパラメータストアへ登録.bat"
    
    ' コマンドラインを作成します。
    cmd = batFile
    
    ' batファイルを実行します。
    Shell cmd, vbNormalFocus
End Sub


~~~

### Batファイル
~~~bat:AWSパラメータストアへ登録.bat
@echo off

set /p profile="AWSプロファイル名を入力してください: "
set filepath=%1

if "%filepath%"=="" (
    set /p filepath="キーファイル名（jsonファイル名）及びファイルパスを指定してください（相対パス可）: "
)

echo;
echo ##登録対象のJSONファイルの表示
echo;
echo %filepath%
type %filepath%
set /p isContinue="上記の内容をAWSパラメータストアに登録しますか？ (y/n): "
if /i "%isContinue%"=="n" (
    echo ユーザーにより中断されました。
    pause >nul
    exit /b
)

echo;
echo ##SSOログイン
echo;
aws sso login --profile %profile%
if %errorlevel% neq 0  (
    echo エラーが発生しました。何かキーを押して終了してください。
    pause >nul
    exit /b %errorlevel%
)

echo;
echo ##get-parameter
echo;
aws ssm get-parameter --with-decryption --name /key-test --profile %profile%
if %errorlevel% neq 0 (
    echo エラーが発生しました。何かキーを押して終了してください。
    pause >nul
    exit /b %errorlevel%
)

echo;
echo ##put-parameter
echo;
aws ssm put-parameter --name "/key-test" --type "SecureString" --value file://%filepath% --overwrite --profile %profile%
if %errorlevel% neq 0  (
    echo エラーが発生しました。何かキーを押して終了してください。
    pause >nul
    exit /b %errorlevel%
)

echo;
echo ##get-parameter
echo;
aws ssm get-parameter --with-decryption --name /key-test --profile %profile%
if %errorlevel% neq 0  (
    echo エラーが発生しました。何かキーを押して終了してください。
    pause >nul
    exit /b %errorlevel%
)

echo パラメータストアへの登録が正常に完了しました。

pause

~~~


## Copilotを使ってみた所感
- VBAはほぼ触ったことはなかったのですが、Copilotとの対話で簡単にVBAスクリプトを実装することができて、自身の開発の幅が広がりました。
  - 生成AIはものすごいと思う反面、VBAのスキルが身に付いたかといわれると…そもそも自身にVBAのスキルが必要かといわれると微妙なので今回は良しとしますが、今後はCopilotの出力結果をきちんと理解できるプログラミングスキルが必要だと思いました。
- 「こんな感じの表を、こんな感じに出力して」のような漠然とした指示ではなく、より具体的に、入力値のExcelや出力となるJsonの形式をCopilotに与えてあげると期待するコードを出力してくれました。
- 入出力の処理が完成した後、「このコードにXXXXの処理を追加して」のような指示を出し、周辺のロジックを付け加えていきました。
    **後から追加した主なロジック**
    - Excelの無効行（ハイフン行）はJsonに出力させない
    - Excelの行が増えた際の対応として「この行より上に記載する」という文字列が含まれる場合にJson出力を終了させる
    - VBAからBatファイルを呼び出して、パラメータストアへの登録まで一気通貫で行う
    - Batファイル内でAWSの認証情報をユーザに入力させる
    などなど
- 今回はお試しだったため未実施ですが、商用利用する際に入力ちのバリエーションを考慮したテストパターンもCopolotで生成するとよいと思いました。
- たまに「全然的を得ない回答だな…」と思ったら、CopilotがデフォルトのGPT-3.5（よりバランスよく）になっていたことにしばらく気づかないことがありました。。。

## 2024/3/12更新:Copilot(生成AI)の普及により、業務効率化の敷居が下がった
今回のように、Excelでのユーザ管理を行っている組織って多いと思います。
そして、そのような組織では
- 専用のシステムやデータベースを導入するほどではないが、地味に運用に負担がかかっている。
- 自動化したいけど、このためだけのためにVBAを習得したり、スクリプトを書いたりする労力が惜しい。

といった状況で、なかなか自動化・効率化が進まなかったことが多々あると思います。
Copilotをはじめとする生成AIの普及により、上記のような**抜本的に改善するほどではないけど地味に負担になっている作業を「誰でも、簡単に」自動化できるようになった**ことにすごく意義があると感じました。
特に「誰でも」できるようになったことで、実際に運用しているメンバが自身で効率化を試みることも、日々運用者の負担を減らしたいと思っているマネージャーやリーダ層が仕組みを整えてあげるといったことも柔軟にできるようになりました。

改めて、身の回りに「色々な理由が重なり自動化を諦めていた箇所がないか」を探してみるとよいと感じました。 


## まとめ
Copilotとの対話で触ったことのない言語（VBA）でも簡易的なものなら簡単に実装できることが分かりました。今後も自身の身の回りの自動化・効率化にCopilotを使っていければと思います。