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

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

ただいまの
回答率

90.03%

フォームで入力したスプレッドシートのデータをGASプログラムで削除したい

解決済

回答 3

投稿 編集

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

handymatsu

score 24

前提・実現したいこと

GoogleFormで入力されたGoogleSpreadSheet上のデータがあります。Google Apps Scriptプログラムで,このスプレッドシートファイルのコピーを作り編集しようとしています。具体的には,特定のcolumnを削除したいのです。

発生している問題・エラーメッセージ

Google Apps Script上のプログラムではエラーが出ませんが,削除もできません。そこで,手動で特定のcolumnを削除しようとしたところ,

問題が発生しました
フォームデータを含む列は削除できません。代わりに列を非表示にできます。

というメッセージが出ます。
そこで,スプレッドシートの「フォーム」メニューから,「フォームのリンクを解除」を実行すると,Google Apps Scriptプログラムで特定のcolumnを削除できるようになります。
いちいち,手動で解除していては大変なので,フォームのリンクの解除をGoogleAppsScriptプログラムでなんとか実行したいのですが,やり方がわかりません。

マクロの記録をしてみましたが,マクロとしては記録されていませんでした。

該当のソースコード

  var ssIDforS = copyFileInFolder(folderId2, ssID0, todayNow+"求人データ(学生用)");//ssID0はformで入力されるspreadSheet
  var ssForS = new Ssheet(ssIDforS);
  ssForS.deleteColumn(0,40);//formからのリンクが削除できず,deleteできない



//フォルダID,ファイルID,ファイル名を受け取り,ファイルIDのコピーをフォルダ内に作成して,ファイルのIDを返す
function copyFileInFolder(folderID, srcID, fileName) {
  var originalFile = DriveApp.getFileById(srcID);
  var folder = DriveApp.getFolderById(folderID);
  var copiedFile = originalFile.makeCopy(fileName, folder);
  copiedFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.EDIT);//リンクからアクセスできる人は編集可能にする
  var copiedFileId = copiedFile.getId();//コピーのファイルIDをゲット
  return copiedFileId;
}

//////////Ssheetクラスの定義開始(コンストラクタとメンバ関数で構成)2019/02/05
//Ssheetクラスのコンストラクタの記述
Ssheet = function(id){
  this.id = id;
  this.ssFile = SpreadsheetApp.openById(id);
  this.ssFileName = this.ssFile.getName();
  SpreadsheetApp.setActiveSpreadsheet(this.ssFile);//値を返さない
  this.activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
}
//spreadsheetの指定列colを削除
Ssheet.prototype.deleteColumn = function(sheet,col){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  this.activeSheet.deleteColumn(col);//列を削除
}

試したこと

あきらめて,spreadSheetを新規作成し,セルを一つ一つコピーするGoogleAppsScriptプログラムを作りましたが,ハイパーリンクを含むセルは,見た目のセルの値だけが,コピーされてしまい,ハイパーリンクが消えてしまいます。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • papinianus

    2019/02/13 09:44

    そもそもなぜそのような業務が頻繁に発生するのでしょうか?フォームに不要な項目があるのであればフォームを見直すべきではないかと思うのですが。

    キャンセル

  • handymatsu

    2019/02/13 12:27

    コメントありがとうございます。管理者と閲覧者がスプレッドシートを見るのですが,閲覧者には個人情報部分をカットした物を見せるようにしたいためです。

    キャンセル

  • papinianus

    2019/02/13 12:42

    その利用状況ですと、もしプログラム操作が可能であっても、リンク解除して列を削除する、はやってはいけないことのように思います(その個人情報が失われるので)。回答としてシートの保護を提案いたしました。

    キャンセル

  • handymatsu

    2019/02/13 14:07

    papinianus様,
    コメントありがとうございます。
    いえ,ファイルはコピーして二つにしますので,そのうちの片方を見せたくない部分だけカットしたいのです。なかなか難しいです。

    キャンセル

回答 3

checkベストアンサー

+1

var newSheet = SpreadsheetApp.create(”newSheet”);
var sheet = SpreadsheetApp.getActiveSheet().copyTo(newSheet);


新規にスプレットシートを作成して、そこにシートのコピーを作成するのはどうでしょうか。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/13 14:52

    papinianus様
    確かに誤解していたのですが,teritama様のJavaScriptを見て,別のブックとは気がつきませんでした。早速試してみます。

    キャンセル

  • 2019/02/13 17:22

    teritama様,papinianus様,
    アドバイス,ありがとうございました。上に書きましたとおり,解決できました。結構めんどくさかったですが,思った通りの動作を実現できました。

    キャンセル

  • 2019/02/14 05:11

    papinianus様
    コメントのフォローありがとうございます。

    handymatsu様
    言葉足らずですみませんでした。
    実現できてよかったです。

    キャンセル

+1

回答の一部を隠蔽して参照させたい、という用途であれば、

  • 列の非表示
  • シートの保護

で良いのではないでしょうか?
URLがクリックできる状態になるかは確認していませんが、すくなくとも保護されたシートでもフォームからの書き込みが行え、保護シートを編集する権限がないユーザは列を再表示できないことを確認しての回答です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/13 12:52

    papinianus様,
    アドバイスありがとうございます。
    状況の説明不足で,申し訳ありません。実は,
    ●絶対に見せたくない列
    ●必要に応じて見せたい列
    ●常に見せたい列
    の3種類あります。スプレッドシートはエクセルに変換して,メール添付で配布しますが,常に見せたい列だけが見える状態で配布します。閲覧者は必要に応じて再表示して閲覧します。個人情報については最初からカットしてしまいたい・・・,という状況です。

    キャンセル

  • 2019/02/13 12:58

    絶対に見せたくない列は,メールアドレスや氏名で,これは管理者だけが見たいという状況です。

    キャンセル

+1

アドバイスありがとうございました。解決できました。こんな感じです。

  var folderId2 = "******************************";
  var ssIDforT = createSpreadsheetInFolder(folderId2, "データ(管理用)");
  var ssForT = new Ssheet(ssIDforT);
  ssOrg.sheetCopyToSheetOfAnotherSS(0,ssForT);//ブックssOrgの0番シートをブックssForTに挿入コピー
  ssForT.deleteSheet(0);//最初からある不要なシートを削除
  var ssIDforS = createSpreadsheetInFolder(folderId2, "データ(閲覧用)");
  var ssForS = new Ssheet(ssIDforS);
  ssOrg.sheetCopyToSheetOfAnotherSS(0,ssForS);
  ssForS.deleteSheet(0);//最初からある不要なシートを削除


//////////Ssheetクラスの定義開始(コンストラクタとメンバ関数で構成)2019/02/05
//Ssheetクラスのコンストラクタの記述
Ssheet = function(id){
  this.id = id;
  this.ssFile = SpreadsheetApp.openById(id);
  this.ssFileName = this.ssFile.getName();
  SpreadsheetApp.setActiveSpreadsheet(this.ssFile);//値を返さない
  this.activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
}
//シートを他のファイルのシートとしてコピー挿入する
Ssheet.prototype.sheetCopyToSheetOfAnotherSS = function(sheet,dstSS){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  return this.activeSheet.copyTo(dstSS.ssFile);
}
///////////////////////////////////Ssheetクラスの定義終了(大半を省略)



//フォルダID,ファイル名を受け取り,スプレッドシートを指定フォルダ内に新規作成しそのファイルIDを返す
function createSpreadsheetInFolder(folderID, fileName){
  var folder = DriveApp.getFolderById(folderID);
  var newSS=SpreadsheetApp.create(fileName);
  var originalFile=DriveApp.getFileById(newSS.getId());
  var copiedFile = originalFile.makeCopy(fileName, folder);
  DriveApp.getRootFolder().removeFile(originalFile);
  var copiedFileId = copiedFile.getId();//コピーのファイルIDをゲット
  return copiedFileId;
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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