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

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

ただいまの
回答率

88.37%

GAS メール内容保存 ドライブ自動保存、保存先をスプレッドシートに記述 エラーについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 701

Yotpp

score 5

GASで特定件名の受信内容と添付ファイルのドライブ自動保存、保存先をスプレッドシートに記述する動作を作成しています。

デバック中にに以下のエラーメッセージが発生しました。

☆次のオブジェクトを取得できません。イテレータが末尾に到達しました。(行 31、ファイル「コード」)
☆ 該当のソースコード
var hyperlink_formula = "=HYPERLINK(\"" + fol.getFilesByName(newName).next().getUrl() + "\",\"" + newName + "\")";
valMsgs.push([date,from,subj,body,msid,perm,attach,hyperlink_formula]);
}

★原因としては添付ファイルが無いメールもあるのでfol.getFilesByName(newName).next().getUrl()が実行できないと思われます。
var hyperlink_formula = もしくはvalMsgs.push([date,from,subj,body,msid,perm,attach,hyperlink_formula]);
の前に添付ファイル有り無しを確認することは可能なのでしょうか?
以下がコード全文になります

var mySheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('メール蓄積テスト');

function searchContactMail() {

/* Gmailから特定条件のスレッドを検索しメールを取り出す */
var strTerms =  '(subject:"件名+’’ OR "from:mail@address")';
var myThreads = GmailApp.search(strTerms,0,30);
var myMsgs = GmailApp.getMessagesForThreads(myThreads);//二次元配列
var fol = DriveApp.getFolderById('添付ファイル保存先フォルダID');
var valMsgs = [];

/* 各メールから日時、送信元、件名、内容、ID、添付ファイルを取り出す */
for(var i=0;i<myMsgs.length;i++){
for(var j=0;j<myMsgs[i].length;j++){
var msid = myMsgs[i][j].getId();//メッセージIDを取得
//もしメッセージIDがスプレッドシートに存在しなければ
if(!hasId(msid)){
var date = myMsgs[i][j].getDate();
var from = myMsgs[i][j].getFrom();
var subj = myMsgs[i][j].getSubject();
var body = myMsgs[i][j].getPlainBody().slice(0,200);
var perm = myThreads[i].getPermalink();
var attach = myMsgs[i][j].getAttachments();
for(var k = 0; k < attach.length; k++){
var blobFile = attach[k]; 
var originalName = blobFile.getName();
var newName = Utilities.formatDate(date, 'JST', 'yyyy/MM/dd/HH:mm (E)') + originalName ;
blobFile.setName(newName);
fol.createFile(blobFile);//ドライブに添付ファイルを保存
}
var hyperlink_formula = "=HYPERLINK(\"" + fol.getFilesByName(newName).next().getUrl() + "\",\"" + newName + "\")";
valMsgs.push([date,from,subj,body,msid,perm,attach,hyperlink_formula]);
}
}
}

/* スプレッドシートに出力 */
if(valMsgs.length>0){//新規メールがある場合、末尾に追加する
var lastRow = mySheet.getDataRange().getLastRow();
mySheet.getRange(lastRow+1, 1, valMsgs.length, 8).setValues(valMsgs);
}
}

function hasId(id){

var data = mySheet.getRange(1, 5, mySheet.getLastRow(),1).getValues();//E列(メッセージID)を検索範囲とする
var hasId = data.some(function(value,index,data){//コールバック関数
return (value[0] === id);
});
return hasId;
}

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • papinianus

    2020/03/04 21:58

    ご自分で書いたコードでないとの想定です。
    引用元を書いてください。それを公開している人の労力で利益を得ようとしているのに、その人の著作権をふみにじる真似をすると、そういう善意の人が減るだけで結局損をします。

    キャンセル

  • Yotpp

    2020/03/05 09:22

    いろいろな方のコードを自分なりに組みなおしており、完全に引用はしていないのですが、どの部分がこれ、この部分はこれと引用元を掲示したほうがよろしいでしょうか?
    自分もそれなりに時間を使って現状までたどり着きました。

    キャンセル

  • Yotpp

    2020/03/05 14:02

    基本にした参考 コード
    https://tonari-it.com/gas-gmail-messageid/

    ここに添付ファイルの保存先ハイパーリンクを追加できるように検索、探索して、いじくり回して、なんとか質問のできるところまでたどり着けました、、、、

    キャンセル

回答 1

checkベストアンサー

+1

可能です。

では満足しないのでしょうね。

                var hyperlink_formula = "=HYPERLINK(\"" + fol.getFilesByName(newName).next().getUrl() + "\",\"" + newName + "\")";


                var hyperlink_formula = attach.length ? "=HYPERLINK(\"" + fol.getFilesByName(newName).next().getUrl() + "\",\"" + newName + "\")" : "";


でよいのではないかと想像します。

なお、この方法だとハイパーリンクされるのは最後の添付ファイル 1 個になってしまいます。元のコードの作者は何らかの前提をおいていたことが想像されます。


var mySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('メール蓄積テスト');

function searchContactMail() {

    /* Gmailから特定条件のスレッドを検索しメールを取り出す */
    var strTerms = '(subject:"件名+’’ OR "from:mail@address")';
    var myThreads = GmailApp.search(strTerms, 0, 30);
    var myMsgs = GmailApp.getMessagesForThreads(myThreads);//二次元配列
    var fol = DriveApp.getFolderById('添付ファイル保存先フォルダID');
    var valMsgs = [];

    /* 各メールから日時、送信元、件名、内容、ID、添付ファイルを取り出す */
    for (var i = 0; i < myMsgs.length; i++) {
        for (var j = 0; j < myMsgs[i].length; j++) {
            var msid = myMsgs[i][j].getId();//メッセージIDを取得
//もしメッセージIDがスプレッドシートに存在しなければ
            if (!hasId(msid)) {
                var date = myMsgs[i][j].getDate();
                var from = myMsgs[i][j].getFrom();
                var subj = myMsgs[i][j].getSubject();
                var body = myMsgs[i][j].getPlainBody().slice(0, 200);
                var perm = myThreads[i].getPermalink();
                var attach = myMsgs[i][j].getAttachments();
                var links = ["","",""];
                for (var k = 0; k < attach.length; k++) {
                    var blobFile = attach[k];
                    var originalName = blobFile.getName();
                    var newName = Utilities.formatDate(date, 'JST', 'yyyy/MM/dd/HH:mm (E)') + originalName;
                    blobFile.setName(newName);
                    var f = fol.createFile(blobFile);//ドライブに添付ファイルを保存
                    links.unshift(`=HYPERLINK("${f.getUrl()}","${newName}")`)
                }
                valMsgs.push([date, from, subj, body, msid, perm, attach].concat(links.slice(0,3)));
            }
        }
    }

    /* スプレッドシートに出力 */
    if (valMsgs.length > 0) {//新規メールがある場合、末尾に追加する
        var lastRow = mySheet.getDataRange().getLastRow();
        mySheet.getRange(lastRow + 1, 1, valMsgs.length, 10).setValues(valMsgs);
    }
}

function hasId(id) {

    var data = mySheet.getRange(1, 5, mySheet.getLastRow(), 1).getValues();//E列(メッセージID)を検索範囲とする
    var hasId = data.some(function (value, index, data) {//コールバック関数
        return (value[0] === id);
    });
    return hasId;
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/03/05 14:03

    ありがとうございます。 最大3個の添付ファイルまでとしたいです。

    キャンセル

  • 2020/03/05 22:58

    後ろから最大3つになるようなかきかたをしました。

    キャンセル

  • 2020/03/06 08:36

    ただコピペするだけでなく、どこをどう変えていただいたのか わかる範囲で調べてから使わせていただくことにします。ありがとうございます。

    キャンセル

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

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

関連した質問

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