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

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

ただいまの
回答率

88.59%

GASで指定スプレットシートの全シートをアクテイブシートにコピーしたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,218

ishikoro.1234

score 14

前提・実現したいこと

Google AppScriptで別のフォルダにあるスプレットシートを一つのスプレットシートにまとめたいので、スプレットシートのIDで当該のスプレットシートにある全シートを指定したいコピー先にコピーするコードを書きたいです。
もし可能であれば、シートをコピーしたあとにシート名にある(コピー)を削除し、スプレットシートの頭に新しいシートを作成し、全てシートの名前の一覧を作成したいです。
しかし、全シートをコピーしたかったので、自分なりにコードを変えてみましたが、今度はコードを起動しても何も起こらなかったです。
説明がわかりにくくて申し訳ございません。
まだまだ初心者なので、ご教授頂ければ幸いでございます。

該当のソースコード

function function_name() {

var source = SpreadsheetApp.openById('元のファイルID');

var ss_num = new Array();

if (source.length >= 1) {

  for(var i = 0;i < source.length; i++)

var sheet = source.getSheets()[i];

var destination = SpreadsheetApp.openById('コピー先ID');

 sheet[i].copyTo(destination);
}
}

シート名取得コード

  function getname(sheet_no) {
  var name= SpreadsheetApp.getActive().getSheets()[sheet_no - 1].getName();
return name;
}

現在のコード

  function q189933() {
  const destination = SpreadsheetApp.openById('コピー先ID');
  SpreadsheetApp.openById('元のファイルID').getSheets().forEach(
    function(e) {
      e.copyTo(destination);
    }
  );
}
function q189933_() {
  SpreadsheetApp.openById('コピー先ID').insertSheet('Sheet List', 0);

 var sheetlist = SpreadsheetApp.openById('コピー先ID');
 var movesheet = sheetlist.getSheetByName('Sheet List');
sheetlist.setActiveSheet(movesheet);
sheetlist.moveActiveSheet(1);

}
function q189933__() {
  const sheet = SpreadsheetApp.openById('コピー先ID').getSheetByName('Sheet List');
  sheet.clear();
  const dat = SpreadsheetApp.openById('コピー先ID').getSheets().map(function(e){return [e.getSheetName(), e.getSheetId()];}).filter(function(e){return e[0] !== 'Sheet List';});
  sheet.getRange(1, 1, dat.length, 2).setValues(dat);
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • papinianus

    2019/05/20 18:49 編集

    シートidはただの数字ですよ、確か。それのどこが目次として意味があるのですか?
    というかリンクにもならないそのidが目次に必要ですかね?
    (シート名の必要性は理解してます。これはteratail初心者とかプログラム初心者とか関係なく、ユーザ体験として聞きたい事項です)

    キャンセル

  • ishikoro.1234

    2019/05/20 19:02

    お忙しい中、ご回答いただき誠にありがとうございます。
    シートidは他のコードで使用する必要がある場合に備えて、シート一覧にまとめておきたいと思いました、たしかに必要がないかもしれません...。

    業務上、翻訳するスプレットシートをいくついただくのですが、それらを一つのスプレットシートにまとめて、シート名の一覧及び文字数の統計が必要になります。
    いつもは手作業でしたが、Google AppScriptの存在を知り、効率化を捗るために独学をしており、それでいくつのスプレットシートを一つのスプレットシートにまとめて、一覧表を作成するコードを書いてみました。
    現在、コピーしたシート名には(コピー)の文字がついているので、そちらをを削除したいのですが、ご教授いただけないでしょうか。
    コピーする際に名前を指定する関数は調べましたが、今回のように一括にコピーする場合はどのようにコピーの文字だけを削除できますか。
    参考したコード:SpreadsheetApp.openById(コピー先ID).Copy("名前の指定")

    キャンセル

  • papinianus

    2019/05/20 19:20

    例えばpdfにするとかだとidの出番があるかもしれません。あとはシートの場所を移動するとかなら。しかし移動するとidが変わる可能性があるのでこれも微妙。一般的にシート名がわかっているならそれに加えてidは不要に思えます。
    コピーの、名前は調べて回答に追記します

    キャンセル

回答 2

checkベストアンサー

+1

function procedure() {
    const dest = SpreadsheetApp.openById('コピー先ID');
    const sheetName = 'シート一覧';
    const folderName = '翻訳元_未コピー';
    pickSpreadsheetInFolderNamed(folderName).forEach(function (e) { copyAll(dest, SpreadsheetApp.open(e)); });
    resetSheetIndexSheet(dest, sheetName);
}
function pickSpreadsheetInFolderNamed(name) {
    var files = [];
    const folderIter = DriveApp.getFoldersByName(name);
    while (folderIter.hasNext()) {
        var folder = folderIter.next();
        var fileIter = folder.getFilesByType('application/vnd.google-apps.spreadsheet');
        while (fileIter.hasNext()) {
            files.push(fileIter.next());
        }
    }
    return files;
}
function copyAll(destSpreadsheet, sourceSpreadsheet) {
    sourceSpreadsheet.getSheets().forEach(
        function (e) {
            e.copyTo(destSpreadsheet).setName(e.getName());
        }
    );
}
function upsertSheet(spreadsheet, sheetName) {
    const sheet = spreadsheet.getSheetByName(sheetName);
    if (sheet !== null) { return sheet; }
    return spreadsheet.insertSheet(sheetName, 0); //0が挿入位置を示しており、先頭。移動の必要はないと考えた(https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#insertSheet(String,Integer))
}
function resetSheetIndexSheet(spreadsheet, sheetName) {
    const sheet = upsertSheet(spreadsheet, sheetName);
    sheet.clear();
    //const dat = spreadsheet.getSheets().map(function (e) { return [e.getSheetName(), e.getSheetId()]; }).filter(function (e) { return e[0] !== sheetName; });
    const dat = spreadsheet.getSheets().map(function (e) { return [e.getSheetName(),]; }).filter(function (e) { return e[0] !== sheetName; });
    sheet.getRange(1, 1, dat.length, dat[0].length).setValues(dat);
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/22 22:09

    1つミスがあって直しました。しかし仰る挙動になるのは「翻訳元_未コピー」相当のフォルダにスプレッドシートがない場合のように思えます。あるいはフォルダの下にフォルダがあるのでしょうか。多重階層の場合の確認はしていないです。
    フォルダidには対応していません。どちらでも動くようにするのは無駄に大変なので。あとフォルダはDriveAppで操作します。イテレータが返されるので扱いが面倒です。そういう書き方は通用しないです
    設計はご想像のとおりです。"定数"の使い方が変です。

    キャンセル

  • 2019/05/22 22:14

    対象となるスプレッドシートが「翻訳元_未コピー」相当のフォルダのなかにあるときは要件通り動作しましたが、さらにフォルダをはさんでその下にあると仰る挙動になりますね。

    キャンセル

  • 2019/05/23 10:11

    いつもお世話になっております。
    コードの更新及び詳しい説明、誠にありがとうございます。
    新しいコードは正常に使用できました。
    この度はお忙しい中、何度もご教授してくださり、重ね重ね感謝致します。

    キャンセル

0

シート名取得コード

function getNames() {
    const sheetCounts = SpreadsheetApp.getActive().getNumSheets();
    const dat = [];
    for (var i = 1; i <= sheetCounts; i++) {
        dat.push([getname(i)]);
    }
    return dat;
}

function getname(sheet_no) {
    return SpreadsheetApp.getActive().getSheets()[sheet_no - 1].getName();
}

質問者さまのコードを無視して近しいことをやるなら

function re_getname() {
    const sheets = SpreadsheetApp.getActive().getSheets();
    const dat = [];
    for (var i = 1; i <= sheets.length; i++) {
        dat.push([sheets[i].getName()]);
    }
    return dat;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/21 13:23

    1つのスプレッドシートに最大30シートほどあるとのこと。これでも確かに時間制限にはかからないと思います。
    しかしあえて遅くする理由がないので、こちらはお勉強用とご理解ください

    キャンセル

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

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る