@prado7000

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

[GAS]ソート指定のあるフィルタビューで選択している実際のセルを取得したい

解決したいこと

ソート指定のあるフィルタビューで表示している状態で、ユーザーが選択しているセル(行)に対して処理を行いたいのですが方法が分かりません。
もしご存知の方がいらっしゃいましたら教えてください。

発生している問題

下の図は、元の表とフィルタビューの関係性をわかりやすくするために、
左の表 A:Bを D:Eにコピーしてから、フィルタビューを作成し E列の「値」順にソートしています。

ここで例えば E2を選択した状態で、ActiveCellの値を取得すると、ユーザーの目に見えている「A」ではなく、元の表のこの番地の値「F」が返ってきてしまいます。
これを「A」が返ってくるように、というより実際はこの行に対して処理を行いたいので、2行目に対して行った処理が正しく元の 5行目に反映してくれるか、本当の行番号の 5を取得するかしたいのですが、方法はあるでしょうか?

いまユーザーには「フィルタで絞っても良いけど行の並び替えは絶対にしないで!」と言っています。

image.png

該当するソースコード

上の GASは以下の通りです。

function showSelection() {
  let mySheet = SpreadsheetApp.getActiveSheet();
  let myActiveCell = mySheet.getActiveCell();
  let myRow = myActiveCell.getRow();
  let myValue = myActiveCell.getValue();
  Browser.msgBox("行番号は:" + myRow + "、セルの値は:" + myValue, Browser.Buttons.OK);
}

自分で試したこと

元の表に対してソートしたり、またフィルタビューに選択条件をつけても行番号は変わらないので問題ないのですが、フィルタビューにソート条件を付けてしまうと、どうしても正しい行番号が取れない状況です。
なんらか適したメソッドやプロパティがあるのか探してみても今のところ見つかりません。

0 likes

3Answer

現物のシートが公開されてないので、検証用に作るしか無かったのですが、ようはこのように成れば良いのですね。

output.gif

コードも1から書いてますがほぼ同一です。なので提示されてるコードには問題がないように思えます。
可能性としてはそのシートに付属したコードでは無く、別のシートのコードを編集していませんか?


検証に使ったシートとgsコード

function testCase() {
	const activeSheet = SpreadsheetApp.getActiveSheet();
	const target = activeSheet.getCurrentCell();
	const activeCell = activeSheet.getActiveCell();
	if (target === null || activeCell === null) {
		throw new Error('No range!!');
	}
	const row = target.getRow();
	const val = target.getValue();

	console.log(`Row = ${row}, Value = ${val}`);
	console.log(`activeCell.getRow = ${activeCell.getRow()}, activeCell.getValue = ${activeCell.getValue()}`);

	this.dialogInfo(`行: ${row.toString()}\r\n値: "${val.toString()}"`);
}

function dialogInfo(prompt, title = '結果') {
	const ui = SpreadsheetApp.getUi();
	return ui.alert(title, prompt, ui.ButtonSet.OK);
}
1Like

Comments

  1. @prado7000

    Questioner

    わざわざ再現してくださり大変ありがとうございます!
    お時間を使ってくださり感謝です!m(__)m

    そしてすみません、図々しく勝手にシートをコピーさせていただきました m(__)m
    「シート1 のコピー」のフィルタビュー「値順」

    フィルタビューは、複数人が共有して作業するシートの並び順やレコード選択を変えずにその人だけの見た目を得られるものなので、とても便利でユーザーに使わせたいのですが、これを使うと、ユーザーが見て選択している行に対して処理をするGASがどうしても上手くいかない(選んでる行の実体が取れない)という悩みなのです・・
    image.png

  2. 「フィルタ」ではなく「フィルタビュー」なら実データに(保存されるまで)反映されてないわけですからGASでも参照できません。つまりGASだけでは無理です。

    もうそれを可能にしたいと考えるなら、ブラウザの拡張機能で受け渡しするとかのレベルになってきます。
    フィルターを全員に使う事を許すか、列を崩されるまえにGAS側で保持しておくぐらいでしょうか。

ソースは問題無さそうですが実環境は不明なので
myActiveCell.getColumn を使って列が Eにあるのか確認してください

0Like

Comments

  1. @prado7000

    Questioner

    ありがとうございます!

    function showSelection() {
      let mySheet = SpreadsheetApp.getActiveSheet();
      let myActiveCell = mySheet.getActiveCell();
      let myRow = myActiveCell.getRow();
      let myColumn = myActiveCell.getColumn(); //カラム
      let myValue = myActiveCell.getValue();
      Browser.msgBox("行番号は:" + myRow + "、カラムは:" + myColumn + "、セルの値は:" + myValue, Browser.Buttons.OK);
    }
    

    カラムは Eを取っていますね。
    image.png

    フィルタビューはあくまでユーザーの見た目なので、クラウド上で実行されるGASは、フィルタビューを介さない、スプレッドシートの生の番地(2行目 5カラム)の値をとるしかないのでしょうか・・
    (元の質問の絵でB列のセルにマークしていたのがまぎらわしくてすみません。D:E列のフィルタビューを解除するとこうなっています)
    image.png

    フィルタビューを作成して E列を昇順にソートするとこの現象が起きています。
    image.png

  2. ということはGAS(Excelもそうかもしれませんが)では
    フィルターはあくまで見た目が変わっているだけなので
    GASの中でフィルターでやっていたソート処理をしないといけないですね

  3. @prado7000

    Questioner

    GASを実行したユーザーがどんなフィルタビューで見てるのかさえ取れなそうですので、現在の仕様ではお手上げなのかもですね
    ありがとうございました!

一時的にBasic filterを使用しますが、このような回避策はいかがでしょうか。英語で恐縮です。

0Like

Comments

  1. @prado7000

    Questioner

    貴重なご提案をいただきありがとうございます!
    ただ、複数人が同時に作業するスプシのため、シート本体でのフィルタやソートを禁じている状況です。

    お示しいただいたページの中にフィルタビューに関するコードがあるようにお見受けしますので、まだよく理解できていませんが、是非参考にさせていただきたいと思います。
    どうもありがとうございました!

Your answer might help someone💌