[あすかぜ・ねっと]あすかぜ・ねっと自作ソフトCassava > サポート掲示板

Cassava Editor サポート掲示板

スレッド一覧に戻る返信

[875] マクロによる計算横軸

まくろしょしんしゃ [2024/11/26 17:13:27]

いつもお世話になっております。

横になるデータで合計を出したいです。
データによって項目数が変わってしまうのですが右に伸びてくので問題ないとおもうのですが…


3 4 1 5 6
4 2 1 5 7
4 2 1 5

↓1列目に合計値

19 3 4 1 5 6
20 4 2 1 5 8
12 4 2 1 5

sumのマクロでの使い方がわかりません…
すみませんがよろしくお願いいたします。

Re: [875] マクロによる計算横軸

あすかぜ [2024/11/26 21:38:32]

次のようなマクロでどうでしょうか。

InsertCol(1);
for (y = 1; y <= Bottom; y++) {
  [1,y] = sum(2, y, Right, y);
}

「Right」は一番右の列番号を表します。
sum() は空白のセルを無視するので、項目数が違っていても 2 列目から一番右までと指定すればよさそうです。
試してみてください。

Re: [875] マクロによる計算横軸

まくろしょしんしゃ [2024/11/30 10:12:28]

ありがとうございます!
そうやってsum使うのですね…。


さらになんですけど…
・同じ内容だったら削除&行数カウント
・違う内容だったら削除しない
という事をしたいのですが…


ヘッダあり
---
3 4 1 5 6
3 4 1 5 6
4 2 1 5 7
4 1 2 5 7
4 2 1 5


↓1列目にカウント、2列目に合計値

ヘッダあり
---
2 19 3 4 1 5 6
1 20 4 2 1 5 7
1 20 4 1 2 5 7
1 12 4 2 1 5





この場合いつもこんな感じで書くのですが、、、
カウント用の場所作って、

InsertCol(1);
[1,1] = "カウント用";
x = 1;
for (y = 2; y <= Bottom; y++) {
  [x,y] = "1";
}

InsertCol(2);
[2,1] = "合計値";
for (y = 2; y <= Bottom; y++) {
  [2,y] = sum(2, y, Right, y);
}

Sort(1, 2, Right,Bottom, 2, false, true, false, false);


function find(str, max) {
  for (y = 2; y < max; y++) {
    if ([2,y] == str) {
      return y;
    }
  }
  return 0;
}


for (y = Bottom; y > 2; y--) {
  found = find([2,y], y);
  if (found > 0) {
    [1,found] = [1,found] + [1,y];
    DeleteRow(y);
  }
}

でも「違う内容だったら削除しない」というのをスマートに表現できなく、
良い書き方ありますでしょうか…?


Re: [875] マクロによる計算横軸

あすかぜ [2024/11/30 22:47:26]

2 つの行が同じかどうかを判別するための簡単な関数などは用意していないので、
1 セルずつ内容を比較して条件分岐をする必要があります。
次のような感じでしょうか。

// Sort() までは変更なし

function areSame(y1, y2) {
  for (x = 3; x <= Right; x++) {
    if ([x,y1] != [x,y2]) {
      return false;
    }
  }
  return true;
}

function find(target) {
  for (y = target - 1; y > 1; y--) {
    if ([2,y] != [2,target]) {
      return 0;
    }
    if (areSame(y, target)) {
      return y;
    }
  }
  return 0;
}

for (y = Bottom; y > 2; y--) {
  found = find(y);
  if (found > 0) {
    [1,found] = [1,found] + [1,y];
    DeleteRow(y);
  }
}

2 列目でソート済みのようなので、すべての行と比較するのではなく、2 列目が違う行を見つけた時点であきらめるようにも書き換えてみました。
試してみてください。

Re: [875] マクロによる計算横軸

まくろしょしんしゃ [2024/12/02 09:28:59]

ありがとうございます。
ソートしてるのですが複数条件ソートしてないので揃っているのが1列目だけでした。
sort.cms使わずにソートするorすべての行と比較するにはどうしたらよいでしょうか…

Re: [875] マクロによる計算横軸

まくろしょしんしゃ [2024/12/02 13:11:49]

やっぱりソートマクロ作成しました。

bbs216_20110124.cms のもので
function compare(y1, y2, x) {

  // 最初に 1 列目を比較する
  for (x = 2; x < Right; x++) {
  r = [x,y1] - [x,y2];
  if(r != 0){ return r;}

  // 1, 2, 3 列目すべてが等しければ 0 を返す
  return 0;
}

で2~後ろを繰り返しソートして先ほどので上手くいきました。

避けてた理由の1つなのですが、
ソートのマクロの位置が、Macro直下じゃないといけないためです。
たくさんマクロがあり、フォルダで整理しているので、せっかくならどこかにまとめておきたいなあというのが希望です。

Re: [875] マクロによる計算横軸

あすかぜ [2024/12/02 22:00:51]

Ver.2.4 以降では、Macro フォルダ内の「lib」サブフォルダのマクロも「ファイル名.関数名()」という形で呼び出せるようになりました。
lib サブフォルダは [マクロ] メニュー内には表示されないので、マクロ管理の邪魔になりにくいかと思います。
Sort.cms も lib サブフォルダに移動してみてください。


また、Ver.2.0 で追加した import 文を使用すれば、それ以外の好きなフォルダにマクロを置くこともできます。
マクロファイルの先頭に
import { qsort } from "path/to/Sort.cms";
と記述すると、qsort(...); という関数呼び出しで path/to フォルダに置いた Sort.cms 内の qsort 関数を呼び出せるようになります。


なお、すべての列を比較してソートするのであれば、隣の行のみをチェックすればよいので、find() は不要かもしれません。

for (y = Bottom; y > 2; y--) {
  if (areSame(y - 1, y)) {
    [1,y-1] = [1,y-1] + [1,y];
    DeleteRow(y);
  }
}

ご参考までに。

スレッド一覧に戻る返信