84005
**したいこと**  
スプレットシートの情報を取得し、複数のdiscordのチャンネルに文章として送信するプログラムをしばらく使用していました。

そこで、discordに送信する文章の内容を増やしたいとおもいました。  
今までは各々のdiscordのチャンネルに数値であるhaisintimeという値だけを変えてそれぞれに送信していましたが、今回もう一つ数値の値と、文字式を送ろうと思い、get_value()関数にallpointとcomrankという変数を作り、スプレットシートから取得して送信しようとしました。

**できなかったこと**  
haisintimeと同じ数値であるallpointに関してはうまくいきましたが、conrankを追加しようとした結果、エラーになりました。おそらく、文字列が問題なのかなと思ったのですが、具体的にどうすればよいかがわかりません。教えていただけると幸いです。

**試したこと**  
文字列であるcomrankのところを、 getDisplayRange()で試してみたがうまくいかなかった。

```

    function submit(){
      discord()
    };
    
    function get_value() {
      var sheet1 = get_sheet('https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxx',0);
        //日付
        var datecoord = sheet1.getRange(2,3);
        var date = datecoord.getValue();
          //format
        var formatcoord = sheet1.getRange(3, 3);
        var format = formatcoord.getValue();
    
        
        //配信時間
        var messages_array = []; // initialize
        
    
        
      for (let i = 11; i <= 16; i++) {
        var timecoord = sheet1.getRange(i,6); 
        var haisintime = timecoord.getValue();
        var pointcoord = sheet1.getRange(i,4);
        var allpoint = pointcoord.getValue();
        var rankcoord = sheet1.getRange(i, 18);
        var comrank = rankcoord.getValues();
        var message = 'None'
        if (haisintime > 0) {
          var message = Function('var date = ' + date + '; var haisintime = ' + haisintime + '; var allpoint = ' + allpoint   + '; var comrank = ' + comrank + '; return ' + format + ';')();
          } 
        
        messages_array.push(message); // push
      }
      return messages_array; // return
        
      
    };
    
    //googleスプレットシート  自動送信
    function get_sheet(gss_url,sheet_num) {
      var ss = SpreadsheetApp.openByUrl(gss_url);
      var sheet = ss.getSheets()[sheet_num];
      return sheet;
    };
    
    
    function get_sheet2(gss_url,sheet_num) {
      var discord = SpreadsheetApp.openByUrl(gss_url);
      var sheet2 = discord.getSheets()[sheet_num];
      return sheet2;
    };
    
    function discord(message) {
        var sheet2 = get_sheet2('https://docs.google.com/spreadsheets/d/yyyyyyyyyyyyyyyy',0);
    
        var messages = get_value();  // call get_value() at here
    
        var lastRow2 = sheet2.getLastRow();  //最終行取得
        
        for (let j = 11; j <= lastRow2; j++) {
    
          //webhook
          var webhookcoord = sheet2.getRange(j,3);
          var webhook = webhookcoord.getValue();
    
        //token
          var tokencoord = sheet2.getRange(j,4);
          var dtoken = tokencoord.getValue();
          
      　//channel
          var channelcoord = sheet2.getRange(j,2);
          var dchannel = channelcoord.getValue();
          
        //format
          const url        = webhook;
          const token      = dtoken;
          const channel    = dchannel;
          const text       = messages[j-11];
          if (text === 'None') {
            console.log(channel + " : 送信なし"); 
            continue;
          }
    
          
          
    
          const username   = 'aaaaaaaaaaaaaaaaaaaa';
          const avatar_url = "http://drive.google.com/aaaaaaaaaaaaaaaa";
          const parse      = 'full';
          const method     = 'post';
    
          const payload = {
              'token'      : token,
              'channel'    : channel,
              "content"    : text,
              'username'   : username,
              'parse'      : parse,
              'avatar_url' : avatar_url,
          };
    
          const params = {
              'method' : method,
              'payload' : payload,
              'muteHttpExceptions': true   
    
          };
          Utilities.sleep(500);
          
        response = UrlFetchApp.fetch(url, params);
        //実行ログ
        console.log(channel + " : " + text); 
    
    
        }
        
    }
    
```

**エラー内容**

```

    10:30:04    エラー 
    ReferenceError: C3 is not defined
    eval    
    get_value   @ コード.gs:29
    discord @ コード.gs:56
    submit  @ コード.gs:2
    
```

**追記**  
スプレットシートのセルC3に書かれているものはdiscordにおくる文のformatです。  
今回使われている変数で例を作ってみると

"私は今年で" \+ haisintime + "歳になります。誕生日は" \+ allpoint + "です。名前は" \+ comrank +
"です。"

こんな感じでC3に全部書く感じです。同じ感じで書いているのですが、comrankをいれるとうまくいかなくなる感じです。

**追記２**  
必要としている情報を提示できているかわかりませんが、スプレットシートは写真のようになっています。見せられないところは消しましたが、データの配置は全く同じです。  
[![画像の説明をここに入力](https://i.stack.imgur.com/DYTYD.png)](https://i.stack.imgur.com/DYTYD.png)

[![画像の説明をここに入力](https://i.stack.imgur.com/MkshA.png)](https://i.stack.imgur.com/MkshA.png)

また、comrankのデータは上の写真のR列のようになっています。

**追記３**  
文formatが次のような場合どうすればよいでしょうか？C2の"12/1~12/5"というセルの中身を取得して文formatのdateという値に入れたいです。

"期間は" \+ date + "です。私は今年で" \+ haisintime + "歳になります。誕生日は" \+ allpoint +
"です。名前は" \+ comrank + "です。"

出力結果ではdateという値がそのまま表示されます。  
上の例で実行した結果が次です。

```

    10:21:05    情報  test1 : 期間はdateです。私は今年で0歳になります。誕生日は0です。名前はDです。
    10:21:06    情報  test2 : 期間はdateです。私は今年で5歳になります。誕生日は5670です。名前はC3です。
    10:21:06    情報  test3 : 期間はdateです。私は今年で5歳になります。誕生日は11140です。名前はAです。
    10:21:07    情報  test4 : 期間はdateです。私は今年で10歳になります。誕生日は6980です。名前はB2です。
    10:21:08    情報  test5 : 期間はdateです。私は今年で6歳になります。誕生日は10です。名前はC2です。
    10:21:08    情報  test6 : 期間はdateです。私は今年で0歳になります。誕生日は0です。名前はDです。
    
    
```

追記4  
私は元のコードのget_value()関数を丸ごと教えていただいたものに変えました。  
そうすると、以下のようにdateが薄くなっており、変数として見つからない状態になっています。  
[![画像の説明をここに入力](https://i.stack.imgur.com/0APOS.png)](https://i.stack.imgur.com/0APOS.png)

**追記５**  
このdiscord自動送信のシステムは sheet1に数値などの値が入力されていて、  
discord(message)関数のsheet2にdiscordに送信する際に必要なwebhookURLやtokenが写真のように記入されています。

[![画像の説明をここに入力](https://i.stack.imgur.com/OWBQq.png)](https://i.stack.imgur.com/OWBQq.png)

名前は消してあるのでわからないかと思いますが、sheet１の名前(本来ならC列に書かれている）とsheet2の同じであり、上から順に送信すると正しい情報がデータが送信されるようになっていました。

今回、4つ目の質問のおかげでhaisintimeが0のデータは送信されないようになりました。  
ただ今回のフィルターに欠けるやり方だと、上から順にhaisintimeが0でないデータが送られることになります。

例えば、

A：配信時間3時間  
B：配信時間0時間  
C：配信時間4時間  
D：配信時間5時間

というデータの場合、  
A：配信時間3時間  
B：配信時間4時間  
C：配信時間5時間

となってしまうわけです。これだと違う人に違ったデータが渡ってしまいます。

A：配信時間3時間  
C：配信時間4時間  
D：配信時間5時間

このような形にしたいのですが可能ですか？
CC BY-SA 4.0
2021-12-07T01:31:59.817
83990
2021-12-09T11:00:06.487
2021-12-09T11:00:06.487
47546
47546
question
google-apps-script google-spreadsheet
GoogleAppScriptでスプレットシートから文字式がうまく取得できない。
表示していただいたサンプルスプレッドシートから、スクリプトの`get_value()`の`Function('var date = ' + date +
'; var haisintime = ' + haisintime + '; var allpoint = ' + allpoint + '; var
comrank = ' + comrank + '; return ' + format +
';')();`でエラーが発生していると考えられます。この場合、セル"R12"の値である"C3"が変数として変換されてしまうため、`C3 is not
defined`のようなエラーが発生すると思いました。そこで、次のような修正を提案します。

### Modified script:

```

    function get_value() {
      var sheet1 = SpreadsheetApp.getActiveSheet();
      var [[date], [format]] = sheet1.getRange("C2:C3").getValues();
      format = format.replace(/[ 　"+]+/g, "");
      var values = sheet1.getRange("D11:R" + sheet1.getLastRow()).getValues();
      var messages_array = values.map(([allpoint,,haisintime,,,,,,,,,,,,comrank]) =>
        Object.entries({allpoint, haisintime, comrank}).reduce((s, e) => s.replace(...e), format)
      );
      return messages_array;
    }
    
```

修正ポイントは次の通りです。

  * 複数の値を一度に`getValues`で取得するとコストを低くすることができます。
  * 表示されたセル"C3"の値である`"私は今年で" + haisintime + "歳になります。誕生日は" + allpoint + "です。名前は" + comrank + "です。"`を`allpoint, haisintime, comrank`で置換する流れで修正しました。

### 注意点

  * 上記の修正では、V8 runtimeを有効にしていない場合はエラーが発生しますのでご注意ください。V8 runtimeを有効にしてお使いください。

### References:

  * [reduce()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
  * [map()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
  * [replace()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/replace)
CC BY-SA 4.0
2021-12-07T09:15:12.677
84005
2021-12-07T09:15:12.677
19460
83990
answer