GASを使って日常の任意行為のログをGoogleSpreadSheetに保存しよう　作成編

##追記

1/5
　chromeだとform要素にsubmitがなくてもエンターキーでsubmitされてしまう？ようなので入力フォームを修正しました。
　前ので作っちゃった人で困ってる人は現時点でのlog.htmlで更新してみてください。


##何？
 + 非エンジニア向け
 + 無料で
 + 日常行為のログをつけよう

です。
さっそくやりましょう。

##作ろう
###0.前提条件
 + GoogleDriveを知っている
 + アカウントも持っている
 + GoogleSpreadSheetを操作できる

あたりが前提条件になります。わからない人は頑張りましょう。

###1.準備
####新規シートの作成

GoogleDriveの任意の場所にログ保存用の新規スプレッドシートを作成してください。
その後、そのスプレッドシートに「ログ」「タグ」シートを作成してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/50c0c43b-c841-5816-fe11-dbaf25034f2d.png)
左下がこうなっていればOKです。

####「ログ」シートの見出し
ログシートには左からタイムスタンプ、タイトル、作者、URL、メタデータ、タグ、タグ、タグ‥‥‥と記録されます。
なので見出しをつけると見やすいかもしれません。（つけなくてもいいです。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/c7492587-a135-9c9c-c580-d1e3a0c6b862.png)
例えばこうですね。

###2.コードのコピペ
さて、動作するコードをコピペで作っていきます。
まず、スプレッドシートの上にある「拡張機能」から、「Apps Script」を選びましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/07c84378-0d71-96af-6968-179d0cc615c0.png)
こういうのが開きますね。
今コード.gsを開いているのですが、そこに以下のコードを上書きしてください。

```js:コード.gs
const SpreadSheetID = "<SheetID>";
const LogSheetName = "ログ";
const TagCloudSheetName = "タグ";

const TimeZone = "Asia/Tokyo";
const TimeFormat = "yyyy/MM/dd HH:mm:ss";

function doGet(e) {
  if(SpreadSheetID === "" || SpreadSheetID === "<SheetID>"){
    const output = ContentService.createTextOutput();
    output.setMimeType(ContentService.MimeType.TEXT);
    output.setContent("エラー\nSpreadSheetIDを登録してください。\nGoogleSpreadSheetを作成し、シートを追加して「ログ」「タグ」シートを作成してください。\nその後、URL内のID部分をコピーして <SheetID> 部分にコピーしてください。\n");
    return output;
  }
  const logHtmlTemplate = HtmlService.createTemplateFromFile("log");
  const registedTags = getRegistedTags();
  let datalistInnerHTML = "";
  for(const tag of registedTags){
    datalistInnerHTML += '<option value="' + tag + '">\n';
  }
  logHtmlTemplate.tagdatalist = datalistInnerHTML;

  return logHtmlTemplate.evaluate();
}

function registFormdata(formdata){
  let tags = [];
  for(let i = 1;;i+=1){
    if(formdata["tag" + i]){
      tags.push(formdata["tag" + i]);
    }
    else{
      break;
    }
  }
  registLog(new Date(),formdata.title,formdata.author,formdata.url,tags,formdata.meta);
}

function registLog(date,title,author,url,tags,meta){
  const row = [
    Utilities.formatDate(date, TimeZone, TimeFormat),
    title,
    author,
    url,
    meta
  ].concat(tags);
  const sheet = SpreadsheetApp.openById(SpreadSheetID).getSheetByName(LogSheetName);

  const range = sheet.getRange(sheet.getLastRow() + 1,1,1,row.length);
  range.setNumberFormat("@");

  range.setValues([row]);
  //sheet.appendRow(row);

  registTags(tags);
}
function registTags(tags){
  const sheet = SpreadsheetApp.openById(SpreadSheetID).getSheetByName(TagCloudSheetName);
  let tagcloud = [];
  if(sheet.getLastRow() > 1){
    tagcloud = sheet.getRange(1, 1, sheet.getLastRow()).getValues();
  }
  for(const tag of tags){
    if(!tagcloud.includes(tag)){
      tagcloud.push(tag)
    }
  }
  let setrangedata = [];
  for(const tag of tagcloud){
    setrangedata.push([tag]);
  }
  if(tagcloud.length > 0){
    const range = sheet.getRange(1,1,setrangedata.length,1);
    range.setNumberFormat("@");
    range.setValues(setrangedata);
  }
}
function getRegistedTags(){
  const sheet = SpreadsheetApp.openById(SpreadSheetID).getSheetByName(TagCloudSheetName);
  let tagcloud = [];
  if(sheet.getLastRow() > 1){
    tagcloud = sheet.getRange(1, 1, sheet.getLastRow()).getValues();
  }
  return tagcloud;
}
```

しましたね。
そうしたら、一行目にある"\<SheetID\>"を設定します。
さっきのスプレッドシートに戻ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/e50ff19e-c4f9-4224-6a4f-d132d1ca0e46.png)
URLにある「/d/XXXXXXXXXXXXXX/edit」の「XXXXXXXXXXXXXX」部分をすべてコピーします。
これがシートIDです。
"\<SheetID\>"を"XXXXXXXXXXXXXX"に上書きします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/61f03298-2b2f-a6d2-d46c-a244e78a302d.png)
こうですね。
コード.gsは以上です。

そうしたら、次にログを入力する画面をコピペします。
「ファイル」の横にある＋をクリックしてください。
そしてHTMLを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/dd0cda48-b2ff-6b7f-1ece-0812922fa258.png)
こうです。
「log」と名前をつけてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/0d94d82b-d9d7-a9a2-704e-903102382f1e.png)
こうです。
「log.html」となれば成功です。喜びましょう。
そして以下のhtmlを上書きコピペしてください。

```html:log.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <form id="logform" onsubmit="return false;">
        <table>
            <tbody>
                <tr>
                    <th>Title</th>
                    <td>
                      <input type="text" name="title">
                    </td>
                </tr>
                <tr>
                    <th>Author</th>
                    <td>
                      <input type="text" name="author">
                    </td>
                </tr>
                <tr>
                    <th>URL</th>
                    <td>
                      <input type="url" name="url">
                    </td>
                </tr>
                <tr>
                    <th>Meta</th>
                    <td>
                      <textarea name="meta"></textarea>
                    </td>
                </tr>
                <tr id="tags">
                    <th>Tags</th>
                    <td id="tagarea">
                    </td>
                </tr>
                <tr>
                    <th>   
                    </th>
                    <td>
                      <input list="tagdatalist" type="text" id="taginput">
                      <datalist id="tagdatalist">
                        <?=tagdatalist?>
                      </datalist>
                      <button onclick="addtag();">追加</button>
                    </td>
                </tr>
            </tbody>
        </table>
        <input type="button" id="sendbutton" name="send" onclick="onSendClick();" value="登録する">
        <div hidden id="hiddenformdiv"></div>
    </form>
    <script>
      let tags = [];
      const addtag = () => {
        const taginput = document.getElementById("taginput");
        if(taginput.value){
          tags.push(taginput.value);
          taginput.value = "";
          drawTags();
        }
      }
      const drawTags = () => {
        const tagarea = document.getElementById("tagarea");
        tagarea.innerHTML = "";
        tags.forEach((tag)=>{
          const tagelement = document.createElement("div");
          tagelement.innerHTML = tag;
          tagelement.classList.add("taglabel");
          tagarea.appendChild(tagelement);
        });
      }
      const onSendClick = () => {
        const tagarea = document.getElementById("tagarea");
        const hiddenformdiv = document.getElementById("hiddenformdiv");
        tags.forEach((element,index)=>{
          const hidden = document.createElement("input");
          hidden.type = "hidden"
          hidden.name = "tag" + (index + 1);
          hidden.value = element;
          hiddenformdiv.appendChild(hidden);
        });

        document.getElementById("sendbutton").disabled = true;
        google.script.run.withSuccessHandler(succeedAlert).registFormdata(document.getElementById("logform"));
      }
      const succeedAlert = (result) => {
        window.alert("登録しました");
        document.getElementById("sendbutton").disabled = false;
        const hiddenformdiv = document.getElementById("hiddenformdiv");
        hiddenformdiv.innerHTML = "";
      }
    </script>
  </body>
</html>
```

しましたね。
おめでとう。コピペは終了です。
最後にセーブしてください。
Ctrl+Sか、左上のフロッピーとか言う知らん機械のマークです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/328a2dcd-c6b9-a6b3-9b64-85ae03c24187.png)
コード.gsとlog.htmlの左のオレンジ色がなくなればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/ffa734a2-4638-5eb6-6f05-67d18f6c5203.png)

###3.デプロイ
続いてデプロイします。
Webアプリにします。
Apps Scriptの画面の右上、「デプロイ▼」をクリックします。
そして「新しいデプロイ」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/a7a58fdb-7b21-ed33-f10b-9ad60350bfdd.png)
開きましたね。
「種類の選択」の左の歯車をクリックし、「ウェブアプリ」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/a6d4b362-a7ed-bb82-09dc-9fc29e553cf5.png)
そして設定はデフォルトのまま青い「デプロイ」をクリックします。
しばらく待つとスプレッドシートへのアクセス許可が出てくるので、許可します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/c0039789-9047-423b-8297-fdfaab01cbd8.png)
承認すると出てくるウインドウで「スプレッドシートを作成したアカウント」を選択し、「詳細を表示」から「無題のプロジェクト（安全ではないページ）に移動」をクリックします。
以下、私のメールアドレスが出ますがここは自分のアドレスが出るはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/3dcbf7fb-614f-ab31-a004-96b2d62cf3ea.png)
その後出てくるウインドウではスプレッドシートを書き換える危いスクリプトだよって言われるので「許可」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/bb490f80-3902-ebd6-0054-0b0c9082c6af.png)
めんどくさいですね。
元の画面に戻るので、しばらく待ちます。

最終的にこんなのが出るはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/e86ed2cd-6f70-046d-a29a-a327fb3d333c.png)
お疲れさまでした。
このURLがアプリのURLです。保存しておいてください。

##ログを記録する
アプリのURLを開くと、こんな画面になるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/28e68b69-3921-bfc6-1b67-e407a3a34f53.png)
ここに適宜入力して「登録する」を押すと、押した時点のタイムスタンプでログが登録されます。

##何に使うの？
読書記録とかにすれば良いんじゃないでしょうか？

ちなみにMetaは「何か」「ログ内容ではないが記録するもの」とかそういった感じの意味合いです。多分。
雰囲気でやってるので聞かないでください。

##記録を見たい
例えば「一日ごとにログ回数を見たい」場合、
1.別のシートに=TEXT('ログ'!A1,"yyyy/mm/dd")とかで転写するとyyyy/mm/dd形式で日時のみで転写できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/eb2f1c44-49e6-e750-d976-9cc1e58dfe7f.png)
2.適当な列に2022/01/01からオートフィルして日付を作成して、
3.隣に=COUNTIF(A:A,C1)みたいな式でオートフィルして数える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461661/1e770e71-64ca-972c-3f3b-1d9489d312f9.png)
とかすればいいんじゃないですかね？
あるいはGASで表示用のページを作ることもできます。（いつか書くかもしれません。）

##改造編
もしかしたら他記事で

+ 記録内容を増やしたい
+ グラフとかタグ絞り込みログ回数とか表示するページが欲しい

とか書くかもしれません。
書かないかもしれません。

##何に使うの？
読書記録とか食事記録とかじゃないですか？