0

I got this one that looks hairy to me, but I'm confident you guys can crack it while having fun.

The problem:

  1. Check of Company exists in the range
  2. If not, get the latest ID prefix, which looks like AA, AB, etc
  3. Generate a new prefix, which would be the following, according to item above: AC
  4. If that company occurs more than once, then increment the ID number suffix XX001, XX002, etc.

This is what I've come up with so far:

function generateID() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const clientSheet = ss.getSheetByName('Clients');
  const dataRng = clientSheet.getRange(8, 1, clientSheet.getLastRow(), clientSheet.getLastColumn());
  const values = dataRng.getValues();

  const companies = values.map(e => e[0]);//Gets the company for counting

  for (let a = 0; a < values.length; a++) {
    let company = values[a][0];

    //Counts the number of occurrences of that company in the range 
    var companyOccurrences = companies.reduce(function (a, b) {
      return a + (b == company ? 1 : 0);
    }, 0);

    if (companyOccurrences > 1) {
      let clientIdPrefix = values[a][2].substring(0, 2);//Gets the first 2 letters of the existing company's ID

    } else {
      //Generate ID prefix, incrementing on the existing ID Prefixes ('AA', 'AB', 'AC'...);
      let clientIdPrefix = incrementChar(values[a][2].substring(0,1));
      Logger.log('Incremented Prefixes: ' + clientIdPrefix)
    }
  }
}

//Increment passed letter
var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
function incrementChar(c) {
    var index = alphabet.indexOf(c)
    if (index == -1) return -1 // or whatever error value you want
    return alphabet[index + 1 % alphabet.length]
}

...and this is borrowing from tckmn's answer, which deals with one letter only.

This is the expected result: enter image description here

This is the link to the file, should anyone want to give it a shot.

Thank you!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
onit
  • 2,275
  • 11
  • 25
  • Can you provide more details on what is the error you are getting? Is the 3rd column expected to be there or is it for explanation purposes? The prefix AA should be created automatically or is a combination of something else? – Kessy Apr 29 '22 at 13:37
  • Hi, @Kessy! Thanks for replying. 3rd column is an example only. The prefix AA, AB, etc will be created automatically as data come in and, of course, based on the history. – onit Apr 29 '22 at 13:42

1 Answers1

0

In your situation, how about the following modification?

Modified script:

// Please run this function.
function generateID() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName('Clients');
  const dataRng = sheet.getRange(8, 1, sheet.getLastRow() - 7, 1);
  const values = dataRng.getValues();
  let temp = "";
  let init = "";
  let count = 0;
  const res = values.map(([a], i) => {
    count++;
    if (temp != a) {
      count = 1;
      temp = a;
      init = i == 0 ? "AA" : wrapper(init);
    }
    return [`${init}${count.toString().padStart(3, "0")}`];
  });
  console.log(res)
  sheet.getRange(8, 4, res.length, 1).setValues(res);
}

//Increment
var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')
function incrementChar(c) {
  var index = alphabet.indexOf(c)
  if (index == -1) return -1 // or whatever error value you want
  return alphabet[index + 1 % alphabet.length]
}

// I added this function.
function wrapper(str) {
  const [a, b] = [...str];
  const r1 = incrementChar(a);
  const r2 = incrementChar(b);
  return (r2 ? [a, r2] : (r1 ? [r1, "A"] : ["over"])).join("");
}
  • In this modification, I added a wrapper function. This wrapper function uses your showing script of incrementChar.
  • When this script is run to your sample Spreadsheet, console.log(res) shows [["AA001"],["AA002"],["AA003"],["AA004"],["AA005"],["AB001"],["AB002"],["AB003"],["AC001"]]. And this value is put to the column "D".

Note:

  • This modified sample is for your provided Spreadsheet. So please be careful this.

Reference:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Thank you very much! I was looking at what could be changed so that the ID would be given as each row comes in, since this will be run on form submission. Would using ```setValue()``` instead work maybe? – onit Apr 29 '22 at 14:54
  • @santosOnit Thank you for replying. I'm glad your issue was resolved. About your new question of `I was looking at what could be changed so that the ID would be given as each row comes in, since this will be run on form submission. Would using setValue() instead work maybe?`, although I'm not sure about your actual situation, I think that a value can be put to the column "D" of the last row using `setValue`. But, in that case, for example, how about `sheet.getRange(sheet.getLastRow(), 4).setValue(res.pop())` instead of `sheet.getRange(8, 4, res.length, 1).setValues(res)`? – Tanaike Apr 29 '22 at 23:23