GSS上の特定セルを参照し、全シートで一致するデータを書き換える
お世話になります。
500件ぶんの案件管理表x4の書き換えを一括で行いたいと思っています。
ちょっとややこしい説明で申し訳ありませんが……
1つのスプレッドシートの中に
・マスターシート(500件程度、重複なしのユニークデータがある)
・シートA
・シートB
・シートC
があり、シートA~Cのレコードはマスターのコピーです。
すべて同一の内容ではありますが、書式(背景色)で差別化があり
例えばセルC5は、シートAはクリアだけどBとCはグレーアウト……というような感じです。
シートA~Cはそれぞれ外部公開用としてimportrangeで別SSから参照します。
プロジェクトが進行していく上で、作業が終了したレコードを塗りつぶす必要があるのですが
500件x4シートを手動で繰り返すのは、地味に手間もかかるしミスもありえるので
マスターシート上のみの操作で全シート反映させられないかと考えています。
###希望する動作
マスターシートの特定のセルXに修正したいレコードをコピペしてからGASを実行すると
Xのレコードを取得し、シートA・B・Cの中で一致するデータセルを一括でグレーにする。
それにより、外部公開用の各SSも一括で書式変更を反映できるようにする。
※
ただし、importrangeで呼び出したデータに書式が反映されないそうなので、
コピペ→GAS実行で、例えば同一レコード文末に「.」などを挿入し、
条件付き書式で「.」を含むセルに色をつける……といった強引な方法もアリかなと思っています。
(方法としては美しくはないでしょうが、最終目的は外部公開用のSSに反映させるためなので……)
こちらの場合デフォルトの置換使えばいいのでは?という話が出てくるかと思いますが
操作に不慣れなスタッフもいるため、所定の場所にコピペしたら
その隣にある(トリガーをつけた)ボタンをポチっとするだけ、という形にしたいなと思っています。
プログラミング超初心者のため、ネットで公開されているソースコードを
いじくる形であれやこれや試してみましたが、力不足でした……。
お力をお貸しいただければと思います。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
###回答
プログラム修正できました.
おそらく、仕様通りになっていると思います.
前回のプログラムをベースに作っていましたが、処理時間が500件で2分くらいかかっていたので、ロジックを見直しました.
GASはExcelと違って、セルの値の取得やセットの処理がめちゃくちゃ遅いので、値の取得とセットを1回で実施するようにしました。(外部SSも同じ方式にしました.)この方法だと、データ量が増えても処理時間は大きくは伸びないと思います.
前回:セルの数だけ、値の取得とセットをしていた。
今回:初めに一括でシート内のデータを取得して、書式を変数上で変更して、一括でセルにセットしています.(getBackgroundsとsetBackgroundsの箇所です)
###メインSSのGAS
GAS
1 2function myFunction() { 3 4 var start = new Date(); 5//======================================================================================= 6 var SheetMaster = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('マスターシート'); 7 var SheetA = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートA'); 8 var SheetB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートB'); 9 var SheetC = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートC'); 10 11 var LastRow = SheetMaster.getDataRange().getLastRow(); //シート内の最終行(データ次第) 12 var LastCol = SheetMaster.getDataRange().getLastColumn(); //シート内の最終列(12列) 13 var colorsM = SheetMaster.getDataRange().getBackgrounds(); //Mシート内の色データ(2次元配列) 14 var colorsB = SheetB.getDataRange().getBackgrounds(); //Bシート内の色データ(2次元配列) 15 var colorsC = SheetC.getDataRange().getBackgrounds(); //Cシート内の色データ(2次元配列) 16 17 //AシートにMシートの書式を完全コピー 18 SheetA.getRange(1,1,LastRow,LastCol).setBackgrounds(colorsM); 19 20 //Mシートのカラー情報の中で、白のセルにはBシートのセルの書式をコピー 21 for(var col = 0; col <= LastCol-1; col++) { 22 for(var row = 0; row <= LastRow-1; row++) { 23 if(colorsM[row][col] == "#ffffff"){ 24 colorsM[row][col] = colorsB[row][col]; 25 } 26 } 27 } 28 SheetB.getRange(1,1,LastRow,LastCol).setBackgrounds(colorsM);//書式セット 29 30 //Bシートのカラー情報の中で、白のセルにはCシートのセルの書式をコピー 31 for(var col = 0; col <= LastCol-1; col++) { 32 for(var row = 0; row <= LastRow-1; row++) { 33 if(colorsM[row][col] == "#ffffff"){ 34 colorsM[row][col] = colorsC[row][col]; 35 } 36 } 37 } 38 SheetC.getRange(1,1,LastRow,LastCol).setBackgrounds(colorsM);//書式セット 39//======================================================================================= 40 var end = new Date(); 41 var time_past = (end - start) / 1000; 42 Browser.msgBox(time_past + "SEC"); 43} 44
###外部公開用のGAS
外部公開用はA,B,Cをそれぞれ完全コピーしています.
メインSSは書式のみ反映させるプログラムにしましたが、外部SSは値と書式をコピーしてくるようにしました.書式だけ反映する場合は、プログラム内の「値を取得・セット」と書いてある行を削除してください.
function FormLoad() { Browser.msgBox("マスタースプレッドシートを参照します。"); //参照先スプレッドシート var MasterSS = SpreadsheetApp.openById('12JYHXv-tRlfMNZBv1LeScqB5PurAQDP-fyw0HurZ5ho');//参照先のSSのID var MasterSS_A = MasterSS.getSheetByName('シートA') //参照先のシートA var MasterSS_B = MasterSS.getSheetByName('シートB') //参照先のシートB var MasterSS_C = MasterSS.getSheetByName('シートC') //参照先のシートC //外部用スプレッドシート var SheetA = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートA'); //外部SSのシートA var SheetB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートB'); //外部SSのシートB var SheetC = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートC'); //外部SSのシートC var row var col var values var colors var start = new Date(); //================================================================================================= //外部SSの各シートへ値と書式をコピー //シートA row=MasterSS_A.getDataRange().getLastRow(); col=MasterSS_A.getDataRange().getLastColumn(); values = MasterSS_A.getDataRange().getValues(); //値を取得 colors = MasterSS_A.getDataRange().getBackgrounds(); SheetA.getRange(1,1,row,col).setValues(values); //値をセット SheetA.getRange(1,1,row,col).setBackgrounds(colors); //シートB row=MasterSS_B.getDataRange().getLastRow(); col=MasterSS_B.getDataRange().getLastColumn(); values = MasterSS_B.getDataRange().getValues(); //値を取得 colors = MasterSS_B.getDataRange().getBackgrounds(); SheetB.getRange(1,1,row,col).setValues(values); //値をセット SheetB.getRange(1,1,row,col).setBackgrounds(colors); //シートC row=MasterSS_C.getDataRange().getLastRow(); col=MasterSS_C.getDataRange().getLastColumn(); values = MasterSS_C.getDataRange().getValues(); //値を取得 colors = MasterSS_C.getDataRange().getBackgrounds(); SheetC.getRange(1,1,row,col).setValues(values); //値をセット SheetC.getRange(1,1,row,col).setBackgrounds(colors); //================================================================================================= var end = new Date(); var time_past = (end - start) / 1000; Browser.msgBox(time_past + "SEC"); }
###処理時間遅いプログラム
メインSSだけ、処理時間遅いバージョンも作成しましたので、一応UPします.
タイム計測のコードも書いておきましたので、処理時間比較すると面白いかもしれません.
こちらのプログラムはデータ量に比例して、処理時間が伸びると思います.
動きは同じです.
//処理時間遅い function myFunction1() { var start = new Date(); //======================================================================================= var SheetMaster = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('マスターシート'); var SheetA = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートA'); var SheetB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートB'); var SheetC = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートC'); //A~L列までループ for(var col = 1; col <= 12; col++) { var LastRow = SheetMaster.getRange(1, col).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow(); //各列の行数を取得 for(var row = 1; row <= LastRow; row++) { var color = SheetMaster.getRange(row,col).getBackground(); //背景色取得 //書式に色がついている場合(白じゃない場合) if(color != "#ffffff"){ SheetA.getRange(row,col).setBackground(color); //Aの特定セルに背景色設定 SheetB.getRange(row,col).setBackground(color); //Bの特定セルに背景色設定 SheetC.getRange(row,col).setBackground(color); //Cの特定セルに背景色設定 } } } //======================================================================================= var end = new Date(); var time_past = (end - start) / 1000; Browser.msgBox(time_past + "SEC(1)"); }
###補足
色の指定は、テーマ欄にある色を設定すると黒色が反映されるため、使わない方がいいです.(画像参照)
以上です.仕様通りでない場合やバグありましたら、教えてください.
投稿2019/12/09 14:41
総合スコア640
0
###回答
案件データがどのような形で入力されているかわからなかったので、A列に案件1~案件500まで入っていると仮定して、プログラムを作ってみました。
マスターシートのイメージはこんな感じです(画像参照)
###マスターシートのデータをA~Cに反映
■プログラムの流れ
1.完了した案件を全て塗りつぶす.
2.マスターシート内のボタンをクリック.
3.マスターシートのA列の各セルの背景色を取得.
4.シートA、B、Cに背景色を反映.
※A、B、Cの背景色はすべて同じにしています.詳細がわからなかったため.
プログラムを参考までに以下にUPします.
gas
1function myFunction() { 2 3 var SheetMaster = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('マスターシート'); 4 var SheetA = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートA'); 5 var SheetB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートB'); 6 var SheetC = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートC'); 7 const FValues = SheetMaster.getRange('A:A').getValues(); //A列の値を全て取得 8 const LastRow = FValues.filter(String).length; //空白の要素を除いた長さを取得(A列に入っているデータ数) 9 10 //マスターのA列に入っているデータの数だけ処理する 11 for(var i = 1; i <= LastRow; i++) { 12 //処理 13 var color = SheetMaster.getRange(i,1).getBackground(); //背景色取得 14 SheetA.getRange(i,1).setBackground(color); //Aに背景色設定 15 SheetB.getRange(i,1).setBackground(color); //Bに背景色設定 16 SheetC.getRange(i,1).setBackground(color); //Cに背景色設定 17 } 18}
###外部公開用のSSについて
importrange関数では書式が反映されないので、こちらもGASで書いてみました。
■プログラムの流れ
1.外部公開用のスプレッドシートが開いた時に、プログラム起動.
(ファイル起動時にGASを自動起動する設定ができます.)
2.参照先のデータを取得(マスター、A、B、C).
3.外部SSのシート(マスター、A、B、C)に値と書式をセット.
プログラムを参考までに以下にUPします。
gas
1 2function FormLoad() { 3 Browser.msgBox("マスタースプレッドシートを参照します。"); 4 //参照先スプレッドシート 5 //以下のIDは参照先のスプレッドシートのIDを入力してください. 6 //https://docs.google.com/spreadsheets/d/【ここがIDの文字列です】/ 7 var MasterSS = SpreadsheetApp.openById('12YHdfXv-tRlfMdZBLscqBsPusaQDP-fyd0s1sdfsd');//参照先のSSのID 8 var MasterSS_M = MasterSS.getSheetByName('マスターシート') //参照先のシート(マスター) 9 var MasterSS_A = MasterSS.getSheetByName('シートA') //参照先のシートA 10 var MasterSS_B = MasterSS.getSheetByName('シートB') //参照先のシートB 11 var MasterSS_C = MasterSS.getSheetByName('シートC') //参照先のシートC 12 const FValues = MasterSS_M.getRange('A:A').getValues(); //A列の値を全て取得 13 const LastRow = FValues.filter(String).length; //空白の要素を除いた長さを取得 14 15 //外部用スプレッドシート 16 var SheetMaster = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('マスターシート'); //外部SSのマスターシート 17 var SheetA = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートA'); //外部SSのシートA 18 var SheetB = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートB'); //外部SSのシートB 19 var SheetC = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シートC'); //外部SSのシートC 20 21 22 //マスターのA列に入っているデータの数だけ処理する 23 for(var i = 1; i <= LastRow; i++) { 24 //マスター 25 var value = MasterSS_M.getRange(i,1).getValue(); //参照先の値取得 26 var color = MasterSS_M.getRange(i,1).getBackground(); //参照先の背景色取得 27 SheetMaster.getRange(i,1).setValue(value); //外部SSのマスターシートに値設定 28 SheetMaster.getRange(i,1).setBackground(color); //外部SSのマスターシートに背景色設定 29 //A 30 value = MasterSS_A.getRange(i,1).getValue(); //参照先の値取得 31 color = MasterSS_A.getRange(i,1).getBackground(); //参照先の背景色取得 32 SheetA.getRange(i,1).setValue(value); //外部SSのマスターシートに値設定 33 SheetA.getRange(i,1).setBackground(color); //外部SSのマスターシートに背景色設定 34 //B 35 value = MasterSS_B.getRange(i,1).getValue(); //参照先の値取得 36 color = MasterSS_B.getRange(i,1).getBackground(); //参照先の背景色取得 37 SheetB.getRange(i,1).setValue(value); //外部SSのマスターシートに値設定 38 SheetB.getRange(i,1).setBackground(color); //外部SSのマスターシートに背景色設定 39 //C 40 value = MasterSS_C.getRange(i,1).getValue(); //参照先の値取得 41 color = MasterSS_C.getRange(i,1).getBackground(); //参照先の背景色取得 42 SheetC.getRange(i,1).setValue(value); //外部SSのマスターシートに値設定 43 SheetC.getRange(i,1).setBackground(color); //外部SSのマスターシートに背景色設定 44 } 45} 46
以上です。不明点ありましたら、お気軽にどうぞ。
投稿2019/12/06 22:07
編集2019/12/06 22:11総合スコア640
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/09 07:25
2019/12/09 09:01
2019/12/09 10:37
2019/12/09 11:19 編集
2019/12/09 11:44
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/10 09:42
2019/12/10 09:48