【MACRO】Google Apps Script 質問スレ【DRIVE】
Google Apps Script でのプログラミング等に関する質問スレです
Excel や Access の VBA に不満のあるあなた
web アプリだけでなくクライアントアプリからも利用したいあなた
ローカルなデータベースやファイルだとバックアップに不安のあるあなた
ム板に無かったので立ててみます
Google Apps Script
ttps://developers.google.com/apps-script/
Google Drive API
ttps://developers.google.com/drive/
Getting Started with the Google Data Python Library
ttps://developers.google.com/gdata/articles/python_client_lib
■関連スレ
Google Maps API 質問箱
http://peace.2ch.net/test/read.cgi/tech/1131627583/
Microsoft SkyDrive API
http://peace.2ch.net/test/read.cgi/tech/1385604796/
【GoogleAppsScript】猿92【研究せよ!!!】
http://nozomi.2ch.net/test/read.cgi/php/1398600864/
GoogleAPIってどうよ?
http://nozomi.2ch.net/test/read.cgi/php/1018614427/
Google App Engine for Python 6アプ目
http://nozomi.2ch.net/test/read.cgi/php/1358570953/
Google App Engine for java
http://peace.2ch.net/test/read.cgi/tech/1317639323/
GoogleWebToolkit[GWT]について語ろう
http://nozomi.2ch.net/test/read.cgi/php/1147975874/ >>204
君はGoogleのドキュメントがろくにメンテされてないこと知ってんの?
それと、GASで使うのにOAuthなんて使わないよw
JavaScriptで使う場合には必要だがそっちだって、OAuth2.0でのコーディングに
関しては別のページにあるし。GASやGoogle APIを弄っている人間とは到底思え
ない発言だなw > それと、GASで使うのにOAuthなんて使わないよw
ひょ、標準APIとの違いも解らない奴がココに居るのか
ちょっとキミにはこのスレちょっと早い 煽るだけで具体例のない言葉は何の役にも立たねって
ばっちゃが言ってた 知らないから自演も満足に出来ないんだろうが
煽り方が下手だと思う >>206-207
だから、使ってからほざけよ。
コード書いてみ?GAS内でDrive API使うコードをな。
実際に開発やってる奴に、釈迦に説法って言葉覚えておけよ三流。 >>204
それとお前。
OAuth1.0だから何?そんなもの自分で2.0の実装でも換装すりゃいいだけの
話だろww
馬鹿なの?それとも2.0のコードでも書けとか言ってるわけ?馬鹿には無理だ
から引っ込んでろ なんか急にonEditのe.userにメールアドレスが入ってこなくなったんだが
同じ現象の人いる? これで良くね
ttp://stackoverflow.com/questions/26702330/why-does-google-apps-script-return-a-url-rather-than-a-pdf-file-when-i-try-to-cr >>211
そんなのしょっちゅうあるぜ?
session.userなんてメアド取れなくなったりとかね。
Googleって馬鹿だからバグ採りもせずにデプロイしてやがるのでこういうことがGoogle Apps for Workでも起きていてもんだいになってる。 書式設定を変えるようなスクリプトを作っても反映されないんだけど、
スプレッドシートの既知の問題?
例えば下のスクリプトを実行すると、既に長い文字列が入ってるセルがあっても
折り返してくれない。
(スクリプト実行後、ボタンはちゃんと「テキストの折り返し」になってるし、ボタン押せば折り返す)
function test() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange('A:A');
range.setWrap(true);
}
この問題って、フォームから文字列が入力されても既に書式設定してあるセルで
同じ事が起きるんだけど、地味に困ってる。 TwitterBotを作成しているのですが
OAuth1 for Apps Script
https://github.com/googlesamples/apps-script-oauth1/blob/master/samples/Twitter.gs
にCONSUMER_KEYとCONSUMER_SECRETを入れてrunを実行しても投稿されません。
ログには Open the following URL and re-run the script
表示されるアドレスにアクセスするとSuccess!と表示されますが投稿されません。
どうしたら投稿できるようにできますか? atomのlinkのhrefを取得したいのですがどうすればいいのでしょうか
function kochiRSS() {
var sheet = SpreadsheetApp.getActiveSheet();
var row = 1;
var feedURL = 'http://www.pref.kochi.lg.jp/news/index.atom';
var xml = UrlFetchApp.fetch(feedURL).getContentText();
var document = XmlService.parse(xml);
var root = document.getRootElement();
var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
var entries = root.getChildren('entry', atom);
for(i in entries) {
var title = entries[i].getChild('title', atom).getText();
var link = entries[i].getChild('link', atom).getValue();
var updated = entries[i].getChild('updated', atom).getText();
sheet.getRange(row,1).setValue(title);
sheet.getRange(row,2).setValue(link);
sheet.getRange(row,3).setValue(updated);
row++;
}
sheet.sort(3, false);
} .getAttribute('href').getValue(); たびたびすみません。
RSSを取得するプログラムを作っているのですが
RSS2.0は
var items = root.getChild('channel').getChildren('item');
ATOMは
var entries = root.getChildren('entry', atom);
で取得できるのですが
RSS1.0だとitemが<item rdf:about="記事のURL">なため
var items = root.getChildren('item');
では取得できません。
どういう書き方にすれば取得できるようになるのでしょうか? 一部変な奴もいるけど気にせずに馬鹿はどんどん質問してくださいな 正直、DOM系の話題はなしにしたいものだ
DOMの話題ってjsの使い方一辺倒になっちまうから
GASそのものの本質を追究する姿勢が培われなくなってしまう GASはハウツー的な日本語ドキュメントが少ないから仕方ないかと
誰かその辺りをまとめてくれると(俺も)助かるんだがなー…(チラッチラッ >>223
>RSS1.0だとitemが<item rdf:about="記事のURL">
属性はattributeと言う。
こんな感じかな。
items[0].getAttribute("about","rdf").getValue();
上は未実証なので詳しくはreferenceを参照。
https://developers.google.com/apps-script/reference/xml-service/element#getAttribute(String,Namespace) ありがとうございます。
rdf:aboutのようなのは名前空間というみたいで
XmlService.getNamespaceを指定すると使えるようです。
詳しくはこちらに載っていました。
https://msdn.microsoft.com/ja-jp/library/aa468565.aspx いやここはGASのスレだしw
XMLの基本を鼻高々に解説されても google apps script のウェブアプリケーションの公開するとき
指定したグーグルアカウントだけに利用させるって出来ないんですかい?
共有でそういうのあったんですけど、共有はコード見れるとかそういうのだったんで スレ違いだけどできないはずはないと思うよ
appsにアカウント登録できるはず >>235
1) googleアカウントでログインしてるユーザーだけに実行させることが出来る
2) アプリケーション側でどのアカウントで実行されているか把握することが出来る
1) と 2) を組み合わせれば可能 出来たよありがとう
"無ければ作れ"がGASでも通用したとか最高だ GASに初トライしていて問題にブチあたりました。
解決方法があれば教えてください。
■やりたいこと
スプレッドシート内で
外部ページ情報を取得しリアルタイム・もしくはインターバル更新表示しい。
基本は自動更新
■更新条件
スプレッドシートを開いた
スプレッドシートのセルにユーザーから入力があった。
の両方です。
■ためしたこと。
1.=ImportXMLを使って取り込み
単純な目的は果たせるがセルに埋め込むと取得データを加工するにしても限度がある。
また、同じURLを指定したセルが複数ある場合、同じデータなのにアクセスさせるのが無駄
2.GASでImportXML相当のことをしてみる
セルから呼び出せる関数でUrlFetchApp.fetchを使ってみる。
当初の目的は果たせるようになったが、セルの数が多く、
またスクリプト実行テストを繰り返しているとあっというまに1日の呼び出し回数制限に達してしまう(無料アカなので2万回)
3.呼び出し制限に達しないようにするための工夫
URLから取得した情報をプールしておき、前回取得からのインターバル時間を経過したら再取得してキャッシュ更新。
または、キャッシュに存在しないデータを要求された場合もキャッシュ更新。
キャッシュ場所は、自分のスプレッドシート内にcacheシートを生成してそこに書き込んでおく。
4.3までのロジック実装は完了し、スクリプトエディタの関数実行テストまでは正常完了
続きます。 4からが問題でして、エディタ内の関数単体テストでは、データ取得・キャッシュシート生成まで問題なく動作しました。
しかし、これの関数をセルから呼び出そうとするとエラーになります。
エラーはシートに対して操作権限がないといわれます。
調べたところセルで関数を呼び出した場合、
var ss = SpreadsheetApp.getActiveSpreadsheet();
var cacheSheet = ss.getSheetByName( g_stocksSheetName );
で取得したシートに対して、作成・修正・削除などの操作が出来ないようです。
つまりセルから呼び出した場合オブジェクトの参照関数しか呼び出しが許可されない?
ss.insertSheet( 'cacheSheet' )
とか
cacheSheet.getRange( 1, 1 ).setValue( new Date() );
もダメでした。
5.イベントハンドラを使ってみる
しょうがないので、書き込み権限を与えてくれそうな仕組みがないかテストしていたところ
onEvent,onOpenなどならいけそうだったので、
onEventから呼び出してみました。
すると、シート作成・データセットまではうまくいきますが、
UrlFetchApp.fetchでエラーになっているらしく、
上流で捉えた例外は
fetch を呼び出す権限がありません
でした。 6.キャッシュの保存場所
自分に書き込めない場合、どっかに保存できないの?と思い調べてみると
ScriptDb とか言うのがあるみたいですが、サービス終了予定の機能ぽいですし、
Google Cloud SQLとかいうのを使うしかない?有料??
■知りたい事
・1〜6の流れで問題となっているアクセス権を解決できる方法はありますか?
・無理な場合の代替え手法はありますか?
・そもそもアプローチが間違っている、こうしたほうが良いよ。
という感じでうs。
このまま、いろいろ渡り歩いていても遠回りになりそうな予感なので質問してみました。
よろしくお願いします。 >>242
htmlservice + oauth2 >>243
> >>242
> htmlservice + oauth2
ありがとうございます。
調べてみます。 htmlからツイにつぶやくのをやってたら
(>_<)この顔文字が(>_<)こんななってたぶんそのせいででエラー吐くんだけどこれはreplaceすればいいのかな?
こういう表記になる文字ってたくさんあるのかな? >>245
おいてめーそれ「はじめてのホームページビルダー」レベルじゃねぇか >>245
そういうのはエンコードすべきなんじゃないのか? >>246
PHPはちょっと良くわかんないです
gasですし
>>247
そうなんですよね〜
初心者なんです
>>248
エンコードですか
調べてみます >>243
> >>242
> htmlservice + oauth2
あれから調べてみましたが、これらを使ってどうアプローチしていいか分かりませんでした。
どういうアプローチを取って良いのか、もう少し詳しく教えていただけないでしょうか?
自分が上でやっていてダメだったアプローチは以下のAuthorization modesをみると納得なのですが
https://developers.google.com/apps-script/add-ons/lifecycle
これらの状況の中でどうやって目的を達成していいか分かりませんでした。
Htmlservice, oauth2ということだったので、
外部サイト情報から取得したキャッシュをHtmlにしてGoogleDrive側に保存すればいいのかな?
とか思っていたのですが、
AuthMode.LIMITEDやAuthMode.CUSTOM_FUNCTIONでは他のサービスへのアクセスは
Any services that don’t access user data
とのことで、キャッシュを書き込めないようです。
実際に試してみましたが、スクリプト単体テストではOKでしたが、イベントハンドラから呼び出すとDrive周りの関数で権限がないといわれました。
oauth2に関してはいまいちよく分かりませんでした。
他社サービスIDなどで別サイトのサービスにアクセスする場合などの認証などに使ったりするようですが、
Googleのアカウントで自身にログインして何かをしろという事でしょうか?
どちらにしろ、AuthMode.FULLで行えるような権限を得られないと、
・キャッシュを作るための外部サイトアクセスとコンテンツ取得
・取得したコンテンツから生成したキャッシュデータの保存(シートorファイル)
が実現できないと思うのですが、どうでしょう? 分かる人がいたら教えて下さい
function upload() {
var clientId = '*************';
var imgUrl = 'http://www.google.co.jp/images/srpr/logo11w.png';
var service = getService(); //aouth2のなんか
if (service.hasAccess()) {
var url = 'https://api.imgur.com/3/image';
var response = UrlFetchApp.fetch(url, { //ここでエラーが出る
method: 'post',
headers: {
Authorization: 'Client-ID ' + clientId,
},
data: {
image: imgUrl,
type: 'URL'
}
});
var result = JSON.parse(response.getContentText());
return result;
} else {
こういうエラーが出ます
{"data":{"error":"No image data was sent to the upload api","request":"\/3\/image","method":"POST"},"success":false,"status":400}
どこが間違えてるんでしょうか
imgur apiのページ
https://api.imgur.com/ ttp://www.google.co.jp/images/srpr/logo11w.png
404
The requested URL /images/srpr/logo11w.png'; was not found on this server. 普通に繋がるんですが・・・
というか画像のURLに関しては色々試してます data: {
type: 'base64',
image: 'hogehoge(base64data)hogehoge'
}
ためしてみたけど
400
Image format not supported, or image is corrupt.
なんぞこれ >>254
OAuth2の認証系をしっかり組んでないからじゃないかね。
http://wp.me/p5KJV2-9k >>260>>261
そっちなんですね
読んできます
ありがとうございます 読んでも全然わかんないや(´・ω・`)
ツイとかはコピペでなんとかなったけどimgurはあんまり見つかんないからやっぱ自力じゃ無理なのかな getの方は出来たんだけどなぁ
もうちょっと読んでみよ英語分かんないけど
function getImage(id) {
var service = getService();
if (service.hasAccess()) {
var url = 'https://api.imgur.com/3/image/' + id;
var response = UrlFetchApp.fetch(url, {
method: 'get',
headers: {
Authorization: 'Bearer ' + service.getAccessToken()
}
});
var result = JSON.parse(response.getContentText());
return result;
// Logger.log(result);
} else {
var authorizationUrl = service.getAuthorizationUrl();
Logger.log('Open the following URL and re-run the script: %s',
authorizationUrl);
}
} >>254 のは匿名うp用の認証してるからOAuth2は関係ないね Content-Type: application/json
つけたらでけた どこに付ければいいか分からないので適当に色々なところに付けてみましたが出来ませんでした
もう少し詳しくお願いします headers: {
Authorization: 'Client-ID ' + clientId,
Content-Type: 'application/json'
}, >>268
そう書くと保存の時に「プロパティ ID の後に : がありません。」ってエラーが出るんですけどなんでだろう
headers: {
Authorization: 'Client-ID ' + clientId,
Content-Type: 'application/json' ←この行
}, 'Content-Type': にしてみてもダメでした multipartで渡してエラー吐くと思ったらJSONで渡すんだねこれ… 独自関数(自作)でbackGroundの色が特定の色の場合にsumする関数をつくりたいんだけど、
引数でバックグラウンドの色ってとりだせるの?
というより、適当に作ったんだけど、スクリプト保存しないと独自関数を使用しているセルが更新されなくて困ってる。 何でもできるようになってきて
すごくありがたく使わせてもらってるんだけど
実行速度が遅いのは何とかしてほしいなぁ 遅いね
あとREMOTE_ADDRとか取れなかった気がするのも痛い スプレッドシートの0:00とか時間表記でのものを時と分に分けて数値として扱いたくて
getRangeで2次元配列で読み込んで時間の部分をsplit使って:で分けました
でもSSの時間部分の書式が日付になるとWed Nov 18 2015 00:00〜みたいなDateで読み込まれるし
書式なしテキストにするとStringになって数値として扱えないんです(8:00だったら8と00になって足すと800になる)
どうすればいいでしょうか? >>282
固定させたいカラムを晒してくれないとわからない
カラムによってはその機能が備わってるみたいだし ごめんなさい
自己解決しました
Number()ってのをつかったらいけました グローバルでconstを使うと、
「TypeError: 定数 **** の再宣言。」
とエラーが出るのですが、グローバルではconstは使えないのでしょうか? シート上のデータをまとめてカレンダーに移したいのですが
GASからbatch requestで処理できますか?
もしできるなら似たような事例でコードがわかるものを教えてください >>291
CalendarApp使えばいいじゃん >>290
すみません、説明が不足していました。
constで定義した名前は他の場所では宣言していません。
ただ、グローバルでconstを使うと、再宣言していない定数でも
「TypeError: 定数 **** の再宣言。」とエラーになってしまいます。
(function内などのスコープではconstは普通に使えています。)
constでなくvarを使うと再宣言のエラーは出ません。
また、const指定する定数の名前は何にしても再宣言のエラーが出ます。
constの使い方が間違っているのかもしれませんが、何かおかしい点があれば教えていただけないでしょうか? すごく初歩的な質問だと思うのですが原因が解りません
どなたか教えて下さい
下記サイトを参考にスクリプトを作成したのですが
http://chaika.hatenablog.com/entry/2015/09/03/143622
デバッグすると一番最初の
var ss = evt.source.getActiveSheet();
の箇所で
TypeError: undefined からプロパティ「source」を読み取れません。(行 3、ファイル「コード」)
と出てしまいます
ググったところ、スクリプトの作成元が間違っていると出たりするようですが
参考サイトではスプレッドシートから作成、とあるので間違いではないと思います
かといって何が問題なのか解りません 3. エディタのリソースをクリックして、**現在のプロジェクトのトリガー**を選択
4. 実行をonEditEvent、イベントをスプレッドシートから・編集時 にして保存 >>297
296です
その設定はやってあります
再度確認しましたがその通りになっています
ですが、デバッグすると296の通りです
https://i.gyazo.com/196e454d6eee012351e550aa5cbf3cd3.png 関数指定してデバッグボタン押しただけとか?
まさかなー >>299
296です
私へのレスでしょうか?
何かやり方が間違っているのでしたら教えていただけませんか? いや、俺もトリガーの機能をここのやり取りで知ったぐらいだけど、
デバッグボタンを押すだけだったら
onEditEvent();
と呼び出されるだけじゃない
evtがundefinedなのはそのせいかなと思って
実際どうなん?
正式なやり方はしらんけど、Loggerでトリガーが起動された時に
どんなオブジェクトが渡されてくるかを調べる
そういうオブジェクトを自力で用意してonEditEventに渡す関数を作成する
その関数をデバッグモードで起動
とかするんじゃないのかな
ググってみればやっている人いるかも とりあえず、「Hello,World」から始めようと思ってやってみたんですが、
「Cannot call Browser.msgBox() from this context;
have you tried Logger.log() instead? (line 1, file "helloworld")」
とエラーがでていきなり動きません。
エラー内容で検索してみたのですが、
同様のケースは見つからず困っています。
原因は何なのでしょう?
ソースは以下の通りです。↓
function myFunction() {
Browser.msgBox("Hello World!");
} スプレッドシートで やったら普通に動いたよ
this contextとある様にどんな状況でスクリプトを実行しているかが問題だと思う