それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

debianのphpでapcuを有効にする。

APCuが有効にならない。

sudo -u www-data php occ
An unhandled exception has been thrown:
OC\HintException: [0]: Memcache \OC\Memcache\APCu not available for local cache (Is the matching PHP module installed and enabled?)

清く正しくdebian提供の、コマンドphpenmodでモジュールを有効にする。

# phpenmod apc

apc のモジュールはロードされている。

ls -l /etc/php/*/*/*apc*
-rw-r--r-- 1 root root  31 Nov  4  2018 /etc/php/7.3/mods-available/apcu_bc.ini
-rw-r--r-- 1 root root 109 Jul  5 15:14 /etc/php/7.3/mods-available/apcu.ini

しかし、有効にならない。

sudo -u www-data php occ
An unhandled exception has been thrown:
OC\HintException: [0]: Memcache \OC\Memcache\APCu not available for local cache (Is the matching PHP module installed and enabled?)

php -i で状況を見る。有効にならない・・・

# php -i | grep -i apcu

/etc/php/7.3/cli/conf.d/20-apcu.ini,
/etc/php/7.3/cli/conf.d/25-apcu_bc.ini
APCu Version => 5.1.17
apcu
APCu Support => Disabled
APCu Debugging => Disabled

apc 関連のphp.iniが欠損していると気づく。マジか。

cat <<EOF  >> /etc/php/7.3/cli/conf.d/20-apcu.ini

[apcu]
apc.enabled=1
apc.shm_size=32M
apc.ttl=7200
apc.enable_cli=1
apc.serializer=php

EOF

APCuが有効になった。

php -i | grep -i apcu
/etc/php/7.3/cli/conf.d/20-apcu.ini,
/etc/php/7.3/cli/conf.d/25-apcu_bc.ini
APCu Version => 5.1.17
apcu
APCu Support => Enabled
APCu Debugging => Disabled

結論

debianphp-apcu のモジュールでは apc.enabled = 1 が欠損している。

debian 系の php-mods のインストールには気をつけろ。

今回は少し古いdebianphpでメンテナンスをしていたので、最新版では治ってるかもしれないが。十分に気をつける必要がある。

nextcloud でまた起きた(2022-05-12)

debian をbullseyeにアップデートしたら、このエラーが再現して、nextcloud が死んだ

Internal Server Error

The server encountered an internal error and was unable to complete your request.
Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.
More details can be found in the server log.

php-fpm がエラーになり、nginxが500を返すようになった。

sudo apt install php8.0 php8.0-fpm \
 php8.0-apcu \
 php8.0-xsl \
 php8.0-zip \
 php8.0-mbstring \
 php8.0-curl \
 php8.0-gd \
 php8.0-imagick \
 php8.0-sqlite3 \
 php8.0-redis \
 php8.0-mysql \
 php8.0-intl \
 php8.0-mcrypt \
 php8.0-memcache \
 php8.0-bcmath \
 php8.0-gmp \
 libmagickcore-6.q16-6-extra \

をして、phpenmodをした

phpenmod -v 8.0 apcu

これで生き返ったと思う。

Google Apps Scriptで、セルのK3の参照を出す。カラムの番号( col ) をアルファベットの参照に変える

ColumnとAddressの相互変換

K3 をはそのまま取得できるが 逆が難しい。

getRange( 'K3' )

getRange でアルファベットを使った、相対(絶対)参照をつかってスプレッドシートの領域を取れるのだが、逆に、セルを参照形式に変換するのが、頭を悩ませた。

K3 セルを取るには、どうすればいいんですか?

getRange( 3,10 ) //=> 'K3' にしたい

なのだけど、colum K = col:10 を変換するのが大変。アルファベットのA-Zまでならいいけど、AA-ZZまでくるともう大変だった。

Column番号を、アルファベットに変更

アルファベットの「文字」に変換する。適当なセルに一時的に=ADDRESS(3,10,4) を書き込めば K3が取れる

  findStartColLetter(sheet,col) {
    let tmp = sheet.getRange(1000, 1, 1, 1);// 適当な
    tmp.setValue('=ADDRESS(3,' + col + ',4)')
    let a = tmp.getDisplayValue();
    tmp.clear();
    return a[0];
  }

文字にするには、とりあえず ADDRESS 関数に掛けるのが速いのだが。ADDRESS関数を使った結果を取らないといけない。でもAddressに相当するGAS の関数が見当たらない。仕方ないので、ADDRESSを適当なセルに書き込むことに。

なぜアルファベットのカラム名が必要なのか。

getRange で、数字でアクセスできるのに、なぜ文字列を使ったセル参照名に変える必要があったのか。 それは、条件付き書式の計算である。

条件付き書式を読みやすく指定する。

条件付き書式に AddressやINDIRECTを使うと、うまく動作しなかったのである。また関数が増えるとあとで読んだときにわかりくいのである。

その他のGASの記事

Goole App Script ( GAS ) を始める。記事一覧 - それマグで!

Gitのリモートブランチをcloneする。

git の リモートブランチをclone したい

直接 clone できるわけじゃないけど、新規でclone する場合は結構楽に行える。

いつも流れ作業でやってるし過去にも書いてるんだけど。誰かに伝えるために改めてメモ。

作業の流れ

最初に、メインなブランチ(master)を clone する。 その後にリモートブランチをcheckout する。

作業コマンド

全体の作業の流れはこんな感じ。

git clone ${REPO_URL}
cd ${REPO_DIR}
git fetch 
git checkout -b ${BR_NAME} origin/${BR_NAME}

作業例

既存フォルダがあれば消す。

takuya@osx:~/Desktop$ rm code -rf

clone する

clone した時点では、master(main) ブランチ

takuya@osx:~/Desktop$ git clone git@ssh.mygit.example.com:repo/sample-/code.git
Cloning into 'code'...
remote: Enumerating objects: 413, done.
remote: Counting objects: 100% (413/413), done.
remote: Compressing objects: 100% (143/143), done.
remote: Total 16630 (delta 315), reused 302 (delta 247), pack-reused 16217
Receiving objects: 100% (16630/16630), 98.06 MiB | 13.38 MiB/s, done.
Resolving deltas: 100% (5694/5694), done.
Checking out files: 100% (832/832), done.

git フォルダ内部へ移動

takuya@osx:~/Desktop$ cd code

リモートブランチの状態を調べる

takuya@osx:~/Desktop/code$ git fetch
takuya@osx:~/Desktop/code$ git branch -r
  origin/HEAD -> origin/master
  origin/deploy-test
  origin/master
  origin/staging

リモートブランチをチェックアウト

takuya@osx:~/Desktop/code$ git checkout -b staging origin/staging
Branch 'staging' set up to track remote branch 'staging' from 'origin'.
Switched to a new branch 'staging'

チェックアウト結果を調べる。

takuya@osx:~/Desktop/code$ git branch
  master
* staging

ポイント

git ブランチは、ローカルとリモートで別々に存在します。

リモートのブランチをローカルでチェックアウトして使います。

チェックアウト時に、ローカルで変更(差分)があると、コンフリクトが発生したり、自動マージが走ったりします。注意してください。

lxc でCentOSのコンテナを起動する

centos をぱぱっと作る

LXCでCentOSのコンテナを起動して動作させる。

docker と違い ちゃんとinit.d / systemd が起動した centos なので実験・テスト環境にはとても楽。

LXD はほんと、ちょっとしたコツを覚えれば快適に実験環境を作れる。

centos を lxc で作成する

lxc launch images:centos/8 

名前は docker のように適当な単語を使って名付けられる。

自分でコンテナを名付けたいとき

lxc launch images:centos/8 my-example-cent8

ログインする

lxc shell my-example-cent8

名前がわからないときは、 lxc list  で起動中の一覧を取得できる。

centos を探す

lxc で 起動できる centos を一覧するには次のようにする。

lxc image list images:centos

cent / fedra などの起動

2021-06-17 lxc の記事をいくつか書いていたが centos や fedra についてだけ書いた記事を作ってなかったのでまとめ直した。

関連資料

https://takuya-1st.hatenablog.jp/entry/2020/09/11/150007

Goole App Script ( GAS ) を始める。記事一覧

Google Apps Script をはじめました。

GoogleAppScriptを始めたときに、思い通りのコードが書けるまで、四苦八苦しながら調べたことをまとめて記事にしています。

おもに、ハローワールドを実行し、実行方法を調べています。

また、その次にGASをファイルに分けたりgitで管理するとか、コードをいかに管理するかという視点が多いですね。

記事一覧

GAS はソコソコ枯れたツール

登場から随分時間が立つので、Google Apps Scriptはソコソコ情報も充実している。

そのため、わからないことを調べたら出てくるのですが。E○cel V○Aのような、いかがでしたかサイトの、検索汚染が激しい。

そこで、始めてから、コードを実行し、ファイルに分割し、Classに分割し、git 管理するまでを記事にまとめておいた。

表記揺れ

後で気づきました、Google Apps Script が正式名称ですが、google app script とずっと書いてしまっています。

参考資料

Goole App Script ( GAS ) の基本的な操作方法。18. clasp run でコンソールから実行

clasp run で ローカルからGAS実行

clasp run をつかえば、コマンドからGASを実行できます。

f:id:takuya_1st:20210608021310p:plain

clasp コマンドをうまく使えば便利かもしれないので、使い方を見ておく。

全体の流れ

結構手順が多いのです。

  • clasp コマンドをインストール
  • GASプロジェクトを設定
  • GCPプロジェクトを作成設定
  • GASとGCPを紐付け
  • clasp と GASを紐付け・認証
  • clasp に GCPを紐付け・認証
  • clap run

run を使うまでの手順が、煩雑で多いのです。OAuth関連の設定が多くてね。

clasp run は GCP にリクエストを投げ、GCPが GAS api を叩き、最新のコードを実行し結果を返してくれます。

clasp インストール

npm で clasp をインストールします。

npm install -g @google/clasp

GAS プロジェクト作成

https://script.google.com/ にアクセスして、プロジェクトを新規作成。

f:id:takuya_1st:20210608002540p:plain:w300

GCP プロジェクトを新規作成

GCP コンソールにアクセスして、プロジェクトを作成

GCP で作って保存するもの

GCPのコンソールでは、次の情報取得とAPI有効化をやります。

  • 必要情報の取得
    • プロジェクトID
    • プロジェクト番号(int)
    • OAuthクライアントのJSON
  • APIの有効化
    • apps scripts API の有効化

プロジェクトの作成と保存は、煩雑なので記事の末尾にスクショ付きで書いておきます。→ GCPプロジェクトの手順

GAS に GCP を紐付け

プロジェクト番号(数値)をGASに設定する

プロジェクト→ 設定

Google Cloud Platform(GCP)プロジェクト番号(数字)を貼り付ける。

f:id:takuya_1st:20210608005925p:plain:w320

clasp とGASを紐付け。

clasp login は終わっているものとします。

clone よる紐付け。

mkdir sample && cd sample
clasp clone ${スクリプトID}

または、create による紐付け

create → standalone でローカルで新規作成し、リモートへpush します。

mkdir sample && cd sample
clasp create myGas
clasp push

claspプロジェクトと GCP を紐付け

ローカルプロジェクトを、GCPと紐付けします。

GCPでダウンロードした認証情報JSONをプロジェクトへ移動

GCPから取得した認証情報JSONをプロジェクトへ

JSONは、GCP→ 認証情報→ クライアント→ダウンロードボタンでダウンロード。

clasp_project_dir=~/sample
mv client_secret_xxxx2697-xxxxonbxxxj.apps.googleusercontent.com.json \ 
${clasp_project_dir}/creds.json

clasp に projectIDを登録

clasp コマンドでプロジェクトに紐付ける。

GCP で作成したプロジェクトID(英数字名前)を入れる。

GCP_PROJECT_ID=gas-sample-001
clasp setting projectId ${GCP_PROJECT_ID}

json からプロジェクトを認証

json認証情報を使って、プロジェクトをOAuthする。

 clasp login --creds creds.json

ここでのログインは、プロジェクトがGCPへログインする。

ブラウザでOAuth

ブラウザが起動するので、GoogleアカウントでGCPのアカウントでログインして認証する。

終わったら次のような画面になる。

f:id:takuya_1st:20210608011412p:plain

コードを書く。

エディタを開き。関数を作り return を書く。忘れずにreturn を書く。

f:id:takuya_1st:20210608011604p:plain

return を書く理由は clasp run 実行後にコンソールに表示されるのが、関数の戻り値だから。

リモートへ送る

ローカルで作成したコードをscript.google.com へ push する。

clasp push 

デプロイ(公開する)

GASのプロジェクト・ページへ移動して、デプロイを作る。

デプロイを作成

GASのプロジェクト画面→デプロイ→新規作成→歯車→実行可能API

f:id:takuya_1st:20210608012202p:plain

clasp run 実行する

ようやく、本題の clasp run が出来ます。

clasp run

実行結果(戻り値)

実行すると、関数の戻り値が表示されます。

f:id:takuya_1st:20210608012628p:plain

実行結果(Console.log)

console.log で出力した、実行ログは、clasp logs コマンドで確認します。

f:id:takuya_1st:20210608012852p:plain

コードを更新して実行

次回以降は、push && run を繰り返せばいい。

clasp push 
clasp run myFunction 

clasp runは dev モードで動くので、push されたコードが常に実行される。

run 遅い

せっかくここまで設定したけど、push && run の clasp が遅い。表現したくないほど遅い。   

本当に遅いんですよ。 push && run をするのに待たされる。   

push に掛かる時間

f:id:takuya_1st:20210608022408p:plain

run に掛かる時間

f:id:takuya_1st:20210608022427p:plain

実行結果はスグ返るのに、終了が遅い。

実行自体はスグ終わります。その後なんの処理かわからないけど、終了処理で凄く待たされる。Ctrl-Cで中断したらプロジェクトの動作がおかしくなった。

clasp のclasp run 使えないかも。

CI/CD で回すならいいかも。

ローカルでコード書いて実行し、エラー見つけて修正、コード書いて実行みたいな使い方はとてもストレスなので使えないと思います。

自動実行をCI/CDでまわすなら、バックグラウンドで動くのでストレスなく使えるかもしれない。

git に push タイミングでGASにデプロイしてテストで実行する程度ならいいんじゃないですかね。

APEENDIX(GCPプロジェクト)

GCP プロジェクトの作成手順

GCP のプロジェクト作成で、GCP経由でGASのスクリプトを起動できるようにします。

保存するもの

プロジェクトを作成し、次のものを保存してclasp の設定に備える。

  • プロジェクトID
  • プロジェクト番号
  • 認証情報JSONの取得

設定するもの

GCP のプロジェクトで次を設定し、APIが利用できるようにする。

  • OAuth 同意画面
  • OAuth デスクトップ・クライアント
  • ライブラリ Gooogle App Script API

設定の流れ

設定は、次の流れで行う。

  • GCPコンソールにアクセス
  • プロジェクトを作成
  • プロジェクト番号とIDを保存
  • OAuth 同意画面の作成
  • OAuth クライアントを作成
  • JSONの保存
  • GAS Api の有効化

やることが多いです。

プロジェクトの新規作成

f:id:takuya_1st:20210608003002p:plain

プロジェクト情報の確認

ここで、ID(名前)と番号(数字)をメモります。

f:id:takuya_1st:20210608005753p:plain

OAuth 同意画面の作成

左上のメニュー → APIとサービス → OAuth同意画面

f:id:takuya_1st:20210608003200p:plain

同意画面は、必須項目を埋めるだけでいい。必須項目はメアドくらい。

自分しか使わないし。考えることはない。

OAuth認証情報の作成

左上のメニュー → APIとサービス → 認証情報→認証情報を作成

f:id:takuya_1st:20210608003309p:plain

クライアントIDを選ぶ

ここでは、クライアントを作るのでクライアントを選ぶ。

f:id:takuya_1st:20210608003331p:plain

種類はデスクトップアプリ

種類の選択で、デスクトップアプリを選ぶ

f:id:takuya_1st:20210608003357p:plain

JSONダウンロード

認証情報が作成されたら、デスクトップ用のJSONがダウンロードできる。

f:id:takuya_1st:20210608003454p:plain

API の有効化

プロジェクトで Google App Script API 有効にする。

ライブラリにゆく

f:id:takuya_1st:20210608003532p:plain

apps script api を有効にする。

f:id:takuya_1st:20210608003953p:plain

GCP 準備完了

これでGCPの準備は出来ました。次の情報が得られているはずです。

  • プロジェクトID
  • プロジェクト番号
  • 認証情報JSONの取得

これを、CLASPとGASに登録します。

プロジェクト番号(数字)は、GASへ登録

プロジェクトIDと認証情報は、clasp login で使います。

gcp 準備が完了したら、clasp をあとは実行するだけです。

GAS 目次

ひとまずここで筆を置きます。GASに関しては次が目次です。

Goole App Script ( GAS ) を始める。記事一覧 - それマグで!

Goole App Script ( GAS ) の基本的な操作方法。17. claspで GASをローカルからVisualStudioCode編集して補完し、git管理する。

f:id:takuya_1st:20210607213754p:plain

インストール clasp

clasp コマンドは @google/clasp で提供されています。 @google/clasp をグローバルにインストールしてclasp コマンドを使えるようにします。

npm install -g @google/clasp

npm なのでインストールは時間が必要です。

インストール確認

clasp コマンドがインストールされたかチェックしておきます。

which clasp #=> /usr/bin/clasp
clasp help

初期設定

インストールが終わったら初期設定です。google アカウントと紐付けます。

ログインしてOAuthします。

clasp login

scrpipt.google.com にログインして、プロジェクトにアクセスできるようにしなくてはいけません。login を実行してブラウザを立ち上げて、clasp コマンドにパーミッションを与えます。 ローカルホストでWEBが起動しブラウザ経由でOAuthします。

oauth 完了

f:id:takuya_1st:20210607214445p:plain

設定ファイル

Googleアカウントの権限付与したら、設定ファイル~/.clasprc.json が作られます。

$ ll  ~/.clasprc.json
-rw------- 1 takuya takuya 2267 Jun  7 21:44 /home/takuya/.clasprc.json

準備完了

これで、プロジェクトをローカルに取り込む準備ができました。

clasp clone

既存のプロジェクトをclone する。

まずは、既存のプロジェクトをデスクトップにコピーしてきます。

mkdir してから clasp clone

clasp clone コマンドでGASの一覧から、スクリプトをコピーできる。

サンプル
## プロジェクトフォルダをつくる。
mkdir myGas
cd myGas
mkdir src
## GASからコードを取り出す。
clasp clone 0wmjSXXXXXXXXXXsx98zZtcpljDBc
## 編集したら pushする
clasp push

フォルダは自動生成されません。

フォルダは作成されないので、さきにフォルダをつくり、clone します。 git clone のようにフォルダが自動生成されないので注意(大事なので2回書いています。)

clone 後は、ローカルファイルとして編集できます。編集が終わったら push します。

clasp push

push すればアップロードされアップデートされます。

clasp push 

clasp push でアップロードです。`ローカル→script.google.comへアップロード

プロジェクトIDの発見方法。

GASの「プロジェクト」には固有のプロジェクトIDが割り振られています。これを取得します。

アドレスの文字列をコピーします。

プロジェクトを開いたときのアドレスをコピーすればOKです。

https://script.google.com/home/projects/{ここ}/

複数アカウントGoogleログインしている場合はURLが異なります。

https://script.google.com/u/2/home/projects/{ここ}/

google サービスは複数アカウントのログイン時にhostname.google.com/u/{number}/ のようなアドレスになりますが、もうずっと10年以上複数アカウントの不具合が残ってます。今使ってるアカウントには注意しておきます。

プロジェクトの設定画面

プロジェクトの設定画面からもプロジェクトの固有IDを見つけることが出来ます。 f:id:takuya_1st:20210607214857p:plain

clone は時間がかる。

clasp の clone はすこし時間がかかります。辛抱強く待ってください。

ローカルで管理するメリット。

ウェブサイトで開発できるのに、わざわざローカルにコピーするメリットはいくつかあります。

  • git によるコード管理・属人化の防止
  • トランスパイラ利用
  • エディタ

git による管理。

ファイルがローカルになることで、git push 管理できます。git にすることで変更点を残しておけます。

cd CLASP_DIR
git init 
git remote add origin ssh://xxxx
git commit -m import 
git push 

これで、コードを管理しやすくなります。とくに共通コードをまとめて管理できるようになるはずです。

Google Driveからの独立

Google Driveから独立して管理できるので、個人のGoogle Driveやscript.google.com から独立し、自立できます。個人のGoogle Driveに依存しないので、ドキュメント類を残したり手順を標準化しやすくなります。

トランスパイラ利用(コンパイル)ができるようになる。

polyfill を使ったり TypeScript を書いたものを gs/js にトランスパイルすることで、記述を柔軟にできるようになって便利です。gas を typescript で書いたり reactできるようになって便利です。

外部ライブラリをまるっと取り込んでnpm の恩恵に預かれる。

エディタを選べて補完ももできる。

自由にエディタを選べるようになります。

コード補完をする。

次のパッケージを使えばコード補完もできるようになります。

npm install --save @types/google-apps-script

@types/google-apps-script が GASの補完などのファイル・タイプ定義ですね。

補完例

Visual Studio Code で GASを補完しながら書いている例です。completion は特に設定しなくても install するだけで大丈夫です。

f:id:takuya_1st:20210607221319p:plain

おまけ、clasp /git 管理は、 --rootDirをつける

claspを使ってGASをgit 管理するとき、clasp clone --rootDir を使いましょう。

cd project
mkdir src
clasp clone  --rootDir=src

--rootDir を設定することで、gas の管理が楽ちんになります。GASは全ファァイルをロードするので、うっかりすると必要のないファイルまでpushされ、GASロードされちゃいます。

なので --rootDir がないとき、 .claspignore で .git を無視する必要があります。そのために、 --rootDir を使います。必ずつけましょう。

またトランスパイラを通すときは、トランスパイラの出力フォルダ dist を 指定します。 --rootDir=dist ですね。

次回へ続く

長いので分割しました→次回

Goole App Script ( GAS ) の基本的な操作方法。 16. 専用サイトでGASプロジェクトを管理する。

GAS は Google drive

GASの一覧と管理は、Google Driveで行うのが基本になるみたいですね。

Google Driveのフォルダに、プロジェクトが作成される。

プロジェクトは固有IDを持ち、好きなフォルダに設置することができる。スプレッドシートからスクリプトエディタを開いたときは、スプレッドシートと同じフォルダに設置される。

スクリプトが増えてくると、スクリプトシートと紐付いているのを無視して管理したくなる。そのときに便利なのがプロジェクトを一覧するサイト。

google app script は次のサイトで一覧できる。

GASのプロジェクトファイルは、次のサイトでDriveに四散しているプロジェクトファイルを見ることができる。

https://script.google.com/home

自分のプロジェクトの一覧を見ることができる。

f:id:takuya_1st:20210607211718p:plain

タイマーの一覧も見れる。

トリガーで作ったタイマーも、プロジェクトを横断して確認できる。

f:id:takuya_1st:20210607212231p:plain

https://script.google.com/home でプロジェクト単体として存在できる。

https://script.google.com/homeで管理するのはプロジェクト単体な、プロジェクトである。スプレッドシートやスライドと紐付かず、独立したプロジェクトとしても作成できる。

ドキュメントから独立したプロジェクトの魅力

単体プロジェクトは、ドキュメントとペアにせず、単独のプロジェクトとして、作成管理できる。

そのため、テンプレートから新規ファイルを作るプロジェクトや、結果を新規ドキュメントに保存するようなプロジェクトを作成して管理しやすくなって便利ですね。

## 次回へ続く

長いので分割しました→次回

Goole App Script ( GAS ) の基本的な操作方法。15. GAS をスケジュールで実行する

GAS の実行方法の種類

GASを実行するには、いくつか方法があって、ボタンを押して実行、メニューから実行、実行ボタンを押す、HTMLで実行、スケジュールで実行、APIで実行がある。

分類すると次のようになる。

  • ドキュメント内イベントハンドラで実行
    • ボタンを押す
    • 開く・編集で実行
    • メニューから実行
  • HTML を使う。
    • HTMLを表示で実行
    • フォーム送信で実行
  • 単体で実行
    • タイマーで実行
    • APIで実行

今回は、タイマーで実行する方法を見ておく。

GoogleAppScript をタイマー実行する

GASはスケジュールで実行の設定ができる。スケジュール実行は、とてもかんたん。

トリガーを作る

スクリプトメニューから、トリガーを選択

f:id:takuya_1st:20210607150639p:plain

トリガーを追加

時刻でトリガーを追加する。

実行する関数と、実行する時間・日付をきめてトリガーを作成すればオッケ。

f:id:takuya_1st:20210607150620p:plain

便利ですね。

追加費用もなしで、スクリプトをタイマーで実行できるのはいいですね。

レンタルサーバーなどではcrontab などが必要で実行数が規制されたりするし、crontab/systemd を使うと設定に知識が必要なのに、GASは本当にかんたんに実行できる。

次回へ続く

長いので分割しました→ 次回

Goole App Script ( GAS ) の基本的な操作方法。14.スプレッドシートに追記する。

スプレッドシートに追記したい。

スプレッドシートのデータの範囲に、次の行を書くにはどうするのか。同じデータを連続して書き込むにはどうするのか。少し考えてみた。

セルに続けて書きたい。

セルの最終行に次行のレコードを書き込んでログのように記録を取りたい

次のように、続けて書き込みたい。

f:id:takuya_1st:20210605022853p:plain:w200

GASの例

function main(){
  addCell();
}
function addCell() {
  let app = SpreadsheetApp.getActiveSpreadsheet();
  let sh = app.getActiveSheet();
  let range = sh.getDataRange();
  let r = range.getLastRow();
  let c = range.getLastColumn();
  let nextCell = sh.getRange(range.getLastRow()+1,1,1,2);
  let data = [
    [getCurrentIp(),currentDateTime()]
  ]
  nextCell.setValues(data)

}
// データ
function getCurrentIp() {
  let ip = 'x.x.x.x'
  let url = 'https://api.ipify.org?format=json'
  let json = UrlFetchApp.fetch(url);
  let obj = JSON.parse(json);
  //ip = (obj) ? obj.ip : ip;
  return ip;
}
function currentDateTime(){
  let d = new Date()
  let str = Utilities.formatDate(d, 'Asia/Tokyo','yyyy/MM/dd HH:mm:ss')
  return str;
}

実行すると。

最初、空っぽの状態から、データがログのように書き込まれる。
f:id:takuya_1st:20210605021733p:plain:w200

f:id:takuya_1st:20210605021815p:plain:w200

コードについて。

今回使ったコードの冒頭部分について。

現在データが書き込まれている範囲を取る。

getDataRange は、CTRL-Aで選択して自動的に作られる選択範囲を取得する。

  let app = SpreadsheetApp.getActiveSpreadsheet();
  let sh = app.getActiveSheet();
  let range = sh.getDataRange();
  let r = range.getLastRow();
  let c = range.getLastColumn();

次の行の範囲を取る。

次の行を選ぶのでgetLastRow()+1 を使う。列は先頭からなので、1を入れる。(プログラミングになれた人は、ここで配列と同じ入れがちなので注意、セルは1から数えます。)

sh.getRange(range.getLastRow()+1,1,1,2);

getRange は矩形選択、Rectangleの描画と同じ

getRange は1,2引数で選択開始位置。(開始座標)
getRange は3,4引数で選択する個数。(縦横長さ)

getRange( startRow, StartCol, numOfRow, numOfCol) 

選択範囲にデータを貼り付け

選択範囲にデータを貼り付けするのは setValues を使う。

setValues([  [ COL_A, COL_B ]  ] )

setValue の引数は、ネストした多次元配列。

多次元配列には、行ごとにデータを入れる。

data = [
 [ "A1", "B2" ] //  1行目
 [ "A2", "B2" ] //  2行目
]

データの追記はよくやるので

データ追記はよくやるので、ぱぱっとできるといいな。

2021-06-07 追記

似たような方法に次のような方法がある。 getLastRow 関数を利用する。

getLastRow はデータ領域の最終行が返されるので、不定数のカラムを書き込むのであれば、getLastRowもいいと思う。

この記事では、行の下方向に決まったデータを追記するので、getDataRange() を使ってます。

getLastRow は次のペアで覚えておくと便利です。

sheet.getLastRow();
sheet.getLastColumn();

次回へ続く

長いので分割しました→次回

Goole App Script ( GAS ) の基本的な操作方法。13.スプレッドシートのセルの基本操作

前回の続き

前回までで、GASでコードを書いて実行する方法がわかった。

今回はセル操作

今回は、Spreadsheetの基本的な使い方を見ておく。

セルの取得=範囲の取得

EXCELでも同じ。知っていると思うけど知らないと混乱するので注意。

セルを取得するとは、範囲=1の選択範囲を作るということ。

範囲を選択する

let sps = SpreadsheetApp.getActiveSpreadsheet();
let sht = sps.getSheets()[0];
let rg  = sht.getRange("B5:B6");
g.activate();

範囲を選択するのに1つだけ選択したら、セルを選択。

let sps = SpreadsheetApp.getActiveSpreadsheet();
let sht = sps.getSheets()[0];
let rg  = sht.getRange("B6");
g.activate();

セルを取得

let sps = SpreadsheetApp.getActiveSpreadsheet();
let sht = sps.getSheets()[0];
let rg  = sht.getRange("B5");
rg.activate();

セルの値を取得

let sps = SpreadsheetApp.getActiveSpreadsheet();
let sht = sps.getSheets()[0];
let rg  = sht.getRange("B5");
rg.activate();
let val = rg.getValue();
console.log(val)  

セルの書式(表示形式)を取得

数値は、表示形式が重要なので、数値の表示形式を見ておく。

let fmt = rg.getNumberFormat();
console.log(fmt)

日付形式 yyyy/MM/dd 日付と時刻 yyyy/MM/dd H:mm:ss 時刻 HH:mm:ss

セルの値を更新

セルの値を更新して、数字の表示形式を入れていく。

  rg.setValue('2021年6月4日');
  rg.setNumberFormat('yyyy/MM/dd');

セルに背景を設定

  let sps = SpreadsheetApp.getActiveSpreadsheet();
  let sht = sps.getSheets()[0];
  let rg  = sht.getRange("B5");
  rg.setBackgroundRGB( 250,120,120 );

セルの背景色を解除

背景色を解除するのには、setBackgroundで null を設定する。 クリアでは、値ごとすべて解除される。

let sps = SpreadsheetApp.getActiveSpreadsheet();
let sht = sps.getSheets()[0];
let rg  = sht.getRange("B5");

rg.setBackground(null);

セルの枠線・ボーダーを設定

ボーダーは、範囲に対して設定する引数の順番に注意、

上下左右を設定する

let rg  = sht.getRange("B5");
rg.setBorder(true, true, true, true, false, false);

内側も含めてすべて設定する。

すべてを true にすると、全部設定できる。

rg.setBorder(true, true, true, true, true, true);

セルの枠線(ボーダー)をすべて解除

すべてを解除するには、false を設定する。

  rg.setBorder(false,false,false,false,false,false);

変更しない=null を設定する。

下だけ変更したいときのように、他を変更したくないときは、 null を渡す。

  rg.setBorder(null,null,true,null,null,null);

引数がどうしても多くなるので使うときに不便ではあるが、覚えておく必要がある。

セルのボーダーの枠線スタイルを決める。

SpreadsheetApp.BorderStyle.SOLID_THICK のように、名前空間の中に入れる。

  • DOTTED / 点線
  • DASHED / 破線
  • SOLID (* デフォルト) / 線
  • SOLID_MEDIUM / 太線
  • SOLID_THICK / 極太
  • DOUBLE / 二重線

引数は、8番目。

range.setBorder(top, left, bottom, right, vertical, horizontal, color, style)

極太線を設定する。

rg.setBorder(true, true, true, true,
    true, true, 
    null,
    SpreadsheetApp.BorderStyle.SOLID_THICK
    );

枠線の色を決める。

色をは HTML と同じ色指定。256色なRGBを #FFFFFF と同じく入れる。

rg.setBorder(true, true, true, true, true, true, 
    "#88AA00",
    SpreadsheetApp.BorderStyle.SOLID_THICK
    );

次回へ続く

長いので分割しました→次回

Goole App Script ( GAS ) の基本的な操作方法。12. キーボード・ショートカット

スクリプト・エディタのキーボードショートカット

実行 / Ctrl-R

  • 実行 / Ctrl -R / ⌘ -R
  • ログ切り替え / Ctrl - Enter / ⌘ - Enter

実行は、選択中の関数が実行される。

選択中の関数とはこれ

選択中の関数とは、このメニューで選択している関数である。

f:id:takuya_1st:20210604045521p:plain

カーソル位置の関数を実行してくれると楽なんだけど、毎回選択し直す必要があるみたい。

編集のショートカット

  • 補完 ctrl-space / ⌘ -Space
  • 単語補完 alt- / (スラ) / ⌘- /
  • コメント・トグル ctrl - / (スラ)
  • 行削除 ctrl -d / ⌘ - D
  • インデント TAB
  • アンインデント Shift-TAB
  • コードの整形 / Alt-Shift-F

補完中の操作

補完中の操作は、通常のIDEと同じ

f:id:takuya_1st:20210604050113p:plain:w280

  • 候補移動 矢印 ↑ ↓
  • 選択 TAB / Enter

タブで補完決定できるのはちょっと好き。

コードの整形もできる

選択範囲のコードの整形ができます。

f:id:takuya_1st:20210604152846p:plain

保存

  • カレントファイル保存 Ctrl - S / ⌘ - S
  • すべて保存 Ctrl-Shift-S / ⌘- Shift - S

キーボード・ショートカットの調べ方

エディタにフォーカスが存在するときに、F1を押せば、コマンドパレットが表示され、キーボードショートカットを見ることができる。

右クリックでメニューを表示

メニューを見れば、キーボードショートカットもわかる。

f:id:takuya_1st:20210604153009p:plain

コマンド・パレットでショートカットを見る。

右クリックから、コマンド・パレットを参照すれば、さらに機能を見ることができる。

コマンドパレットを参照すれば、以外に多機能で、こんなこともできるんだ!っていう発見が多いので、一度は見ておくこと。

f:id:takuya_1st:20210604153159p:plain

次回へ続く

長いので分割しました→ 次回

Goole App Script ( GAS ) の基本的な操作方法。11. ボタンに登録して実行

前回まで

前回までで、コードをスッキリさせて、好きなタイミング実行できるようにした。

今回は、ボタンで実行

今回は、さらにわかりやすくするために、ボタンに登録して実行することにする。

ボタンで実行を作る。

ボタンそのものは存在しないので、図形オブジェクトとして追加する。

手順

以下の手順で作成します。

  • オブジェクトを追加(図形描画)
  • ボタンを作成
  • ボタンをのメニューをクリック
  • スクリプトの割当

オブジェクトの追加

図形描画で図形を作ります。

f:id:takuya_1st:20210604044223p:plain

ボタンを図形描画で作る。

同じ図形を2つ重ねて、枠線の太さと色を変えてボタンっぽくします。 f:id:takuya_1st:20210604044737p:plain

出来ました。

ボタンっぽい画像を作りました。

f:id:takuya_1st:20210604044230p:plain

クリックしてメニューを表示

メニューは、図形を選択すると現れます。

f:id:takuya_1st:20210604044236p:plain

スクリプトの割当。

関数名を指定します。

f:id:takuya_1st:20210604044242p:plain

図形をクリック

図形をクリックすると、割り当てた関数名が実行されます。

f:id:takuya_1st:20210604044710p:plain

スクリプト割当後の注意。

いちど割り当てると、クリックで起動する。

マウスクリックが不能になる。移動・変更は右クリックでやる。

続く

長いので分割しました。

次回に続く→12

 

 

 

Goole App Script ( GAS ) の基本的な操作方法。10.メニューに登録して実行

前回の続き

前回までで、一通り実行ができるようになったので、他人に使ってもらうためにメニューに追加して実行する方法を見ておく。

今回はメニュー

今回は、メニューから好きなタイミングで任意に、スクリプトを実行します。

メニューで実行

メニューに登録して、任意のタイミングで実行。

function addCustomMenu(){
 //メニューを追加
  let my_menu = new Array();
  my_menu.push({name:"ダミー", functionName: "menu_dummy"});
  let s = SpreadsheetApp.getActiveSpreadsheet().addMenu("!!サンプル", my_menu);
}

メニューになる。

この関数を実行すると、メニューが生成され、いつでもスクリプトを実行できる。

f:id:takuya_1st:20210604043437p:plain

起動後にメニューを生成

ドキュメントを開いたあとに、メニューを自動生成することもできる。

onOpen関数を定義すると、ドキュメントを開いた瞬間に実行される。onOpenは存在するだけで自動実行される。

function onOpen(){
    addCustomMenu();
}

メニューを追加(別の方法)

先の方法は、ショートカット的な方法で、メニューを作るのは、こっちがGAS的に正統方法だと思う。

function onOpen(){
  SpreadsheetApp.getUi().createMenu("!サンプル")
  .addItem('アイテム1', "func_name")
  .addItem('アイテム2', "func_name")
  .addSeparator()
  .addItem('アイテム3', "func_name")
  .addItem('アイテム4', "func_name")
  .addItem('アイテム5', "func_name")
  .addSeparator()
  .addSubMenu(
    SpreadsheetApp.getUi()
    .createMenu("アイテム6")
    .addItem('アイテム6-1', "func_name")
    .addItem('アイテム6-2', "func_name")
    .addItem('アイテム6-3', "func_name")
  )
  .addSeparator()
  .addItem('アイテム7', "func_name")
  .addToUi()

}

メニューの上書き

同じ名前で登録すると上書きされるので注意。

続く

長いので分割しました。

次回に続く→11

Goole App Script ( GAS ) の基本的な操作方法。09. 起動時に実行

前回まで

前回までで、ソースの管理、クラス、デバッグを見てきた。

そろそろ十分に準備が整ってきた。

今回はスクリプトの実行タイミング

ファイルを開いたとに、スクリプトを起動する方法を見る。

ドキュメントが開いたときにスクリプト起動

ドキュメントが開いときにスクリプトを起動する onOpen

onOpen 関数を定義しておけば、ファイルを開いときに自動的に実行してくれる。

f:id:takuya_1st:20210604040942p:plain

ドキュメントを開いたとき実行は、少し遅い

onOpenの実行タイミングは、思った以上に遅いので注意する。

一見すると、ファイルが開いてるように見えてもすべての準備が整うまで実行されない。

ドキュメントのローディングバーが進む

メニューの下のローディングバーが進んで消える。

f:id:takuya_1st:20210604041213p:plain

そのあと、最終更新時刻などが取得される。

f:id:takuya_1st:20210604041345p:plain

その後に、ファイルがロードされてonOpenが実行される。(数秒は掛かる。)

f:id:takuya_1st:20210604041137p:plain

シートが複雑だと、そこそこ時間がかかるので辛抱強く待つ必要がある。

複数ファイルにまたがった場合の onOpen

opOpen関数は、どこに書いてもいい。

スクリプトを複数のファイルに分割して書いたとしても、全部ロードしてから onOpenが探される。そのためonOpenをうっかり複数書くと後からロードされたものが優先される。

onOpen 関数はシンプルイベントハンドラなので、いつでも使える。

その他の実行方法

スクリプト・エディタで実行できるのだが、ドキュメント/スプレッド・シートからスクリプトを実行されないと使いにくい。

ファイルが開いたときに実行される onOpen があり、その他にもボタン(図形オブジェクト)にイベントハンドラを貼り付けて使うことができる。

続く

長いので分割しました。

次回に続く→10