-1

I got an array in a single column. I need to reduce fractional part for big numbers like >= 1, keep 1 symbol of fractional part for numbers <1 and >=0,1, keep 2 symbols of fractional part for numbers <0,1 and >=0,01, keep 3 symbols of fractional part for numbers <0,01 and >=0,001. All values can not be rounded, for user view only. For example:

[33800]->33800; 
[468]->468;
[]-> "";
[1170.0000000000002]->1170; 
[2437.5]->2437; 
[2762.5]->2762; 
[322.4]->322; 
[1430.0000000000002]->1430; 
[910]->910; 
[1300]->1300; 
[52]->52; 
[0.023]->0,023; 
[6500]->6500.

I tried to do that but my way is wrong

function recalculate() {
  const sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const sourceValues = sh.getRange(1, 1, sh.getLastRow()).getValues();
  const ratio = sh.getRange(1, 2, sh.getLastRow()).getValues();

  const targetRange = sh.getRange(1, 3, sh.getLastRow());
  let result = [];
  for (let i = 0; i < sourceValues.length; i++){
    result.push([sourceValues[i] * (1 - ratio[i])])
    }
  console.log(result)
  let numFormat = targetRange.setValues(result);
  for (i = 0; i < numFormat.length; i++){
    switch (numFormat[i] > 0) {
      case numFormat < 0.1:
        numFormat[i].setNumberFormat('#,##0.00')
        ;
      case numFormat < 1:
        numFormat[i].setNumberFormat('#,#0.0')
        ;
      default: numFormat[i].setNumberFormat('#0');
      }
  }   
  
}

Can you explain why and where I'm wrong?

Modified script

function recalculate() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sh = ss.getActiveSheet();
  const sourceValues = sh.getRange(1, 1, sh.getLastRow()).getValues();
  const ratio = sh.getRange(1, 2, sh.getLastRow()).getValues();
  const targetRange = sh.getRange(1, 3, sh.getLastRow());
  let result = [];
  console.log(JSON.stringify(sourceValues)) //log: [[13000],[468],[""],[3900],[3250],[3250],[520],[2600],[910],[1300],[52],[0.023],[6500]]
  let value;
  for (let i = 0; i < sourceValues.length; i++){
    value = sourceValues[i][0]
    if (value === "" || value === 0) {
      result.push([""])
    }else{
      result.push([value * (1 - ratio[i])])}
    }
  console.log(JSON.stringify(result)) //log: [[33800],[468],[""],[1170.0000000000002],[2437.5],[2762.5],[322.4],[1430.0000000000002],[910],[1300],[52],[0.023],[6500]]
  let numFormat = targetRange.setValues(result);
  const rangeList = result.reduce((ar, [e], i) => {
  if (e > 1) ar.push(`C${i + 1}`);
  return ar;
  }, []);
  sh.getRangeList(rangeList).setNumberFormat("#");
  ss.setSpreadsheetLocale("fr_CA");
  
}
result on the google sheet

It's what i got

Expected result

expected result

Timogavk
  • 809
  • 1
  • 7
  • 20

1 Answers1

2
  • You want to achieve the number format like 1654.123 -> 1654, 23.456 -> 23, 0.43 -> 0,43, 0.02 -> 0,02, 0.037 -> 0,037 in the cells on Google Spreadsheet.
    • You want to use the values as the number.
  • You want to achieve this using Google Apps Script.

Modification points:

  • In your scrit, numFormat is the range object. Under this situation, when for (i = 0; i < numFormat.length; i++){ is used, the for loop is not correctly run (the script in the for loop is not run.), because numFormat.length is undefined.
  • When you want to change the decimal operator from . to ,, in this case, how about changing the locale of Spreadsheet?
    • At pnuts's answer, Canada (French) is proposed as the locale. Ref

Modified script:

When your script is modified, it becomes as follows.

From:

const sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

To:

const ss = SpreadsheetApp.getActiveSpreadsheet();
const sh = ss.getActiveSheet();

And

From:

for (i = 0; i < numFormat.length; i++){
  switch (numFormat[i] > 0) {
    case numFormat < 0.1:
      numFormat[i].setNumberFormat('#,##0.00')
      ;
    case numFormat < 1:
      numFormat[i].setNumberFormat('#,#0.0')
      ;
    default: numFormat[i].setNumberFormat('#0');
    }
} 

To:

const rangeList = result.reduce((ar, [e], i) => {
  if (e > 1) ar.push(`C${i + 1}`);
  return ar;
}, []);
sh.getRangeList(rangeList).setNumberFormat("#");
ss.setSpreadsheetLocale("fr_CA");
  • From your script, it supposes that the number format of the column "C" is modified.

References:

Added 1:

Although I'm not sure whether this is your current issue, in your script, when the cells are empty in the column "A", the column "C" might not be the empty. If you want to resolve this issue, how about modifying as follows?

From:

result.push([sourceValues[i] * (1 - ratio[i])])

To:

result.push([sourceValues[i][0] ? sourceValues[i][0] * (1 - ratio[i][0]) : ""]);
  • In your script, sourceValues and ratio are 2 dimensional arrays.

Added 2:

Unfortunately, I cannot replicate your situation. For example, when your script and values are used like below script, the following result is retrieved.

33800
468

1170
2438
2763
322
1430
910
1300
52
0,023
6500

Sample script:

const result = [[33800],[468],[""],[1170.0000000000002],[2437.5],[2762.5],[322.4],[1430.0000000000002],[910],[1300],[52],[0.023],[6500]];

const ss = SpreadsheetApp.getActiveSpreadsheet();
const sh = ss.getActiveSheet();
const targetRange = sh.getRange(1, 3, sh.getLastRow());
let numFormat = targetRange.setValues(result);
const rangeList = result.reduce((ar, [e], i) => {
  if (e > 1) ar.push(`C${i + 1}`);
  return ar;
}, []);
sh.getRangeList(rangeList).setNumberFormat("#");
ss.setSpreadsheetLocale("fr_CA");
halfer
  • 19,824
  • 17
  • 99
  • 186
Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Thank you. It works, but not correct for me. I need to reduce fractional part for big numbers like `>= 1`, keep 1 symbol of fractional part for numbers `<1` and `>=0,1`, keep 2 symbols of fractional part for numbers `<0,1` and `>=0,01`, keep 3 symbols of fractional part for numbers `<0,01` and `>=0,001`. All values can not be rounded, for user view only. – Timogavk Mar 31 '20 at 06:22
  • @Timogavk Thank you for replying. I apologize for the inconvenience. I have to apologize for my poor English skill. Unfortunately, I cannot understand about your additional question. So can you provide the sample input and output values you expect? By this, I would like to confirm your additional question. By the way, my modified script is for your sample values in your question. Was my understanding not correct? – Tanaike Mar 31 '20 at 06:31
  • Sorry, my English not well too. So, for example: I got `result` (log`[[33800],[468],[],[1170.0000000000002],[2437.5],[2762.5],[322.4],[1430.0000000000002],[910],[1300],[52],[0.023],[6500]]`) and set it as values to `targetRange`. Need to `setNumberFormat` for each cell depends from values (empties keep empty). – Timogavk Mar 31 '20 at 06:54
  • @Timogavk Thank you for replying. Unfortunately, I cannot still understand about your expected result from your question. This is due to my poor understanding. I deeply apologize for this. So can you provide the sample input and output values you expect? By this, I would like to confirm your additional question. By the way, my modified script is for your sample values in your question. Was my understanding not correct? – Tanaike Mar 31 '20 at 07:01
  • `[33800]->33800; [468]->468; []-> ""; [1170.0000000000002]->1170; [2437.5]->2437; [2762.5]->2762; [322.4]->322; [1430.0000000000002]->1430; [910]->910; [1300]->1300; [52]->52; [0.023]->0,023; [6500]->6500.` – Timogavk Mar 31 '20 at 07:02
  • @Timogavk Thank you for replying. About the values in your replying, the above modified script works for it. So can I ask you about your current issue? By the way, if you cannot understand about my English, please tell me. – Tanaike Mar 31 '20 at 07:11
  • @Timogavk I noticed the situation which might be your current issue. So I added one more modified script. Could you please confirm it? If that was not your current issue, I apologize. – Tanaike Mar 31 '20 at 07:32
  • I added modified script with more explanation – Timogavk Mar 31 '20 at 08:37
  • @Timogavk Thank you for replying. Unfortunately, I cannot replicate your situation. This is due to my poor skill. I deeply apologize for this. I added the script with your values and the result values. Could you please confirm it? So can you provide the detail flow for replicating your situation? By this, I would like to confirm it. – Tanaike Mar 31 '20 at 11:58