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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Q&A

解決済

1回答

5171閲覧

GASで表示行のみ取得したい(フィルタ機能ではなく、hideRowsで非表示にした場合)

Habanero_GAS

総合スコア3

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

0グッド

0クリップ

投稿2021/02/02 14:08

編集2021/02/05 13:35

前提・実現したいこと

スプレッドシート上にデータベースを作成しております。
GASで検索条件に当てはまらない行をhideRowsにより非表示にする、自作検索機能を付けました。
※フィルタ機能による絞り込みではありません。

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

絞り込んだ後のデータのみを取得しコピペしたいのですがうまくいきません。

例えば、全データ数が10個あり、上から2,3,8行目のデータのみが表示されている状態があったとします。(1,4~7,9,10行目が非表示になっている)
ここでgetRange().getValues()により配列を取得すると2行目から8行目まで、7つのデータが入った配列が取得されてしまいます。

GASで、表示されている行のみを取得する方法ってあるのでしょうか?

2021/02/05追記
すみません、例がよくなかったようです…
イメージ説明
上図のように、実は取り出したい配列は「『15行目から最終行のうち』表示されている行」でした。

GAS

1function test(){ 2 const sheet = SpreadsheetApp.getActiveSheet(); 3 const lastrow = sheet.getLastRow(); 4 const values = sheet.getRange(15,1,lastrow-14, 2).getValues(); 5 const show_values = values.filter((row,i) => !sheet.isRowHiddenByUser(i+15)); 6 console.log(show_values); 7}

isRowHiddenByUserの引数を「i」から[i+15」に変えることで
やりたかったことが実現できました。

もう少々お聞きしてもよろしいでしょうか?
filterメソッドの引数(row,i)とisRowHiddenByUserとの関係をご教示いただけますでしょうか。
アロー式にまだ慣れていないので、functionだとどういう書き方となるのか
教えていただけると今の私でも理解できるかもしれません。

大変恐縮ではございますが、せっかくなのできちんと理解しておきたいと思うのです。
宜しくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

GASの質問なので、Google Apps Script のタグを付けた方が回答が得られます。

ご質問の件ですが、isRowHiddenByUser を使うと非表示判定ができるので、
これとfilterを組み合わせれば出来ます。

https://developers.google.com/apps-script/reference/spreadsheet/sheet?hl=ja#isrowhiddenbyuserrowposition

ByUserってあると手動のみっぽいですがGASで非表示にした行でも大丈夫です。

フィルタ機能以外で非表示にしている行なら true を返すので、
表示されている == 非表示ではない ってことですから !をつけてあげるのと、
配列は0スタートなので、行は +1 で取得する点だけ気を付ければ良いかと。

サンプルコード

function teratail_320127(){ const sheet = SpreadsheetApp.getActiveSheet(); const values = sheet.getRange(1,1,10,2).getValues(); const show_values = values.filter((row,i) => !sheet.isRowHiddenByUser(i+1)); console.log(show_values); }

↓もう少し汎用性のある書き方に修正

function teratail_320127b(){ const sheet = SpreadsheetApp.getActiveSheet(); const startrow = 1; //取得を開始する行 const values = sheet.getRange(startrow,1,sheet.getLastRow(),2).getValues(); const show_values = values.filter((row,i) => !sheet.isRowHiddenByUser(i+startrow)); console.log(show_values); }

↓アロー関数使わない場合。あんま変わらないです。

function teratail_320127c(){ const sheet = SpreadsheetApp.getActiveSheet(); const startrow = 1; //取得を開始する行 const values = sheet.getRange(startrow,1,sheet.getLastRow(),2).getValues(); const show_values = values.filter(function(row,i){ retun !sheet.isRowHiddenByUser(i+startrow); }); console.log(show_values); }

↓filterを使わず forループでやる場合。これが一番しっくりくるなら、それでもOK

function teratail_320127_d(){ const sheet = SpreadsheetApp.getActiveSheet(); const startrow = 1; //取得を開始する行 const values = sheet.getRange(startrow,1,sheet.getLastRow(),2).getValues(); let show_values =[]; for(i=0; i<values.length; i++){ if(!sheet.isRowHiddenByUser(i+startrow)){ show_values.push(values[i]) } }; console.log(show_values); }

引用テキスト①iは0からvalues.length-1までインクリメントされる
また、アロー式の引数である(row,i)のrowは何を指しているのでしょうか?

iは、その理解でOKです。valuesという配列の個々の要素が row で i がindex(ざっくり言えば順番)です。
いきなり宣言してない rowなんてのが出てくるんで、私も最初の頃は ??ってなりましたが、
これは別に適当にvaluesって配列の個々の要素を row っておいただけで、別に value でも、vでもなんでもよいのです。スプレッドシートで取得した二次元配列は行成分を指すので、個人的にはrowって置くことが多いです。

引用テキスト②!sheet.isRowHiddenByUserの値がtrueであればshow_values.push(values[i])のような操作がされるという理解でよいのでしょうか?

for ループのコードも書きましたが、その理解で大丈夫と思います。

慣れないうちは 普通にforでループさせる書き方でよいと思います。

だんだんカッコよく書きたい、もっと短いコードで書きたいってなってきたら、今回使った filterやmap,
reduceなんかを使うようになって、徐々に理解もしていきます。

配列の要素を一つずつ関数に入れていくイメージで、結局やってることはforと一緒ですから。

参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

珍しくコードを多く書く回答してしまった。。

投稿2021/02/03 00:25

編集2021/02/06 13:04
sawa

総合スコア3002

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

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

Habanero_GAS

2021/02/04 14:09

ご回答ありがとうございます。 タグにつきましては「GAS」でタグ検索しておりました…。 次回より略さずに「Google Apps Script」のタグをつけようと思います。 ご教示いただきましたコードを実行してみましたが、やはりvaluesで取得した配列全てがshow_valuesに入ってしまいます…。
sawa

2021/02/05 00:38

あれ?うまくいきませんか。もしかしたら認識にズレがあるのかもしれません。 実行されたコードと非表示になってるシートのスクショ(行番号のあたりが見えればよい)を掲載可能でしょうか?
Habanero_GAS

2021/02/05 13:48

お世話になります。 スプレッドシートの状態と、コードを追記いたしました。 filterメソッドとその引数について追加でお聞きしたく存じます。 const show_values = values.filter((row,i) => !sheet.isRowHiddenByUser(i+15)); filterメソッドとその引数についての質問なのですが ①iは0からvalues.length-1までインクリメントされる ②!sheet.isRowHiddenByUserの値がtrueであればshow_values.push(values[i])のような操作がされる という理解でよいのでしょうか? また、アロー式の引数である(row,i)のrowは何を指しているのでしょうか? すみません、もう少しだけお付き合い頂けますと幸いです…。 宜しくお願いいたします。
sawa

2021/02/06 13:09 編集

回答に追記、補足説明を入れときました。ただ、私はエンジニアではないですし、ちゃんとに学んだわけではないので参考程度にお考え下さい。 私も最初のうちは、Array.prototype のメソッドは理解するのに時間かかりましたが、似たようなコード書いてるうちに慣れて腹に落ちます。徐々に活用できそうな処理を forループを使わないコードに切り替えていけば良いです。
Habanero_GAS

2021/02/06 13:52

非常に丁寧なご解説、誠にありがとうございます。 そうなんです、アロー式については「慣れてはないけど何となくわかる」程度だったのですが、 宣言していない変数が急に出てきたところが理解できなくて…。 また、for文での書き方のご解説もありがとうございました。 「filterメソッドの働き」が理解できました。(内部では違う動きをしているのかもしれませんが) 最後までお付き合いいただき本当にありがとうございました。 今後とも何卒よろしくお願い申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問