見出し画像

盆栽の管理向上をめざして 10:こまごまとした修正


盆栽を保護している温室の片隅で事務机を置きPCを操作している30歳代の日本人男性。モニタには表計算ソフトの表が複数表示されている様子。
薄暗い中、夜の照明と、PCの明かり照らされている。

プロンプト

画像の評価:
もともとのプロンプトが正しい日本語になっていないにも関わらず、それらしい結果を返してくれる。日本人男性と指定すると、三苫選手のような顔になる。

はじめに

前回記事で「盆栽カルテ」を作成し、入力から出力までの一連の処理をGoogleスプレッドおよびLINE Botにて行うようにしました。
一番欲しかった機能を手に入れて、とても満足しています。あとはじっくりと追加実装を行い、機能を上げていきたいと思っていたところ、テンプレートの公開を考え始め、そちらの作業に追われていました。

それでも、日々使うデータベース。いろんなことに気づきます。

よかったこと

冬のこの時期、手入れすることは少ないのですが、毎日棚場をまわって樹の状態を見ています。冬は樹が休んでいることが多く、水やりの頻度も減るのですが、油断はできません。

今までは、なんとなく見回りを行い、ぼんやりと次の構想を考えながらも、一回りしているうちに忘れてしまう、の繰り返しでした。

このシステムを使うようになってから、今までは記録もしなかった樹でもちょっと気になることや気づいたことがあれば立ち止まり、都度LINE Botで写真、key、コメントを投稿するようになりました。

あとから落ち着いて振り返ることができますので、これはとても大きな道具を手に入れたと思っております。

小さなことに気が付けるようになったため、今までは放置しがちだったちょっとした手入れもするようになりました。

最初はちょっと気になって、現状報告のためだけに写真を撮ったものについても、写真を確認するうちに、もう少し手を入れる方が良いことに気づき、作業を行うこともあります。

写真を用いての手入れは、客観的に盆栽を見れるよい方法だと思います。

LINE Botを使いながら感じたこと

かねてから予想をしていたのですが、札の番号がなくなってしまっているものがありました。風で飛んでしまったか、小鳥が札を抜いてしまったか。ひょっとして、もともとつけ忘れていたか。

今回は先に進むため、keyを000として、札不明とコメント欄に書いておきました。
今後このようなものが増えてくるものと思われます。対策が必要です。

アクティビティがあまり活用できていない

盆栽管理する上で、アクティビティの管理は不可欠だと思っていたのですが、今のところ、アクティビティはうまく活用できておりません。

そもそも、LINE Botで画像付きでコメントするので、そこにアクティビティの元となる情報を記入しています。あとから見返して、その内容をアクティビティに落とし込んでいく流れなのかなと思います。

しばらく様子を見てみることにします。
そこで今回取り組むのは。。。

こまごまとした修正を行います

セルの数式の羅列を解消しました

画像urlがそのままでは使えず、変換が必要だとわかった時に、とにかくできる方法として、今までEXCELで行っていたように数式をコピーして、下のセルへ100セル分ペーストしていました。

これだと、100を超えるとNGになるだけではなく、セル毎に関数がぶら下がるのでファイルサイズが大きくなる可能性があります。また、修正が必要になったときには、数式をコピペする必要があるため何とかならないかと思っていました。

あちこちの情報を集めている中で、ARRAYFORMULA関数の使い方を知りました。

=ARRAYFORMULA(関数(範囲,...))

セルに対して

=REGEXREPLACE(I4,"https://drive.google.com/file/d/(.*)/view(.*)","https://drive.google.com/uc?id=$1")

としていたものを、頭のセルで

=ARRAYFORMULA(REGEXREPLACE(I4:I,"https://drive.google.com/file/d/(.*)/view(.*)","https://drive.google.com/uc?id=$1"))

に書き換えることで解決できました。

盆栽カルテにkeyの+-をするボタンを追加する

E1のセルはプルダウンにして、keyの一覧を作って簡単に変えられるようにしています。
文字入力で指定することもできます。

それでもなお使い勝手を良くしたいと思っています。ボタンを用意し、keyの一覧の次、前を変えられるようにしたいと思います。

これぐらいの仕事はもうAIに任せられるのではないでしょうか?ChatGPTで作ってみたいと思います。プロンプターの技量が試される所です。

GoogleスプレッドシートのGASを以下の仕様で作成してください。:セルE1はプルダウンで、その範囲は「A2:A」です。セルE1の内容と「A2:A」を比較し、一致する項目を見つけたのち、その次の項目を得るfunction getNextItem()と前の項目を得るfunction getPrevItem()です。それぞれの関数はボタンに割り付けられ呼び出されます。関数内でセルE1の値を取得し、「A2:A」の項目にマッチさせ、その次の項目、もしくは前の項目にセルE1を書き換えてください。

プロンプト

理解しました。以下が、指定された仕様に基づいて、Google Apps Scriptを使用して作成されたサンプルコードです。このスクリプトは、セルE1のプルダウンが変更されたときに、ボタンがクリックされることでそれぞれ次の項目と前の項目を取得し、セルE1の値を書き換えます。

// プルダウンの変更時に呼び出される関数
function onDropdownChange(e) {
  // 選択された値を取得
  var selectedValue = e.value;
  
  // 次の項目を取得してセルE1に設定
  var nextItem = getNextItem(selectedValue);
  SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('E1').setValue(nextItem);
}
// ボタンがクリックされたときに呼び出される関数(次の項目をセット)
function setNextItem() {
  // セルE1の値を取得
  var currentValue = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('E1').getValue();
  
  // 次の項目を取得してセルE1に設定
  var nextItem = getNextItem(currentValue);
  SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('E1').setValue(nextItem);
}
// ボタンがクリックされたときに呼び出される関数(前の項目をセット)
function setPrevItem() {
  // セルE1の値を取得
  var currentValue = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('E1').getValue();
  
  // 前の項目を取得してセルE1に設定
  var prevItem = getPrevItem(currentValue);
  SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('E1').setValue(prevItem);
}
// 次の項目を取得する関数
function getNextItem(selectedValue) {
  return getAdjacentItem(selectedValue, 1);
}
// 前の項目を取得する関数
function getPrevItem(selectedValue) {
  return getAdjacentItem(selectedValue, -1);
}
// 隣の項目を取得する関数(1: 次の項目, -1: 前の項目)
function getAdjacentItem(selectedValue, offset) {
  // データが入っている範囲を取得
  var dataRange = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('A2:A');
  
  // データを取得
  var data = dataRange.getValues();
  
  // 一致する項目を探す
  for (var i = 0; i < data.length; i++) {
    if (data[i][0] == selectedValue) {
      // 一致したら、隣の項目を取得
      var adjacentIndex = i + offset;
      if (adjacentIndex >= 0 && adjacentIndex < data.length) {
        return data[adjacentIndex][0];
      }
    }
  }
  
  return "該当する項目がありません";
}

このコードをGoogle Apps Scriptエディタに貼り付け、ボタンに対して setNextItem と setPrevItem をトリガーに割り当てることで、ボタンがクリックされたときにそれぞれ次の項目と前の項目がセルE1にセットされます。

ChatGPT

実はここまでで、数回のやり取りをしています。
でも、ほとんど知識がない状態でここまでのスクリプトを書いてもらえるのはとてもありがたいです。

ただ、少し癖のある書き方をしているので、純粋にAIが考えたというより、文脈を理解した上でよく似たサンプルを取り寄せ少しいじった感じのするソースです。

最初の起動で認証が求められます。

エラーが発生しました。

エラーをChatGTPに報告して、直してもらう方法もありますが、ごにょごにょいじっているうちに、エラーは取れたので先に進みます。

現時点での課題はうまく回り込んでくれないことと、動作が遅い事です。

「拡張機能」の「Apps Script」を選び、次のコードを書き入れました。


// ボタンがクリックされたときに呼び出される関数(次の項目をセット)
function setNextItem() {
  // セルE1の値を取得
  var currentValue = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('E1').getValue();
  // 次の項目を取得してセルE1に設定
  var nextItem = getNextItem(currentValue);
  SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('E1').setValue(nextItem);
}
// ボタンがクリックされたときに呼び出される関数(前の項目をセット)
function setPrevItem() {
  // セルE1の値を取得
  var currentValue = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('E1').getValue();
  // 前の項目を取得してセルE1に設定
  var prevItem = getPrevItem(currentValue);
  SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange('E1').setValue(prevItem);
}
// 次の項目を取得する関数
function getNextItem(selectedValue) {
  return getAdjacentItem(selectedValue, 1);
}
// 前の項目を取得する関数
function getPrevItem(selectedValue) {
  return getAdjacentItem(selectedValue, -1);
}
// 隣の項目を取得する関数(1: 次の項目, -1: 前の項目)
function getAdjacentItem(selectedValue, offset) {
  // データが入っている範囲を取得
  var dataRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('_盆栽管理の参照').getRange('A2:A');
  // データを取得
  var data = dataRange.getValues();
  // 一致する項目を探す
  for (var i = 0; i < data.length; i++) {
    if (data[i][0] == selectedValue) {
      // 一致したら、隣の項目を取得
      var adjacentIndex = i + offset;
      if (adjacentIndex >= 0 && adjacentIndex < data.length) {
        return data[adjacentIndex][0];
      }
    }
  }
  return "該当する項目がありません";
}

この改良のおかげで、ずいぶん扱いやすくなりました。盆栽カルテの中で、いわゆる「ブラウズ」ができるようになりました。

ここまでの様子を動画にしてみました。
ご覧ください。

画像を見ながら選びたい

keyを選んで詳細を表示する盆栽カルテですが、画像の一覧を見ながら選択したいとも思うようになってきました。

今まで学んだことを組み合わせれば、それほど難しくないように思います。
まずは、モックアップを作って、PCとスマホでの見え方を確認します。

5列の画像
10枚並べました
スマホ用でしょうか。


スマホでチェック
こちらもスマホで。画面が見切れます。
こちらもスマホです。縮小すれば10列も行けます。

PCは横型ワイドモニタ、スマホは縦画面です。自分で使う環境はほぼ固まっているので、それぞれの画面を用意する事にします。

最初はページの事も考えましたが、処理が大変そうなので、すべてのデータを配置しておいて、スクロールで見せることにしました。

機能としては、key毎の画像の一覧を表示し、クリックすると、そのkeyの「盆栽カルテ」を表示できるようにしたいと考えています。

実装のようす

ファイル「画像一覧」は下記の構成です。
   シート「画像一覧10」:横に10枚画像を並べる。PC用
   シート「画像一覧5」:横に5枚画像を並べる。スマホ用
   シート「_画像」:ファイル「画像管理」から画像のurl一覧リストを得る。
   シート「_盆栽管理の参照」:ファイル「盆栽管理」-シート「アイテム」の内容をコピーし、シート「_画像」とマッチする項目を抜き出し、変換する。

シート「_画像」、シート「_盆栽管理の参照」で一覧表示するための情報を取得し、シート「画像一覧10」、シート「画像一覧5」で表示します。

セルB3は次のように書かれています。

=HYPERLINK(INDEX('_盆栽管理の参照'!$I$3:$I,($A3*10+B$2),1),IMAGE(INDEX('_盆栽管理の参照'!$I$3:$I,($A3*10+B$2),1)))

HYPERLINK関数に、画像のurlとその画像を渡しています。
また、セルB4は次のように書いています。

INDEX('_盆栽管理の参照'!$I$3:$I,($A3*10+B$2),1)

で、INDEX関数を使い、2行、A列に書いた数字を元に参照すべきセルを割り出しています。
なるだけ、コピペで250個の表示ができるように組んでみました。
2行、A列は通常は非表示にしておきます。

もう少し勉強すれば、冗長な記述をなくせそうなのですが、今のところはこれが限界です。

Googleスプレッドシートの素晴らしい機能のおかげで必要な箇所だけ表示されるので、細かい処理を全く考えることなく、そこそこのパフォーマンスを発揮してくれます。

これだけの画像を扱いながら、ファイル「画像一覧」のファイルサイズは55KBと非常にコンパクトにできました。

当初はクリックすると、そのkeyの盆栽カルテを表示させようと考えていましたが、ちょっといい考えが思いつかず、保留といたします。

スマホで見た感じ。10枚は入りきりません。
5枚だといい感じ。

さいごに動作の様子を動画にしました。
ご覧ください。

盆栽カルテから次の展開へ

次に取り組みたいことを考えておりました。
 ・盆栽リストのビジュアル化
 ・X(旧Twitter)の写真付き投稿をリスト化
 ・Instagramの投稿をリスト化
など

と考えてあれこれしているうちに、次第に思いがが定まってきました。

名付けて

ポスト(旧:ツイート)生け捕り大作戦!

画像管理は大成功で、私の盆栽キャリアの中でも大きな変革をもたらしました。

データベースの面白いところは、良い設計ができると、自ずとデータを吸い寄せるところです。自動で吸い寄せる機能はなくても、それを使うユーザーが「もっと使いたい」、「もっと活用したい」と思い、その熱量がデータを引き寄せます。

私ももっとたくさんの情報を集めることができないか思うようになり、過去にたくさん投稿したポスト(旧:ツイート)の情報を盆栽管理に役立てたいと考えました。

Powered by DALL·E 3

次回へ続く。。。

今回はこのあたりで終了いたします。
続きは次回で。
最後までお読みいただき誠にありがとうございました。

#盆栽管理 #Googleスプレッドシート #ARRAYFORMULA #GAS #GoogleAppsScript   #ChatGPT #改良 #体験記 #INDEX #QUERY

この記事が気に入ったらサポートをしてみませんか?