Apps Scriptリファレンス: Apps Script Reference |障害・課題追跡: IssueTracker |Google Workspace: Status Dashboard - Summary

2018年6月29日金曜日

HTML ServiceでgetValuesではnullになるのでgetDisplayValuesを使った


こういうシートがあって
HITML Serviceに getValues()で値を返すとnullになったので
getDisplayValues()で返すようにしたときの備忘録です

B列のdateの値を
上部メニュー>表示形式>数字>書式なしテキスト
にするとうまくいきますが

コードで解決したいときは
getDisplayValues()
を使うと良さそう



コード.gs
function doGet () {
  return HtmlService.createHtmlOutputFromFile("index");
}

function get_value_gs () {
  var ss_url = "https://docs.google.com/spreadsheets/d/1HqeYgrE6N_YEID_R59PHWjVzT1veWPAdskcUo0e0oh4/edit#gid=0";
  var sheet = SpreadsheetApp.openByUrl(ss_url);
  var range = sheet.getRange("A1:B");
  var values = range.getValues();
  Logger.log(values);
  return values;
}



index.html
<!DOCTYPE html>
<html>
  <body>
  <script>
    get_values();
    function get_values() {
      google.script.run
        .withFailureHandler(onFailure)
        .withSuccessHandler(onSuccess)
        .get_value_gs()
    }

    function onSuccess(values) {
      alert(values);
    }

    function onFailure(e) {
      alert([e.message, e.stack])
    }
    </script>
  </body>
</html>


getValues()の場合


上記のコード.gsでget_value_gs()を実行すると
Logger.log(values)では以下のようなログが出る


ウェブアプリケーションを開くと
null



getDisplayValues()の場合

コード.gsの

var values = range.getValues()



var values = range.getDisplayValues()

に変えて以下のようにする


コード.gs
function doGet () {
  return HtmlService.createHtmlOutputFromFile("index");
}

function get_value_gs () {
  var ss_url = "https://docs.google.com/spreadsheets/d/1HqeYgrE6N_YEID_R59PHWjVzT1veWPAdskcUo0e0oh4/edit#gid=0";
  var sheet = SpreadsheetApp.openByUrl(ss_url);
  var range = sheet.getRange("A1:B");
  var values = range.getValues();
  Logger.log(values);
  return values;
}


get_value_gs()を実行すると

Logger.log(values)では以下のようなログが出る



ウェブアプリケーションを開くと
セルの値が表示される


関連記事


2018年6月26日火曜日

-bash: rspec: command not foundをgem install rspecで解決


AppsScriptではなくRubyですが


$ rspec FILE_NAME.rb

をしたら

-bash: rspec: command not found

とおこられたので

$ gem install rspec

をしたら解決した

Googleドライブ内で同名ファイルをremoveする


同じフォルダ内に同名ファイルを複数作ってしまい(1000以上)
手動で消すのが大変なのでコードを書きました

フォルダからremoveするのでどのフォルダにも属さなくなる
完全削除はされない



コード.gs
function myFunction() {
  var FOLDER_ID = "ID";
  var FILE_NAME = "NAME";
  var folder = DriveApp.getFolderById(FOLDER_ID);
  var contents = folder.getFilesByName(FILE_NAME);
  var ids = [];
  while(contents.hasNext()) {
    var file = contents.next();
    var id = file.getId();
    ids.push(id);
    folder.removeFile(file);
  }
  Logger.log([ids.length, ids])
}


参考

getFilesByName(name)
https://developers.google.com/apps-script/reference/drive/drive-app#getfilesbynamename

removeFile(child)
https://developers.google.com/apps-script/reference/drive/drive-app#removeFile(File)

2018年6月24日日曜日

2つの配列で共通するものと新しく追加されるものを抽出する


やりたいこと
  • input1とinput2のキーワードを比較する
  • input1とinput2の両方に存在するものをsameに出力する
  • input2にしか存在しないものをnew_wordに出力する




デモ






コード.gs
function doGet() {
  return HtmlService.createHtmlOutputFromFile("index");
}
意訳
この機能がやること
指定したHTMLファイルを表示する




index.html
<!DOCTYPE html>
<html>
  <head>
    <style>
      textarea {
        width: 240px;
        height: 360px;
      }
    </style>
  </head>
<body>
  <textarea id="ta1" placeholder="input1"></textarea>
  <textarea id="ta2" placeholder="input2"></textarea>
  <textarea id="same" placeholder="same" disabled></textarea>
  <textarea id="new_word" placeholder="new_word" disabled></textarea>

<script>
function get_elem(id){
  return document.getElementById(id);
}

var ta1 = get_elem("ta1");
var ta2 = get_elem("ta2");
var same = get_elem("same");
var new_word = get_elem("new_word");

ta1.onkeyup = ta_keyup;
ta2.onkeyup = ta_keyup;

/************************************
ta1とta2にキーワード一覧コピペすると

sameには共通のキーワードが出力される
new_wordにはta2にあってta1にないキーワードが出力される
************************************/
function ta_keyup(){
  var ta_values = ta1.value.split("\n");
  var ta2_values = ta2.value.split("\n");
  var filtered = filter_array(ta_values, ta2_values)
  same.value = same_words.join("\n");
  new_word.value = new_words.join("\n");
}

/************************************
same_wordsとnew_wordsを抽出する
************************************/
var same_words;
var new_words;
var value;

function filter_array(array, array2) {
  new_words = [];
  same_words = [];
  for(var i = 0; i < array2.length; i++){//obj2の要素数だけ繰り返す
    value = array2[i];//obj2のenを一つずつ取得
    var filtered = array.filter(judge);
    
    var result = get_result(filtered);
    same_or_new(result, i, array2)
  }
}

function judge(obj_item) {
  var result = value === obj_item;
  return result;
}

function get_result(filtered) {
  var result = [];
  for (var i = 0; i < filtered.length; i++) {
    result.push(filtered[i]);
  }
  return result;
}

function same_or_new(result, i, array2){
  if(result == ""){
    new_words.push(array2[i]);
  }else if(result != ""){
    same_words.push(array2[i]);
  }
}
</script>
</body>
</html>



2018年6月23日土曜日

配列の文字列をユニークにして重複を抽出したい


やりたいこと
  1. inputに重複を含む文字列を入力(スプレッドシートなどからコピペ)すると
  2. uniqueの欄にはユニークにした文字列を抽出して
  3. dupの欄には重複する文字列を抽出する




配列内で重複する値の発生数を取得してオブジェクトを配列に入れて返す(発生件数の降順)



  • オブジェクトの中から条件に一致する要素を抜き出す(filter)

  • デモ






    コード.gs
    function doGet() {
      return HtmlService.createHtmlOutputFromFile("index");
    }
    
    意訳
    この機能がやること
    指定したHTMLファイルを表示する
    
    



    index.html
    <!DOCTYPE html>
    <html>
      <head>
        <style>
          textarea {
            width: 240px;
            height: 360px;
          }
        </style>
      </head>
    <body>
      <textarea id="ta1" placeholder="input"></textarea>
      <textarea id="unique" placeholder="unique" disabled></textarea>
      <textarea id="dup" placeholder="dup" disabled></textarea>
    
    <script>
    function get_elem(id){
      return document.getElementById(id);
    }
    
    var ta1 = get_elem("ta1");
    var unique = get_elem("unique");
    var dup = get_elem("dup");
    
    ta1.onkeyup = ta_keyup;
    
    /************************************
    ta1にキーワード一覧をコピペすると
    uniqueにはta1のキーワードをユニークにしたものが出力される
    dupには重複するキーワードが出力される
    
    ユニークにしてカウントした時にcountが2以上のものをdupに入れる
    ************************************/
    function ta_keyup(){
      var values = ta1.value.split("\n");
      var match_count = get_unique(values);
      var desc = sort_obj(match_count);
      var filtered = get_filtered_obj(desc);
      unique.value = filtered["unique"].join("\n");
      dup.value = filtered["dup"].join("\n");
    }
    
    /************************************
    ユニークにしてカウントする
    ************************************/
    function get_unique(){
      var array = ta1.value.split("\n");
      var match_count = get_match_count(array);
      return match_count;
    }
    
    function get_match_count(array){
      var sorted = array.sort();
      var arrays = [];
      var count;
      var unique_i;
      for(var i = 0; i < sorted.length; i++){
        var obj = {}
        var value = sorted[i];
        if(value === sorted[i-1]){
          count++;
          arrays[unique_i]["count"] = count;
        }else{
          count = 1;
          obj["text"] = value;
          obj["count"] = count;
          unique_i = arrays.length;
          arrays.push(obj);
        }
      }
      return arrays;
    }
    
    function sort_obj(arrays){
      var desc = arrays.sort(sorting);
      return desc;
    }
    
    function sorting(a, b){
      return b["count"] - a["count"];
    }
    
    /************************************
    ユニークにした配列をuniqueに入れて、countが2以上ならdupの配列に入れて返す
    ************************************/
    function get_filtered_obj(obj) {
      var unique_filtered = obj.filter(judge_unique);
      var dup_filtered = obj.filter(judge_dup);
      var unique = get_result(unique_filtered);
      var dup = get_result(dup_filtered);
      var filtered = { "unique": unique, "dup": dup };
      return filtered;
    }
    
    //ユニークを返す
    function judge_unique(items) {
      var unique = items["count"];
      return unique;
    }
    
    //countが2以上のものを返す
    function judge_dup(items) {
      var dup = items["count"] >= 2;
      return dup;
    }
    
    function get_result(filtered) {
      var result = [];
      for (var i = 0; i < filtered.length; i++) {
        result.push(filtered[i]["text"]);
      }
      return result;
    }
    </script>
    </body>
    </html>
    


    2018年6月19日火曜日

    Googleスライドでカギ型コネクタに矢印をつける


    Apps Scriptの話ではないですがやり方がわからなかったので
    実現した方法を書き残しておきます


    やりたいこと


    2つの図形をカギ型コネクタでつないで終点を矢印にしたい

    このように


    やり方


    ここで終点の形状を指定できた



    2018年6月15日金曜日

    スプレッドシートのURLをsplit()してスプレッドシートのIDを抽出する


    スプレッドシートのURL
    https://docs.google.com/spreadsheets/d/ID/edit#gid=0

    この中からIDにあたる部分だけを抽出する

    たまにやるので書き残しておこうと思い



    コード.gs
    function get_ssid_from_ssurl(){
      var SS_URL = "https://docs.google.com/spreadsheets/d/ID/edit#gid=0";
      var SS_ID = SS_URL.split("/d/")[1].split("/")[0];
      Logger.log(SS_ID);
    }
    
    意訳
    この機能がやること
    スプレッドシートのURL
    /d/で区切った1番目を/で区切った0番目
    をログに出す
    
    



    2018年6月10日日曜日

    ScriptPropertiesを読み書きしてみる


    ScriptPropertiesを読み書きして

    こういうデータを保存して取得してみる

     {key1=hello, key2=world}



    コード.gs
    var ScriptProperties = PropertiesService.getScriptProperties();
    
    function myFunction(){
      var value1 = "hello";
      var value2 = "world";
      set_property("key1", value1);
      set_property("key2", value2);  
      Logger.log(get_properties());
    }
    
    function set_property(key, value){
      ScriptProperties.setProperty(key, value); 
    }
    
    function get_properties() {
      return ScriptProperties.getProperties();
    }
    
    function delete_properties() {
      ScriptProperties.deleteAllProperties();
    }
    


    set_properties()でScriptPropertiesに保存する
    get_properties()で保存されているScriptPropertiesを取得する
    delete_properties()でScriptPropertiesの中身を削除できる


    実行結果

    myFunction()を実行したログ



    参考

    Class PropertiesService
    https://developers.google.com/apps-script/reference/properties/properties-service

    Macでスクリーンショットを撮ってクリップボードに保存する


    Mac でスクリーンショットを撮る方法
    https://support.apple.com/ja-jp/ht201361

    ⌘  SHFT  3 画面全体を撮影
    ⌘  SHFT  4 範囲を選択して撮影
    撮影したスクリーンショットはデスクトップに保存される
    CONTROLを同時に押すとクリップボードに保存される


    クリップボードに保存すると
    Google Documentなどに ⌘ V で貼り付けることができる


    参考

    Mac でスクリーンショットを撮る方法
    https://support.apple.com/ja-jp/ht201361

    Mac のキーボードショートカット
    https://support.apple.com/ja-jp/HT201236

    オブジェクトのvalueに関数を入れて呼び出したい


    ブラウザ上で押されたキーに応じた処理を実行する
    では以下のように書きましたが

        var key_obj = {
          37: "左",
          39: "右"
        }    


    今回は押されたキーが37「←」か39「→」の場合に
    それぞれ用意した関数を実行してみる


    オブジェクの中で関数を設定して

    var key_obj = {
      37: function(){left_arrow()},
      39: function(){right_arrow()}
    }

    一致した場合に設定した関数を実行する
    key_obj[key_code]()




    コード.gs
    function doGet() {
      return HtmlService.createHtmlOutputFromFile("index");
    }
    
    意訳
    この機能がやること
    指定したHTMLファイルを表示する
    
    



    index.html
    <!DOCTYPE html>
    <html>
    <body>
      <script>
        window.onkeyup = window_keyup;
        
        var key_obj = {
          37: function(){left_arrow()},
          39: function(){right_arrow()}
        }
        
        function window_keyup(e) {
          var key_code = e.keyCode;
          var func = key_obj[key_code];
          if(func){
            func();
          }
        }
    
        function left_arrow(){
         alert("左")
        }
    
        function right_arrow(){
         alert("右")
        }
      </script>
    </body>
    </html>
    意訳
      
    
    
    
    キーを押して離したらwindow_keyupを実行する
    
    オブジェクトを用意する
    37の場合の関数
    39の場合の関数
    
    
    この機能が実行すること
    押されたキーのコードを取得して
    key_objから一致するものを見つけて
    見つかれば(funcがtrueなら)
    その関数を実行する
    
    
    
    この機能がやること
    アラートに"左"を出す
    
    
    この機能がやること
    アラートに"右"を出す
    
    
    
    
    


    ブラウザ上で押されたキーに応じた処理を実行する


    ブラウザ上でキーボードの左矢印「←」と右矢印「→」が押された時にそれぞれアラートを出してみる




    コード.gs
    function doGet() {
      return HtmlService.createHtmlOutputFromFile("index");
    }
    
    意訳
    この機能がやること
    指定したHTMLファイルを表示する
    
    



    index.html
    <!DOCTYPE html>
    <html>
    <body>
      <script>
        window.onkeyup = window_keyup;
        
        var key_obj = {
          37: "左",
          39: "右"
        }    
        
        function window_keyup(e) {
          var key_code = e.keyCode;
          alert(key_obj[key_code]);
        }
      </script>
    </body>
    </html>
    
    
    意訳
     
    
    
    
    キーを押して離したらwindow_keyupを実行する
    
    オブジェクトを用意しておく
    37なら左
    39なら右
    
    
    この機能がやること
    押されたキーのコードを取得して
    key_objから見つけてアラートに出す
    
    
    
    
    
    


    ifでやる場合

    index.html
    <!DOCTYPE html>
    <html>
    <body>
      <script>
        window.onkeyup = window_keyup;  
        
        function window_keyup(e) {
          var key_code = e.keyCode;
          if(key_code === 37){
            alert("左");
          }else if(key_code === 39){
            alert("右");
          }
        }
      </script>
    </body>
    </html>
    
    
    意訳
     
    
    
    
    キーを押して離したらwindow_keyupを実行する
    
    この機能がやること
    押されたキーのコードを取得して
    37なら
    
    39なら
    
    
    
    
    
    
    
    


    Switchでやる場合

    index.html
    <!DOCTYPE html>
    <html>
    <body>
      <script>
        window.onkeyup = window_keyup;
            
        function window_keyup(e) {
          var key_code = e.keyCode;
          switch(key_code){
            case 37:
              alert("左");
              break;
            case 39:
              alert("右");
              break;
          }
        }
      </script>
    </body>
    </html>
    
    
    意訳
     
    
    
    
    キーを押して離したらwindow_keyupを実行する
    
    この機能がやること
    押されたキーのコードを取得して
    処理を分ける
    37の場合
    
    
    39の場合
    
    
    
    
    
    
    
    
    



    2018年6月9日土曜日

    スプレッドシートのノートを取得する


    ここで言う「ノート」は
    メニュー > 挿入 > メモ
    で入力できるテキスト



    例では以下のようなノートが入力されている状態


    A1にhello

    A2にworld



    コード.gs
    function get_notes() {
      var ss_url = "URL";
      var ss = SpreadsheetApp.openByUrl(ss_url);
      var sh = ss.getSheets()[0];
      var col = "A";
      var start_row = 1;
      var last_note_row = get_last_note_row(sh, col);
      var notes = sh.getRange(col + start_row + ":" + col + last_note_row).getNotes();
      Logger.log(notes);
    }
    
    function get_last_note_row(sh, col) {
      var notes = sh.getRange(col + ":" + col).getNotes();
      for (var i = notes.length - 1; i >= 0; i--) {
        if (notes[i] != "") {
          break;
        }
      }
      var last_note_row = i + 1;
      return last_note_row;
    }
    



    実行結果



    関連記事

    スプレッドシートのセルにノートを入力する


    参考

    getNotes()
    https://developers.google.com/apps-script/reference/spreadsheet/range#getnotes

    テキストエリア内の空行を削除したい






    コード.gs
    function doGet() {
      return HtmlService.createHtmlOutputFromFile("index");
    }
    
    意訳
    この機能がやること
    指定したHTMLファイルを表示する
    
    



    index.html
    <!DOCTYPE html>
    <html>
      <body>
        <textarea id="ta" style="height:120px"></textarea>
        <button id="bt">空行削除</button>
        <script>
        var ta = document.getElementById("ta");
        ta.value = "\n\n一行目\n二行目\n\n\n三行目";
        var bt = document.getElementById("bt");
        bt.onclick = remove_blank_line;
        
        function remove_blank_line(){
          ta.value = ta.value.replace(/^\n/gm, "");
        }
        </script>
      </body>
    </html>
    
    
    意訳
     
    
    
    テキストエリア
    ボタン
    
    idがtaの要素を取得
    taにテキストを入れる
    idがbtの要素を取得
    btがクリックされたらremove_blank_lineを実行する
    
    この機能がやること
    ta内で先頭に改行がある場合はすべて複数行でも消す
    
    
    
    
    
    



    2018年6月7日木曜日

    setSelectionRangeでテキストエリア内を範囲選択・先頭・末尾にキャレット移動をする


    キャレットの移動とテキスト選択をしてみる

    • setSelectionRange()
      • キャレットの移動と範囲選択
    • select()
      • 全選択



    先頭にキャレット移動

    末尾にキャレット移動

    2番目から5番目を選択

    全選択



    コード.gs
    function doGet() {
      return HtmlService.createHtmlOutputFromFile("index");
    }
    
    意訳
    この機能がやること
    指定したHTMLファイルを表示する
    
    



    index.html
    <!DOCTYPE html>
    <html>
    <body>
      <textarea id="ta">hello</textarea>
      <button id="top_bt">top</button>
      <button id="end_bt">end</button>
      <button id="range_bt">range</button>
      <button id="all_bt">all</button>
      <script>
        var ta = document.getElementById("ta");
        var top_bt = document.getElementById("top_bt");
        var end_bt = document.getElementById("end_bt");
        var range_bt = document.getElementById("range_bt");
        var all_bt = document.getElementById("all_bt");
        
        top_bt.onclick = top_bt_clicked;
        end_bt.onclick = end_bt_clicked;
        range_bt.onclick = range_bt_clicked;
        all_bt.onclick = all_bt_clicked;
        
        function top_bt_clicked() {
          ta.focus();
          ta.setSelectionRange(0, 0);
        }
    
        function end_bt_clicked() {
          ta.focus();
          var len = ta.value.length;
          ta.setSelectionRange(len, len);
        }
    
        function range_bt_clicked() {
          ta.focus();
          ta.setSelectionRange(2, 5);
        }
    
        function all_bt_clicked() {
          ta.select();
        }
      </script>
    </body>
    </html>
    
    
    意訳
      
    
    
    テキストエリア
    ボタン
    
    
    
    
    要素を取得する
    
    
    
    
    
    クリックされたときの処理
    
    
    
    
    この機能がやること
    テキストエリアをフォーカス
    先頭にキャレットを移動する
    
    
    この機能がやること
    テキストエリアをフォーカス
    テキストエリアの文字数
    末尾にキャレットを移動する
    
    
    この機能がやること
    テキストエリアをフォーカス
    テキストの2文字目から5文字目までを選択する
    
    
    この機能がやること
    テキストエリアを全選択する
    
    
    
    
    
    


    2018年6月6日水曜日

    JIRAのWebhookを利用してリアルタイムで更新をキャッチする


    JIRA上の右上の歯車 > JIRA管理 > システム > 左側のメニューの「詳細」 > Webフック > Webフックの作成
    から新規Webhookを作成できる
    Webhookの管理(公式のリファレンス)

    設定する項目は主に以下の4箇所

    • 名前
      • Webhookに名前をつけられる
    • URL
      • Google Apps ScriptでWebアプリを作成して、そのURLをこのWebhookのURL欄に入れる
    • 説明
      • Webhookの説明を書ける
    • イベント
      • JQLで対象のプロジェクトなどを指定
      • 作成、更新、削除など受け取りたい通知設定にチェックを入れて「作成」する



    WebhookのURLに設定するWebアプリのコード例


    e.postData.contentsでJSONを受け取って
    内容をGoogleドライブに書き出してみるコード
    (コード内のFOLDER_IDを任意のフォルダIDに設定)

    コード.gs
    function doPost(e) {
      var json = e.postData.contents;
      create_file(json);
    }
    
    function create_file(json) {
      var content_type = "application/json";
      var file_name = "JIRA_webhook_test";
      var blob = Utilities.newBlob("", content_type, file_name);
      var file = blob.setDataFromString(json, "UTF-8");
      var folder = DriveApp.getFolderById("FOLDER_ID");
      folder.createFile(file);
    }
    

    スクリプトエディタの上部メニューの「公開」 > 「ウェブアプリケーションとして導入」 > 新規作成で変更の内容を書いて > 次のユーザーとしてアプリケーションを実行: で「自分」を選択 > アプリケーションにアクセスできるユーザー: で「全員(匿名ユーザを含む)」を選択 > 「導入」> 現在のウェブ アプリケーションの URL:の欄のURLがこのWebアプリのURL


    ISSUE_KEYを取得してみる



    •   var data = JSON.parse(json)
    •   var key = data["issue"]["key"]

    でISSUE_KEYを取得してGoogleドライブに書き出してみる

    コード.gs
    function doPost(e) {
      var json = e.postData.contents;
      var data = JSON.parse(json);
      var key = data["issue"]["key"];
      create_file(JSON.stringify(array));
    }
    
    function create_file(json) {
      var content_type = "application/json";
      var file_name = "JIRA_webhook_test";
      var blob = Utilities.newBlob("", content_type, file_name);
      var file = blob.setDataFromString(json, "UTF-8");
      var folder = DriveApp.getFolderById("FOLDER_ID");
      folder.createFile(file);
    }
    


    2018年6月5日火曜日

    スプレッドシートでフィルタをかけたときに表示されている最終行を取得したい


    ちょうど良い方法が見つからなかったので
    ちょっと裏技的な方法を考えてやってみました


    前提知識
     フィルタした行での先頭のセルをクリックしてアクティブにして
     キーボードの ⌘ と ↓を同時に押すと
     その行でデータが入っている最終行にカーソルが移動する

    ↑この動作を利用する


    上記の動作をスクリプトにするとどうなるかマクロに記録してみる
    1. マクロの記録を開始する
    2. フィルタをかけたい行で任意のフィルタをかける
    3. ⌘と↓を同時に押す
    4. マクロを保存する


    マクロを記録して自動で作成されたコード


    マクロ.gs
    function myFunction() {
      var spreadsheet = SpreadsheetApp.getActive();
      spreadsheet.getRange('B1').activate();
      var criteria = SpreadsheetApp.newFilterCriteria()
      .setHiddenValues([''])
      .build();
      spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(2, criteria);
      spreadsheet.getCurrentCell().getNextDataCell(SpreadsheetApp.Direction.DOWN).activate();
    };
    



    spreadsheet.getCurrentCell().getNextDataCell(SpreadsheetApp.Direction.DOWN).activate();
    が⌘と↓を同時に押したときのコードっぽい

    ほしい部分だけ抜き出して
    getA1Notationでセルの位置を取得してみる


    マクロ.gsからほしい部分だけ抜き出して書き換えたコード


    コード.gs
    function get_filtered_last_row() {
      var col = "B";
      var sheet = SpreadsheetApp.getActiveSheet();
      var range = sheet.getRange(col + 1).activate();
      var row = range.getNextDataCell(SpreadsheetApp.Direction.DOWN);
      Logger.log(row.getA1Notation());
    }
    


    補足


    フィルタした行の先頭行が空の場合は
    .getNextDataCell(SpreadsheetApp.Direction.DOWN)を2回行う

    このように↓
    var row = range.getNextDataCell(SpreadsheetApp.Direction.DOWN)
                            .getNextDataCell(SpreadsheetApp.Direction.DOWN)


    1回だと一番下に行かずに表示されている2行目(データが入っている)がアクティブになる→もう一度やると一番下に移動する

    これは⌘と↓を押したときと同じ挙動


    参考

    getNextDataCell(direction)
    https://developers.google.com/apps-script/reference/spreadsheet/range#getNextDataCell(Direction)

    Enum Direction
    https://developers.google.com/apps-script/reference/spreadsheet/direction

    Googleドライブの指定したフォルダ内のフォルダの一覧をシートに書き出す


    「書き出すスプレッドシートのURL」と「対象のフォルダID」を指定して
    Googleドライブのフォルダ内のフォルダ一覧を書き出すコードを書きました。



    コード.gs
    var SS_URL = "書き出すスプレッドシートのURL";
    var FOLDER_ID = "対象のフォルダID";
    
    function get_file_info_to_sheet() {
      var names= [];
      var ids = [];
      var createds = [];
      var folder = DriveApp.getFolderById(FOLDER_ID);
      var folders = folder.getFolders();
      while(folders.hasNext()) {
        var folder_i = folders.next();
        var name = folder_i.getName();
        var id = folder_i.getId();
        var created = folder_i.getDateCreated();
        createds.push(created);
        names.push(name);
        ids.push(id);
      }
      var ss = SpreadsheetApp.openByUrl(SS_URL);
      var sh = ss.getSheets()[0];
      var row = sh.getLastRow() + 1;
      var view_path = "https://drive.google.com/drive/folders/";
      for(var i = 0; i < ids.length; i++){
        sh.getRange(row, 1).setValue(names[i]);
        sh.getRange(row, 2).setValue(ids[i]);
        sh.getRange(row, 3).setValue(view_path + ids[i]);
        sh.getRange(row, 4).setValue(createds[i]);
        row++;
      }
    }
    


    参考

    getFolders
    https://developers.google.com/apps-script/reference/drive/drive-app#getFolders()


    2018年6月3日日曜日

    cursor: pointerでカーソルを手のアイコンに変える


    こういう手の形のポインターにしたい




    コード.gs
    function doGet() {
      return HtmlService.createHtmlOutputFromFile("index");
    }
    
    意訳
    この機能がやること
    指定したHTMLファイルを表示する
    
    



    index.html
    <!DOCTYPE html>
    <html>
    <head>
     <style>
     button {
      cursor: pointer;
     }
    </style>
    </head>
    <body>
     <button>ボタン</button>
    </body>
    </html>
    
    意訳
     
    
    
    
    ボタンのスタイル
    カーソルをポインターにする
    
    
    
    
    ボタン
    
    
    


    document.getElementByIdを短くための関数を用意してみる


    document.getElementByIdを毎回書いたりコピペしたりするので
    id名を渡して要素を取得する関数を書いてみる


    function get_elem(id){
      return document.getElementById(id);
    }



    コード.gs
    function doGet() {
      return HtmlService.createHtmlOutputFromFile("index");
    }
    
    意訳
    この機能がやること
    指定したHTMLファイルを表示する
    
    



    index.html
    <!DOCTYPE html>
    <html>
      <body>
        <button id="bt">ボタン</button>
        <script>
        function get_elem(id){
          return document.getElementById(id);
        }
        var bt = get_elem("bt");
        bt.onclick = bt_clicked;
        
        function bt_clicked(){
          alert("hello");
        }
        </script>
      </body>
    </html>
    
    
    意訳
     
    
    ボタン
    
    この機能がやること
    受け取ったidの要素を取得して返す
    
    id名"bt"をget_elemに渡して結果を得る
    btがクリックされたらbt_clickedを実行する
    
    この機能がやること
    hello をアラートに出す
    
    
    
    



    スプレッドシートのセルに画像を挿入する


    Googleドライブ内の画像をシートのセル内に表示したくて調べて実現した方法

    Googleドライブ内の画像をスプレッドシートのセルに表示したい


    =image("https://drive.google.com/thumbnail?sz=w1000&id=IMAGE_FILE_ID",1)

    読み込むときは画像ファイルの公開設定を「リンクを知っている全員」にしておかないと読み込まれないらしい



    Webに公開されている.pngや.jpegなどの画像ファイルをセルに表示したい


    =image("画像URL",1)



    画像のサイズ設定モード


    =image("URL",1) セルのサイズに合わせる
    =image("URL",2) セルのサイズに画像を伸ばす
    =image("URL",3) オリジナルのサイズ
    =image("URL",4, 120, 60) 高さと幅を指定する


    参考 

    画像や動画を挿入、削除する > 数式を使用してスプレッドシートに画像を追加する
    https://support.google.com/docs/answer/97447?co=GENIE.Platform%3DDesktop&hl=ja

    IMAGE
    https://support.google.com/docs/answer/3093333

    Google Docs Help Forum
    https://productforums.google.com/forum/#!topic/docs/gC6zAVKGgWc

    2018年6月2日土曜日

    Googleドライブの指定したフォルダにファイルがいくつあるか取得する


    FOLDER_IDを指定して
    そのフォルダ内に含まれるファイル数を取得したくて書いたコードです



    コード.gs
    function count_files() {
      var folder = DriveApp.getFolderById("FOLDER_ID");
      var contents = folder.getFiles();
      var i = 0;
      while(contents.hasNext()) {
        contents.next();
        i++
      }
      Logger.log(i);
    }
    


    参考

    Class FileIterator
    https://developers.google.com/apps-script/reference/drive/file-iterator

    Latest post

    Googleドキュメントに見出しを追加したい

    今回の例では、ドキュメントの末尾に「見出しD」 を追加します。 見出しA, B, C, Dのスタイルは、見出し3 ( HEADING3 ) に設定しています。  下記Code.gsの  GOOGLE_DOCUMENT_URL を設定して  addHeadingToEnd()  を...