PR

【GAS】IMPORTRANGEで非表示の行が反映されない問題を解決!「見たまま」同期する方法

GAS
記事内に広告が含まれています。

今回はIMPORTRANGEの動画のコメントで非表示にした行は反映されるかとお問い合わせいただいたので検証した結果を記事にしてみました。

Googleスプレッドシートで『IMPORTRANGE』を使っている皆さん。
こんな悩みはありませんか?」
元データで見栄えを整えるために行を非表示にしたのに……飛ばした先のシートでは、なぜか丸見え!これ、地味にストレスですよね。

実は、標準のIMPORTRANGE関数では『行の非表示』を反映させることはできません
今回は、Google Apps Script(GAS)を使って、『人間が目で見ている行だけ』をスマートに同期するコードを作成してみました。

まずは、今回の検証用で家電や家具が並ぶ商品リストデータを用意しました。
この2つのスプレッドシートはリンク元のデータをリンク先で表示するよう設定してます。

コピー元の行を右クリックで非表示にしてみます。画面上からは消えましたね?
ところが、IMPORTRANGEでリンクさせた先を見てみると……はい、しっかり表示されています関数は『セルの中身』しか見ていないので、見た目の設定は無視されちゃうんです。


「これを今から、GASで解決していきましょう!」

Apps Scriptで設定

GASで設定した場合は更新するとコピー元の情報が反映される仕組みになります。
今回は更新ボタンをクリックでリンク元のデータの情報をチェック反映するように作成する方法を記事にしました。

それでは、Apps Scriptを開いてコードを書いていきましょう。
内容を反映したいスプレッドシートを開いた状態で 上部のメニューの拡張機能をクリックします。


Apps Scriptをクリックします。


エディタをクリックします。 コード.gsを選択した状態でコード記入。

今回使用したコード

function rinkSeetRows() {
  try {
    const sourceSsUrl = "スプレッドシートのURL"; 
    const sourceSheetName = "インポート元";
    const targetSheetName = "インポート先";

    const ss = SpreadsheetApp.getActiveSpreadsheet();
    const sourceSheet = SpreadsheetApp.openByUrl(sourceSsUrl).getSheetByName(sourceSheetName);
    const targetSheet = ss.getSheetByName(targetSheetName);

    // データの最終行・列を取得
    const lastRow = sourceSheet.getLastRow();
    const lastCol = sourceSheet.getLastColumn();
    if (lastRow === 0) return;

    // getValues() は「数式」ではなく「計算された後の値」を取得します
    const data = sourceSheet.getRange(1, 1, lastRow, lastCol).getValues();
    let visibleData = [];

    // 高速化のため、行の表示状態を一括でチェック(あるいは1行ずつ慎重にチェック)
    for (let i = 0; i < lastRow; i++) {
      // 行が非表示でない(表示されている)場合のみ追加
      if (!sourceSheet.isRowHiddenByUser(i + 1)) {
        visibleData.push(data[i]);
      }
    }

    // 書き出し
    targetSheet.clearContents();
    if (visibleData.length > 0) {
      // 2次元配列として書き込む
      targetSheet.getRange(1, 1, visibleData.length, lastCol).setValues(visibleData);
    }

  } catch (e) {
    console.error("エラー詳細: " + e.toString());
  }
SpreadsheetApp.getActiveSpreadsheet().toast("データの同期が完了しました!", "GAS実行完了");
}


ここで少しコードの説明 この isRowHiddenByUser という命令
これが『人間が右クリックで隠した行かどうか』を1行ずつチェックしてくれる、いわばセンサーですね!

そしてもう一つのポイントが getValues
これを使えば、元シートにどんなに複雑な計算式が入っていても、その『計算結果の値だけ』をサクッとコピーしてくれます。

皆さんが書き換えるのは、コードの上部にあるURLとシート名の3箇所だけです
自分のスプレッドシートに合わせて変更してくださいね。
URLの場所にはコピー元のスプレッドシートのこの部分になります。

準備ができたら、保存して『実行』をクリック!


初回はGoogleからの承認を求められるので、落ち着いて許可していきましょう。
実行完了と表示されればOKです


コピー先のシートを見てみます コピー元のデータが反映されてます。
これでリンクが完了です。
このままだと毎回Apps Scriptで実行をクリックしないと更新しないのでこのシートに更新用のボタンを作成します。

更新用ボタン作成

上部のメニューの挿入をクリックします。


図形描画をクリックします。


図形をクリックします。


今回は四角のボタンを作成なので四角を選択


ボタンテキストを入力 右上の保存して閉じるをクリックします。


これでスプレッドシートにボタンが表示されるようになりました。


ボタンにカーソル合わせた状態で右クリックすると 選択状態になります


この状態でカーソルを合わすと画像のような手のマークが表示されたタイミングでクリックした状態でマウスを動かすと移動することが可能です。お好みの場所に配置しましょう。


次にこのボタンにGASのコードを登録します
右クリックするとボタンの右側に三点が表示されるので カーソルを合わせた状態でクリックします
スクリプトを割り当てをクリックします。


するとポップアップが表示されるので Apps Scriptのコードのfunctionの横をコピーして貼り付けます。


確定をクリックします。


これでボタンをクリックで更新されるようになりました。

更新が完了すると画面右下に『同期完了!』という通知が出るようにしたので、動いたかどうかも一目でわかります。

メニュー部分に表示

メニュー部分に項目を追加する方法も簡単にやってみます。
下記のコードをApps Scriptのコードの上部に追加します。


これでメニュー部分に更新用の項目が追加されるので今後はそこをクリックで更新可能です。

/**
 * スプレッドシートが開かれたときに実行される関数
* 上部メニューに独自の項目を追加します
 */
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu('★データ同期') // メニューのタイトル
      .addItem('表示名', '実行する関数名') // 表示名と実行する関数名
      .addToUi();
}

/**
 * メインのコピー処理
 */


トリガー設定で自動更新

でも、毎回ボタンを押すのは面倒ですよね。
そこで『全自動化』も簡単に説明しときます。
左側の時計アイコンから『トリガー』をクリックします。


右下の トリガーを追加をクリックします。

実行する関数を選択で、先ほどの関数、今回はrinkSeetRowsを選択。

イベントのソースを選択を『時間主導型』にして、
時間ベースのトリガーのタイプを選択を『分ベースのタイマー』にして、
時間の間隔を選択(分)で、『5分おき』くらいに設定して、
保存をクリックでタイマー設定は完璧です。

これで、あなたが元シートでこっそり行を隠しても、数分後には自動的に反映されるようになります。パソコンの電源を切っていても、Googleのサーバーが勝手にやってくれますよ!

更新・アクセス頻度がそんなにない場合、自動にするよりボタン更新の方がおすすめです。

いかがだったでしょうか? 標準関数では不可能なことも、わずか数十行のGASで解決できてしまいます。

YouTube動画で確認

コメント

タイトルとURLをコピーしました