Home > front end >  Count cells with same string in dynamic range
Count cells with same string in dynamic range

Time:12-25

I've read many articles on Google and StackOverflow, but haven't found any that mention how to count cells (under the same column) containing same string value. The count only considers a part of the sheet: many cells are added/removed in a short time, so the range keeps changing length. In the same sheet there are several ranges, separated by a blank row.

The counters should refer to a single range (counter_1 --> range_1; counter_2 --> range_2 , etc.).

e.g.: if cells can show 4 different options AND there are 5 dynamic ranges in the sheet --> there will be 4 counters for each range (4*5).

Following several websites (like enter image description here

You can see it working here

CodePudding user response:

Here's a non-array answer. The only reason this might be helpful compared to the above two answers is if you have a lot of calculations going and you begin to hit some performance issues. The obvious drawback to the below formula is that you would have to reapply it by dragging down after changes were made. You could build in an app script to reapply the formula as an r1C1 during an onEdit event.

Put this in all cells in columns D:G and assuming D1:G1 have the matching count syntax (i.e D1=1st Option)

=if(And($A2<>"",OR(Row($A2)=2,$A1="")),SUMPRODUCT((--($A:$A=$A2))*(--(D$1=$B:$B))),)

Again the first two answers offer a dynamic solution, which is probably better, but I figured I'd add this just for illustration or maybe to ignite some other ideas.

CodePudding user response:

function countcellswithsamestring() {
  const ss = SpreadsheetApp.getActive();
  const sh = ss.getSheetByName("Sheet0");
  const osh = ss.getSheetByName("Sheet1");
  const sr = 2;//data start row
  const rg = sh.getRange(sr, 1, sh.getLastRow() - sr   1, sh.getLastRow());
  const row = rg.getRow();
  const col = rg.getColumn();
  const vs = rg.getDisplayValues();
  let co = {pA:[]};
  vs.forEach((r,i) => {
    r.forEach((c,j) => {
      if(!co.hasOwnProperty(c)) {
        co[c] = {count:1,loc:[sh.getRange(row   i,col   j).getA1Notation()]}
        co.pA.push(c);
      } else {
        co[c].count  ;
        co[c].loc.push(sh.getRange(row   i,col   j).getA1Notation()) 
      }
    })
  })
  let o = co.pA.map(c => [c,co[c].count,co[c].loc.join(',')]);
  osh.clearContents();
  o.unshift(["String","Count","Locations"])
  osh.getRange(1,1, o.length,o[0].length).setValues(o);
}

Data:

COL1 COL2 COL3 COL4 COL5 COL6 COL7 COL8 COL9 COL10
6 10 0 5 1 2 4 5 2 3
5 7 1 5 8 0 9 8 3 8
5 1 5 5 0 4 8 6 0 3
7 4 0 6 3 8 9 8 3 5
4 7 5 1 7 9 4 6 3 9
0 0 0 7 4 7 9 2 6 1
4 2 10 10 4 4 6 6 6 9
7 0 10 0 2 10 8 0 8 1
0 0 0 0 6 9 1 4 7 8
8 9 5 3 5 8 1 4 1 6
9 5 6 7 1 4 2 5 8 7

Output:

String Count Locations
6 11 A2,H4,D5,H6,I7,G8,H8,I8,E10,J11,C12
10 5 B2,C8,D8,C9,F9
0 15 C2,F3,E4,I4,C5,A7,B7,C7,B9,D9,H9,A10,B10,C10,D10
5 13 D2,H2,A3,D3,A4,C4,D4,J5,C6,C11,E11,B12,H12
1 10 E2,C3,B4,D6,J7,J9,G10,G11,I11,E12
2 6 F2,I2,H7,B8,E9,G12
4 12 G2,F4,B5,A6,G6,E7,A8,E8,F8,H10,H11,F12
3 7 J2,I3,J4,E5,I5,I6,D11
22 K2,L2,K3,L3,K4,L4,K5,L5,K6,L6,K7,L7,K8,L8,K9,L9,K10,L10,K11,L11,K12,L12
7 10 B3,A5,B6,E6,D7,F7,A9,I10,D12,J12
8 12 E3,H3,J3,G4,F5,H5,G9,I9,J10,A11,F11,I12
9 9 G3,G5,F6,J6,G7,J8,F10,B11,A12
  • Related