🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

1回答

1029閲覧

GAS 3行ずつデータを違うシートにコピーしたい

SAKUS

総合スコア0

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

0クリップ

投稿2020/12/03 16:23

編集2020/12/04 15:06

各営業担当の成績とお客様からのコメントをそれぞれのシートに反映したいです。
このような流れで反映を考えています。

①コピー元データのシート3行目に担当の名前、4行目に担当地域が記載してあり、
3行目を元に各担当のシートを作成しています。

【作成方法】
元になるフィードバックシートをコピーし、それぞれの担当者の名前が自動でスプレットシートのタブ名が担当者になります。

<コピー元データのシート>
|||A列|B列|C列|D列|E列|F列|G列|H列|I列
|:--|:--|:--:|--:||:--|:--:|--:|
|1行目|回答者|Aさん|||Bさん|||Cさん|||
|2行目||第2地域|||第3地域|||第4地域|||
|3行目||満足度|獲得数|コメント|満足度|獲得数|コメント|満足度|獲得数|コメント|
|4行目|佐々木さん|8|9||||||
|5行目|佐藤さん|10|11|親切な対応|10|10|話し上手||
|6行目|中村さん|10|11||9|10|||
|7行目|林さん|||||||5|7|連絡が早い|
|8行目|柴咲さん|||||||5|7||

②それぞれの担当者にデータを反映する。
※担当者のシートに転機するのは三行ずつです。
※コメントがない物もありますが、満足度と獲得数は必ず入力されています。
そのため、満足度が入っているセルからそれぞれコピーしたいです。

例.Aさんの場合はA4からC6までのデータをそのまま反映したいです。
Cさんの場合はG7からI8までのデータをそのまま反映したいです。

転機するシート
Aさんの場合

A列B列C列
Aさんのフィードバックシート
満足度獲得数コメント
89
1011親切
1011

上記のような形で、BさんもCさんの分もそれぞれ転機したいです。

①の作業まではなんとかできましたが、②が全く進みません。
セルの長さと横の長さを取得したり、offsetを使って見ましたが、うまく行きませんでした。
4日ほど色々試したのですが、うまくいかず悩んでいます。
教えて頂けますと幸いでございます。
よろしくお願い致します。

作成したスクリプト

function CreateCommentsheet(){ Createsheet(); Copydata(); } function Createsheet() { var folderId = '格納先';//格納先 var spreadsheetId = '転機するシートのマスターのスプレッドシート';//マスターのシート取得 var folder = DriveApp.getFolderById(folderId); var file = DriveApp.getFileById(spreadsheetId); var ss = SpreadsheetApp.getActiveSpreadsheet(); var mySheet = ss.getSheetByName('シート1'); //スプレッドシートのシートを取得 var fileName = "営業担当のコメントシート"; //ファイル名変更 //新しく作成したシートのIDを取得してセルに貼り付けるコード等を書いていますが、 //長くなるため、削除しています。 } function Copydata() { var ss_copyFrom = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss_copyFrom.getSheetByName('シート1'); var strURL= sheet.getRange(1,15).getValue() var ss_copyTo = SpreadsheetApp.openById(strURL); // 書出シートの作成 var ss_sheet_temp = ss_copyTo.getSheetByName("マスターシート"); var lastColomn = ss_copyFrom.getLastColumn(); var lastRow = ss_copyFrom.getLastRow();//最終行を取得 for(var j=2;j<=lastColomn;j++){ var range = sheet.getRange(1,j); var value = range.getDisplayValue(); if(value!= ""){ var SName = sheet.getRange(1,j).getValue(); //担当名 var AreaName = sheet.getRange(2,j).getValue(); //地域名 // データとファイル名の変更 var ss_sheet_copy = ss_sheet_temp.copyTo(ss_copyTo); // 作成後のファイル名に使用する名前を決める。変えたい場合はここで変更 var name = SName + "_" + AreaName var NewNameSheet = ss_sheet_copy.setName(name);//シートの名前を変更 // ★ここから②になりますデータ書き換え  } }

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

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

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

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

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

papinianus

2020/12/03 20:28

3 行ずつとのことですが、BさんはD5から始まりますよね?実際はどうなのですか? あと、A4は8と書いてあるセルだと思うのですが、「コピー元データのシート3行目に担当の名前、4行目に担当地域」の説明からするとそのセルはA7のにも受け取れます。実際はどうなのですか?
SAKUS

2020/12/04 00:34

ご質問ありがとうございます。 BさんはD5から始まります。 記載していませんが、A列の左隣に回答者の名前があるかたちです。(フィードバックシートには回答者の名前は転記しません) A4は8と書いてあるセルになります。 (担当者名が1行目になります。)
papinianus

2020/12/04 06:44

- ①コピー元データのシート3行目に担当の名前、4行目に担当地域が記載してあり、 3行目を元に各担当のシートを作成しています。 - ※担当者のシートに転機するのは三行ずつです。 担当者名は1行目にあり BやCの評価は2行しかないです。 この2箇所を正しい仕様に修正していただけないですか?
SAKUS

2020/12/04 15:09

回答者名を追加致しました。 回答数も営業担当により異なるため、BとCは2行しかありません。 また、営業担当も2名で行うこともあります。例えば、佐藤さんの担当はBとC二人で行なっています。
guest

回答1

0

  • 回答者の列がある時点で「Aさん」と書いてある列が A 列であることはあり得ないです
    質問や補正された内容から類推できるレベルの虚偽があっても対応できる程度のコードを書いてみました
    あとは自力で頑張ってください

javascript

1const q308060 = () => { 2 const sheetName = "シート1"; // 転記元データが書いてあるシートの名前 3 const columnWhereNameListStart = 3; //2; // A さんという名前が始まる列 (A さんと書いてあるセルに =Column() と入力して表示される数値) 4 const rowWhereNameListStart = 2; //1; // A さんという名前が始まる行 (A さんと書いてあるセルに =Row() と入力して表示される数値) 5 const rowForHeader = 6; //3 // 満足度,獲得数,コメントが書いてある列 (満足度と書いてあるセルに =Row() と入力して表示される数値) 6 const dataColumns = 4; //3 // 転記すべき評価項目(満足度,獲得数,コメント)がいくつあるか 7 8 const sheetInfoLength = 2; // unmodifiable 9 const spreadsheet = SpreadsheetApp.getActive(); 10 const source = spreadsheet.getSheetByName(sheetName).getDataRange().getValues(); 11 const book = new pseudoBook(positionGetter(transpose(source.slice(rowWhereNameListStart - 1,rowWhereNameListStart + sheetInfoLength - 1)), columnWhereNameListStart - 1 , dataColumns), dataColumns); 12 book.setSheetHeader(source[rowForHeader - 1].slice(columnWhereNameListStart - 1)); 13 book.distributeData(source.slice(rowForHeader)); 14 book.writeSheets(spreadsheet); 15} 16 17const positionGetter = (array, skip = 1, span = 3) => { 18 const result = new Map(); 19 let prev = ""; 20 for(let i = skip; i < array.length; i += span) { 21 let [name, district] = array[i]; 22 while(name === "" && district === "") { 23 i++; 24 if(i >= array.length) return result; 25 [name, district] = array[i]; 26 } 27 if(name === "") { 28 if (prev === "") throw new Error(`cannot guess owner of district, ${district}`); 29 name = prev; 30 } 31 const key = `${name},${district}`; 32 if(result.has(key)) throw new Error(`duplicate tuple ${key}`); 33 result.set(key, i); 34 prev = name; 35 } 36 return result; 37} 38const transpose = (array) => array[0].map((_, c) => array.map(r => r[c])); 39 40class pseudoBook { 41 constructor(map, length) { 42 this.sheets = [...map.entries()].sort((a, b)=> a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0)).map(e => new pseudoSheet(e[0], e[1])); 43 this.sheetDataLength = length; 44 } 45 setSheetHeader(array) { 46 this.header = array.slice(0,this.sheetDataLength); 47 } 48 distributeData(data) { 49 this.sheets.forEach(e => e.pickData(data, this.sheetDataLength)); 50 } 51 writeSheets(spreadsheet) { 52 this.sheets.forEach(e => e.writeDown(spreadsheet, this.header)); 53 } 54} 55class pseudoSheet { 56 constructor(sheetName, index) { 57 this.sheetName = sheetName; 58 this.index = index; 59 this.content = []; 60 } 61 // メソッド 62 pickData(data, span) { 63 this.content = data.map(r=>r.slice(this.index, this.index + span)).filter(e=>e.some(c=>c !== "")); 64 } 65 writeDown(spreadsheet, header) { 66 if(this.content.length === 0) return; 67 const sheet = spreadsheet.getSheetByName(this.sheetName) || spreadsheet.insertSheet(this.sheetName); // gas では ?? が使えない(構文エラーで保存できない)。挿入位置は activesheet の直後 68 sheet.clearContents(); 69 const vain = [`${this.sheetName.split(",")[0]}のフィードバックシート`, ...(Array.from({length:header.length},_=>""))].slice(0,header.length); 70 sheet.getRange(1,1,this.content.length + 2, this.content[0].length).setValues([header].concat(this.content)); 71 } 72}
ABCDEFGHIJK(非表示)LMNOPQ
1
2回答者AさんBさんCさん
3第2地域第3地域第4地域第5地域
4
5
6満足度獲得数コメントa満足度獲得数コメントb満足度獲得数コメントb満足度獲得数コメントb
7佐々木さん8911111111
8佐藤さん1011親切な対応1010話し上手
9中村さん1013910
10林さん57連絡が早い57連絡が早い
11柴咲さん5757
12aa1234x
13ZZ

text

1// Aさん,第2地域 2Aさんのフィードバックシート 3満足度 獲得数 コメント a 48 9 510 11 親切な対応 610 13 71 2 3 4 8// Bさん,第3地域 9Bさんのフィードバックシート 10満足度 獲得数 コメント a 1110 10 話し上手 129 10 13// Cさん,第4地域 14Cさんのフィードバックシート 15満足度 獲得数 コメント a 161 1 1 1 175 7 連絡が早い 185 7 19// Cさん,第5地域 20Cさんのフィードバックシート 21満足度 獲得数 コメント a 221 1 1 1 235 7 連絡が早い 245 7

投稿2020/12/05 15:58

papinianus

総合スコア12705

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問