質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

解決済

1回答

3524閲覧

【GAS】自作したライブラリ内のHTMLにあるボタンを押して、ライブラリ内のgsファイルの機能を使いたい

lazy

総合スコア36

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

1クリップ

投稿2021/10/16 06:41

前提・実現したいこと

自作した、ライブラリのhtmlファイルをスプレッドシートのサイドバーに表示させて、
サイドバーに配置した、ボタンから、google.script.runを使って、サーバーサイドのgsファイルの機能を利用したい

発生している問題・エラーメッセージ

・ライブラリ化(viewSidebar.gs、sidebar.html、sidebarscript.htmlの3ファイル)
・ライブラリ内のsidebar.htmlをスプレッドシートのサイドバーに表示
・sidebar.htmlから、同ライブラリ内「sidebarscript.html」の<script>処理を読み込み(htmlファイルとscirptを分離したかった)

までは実現したのですが、

sidebarscript.htmlから、google.script.runにてviewSidebar.gsのserverTestFunc()の実行ができません。

ブラウザ開発者ツールのコンソールに

Uncaught TypeError: google.script.run.serverTestFunc is not a function

と表示されます

該当のソースコード

・sidebar.html

html

1<!DOCTYPE html> 2<html> 3 <head> 4 <base target="_top"> 5 <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css"> 6 </head> 7 <body> 8 <div class="sidebar"> 9 <div class="block form-group"> 10 </div> 11 <div class="block"> 12 <button class="blue" onclick="testFunc()">ボタン</button> 13 </div> 14 </div> 15 <?!= HtmlService.createHtmlOutputFromFile('sidebarscript').getContent(); ?> 16 </body> 17</html>

・sidebarscript.html

html

1 2<script> 3 4function testFunc(){ 5 6 // alert("ボタンが押された"); 7 // ↑アラートは表示されたので、サイドバーのボタンを押して、testFunc自体は動いていることを確認 8 9 google.script.run.serverTestFunc("testtest"); 10 11 12} 13</script> 14

・viewSidebar.gs

js

1function showSidebar() { 2 var htmlOutput = HtmlService.createTemplateFromFile('sidebar').evaluate(); 3 htmlOutput.setTitle("サイドバー"); 4 SpreadsheetApp.getUi().showSidebar(htmlOutput); 5} 6 7// 【この関数が実行されない】 8// 表示されたサイドバーのボタンで実行したい 9function serverTestFunc(data){ 10 11 Logger.log(data); 12 13} 14 15// スプレッドシートにサイドバー表示のメニュー追加 16function menuOpen() { 17 var sheet = SpreadsheetApp.getActiveSpreadsheet(); 18 var entries = [ 19 { 20 name :"サイドバー表示", 21 functionName:"showSidebar" 22 } 23 ]; 24 sheet.addMenu("カスタム機能", entries); 25};

【スプレッドシート側】
・コード.gs

js

1// ライブラリのメニュー追加機能を実行 2function onOpen(){ 3 mylibrary.menuOpen(); 4} 5 6// 追加されたメニュー「サイドバー」をクリックして、ライブラリのsidebar.htmlを読み込み 7function showSidebar(){ 8 mylibrary.showSidebar(); 9} 10

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

結論として、ライブラリ化したコードから google.script.run は実行できないと思います。

  • 参照した資料

    1. stackoverflow
    2. Addressing namespace and library methods from google.script.run
  • Sidebar はスプレッドシートの枠組みで実行されている
    google apps script が、スプレッドシートから実行されているので、スプレッドシートから実行可能な関数しか実行できない。

  • スプレッドシート側からみたとき、serverTestFunc は、グローバルスコープに存在しないので、google.script.run.serverTestFunc は実行できません。
    → 資料の 2. を参照。要は、onOpen と同じように、スプレッドシートの側からは mylibrary.serverTestFunc としなければ実行できません。

  • google.script.run.mylibrary.serverTestFunc は利用できない形式(グローバルスコープの関数しか実行できない)

  • 呼び出されたライブラリ側から、呼び元のスクリプトにアクセスすることができない
    → スタックオーバーフローで出ている、dummy や callLibraryFunction といった案をためしましたが、そもそも、ライブラリで作成された html から、スプレッドシートにあるスクリプトを呼び出すことができないです。
    withFailureHandler にコールバックを与えて実行したところ、このコールバックが実行されるので、失敗なのは間違いないのですが、内容を見てもなぜエラーなのか分かりませんでした。


  • 整理
  1. ライブラリを利用する以上 serverTestFunc は mylibrary.serverTestFunc にしかないので、google.script.run.serverTestFunc は実行できない
  2. google.script.run.ライブラリ名.関数名 のような呼び出しはできない(これはライブラリ名に限らず、スプレッドシート内で定義された class であっても同じ。この構文が実行できない)
  3. 仮に stackoverflow のように callLibraryFunction のようなことができるとして、html には、google.script.run.callLibraryFunction("mylibrary.serverTestFunc", ["testtest"]); とかかないといけません。

つまり、このライブラリは必ず mylibrary として読み込まないといけない、ということになりライブラリ化する旨みが減ります。
4. serverTestFunc をライブラリ化することは可能なので、ライブラリでは表示にかかわらない内容の汎用化にとどめて、sidebar の呼び出しは、スプレッドシート側に(重複はあるかもですが)作るのが現実解ではないかと思います。(google にリクエストしてもいいかもですが、すぐに利用できるようになることは期待できないので)
下記のような html と コードをスプレッドシートに作れば、ライブラリ側の関数を呼べることは確認しました。

html

1<script> 2function testFunc(){ 3 google.script.run.dummy("testtest"); 4} 5</script>

javascript

1function dummy(e) { 2 mylibrary.serverTestFunc(e); 3}

投稿2021/10/16 11:59

papinianus

総合スコア12705

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lazy

2021/10/26 06:06

ありがとうございます、同じhtml&機能を複数のスプレッドシートに入れる必要があったので、セットでライブラリ化できればと考えていたのですが、、、>< 詳細に調査していただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問