テーブル内の2つの科目にあてはまる数値を集計してフィールドに入れたい

・テーブル内の2つの科目にあてはまる数値を集計してフィールドに入れたいです。

・下記のフォームを作成し、

媒体のドロップダウンには「媒体A・媒体B・媒体C」、

対応のドロップダウンには「反響・登録・成約」、

媒体毎の反響数・登録数・成約数をフォームに表示させたと思っております。

 

下記の質問者様のソースコードを元に、1つの科目の数値集計は作動しました。

https://developer.cybozu.io/hc/ja/community/posts/115019057363-%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E5%86%85%E3%81%AE%E6%95%B0%E5%80%A4%E3%82%92%E7%A7%91%E7%9B%AE%E3%81%94%E3%81%A8%E3%81%AB%E9%9B%86%E8%A8%88%E3%81%97%E3%81%A6%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%81%AB%E5%85%A5%E3%82%8C%E3%81%9F%E3%81%84

条件科目が複数になった場合はどのようなソースコードになるのでしょうか。

ご教示よろしくお願いします。

以下のような形で可能かと思います。

(() => {
  'use strict';

  let subTable = 'テーブル'; // サブテーブルのフィールドコード
let medium = '媒体'; // 媒体のフィールドコード
let reaction = '対応'; // 対応のフィールドコード
let count = '人数'; // 人数のフィールドコード

  kintone.events.on([
  `app.record.create.change.${medium}`, `app.record.edit.change.${medium}`,
  `app.record.create.change.${reaction}`, `app.record.edit.change.${reaction}`,
  `app.record.create.change.${count}`, `app.record.edit.change.${count}`
], (event) => {
  let record = event.record;
  let sums = {
    '媒体A': {
      '反響': 0,
      '登録': 0,
      '成約': 0
    },
    '媒体B': {
      '反響': 0,
      '登録': 0,
      '成約': 0
    },
    '媒体C': {
      '反響': 0,
      '登録': 0,
      '成約': 0
    }
  };

    record[subTable].value.forEach((row) => {
    if (!row.value[medium].value || !row.value[reaction].value || isNaN(row.value[count].value)) return;

    sums[row.value[medium].value][row.value[reaction].value] += Number(row.value[count].value);
  });

    Object.keys(sums).forEach((mediums) => {
    Object.keys(sums[mediums]).forEach((reactions) => {
      record[`${mediums}${reactions}数の合計`].value = sums[mediums][reactions];
    });
  });

    return event;
});
})();

mls-hashimoto 様

早速、ご回答いただきありがとうございます。

試してみます。取り急ぎお礼申し上げます。

hmc_satomi

hmc_satomi さま

動作確認して1か所間違いがありました。申し訳ありません。

    if(!row.value[medium].value || !row.value[reaction].value || !isNaN(row.value[count].value))return;

この部分を

   if(!row.value[medium].value || !row.value[reaction].value ||isNaN(row.value[count].value))return;

このように変更して下さい。

mls-hashimoto 様

早々にアドバイス頂きまして、どうもありがとうございます。

早速試してみたのですが、数値フィールド(各合計)に人数が反映されない状況です。

(※フィールドコードとフィールド名は同一にしております)

何か見逃しているのかもしれません。。。

大変お手数ですがよろしくお願い致します。

(() => {
  'use strict';

  let subTable = '媒体別'; // サブテーブルのフィールドコード
  let medium = '媒体'; // 媒体のフィールドコード
  let reaction = '対応'; // 対応のフィールドコード
  let count = '人数'; // 人数のフィールドコード

  kintone.events.on([
    `app.record.create.change.${medium}`, `app.record.edit.change.${medium}`,
    `app.record.create.change.${reaction}`, `app.record.edit.change.${reaction}`,
    `app.record.create.change.${count}`, `app.record.edit.change.${count}`
  ], (event) => {
    let record = event.record;
    let sums = {
      '媒体A': {
        '反響': 0,
        '登録': 0,
        '成約': 0
      },
      '媒体B': {
        '反響': 0,
        '登録': 0,
        '成約': 0
      },
      '媒体C': {
        '反響': 0,
        '登録': 0,
        '成約': 0
      }
    };

    record[subTable].value.forEach((row) => {
      if (!row.value[medium].value || !row.value[reaction].value || !isNaN(row.value[count].value)) return;

      sums[row.value[medium].value][row.value[reaction].value] += Number(row.value[count].value);
    });

    Object.keys(sums).forEach((mediums) => {
      Object.keys(sums[mediums]).forEach((reactions) => {
        record[`${mediums}${reactions}数の合計`].value = sums[mediums][reactions];
      });
    });

    return event;
  });
})();

mls-hashimoto 様

無事作動しました。

助かりました。ありがとうございました。

mls-hashimoto 様

度々質問をしてすみません。

●媒体のドロップダウンには「媒体A・媒体B・媒体C」

●対応のドロップダウンには「反響・登録・成約」、

に加えて、

●募集区分のドロップダウン「A・B」

●男女区分のドロップダウン「男・女」

を追加して、媒体毎の

A男の反響数、A女の反響数、B男の反響数、B女の反響数

A男の登録数、A女の登録数、B男の登録数、B女の登録数

A男の成約数、A女の成約数、B男の成約数、B女の成約数

をフォームに表示させたと思っております。

これは可能でしょうか?

まったく違うコードになったりするものなのでしょうか。

ご教示の程、宜しくお願い致します。

hmc_satomi さま

媒体ごとの区分を見落としていたので再度投稿します。

かなりカテゴリが多くなりますね。同じような感じで可能です。フィールドコードは「媒体A募集要項A男の反響数」という想定でいますが、必要に応じて最後の部分を変更して下さい。

(() => {
  'use strict';

let subTable = 'テーブル' // サブテーブルのフィールドコード
  let medium = '媒体'; // 媒体のフィールドコード
let recruitment = '募集区分'; // 募集区分のフィールドコード
let gender = '男女区分'; // 男女区分のフィールドコード
let reaction = '対応'; // 対応のフィールドコード
let count = '人数'; // 人数のフィールドコード

  let mediumValues = ['媒体A', '媒体B', '媒体C'];
let recruitmentValues = ['A', 'B'];
let genderValues = ['男', '女'];
let reactionValues = ['反響', '登録', '成約'];

let events = [];

  [medium, reaction, recruitment, gender, count].forEach((field) => {
  events.push(`app.record.create.change.${field}`, `app.record.edit.change.${field}`);
});

  kintone.events.on(events, (event) => {
  let record = event.record;
  let sums = {};

    mediumValues.forEach((mediumValue) => {
    sums[meduimValue] = {};

    recruitmentValues.forEach((recruitmentValue)=> {
      genderValues.forEach((genderValue) => {
        sums[mediumValue][recruitmentValue + genderValue] = {};

          reactionValues.forEach((reactionValue) => {
          sums[meduimValue][recruitmentValue + genderValue][reactionValue] = 0;
        });
      });
    });
  });

    record[subTable].value.forEach((row) => {
    if (!row.value[meduim].value || !row.value[recruitment].value || !row.value[gender].value || !row.value[reaction].value || isNaN(row.value[count].value)) return;

      sums[row.value[meduim].value][row.value[recruitment].value + row.value[gender].value][row.value[reaction].value] += Number(row.value[count].value);
  });

    Object.keys(sums).forEach((medium) => {
    Object.keys(sums[medium]).forEach((categories) => {
      Object.keys(sums[medium][categories]).forEach((reactions) => {
        record[`${meduim}募集要項${categories}の${reaction}数`].value = sums[medium][categories][reactions];
      });
    });
  });

    return event;
});
})();

 

mls-hashimoto 様

早速ご対応いただき、ありがとうございます。

がんばって試してみます。

早速テストで下記のように作ってみたのですが、

数値フィールド(各合計)に人数が反映されませんでした。

※フィールドコードとフィールド名は同一にしております。

※テストなので媒体ドロップダウンの「媒体C」を削除しています。

お手数ですが、よろしくお願い致します。

(() => {
  'use strict';

  let subTable = '媒体別' // サブテーブルのフィールドコード
  let medium = '媒体'; // 媒体のフィールドコード
  let recruitment = '募集区分'; // 募集区分のフィールドコード
  let gender = '男女区分'; // 男女区分のフィールドコード
  let reaction = '対応'; // 対応のフィールドコード
  let count = '人数'; // 人数のフィールドコード

  let mediumValues = ['媒体A', '媒体B'];
  let recruitmentValues = ['A', 'B'];
  let genderValues = ['男', '女'];
  let reactionValues = ['反響', '登録', '稼働'];

  let events = [];

  [medium, reaction, recruitment, gender, count].forEach((field) => {
    events.push(`app.record.create.change.${field}`, `app.record.edit.change.${field}`);
  });

  kintone.events.on(events, (event) => {
    let record = event.record;
    let sums = {};

    mediumValues.forEach((mediumValue) => {
      sums[meduimValue] = {};

      recruitmentValues.forEach((recruitmentValue)=> {
        genderValues.forEach((genderValue) => {
          sums[mediumValue][recruitmentValue + genderValue] = {};

          reactionValues.forEach((reactionValue) => {
            sums[meduimValue][recruitmentValue + genderValue][reactionValue] = 0;
          });
        });
      });
    });

    record[subTable].value.forEach((row) => {
      if (!row.value[meduim].value || !row.value[recruitment].value || !row.value[gender].value || !row.value[reaction].value || isNaN(row.value[count].value)) return;

      sums[row.value[meduim].value][row.value[recruitment].value + row.value[gender].value][row.value[reaction].value] += Number(row.value[count].value);
    });

    Object.keys(sums).forEach((medium) => {
      Object.keys(sums[medium]).forEach((categories) => {
        Object.keys(sums[medium][categories]).forEach((reactions) => {
          record[`${meduim}${categories}${reaction}数`].value = sums[medium][categories][reactions];
        });
      });
    });

    return event;
  });
})();

hmc_satomi さま

申し訳ありません。typoが何か所かありました。

(() => {
  'use strict';

  let subTable = 'テーブル' // サブテーブルのフィールドコード
let medium = '媒体'; // 媒体のフィールドコード
let recruitment = '募集区分'; // 募集区分のフィールドコード
let gender = '男女区分'; // 男女区分のフィールドコード
let reaction = '対応'; // 対応のフィールドコード
let count = '人数'; // 人数のフィールドコード

  let mediumValues = ['媒体A', '媒体B'];
let recruitmentValues = ['A', 'B'];
let genderValues = ['男', '女'];
let reactionValues = ['反響', '登録', '稼働'];

  let events = [];

  [medium, reaction, recruitment, gender, count].forEach((field) => {
  events.push(`app.record.create.change.${field}`, `app.record.edit.change.${field}`);
});

  kintone.events.on(events, (event) => {
  let record = event.record;
  let sums = {};

    mediumValues.forEach((mediumValue) => {
    sums[mediumValue] = {};

    recruitmentValues.forEach((recruitmentValue)=> {
      genderValues.forEach((genderValue) => {
        sums[mediumValue][recruitmentValue + genderValue] = {};

          reactionValues.forEach((reactionValue) => {
          sums[mediumValue][recruitmentValue + genderValue][reactionValue] = 0;
        });
      });
    });
  });

    record[subTable].value.forEach((row) => {
    if (!row.value[medium].value || !row.value[recruitment].value || !row.value[gender].value || !row.value[reaction].value || isNaN(row.value[count].value)) return;

      sums[row.value[medium].value][row.value[recruitment].value + row.value[gender].value][row.value[reaction].value] += Number(row.value[count].value);
  });

    Object.keys(sums).forEach((medium) => {
    Object.keys(sums[medium]).forEach((categories) => {
      Object.keys(sums[medium][categories]).forEach((reactions) => {
        record[`${medium}${categories}${reactions}数`].value = sums[medium][categories][reactions];
      });
    });
  });

    return event;
});
})();

mls-hashimoto 様

無事動きました!

ありがとうございました。

mls-hashimoto 様

お忙しいところ、度々ご質問失礼します。

「媒体AA男反響数」の数は4なのに、2と表示されるみたいな現象が各数値フィールドでおきてます。

 

●テストの表から変更している部分は下記です。

①「媒体」のドロップダウンの選択数の増加。(※テストでは媒体A・B・Cの3個ですが、本当は10個以上あります)

②「媒体」のドロップダウンを選択しない場合がある。(※必須項目ではないので、「—」のものもあります)

⓷「媒体」のドロップダウンで数字が必要ない項目ある。(※例えば、集計が必要なのは媒体Aと媒体Bのみ。媒体Cの集計は不要なので、グループ欄に数値フィールド(各合計)自体を作成していません。また、その項目はコードにも加えてません。)

大変お手数ですが、よろしくお願い致します。

(() => {
  'use strict';

  let subTable = '媒体別' // サブテーブルのフィールドコード
  let medium = '媒体'; // 媒体のフィールドコード
  let recruitment = '募集区分'; // 募集区分のフィールドコード
  let gender = '男女区分'; // 男女区分のフィールドコード
  let reaction = '対応'; // 対応のフィールドコード
  let count = '人数'; // 人数のフィールドコード

let mediumValues = ['媒体A', '媒体B', '媒体C', '媒体D', '媒体E', '媒体F', '媒体G', '媒体H', '媒体I', '媒体J', '媒体K', '媒体L', '媒体M', '媒体N'];
let recruitmentValues = ['A', 'B'];
  let genderValues = ['男', '女'];
  let reactionValues = ['反響', '登録', '事訪', '成約','稼働'];

   let events = [];

  [medium, reaction, recruitment, gender, count].forEach((field) => {
    events.push(`app.record.create.change.${field}`, `app.record.edit.change.${field}`);
  });

  kintone.events.on(events, (event) => {
    let record = event.record;
    let sums = {};

    mediumValues.forEach((mediumValue) => {
      sums[mediumValue] = {};

      recruitmentValues.forEach((recruitmentValue)=> {
        genderValues.forEach((genderValue) => {
          sums[mediumValue][recruitmentValue + genderValue] = {};

          reactionValues.forEach((reactionValue) => {
            sums[mediumValue][recruitmentValue + genderValue][reactionValue] = 0;
          });
        });
      });
    });

    record[subTable].value.forEach((row) => {
      if (!row.value[medium].value || !row.value[recruitment].value || !row.value[gender].value || !row.value[reaction].value || isNaN(row.value[count].value)) return;

      sums[row.value[medium].value][row.value[recruitment].value + row.value[gender].value][row.value[reaction].value] += Number(row.value[count].value);
    });

    Object.keys(sums).forEach((medium) => {
      Object.keys(sums[medium]).forEach((categories) => {
        Object.keys(sums[medium][categories]).forEach((reactions) => {
          record[`${medium}${categories}${reactions}数`].value = sums[medium][categories][reactions];
        });
      });
    });

    return event;
  });
})();

hmc_satomi さま

原因を調べたいので、別途文字列複数行フィールド等を作成して

let results = [];

    Object.keys(sums).forEach((medium) => {
      Object.keys(sums[medium]).forEach((categories) => {
        Object.keys(sums[medium][categories]).forEach((reactions) => {
          record[`${medium}${categories}${reactions}数`].value = sums[medium][categories][reactions];
results.push(`${medium}${categories}${reactions}数:${sums[medium][categories][reactions]}`);
        });
      });
    });

record['文字列複数行'].value = results.join('');

こちらで結果がどうなるか(フィールドの値と合っているか等)を見ていただいて問題ありませんか?

mls-hashimoto 様

文字列複数行フィールドに追加し、コードも追加しましたが、何も変化ありませんでした。

新しいレコードでもテーブルに入力しましたが、数値フィールド(各合計)に人数が反映されないので、

集計自体が作動してないようです。。。

下記の①②を追加した後から、集計自体が作動してないように思うのですが・・。

①「媒体」ドロップダウンの「スタッフ紹介」「社員紹介」を追加した。

②「対応」ドロップダウンの「成約」を追加した。

※①②は集計が不要なので、数値フィールド(各合計)が存在しません。

何卒よろしくお願い致します。

(() => {
  'use strict';

  let subTable = '媒体別'; // サブテーブルのフィールドコード
  let medium = '媒体'; // 媒体のフィールドコード
  let recruitment = '募集区分'; // 募集区分のフィールドコード
  let gender = '男女区分'; // 男女区分のフィールドコード
  let reaction = '対応'; // 対応のフィールドコード
  let count = '人数'; // 人数のフィールドコード

let mediumValues = ['媒体a', '媒体b', '媒体c', '媒体d','媒体e', '媒体f', '媒体g', '媒体h', '媒体i', '媒体j', '媒体k', '媒体l', '媒体m', '媒体n', '媒体o' , 'スタッフ紹介', '社員紹介'];
  let recruitmentValues = ['グループ', '他社'];
  let genderValues = ['男', '女'];
  let reactionValues = ['反響', '登録', '事訪', '成約','稼働'];

   let events = [];

  [medium, reaction, recruitment, gender, count].forEach((field) => {
    events.push(`app.record.create.change.${field}`, `app.record.edit.change.${field}`);
  });

  kintone.events.on(events, (event) => {
    let record = event.record;
    let sums = {};

    mediumValues.forEach((mediumValue) => {
      sums[mediumValue] = {};

      recruitmentValues.forEach((recruitmentValue)=> {
        genderValues.forEach((genderValue) => {
          sums[mediumValue][recruitmentValue + genderValue] = {};

          reactionValues.forEach((reactionValue) => {
            sums[mediumValue][recruitmentValue + genderValue][reactionValue] = 0;
          });
        });
      });
    });

    record[subTable].value.forEach((row) => {
      if (!row.value[medium].value || !row.value[recruitment].value || !row.value[gender].value || !row.value[reaction].value || isNaN(row.value[count].value)) return;

      sums[row.value[medium].value][row.value[recruitment].value + row.value[gender].value][row.value[reaction].value] += Number(row.value[count].value);
    });

    Object.keys(sums).forEach((medium) => {
      Object.keys(sums[medium]).forEach((categories) => {
        Object.keys(sums[medium][categories]).forEach((reactions) => {
          record[`${medium}${categories}${reactions}数`].value = sums[medium][categories][reactions];
        });
      });
    });
record['文字列複数行'].value = results.join('');
    return event;
  });
})();

hmc_satomi さま

>※①②は集計が不要なので、数値フィールド(各合計)が存在しません。

ここを見落としておりました。存在しないフィールド(例として「スタッフ紹介A男の反響数」等)にアクセスしているためエラーで停止している状態です。フィールドが存在するかのif文を追加し

   Object.keys(sums).forEach((medium) =\>{
     Object.keys(sums[medium]).forEach((categories) =\>{
       Object.keys(sums[medium][categories]).forEach((reactions) =\>{
if (record[`${medium}${categories}${reactions}数`]) record[`${medium}${categories}${reactions}数`].value = sums[medium][categories][reactions];
        });
      });
    });

こちらで問題ないはずです。長いので

   Object.keys(sums).forEach((medium) =\>{
     Object.keys(sums[medium]).forEach((categories) =\>{
       Object.keys(sums[medium][categories]).forEach((reactions) =\>{
let sum = medium + categories + reactions;

if (record[`${sum}数`]) record[`${sum}数`].value = sums[sum];
        });
      });
    });

こちらでも問題ありません。

 

ちなみに文字列複数行には、各集計数が全て文字列で吐き出されるようになっています。フィールドが500を超えてしまう場合はこちらの方法も検討されると良いと思います(その場合はObject.keysの前のresults宣言、ループ中のpushも必要です)。

mls-hashimoto 様

コードをコピペしたのですが、やはり集計が反応しませんでした。

この場合、数値フィールド(各合計)のフィールドコード名が間違っているとかそのような感じでしょうか・・・。

宜しくお願い致します。

(() => {
  'use strict';

  let subTable = '媒体別'; // サブテーブルのフィールドコード
  let medium = '媒体'; // 媒体のフィールドコード
  let recruitment = '募集区分'; // 募集区分のフィールドコード
  let gender = '男女区分'; // 男女区分のフィールドコード
  let reaction = '対応'; // 対応のフィールドコード
  let count = '人数'; // 人数のフィールドコード

let mediumValues = ['媒体a','媒体b','媒体c','媒体d','媒体e','媒体f','媒体g','媒体h','媒体i','媒体j','媒体k','媒体l','媒体m','媒体n','媒体o', 'スタッフ紹介', '社員紹介'];
  let recruitmentValues = ['グループ', '他社'];
  let genderValues = ['男', '女'];
  let reactionValues = ['反響', '登録', '事訪', '成約', '稼働'];

   let events = [];

  [medium, reaction, recruitment, gender, count].forEach((field) => {
    events.push(`app.record.create.change.${field}`, `app.record.edit.change.${field}`);
  });

  kintone.events.on(events, (event) => {
    let record = event.record;
    let sums = {};

    mediumValues.forEach((mediumValue) => {
      sums[mediumValue] = {};

      recruitmentValues.forEach((recruitmentValue)=> {
        genderValues.forEach((genderValue) => {
          sums[mediumValue][recruitmentValue + genderValue] = {};

          reactionValues.forEach((reactionValue) => {
            sums[mediumValue][recruitmentValue + genderValue][reactionValue] = 0;
          });
        });
      });
    });

    record[subTable].value.forEach((row) => {
      if (!row.value[medium].value || !row.value[recruitment].value || !row.value[gender].value || !row.value[reaction].value || isNaN(row.value[count].value)) return;

      sums[row.value[medium].value][row.value[recruitment].value + row.value[gender].value][row.value[reaction].value] += Number(row.value[count].value);
    });
    
  Object.keys(sums).forEach((medium) => {
      Object.keys(sums[medium]).forEach((categories) => {
        Object.keys(sums[medium][categories]).forEach((reactions) => {
          let sum = medium + categories + reactions;

          if (record[`${sum}数`]) record[`${sum}数`].value = sums[sum];
        });
      });
    });
    return event;
  });
})();

hmc_satomi さま

申し訳ありません。またしてもtypoしました。

if(record[`${sum}数`]) record[`${sum}数`].value = sums[medium][categories][reactions];

右側はオブジェクトへのアクセスなので、階層ごとにアクセスする必要がありました。

mls-hashimoto 様

無事作動しました!

助かりました。

本当にありがとうございました。