社宅を管理せよ！～GAS初心者がChatGPTと一緒に挑戦してみた～


## 助けて、ChatGPT！ ##


こんにちは。私は小売業で人事関係の仕事をしています、やまな。です
今の部署になって早半年・・・。

**効率よく仕事ができるようになりたい！！**

特に私がそう思ったのは、社宅の管理をしているときでした。
業務の一つとして「技能実習生の社宅管理」があります。
技能実習生はいろいろな国から働きに来ているので、社宅を用意しています。
入社するときに最低限の準備や登録をして、リストにまとめていますが、それは技能実習生以外の社員のリストとはまた別のものです。
この社宅リストと技能実習生リストを照らし合わせて確認するという業務が、実習生の入れ替えの時期や新規で入社するときに必要になります。

**これが本当に時間がかかるしとても手間！**

ということで、今回私がやりたいことはこれ！

:::note info
社宅リストと技能実習生リストの住所情報を照らし合わせて、誰がどこに住んでいるのか整理する
:::

端的に言うと、これがしたいわけです。


![スクリーンショット (86).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/acc53b37-7386-96c8-3f33-4965b3758ad6.png)



この作業の時間を減らしたいのですが、やはり、人の力だけでは限界が・・・。
簡単に情報を照合できるものはないだろうか。

考えたところで、私はデジタル技術を学び始めたばかりの超初心者です。誰に聞けばいいのかも、何をすればいいのかもわかりません。

そんなとき、ChatGPTという存在を思い出しました。
使ったことはほとんどないけれど、なんでも答えてくれるという噂の存在です。

**そうだ、ChatGPTに質問して考えてもらおう！**

ここから、超初心者の私とChatGPTの挑戦が始まりました。

## 使用したツール ##
・[ChatGPT](https://chatgpt.com/ "ChatGPT")
・Googleスプレッドシート
・[Google Apps Script](https://workspace.google.com/intl/ja/products/apps-script/ "Google Apps Script")



## 私とChatGPTが作り上げたもの ##

これが、私がChatGPTと一緒に作ったGASです。
（今回は社宅リストと従業員リストとの照合でサンプルを作っています。）


#### GASコード ####

```javascript:スプリクト
function compareAddresses() {
  // スプレッドシートを開く
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  
  // 従業員リストシートと社宅情報シートを開く
  var employeeSheet = spreadsheet.getSheetByName("従業員リスト");
  var residenceSheet = spreadsheet.getSheetByName("社宅情報");

  // 従業員リストのD列（住所）、B列、C列の情報を取得
  var employeeAddresses = employeeSheet.getRange(2, 4, employeeSheet.getLastRow() - 1, 1).getValues();
  var employeeInfoB = employeeSheet.getRange(2, 2, employeeSheet.getLastRow() - 1, 1).getValues();
  var employeeInfoC = employeeSheet.getRange(2, 3, employeeSheet.getLastRow() - 1, 1).getValues(); // C列を取得

  // 社宅情報シートのA列とB列を取得し、B列とA列を入れ替え
  var residenceAddressesB = residenceSheet.getRange(2, 2, residenceSheet.getLastRow() - 1, 1).getValues();
  var residenceAddressesA = residenceSheet.getRange(2, 1, residenceSheet.getLastRow() - 1, 1).getValues();
  var residenceAddresses = [];
  
  for (var i = 0; i < residenceAddressesA.length; i++) {
    // B列とA列を入れ替えて結合し、空白を削除、全角を半角に変換、大文字を小文字に統一
    var fullAddress = (residenceAddressesB[i][0] + residenceAddressesA[i][0])
                        .replace(/\s+/g, "")  // 空白を削除
                        .toLowerCase()        // 大文字を小文字に統一
                        .normalize("NFKC")    // 全角を半角に変換
                        .replace(/号室?/g, "") // 「号室」および「号」を削除
                        .replace(/室/g, "");   // 「室」を削除
    residenceAddresses.push([fullAddress]);
  }

  // 結果を格納する配列
  var results = [];
  var currentTime = new Date(); // 現在の日時を取得

  // 比較処理
  for (var i = 0; i < employeeAddresses.length; i++) {
    // 空欄の行をスキップ
    if (!employeeAddresses[i][0] || !employeeInfoB[i][0] || !employeeInfoC[i][0]) {
      continue; // 空欄の行は結果に含めない
    }

    // 従業員の住所から空白を削除し、全角を半角に、大文字を小文字に統一
    var empAddress = employeeAddresses[i][0]
                        .replace(/\s+/g, "")  // 空白を削除
                        .toLowerCase()        // 大文字を小文字に統一
                        .normalize("NFKC")    // 全角を半角に変換
                        .replace(/号室?/g, "") // 「号室」および「号」を削除
                        .replace(/室/g, "");   // 「室」を削除
    var matchFound = false;
    
    for (var j = 0; j < residenceAddresses.length; j++) {
      var resAddress = residenceAddresses[j][0];
      
      // 住所の比較
      if (empAddress === resAddress) {
        results.push([employeeInfoB[i][0], employeeInfoC[i][0], employeeAddresses[i][0], "完全一致", currentTime]);  // C列の情報を追加
        matchFound = true;
        break;
      }
    }
    
    if (!matchFound) {
      results.push([employeeInfoB[i][0], employeeInfoC[i][0], employeeAddresses[i][0], "一致なし", currentTime]); // 一致しない場合もC列の情報を追加
    }
  }

  // 結果を新しいシートに書き込む
  var resultSheet = spreadsheet.getSheetByName("比較結果") || spreadsheet.insertSheet("比較結果");
  resultSheet.clear();  // 前回の結果をクリア
  resultSheet.getRange(1, 1, results.length, 5).setValues(results); // 5列に変更
}

```

#### 実際に使う手順 ####

コードをGASに入力して

![スクリーンショット (81).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/2ecd7d89-a088-bc2a-dd4d-721bb8c13841.png)



実行ボタンを押すと、


![スクリーンショット (45).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/931fab1b-555c-db0b-a009-f85c59edfe2c.png)

この従業員リスト（サンプル）の住所欄と

![スクリーンショット (46).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/f30422f7-f414-5e35-a7fa-6d845a64f5b5.png)

この社宅情報（サンプル）を照合して

![スクリーンショット (47).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/14d623c4-acf6-dc11-7f05-14c129174d2b.png)


欲しい情報だけ書き出してくれました！



## 完成までの道のり ##

これを作るために、ChatGPTとたくさんお話をしました！
その制作過程を紹介します。

### 1\.まずは基本の形を作ってもらう ###

私からの初めての質問と回答がこちら。

![スクリーンショット (51).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/97feeda2-ec15-d5a4-c974-4199114c7ac3.png)



簡潔に聞きすぎたようで、こんなことができますよ、という案内のみで終了。
さらにここから、質問を重ねます。

![スクリーンショット (53).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/44459895-58cc-522e-9b25-60932029a766.png)



最近覚えたばかりのGASを使いたいと思っていたので、使えるか質問してみました。
使えるよ、という回答と、そのコードを書いてくれました。
このコードが基盤となります。

```javascript:スプリクト
function compareAddresses() {
  // スプレッドシートを開く
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  
  // 従業員リストシートと社宅情報シートを開く
  var employeeSheet = spreadsheet.getSheetByName("従業員リスト");
  var residenceSheet = spreadsheet.getSheetByName("社宅情報");

  // 従業員リストのAF列（住所）を取得
  var employeeAddresses = employeeSheet.getRange(2, 32, employeeSheet.getLastRow() - 1, 1).getValues();

  // 社宅情報シートの住所列を取得
  var residenceAddresses = residenceSheet.getRange(2, 1, residenceSheet.getLastRow() - 1, 1).getValues();
  
  // 結果を格納する配列
  var results = [];
  
  // 比較処理
  for (var i = 0; i < employeeAddresses.length; i++) {
    var empAddress = employeeAddresses[i][0];
    var matchFound = false;
    
    for (var j = 0; j < residenceAddresses.length; j++) {
      var resAddress = residenceAddresses[j][0];
      
      if (empAddress === resAddress) {
        results.push([empAddress, "完全一致"]);
        matchFound = true;
        break;
      }
    }
    
    if (!matchFound) {
      results.push([empAddress, "一致なし"]);
    }
  }

  // 結果を新しいシートに書き込む
  var resultSheet = spreadsheet.getSheetByName("比較結果") || spreadsheet.insertSheet("比較結果");
  resultSheet.clear();  // 前回の結果をクリア
  resultSheet.getRange(1, 1, results.length, 2).setValues(results);
}
```

### 2\.細かい修正を入れる ###

このコードだとなぜかAF列を対象として照合しようとしていました。
なので、ここを直しつつ、次のお願いをします。

![スクリーンショット (55).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/587f86cf-3170-4538-7878-9eae89f12de4.png)


 先ほどの完成品で紹介した社宅情報のGoogleスプレッドシート、A列とB列に住所が分かれて入力されていたので、それをつなげて照合してもらいます。
 入力が途中になってしまったのに、しっかりと私の聞きたいことを汲み取ってくれました。さすがです！

 
一度これで試しに実行してみたのですが、すべてが「一致なし」の結果に・・・。
そこで、Googleスプレッドシートのデータがおかしいのかな？と確認していて気が付きました。

:::note info
A列にアパート名、B列に県名や市町村名が書かれていたため、そのまま繋げてしまうと従業員リストの住所とは一致しない
:::

そこでまた、ChatGPTにお願いをします。

![スクリーンショット (57).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/e1545b00-60b6-0cf9-989c-49af142f4dfd.png)


```javascript:スプリクト
// 社宅情報シートのA列とB列を取得し、B列とA列を入れ替え
  var residenceAddressesB = residenceSheet.getRange(2, 2, residenceSheet.getLastRow() - 1, 1).getValues();
  var residenceAddressesA = residenceSheet.getRange(2, 1, residenceSheet.getLastRow() - 1, 1).getValues();
  var residenceAddresses = [];
```

これが追加されました。

このタイミングで「照合した日付」を結果に入れてもらえるようにしました。
ここで試しに実行してみると、住所の並びも正しくなり、「完全一致」という結果が表れるようになりました。
これで一歩前進です。

### 3\.問題発生！どうやって修正する？ ###

ここまで順調に見えたかもしれませんが、実は、ここで一度立ち止まってしまいました。
最終的にすべて一致するようにサンプルを作っているのに、半分以上が一致なし。
結果として表示はされるけれど間違っている、ということしかわからなかったので、コードではなく、シートの情報に問題があるのかもしれないと思い、もう一度Googleスプレッドシートを見直します。
ここでいくつか思い当たるところが見つかりました。

:::note warn
1\.住所とアパート名の間にスペースがあるものとないものがある
2\.数字の半角と全角が従業員リストと社宅リストで統一されていない
3\.「号」や「号室」がついていたりついていなかったりする
:::
これをどうにかして同じものだと照合できればいいのですが、私にはさっぱりなので、ここでもChatGPTの出番です。



![スクリーンショット (82).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/30e55ee8-00a1-51bb-4677-dde7307cf637.png)


![スクリーンショット (83).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/4d54e8bd-22a9-c95d-4341-c4e50a57177f.png)


![スクリーンショット (84).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/a383d992-1f94-62ab-b4a1-78a8e8e22312.png)

このような簡単な質問を一つずつしてできたコードをGASに入力して実行します。


エラーなくできました！が、なぜか一致しているはずの住所が一致なしと出てしまいます。
おそらく号や号室がどこかに引っかかっているのかな、と思うのですが、何となくそう思うだけでどこを直せばいいのかわかりません。
とりあえず、自分が何となく考えたことをChatGPTに伝えてみます。

![スクリーンショット (65).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/c8afa90e-8c2a-bed7-bf4a-59fae60496c3.png)

![スクリーンショット (67).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/5cdcaf7f-7be2-d0a1-6a54-5810b3dda8c8.png)


何度も直してもらいましたが、それでも治らないので、しつこく報告をします。
すると、やっと正しい結果がでるようになりました！

![スクリーンショット (71).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/46144214-2d16-9eb2-f9cd-215f17f2381c.png)

この修正をしてくれたおかげで、やっと正しく動かすことができました！

### 4\.あと一歩！さらに欲しい情報を追加！ ###

そして最後に、従業員番号と氏名を結果に記入したかったので、そこもお願いをしました。
一度に両方をお願いしたところ、なぜかコードがおかしくなったようで、エラーが続出してしまったので、ひとつずつ順番に追加をしてもらいました。

![スクリーンショット (75).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/f3aaf86a-2d1f-59e8-2306-2a95528b4688.png)


![スクリーンショット (78).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888131/552daaa1-9912-cdcb-373c-f59d1bce41f9.png)


従業員番号と氏名を結果に追加してもらえるようにお願いしました。

これでやっとGASのコードが完成です！



## できたこと、もっとやりたいこと

ChatGPTにたくさん自分の意見を伝えて、こうして一つのコードを書くことができました。私一人では絶対に書くことができなかったです。
私がやったことといえば、

**質問してできたコードを実行、結果を伝えてさらに要望を伝える**

たったこれだけです。それなのにGASを動かすことができてしまいました。
改めて自分でCharGPTを使ってみて、その有能さを実感しました。
ただ、注意する点もありました。

:::note alert
質問方法が曖昧だったり、情報量が多いとエラーが出てしまうことがある
:::

これに気を付ければ、今回私が作ったようなものであれば簡単に作ることができます。

今回私が作りたかった、「従業員リストと社宅情報を照合する」ということはできました。
今まで手作業で確認していた時間が削減され、その分ほかの業務に時間を充てることができるようになりました。
削減した時間を使って、そろそろ入社する新規の技能実習生の事前準備を少し早めに終わらせることができました。
今回これを作った意味があったなと感じています。


まだ自分で試している段階ですが、これが完成されたら、同じようなコードを作って社宅だけでなくいろいろな情報の照合手段として使えるようになるかもしれません。
完成したら、職場でもいろいろな人に使ってもらいたいです。

しかし、作ったものを実際の業務で使えるようにコードを書き換えて使用してみると、まだまだ改善したい部分が見つかりました。

:::note warn
・照合結果が「一致なし」だけを別のリストに抜き出したい
・Googleスプレッドシートをで照合したデータをExcelに自動で記載することはできる？
・従業員リストだけでなく、入社時の情報が記載されたリストも同時に照合させたい
:::

実際に使ってみることで見えてくるものは意外と多かったなという感想です。
今回作ったコードに追加したり、GAS以外の方法も模索しながら、さらに実用性の高いものを作りたいと思います。
ChatGPTという力強い味方を手に入れたので、今後もいろいろなことを質問しながら学んでいきます。