避免在forEach循环中向空单元格插入复选框 – Google Apps脚本

huangapple go评论72阅读模式
英文:

Avoid inserting checkbox into empty cells in forEach loop - Google apps script

问题

以下是您要翻译的部分:

"I have a list of ranges where depending on the cell value, a checked checkbox (Completada) or an unchecked checkbox (No completada) should be inserted.

The problem I have is that the script places checkbox in the entire list of ranges, it does not ignore empty cells or cells that do not contain those specific values.

It's probably a very slight problem, but I can't fix it.

Here is a picture of what I need: ibb.co/Fq9ssp8

This is my actual code:

  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const targetSheet = ss.getSheetByName('Calendario');  // Hoja Destino

  var rangesCheckbox = targetSheet.getRangeList(['F6:F98', 'I6:I98', 'L6:L98', 'O6:O98', 'R6:R98', 'U6:U98', 'X6:X98']);
  var rangesCheckboxVal = rangesCheckbox.getRanges();
  
  var c = 'Completada';
  var nc = 'No completada';

  var valores = []
  rangesCheckboxVal.forEach((row)=> {

    if ( row.valueType == SpreadsheetApp.ValueType.CHECKBOX ) return;
    if ( row == '' ) return;

    if ( row == c ){
      valores.push(c);
    } else {
      if ( row == nc ){
      valores push(nc);
      }
    }

  })  

  rangesCheckbox.insertCheckboxes(c, nc);
}
英文:

I have a list of ranges where depending on the cell value, a checked checkbox (Completada) or an unchecked checkbox (No completada) should be inserted.

The problem I have is that the script places checkbox in the entire list of ranges, it does not ignore empty cells or cells that do not contain those specific values.

It's probably a very slight problem, but I can't fix it.

Here is a picture of what I need: ibb.co/Fq9ssp8

This is my actual code:

function checkboxVistaMensual_comparacion() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const targetSheet = ss.getSheetByName('Calendario');  // Hoja Destino

  var rangesCheckbox = targetSheet.getRangeList(['F6:F98', 'I6:I98', 'L6:L98', 'O6:O98', 'R6:R98', 'U6:U98', 'X6:X98']);
  var rangesCheckboxVal = rangesCheckbox.getRanges();
  
  var c = 'Completada';
  var nc = 'No completada';

  var valores = []
  rangesCheckboxVal.forEach((row)=> {

    if ( row.valueType == SpreadsheetApp.ValueType.CHECKBOX ) return;
    if ( row == '' ) return;

    if ( row == c ){
      valores.push(c);
    } else {
      if ( row == nc ){
      valores.push(nc);
      }
    }

  })  

  rangesCheckbox.insertCheckboxes(c, nc);
}

答案1

得分: 2

修改点:

  • 我认为在您的脚本中,forEach 循环中没有进行任何处理。我认为这是导致您当前问题“脚本在整个区域中放置复选框”的原因。

  • 我认为在您的情况下,如果您希望跳过包含复选框、"Completada"、"No completada" 或空白的单元格,那么需要进行较大的更改。

  • 并且,在您的情况下,如果使用 RangeList 将复选框放入每个单元格,处理成本会很高。因此,我认为可能需要修改这种情况。

当这些点反映在您的脚本中时,如何看待以下修改?

修改后的脚本:

function checkboxVistaMensual_comparacion() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const targetSheet = ss.getSheetByName('Calendario');
  var rangesCheckbox = targetSheet.getRangeList(['F6:F98', 'I6:I98', 'L6:L98', 'O6:O98', 'R6:R98', 'U6:U98', 'X6:X98']);
  var rangesCheckboxVal = rangesCheckbox.getRanges();
  var c = 'Completada';
  var nc = 'No completada';
  rangesCheckboxVal.forEach(r => {
    var values = r.getValues();
    var dataValidations = r.getDataValidations();
    var { dataValidation, values } = values.reduce((o, [v], i) => {
      if (v.toString() !== "" && ![c, nc].includes(v) && !(dataValidations[i][0] && dataValidations[i][0].getCriteriaType() === SpreadsheetApp.DataValidationCriteria.CHECKBOX)) {
        o.dataValidation.push([SpreadsheetApp.newDataValidation().requireCheckbox(c, nc).build()]);
        o.values.push([null]);
      } else if (dataValidations[i][0] && dataValidations[i][0].getCriteriaType() === SpreadsheetApp.DataValidationCriteria.CHECKBOX) {
        o.dataValidation.push([dataValidations[i][0]]);
        o.values.push([v]);
      } else {
        o.dataValidation.push([null]);
        o.values.push([v]);
      }
      return o;
    }, { dataValidation: [], values: [] });
    r.setValues(values).setDataValidations(dataValidation);
  });
}
  • 在这个脚本中,对于 [‘F6:F98’, ‘I6:I98’, ‘L6:L98’, ‘O6:O98’, ‘R6:R98’, ‘U6:U98’, ‘X6:X98’] 区域的单元格,只有在单元格非空且不包含“Completada”和“No completada”值以及不包含复选框的情况下,才会插入复选框。

  • 为了降低处理成本,本例中使用了 setDataValidations 插入复选框。

注意:

  • 如果您想更改跳过的值,请修改 ![c, nc].includes(v)

参考链接:

补充:

根据您的回复,

这对我也没有用。代码本身是正确的,但我需要的是包含值“Completado”的单元格变为选中的复选框。包含“No completado”值的单元格变为未选中的复选框。空白单元格或其他值的单元格不应插入复选框。根据您当前的代码,没有发生任何变化。

如果我删除指示 ![c, nc].includes(v) 的短语,那么复选框将插入到包含“Completada”和“No completada”值的单元格中,但包含“Completada”值的单元格不会保持选中。这是我需要的图片:ibb.co/Fq9ssp8

以下示例脚本如何?

在您的脚本中,您使用了“Completada”和“No completada”。但是在您的回复中,使用了“Completado”和“No completado”。在这个修改中,使用了“Completada”和“No completada”。请注意这一点。

示例脚本:

function checkboxVistaMensual_comparacion() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const targetSheet = ss.getSheetByName('Calendario');
  var rangesCheckbox = targetSheet.getRangeList(['F6:F98', 'I6:I98', 'L6:L98', 'O6:O98', 'R6:R98', 'U6:U98', 'X6:X98']);
  var rangesCheckboxVal = rangesCheckbox.getRanges();
  var c = 'Completada';
  var nc = 'No completada';
  rangesCheckboxVal.forEach(r => {
    var values = r.getValues();
    var dataValidation = values.map(([v]) => [[c, nc].includes(v) ? SpreadsheetApp.newDataValidation().requireCheckbox(c, nc).build() : null]);
    r.setDataValidations(dataValidation);
  });
}
  • 通过这种方式,来自 [‘F6:F98’, ‘I6:I98’, ‘L6:L98’, ‘O6:O98’, ‘R6:R98’, ‘U6:U98’, ‘X6:X98’] 区域的包含“Completada”和“No completada”值的单元格将转换为复选框。
英文:

Modification points:

  • I think that in your script, no processes are done in the forEach loop. I think that this is the reason for your current issue of the script places checkbox in the entire list of ranges,.
  • I think that in your situation, if you want to insert the checkboxes to the cells of ['F6:F98', 'I6:I98', 'L6:L98', 'O6:O98', 'R6:R98', 'U6:U98', 'X6:X98'] by skipping the cells with the checkbox, "Completada", "No completada" and the empty, the maijor change is required to be done.
  • And, in your situation, if the checkbox is put into each cell using RangeList, the process cost becomes high. So, I thought that it might be required to also modify this situation.

When these points are reflected in your script, how about the following modification?

Modified script:

function checkboxVistaMensual_comparacion() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const targetSheet = ss.getSheetByName('Calendario');
  var rangesCheckbox = targetSheet.getRangeList(['F6:F98', 'I6:I98', 'L6:L98', 'O6:O98', 'R6:R98', 'U6:U98', 'X6:X98']);
  var rangesCheckboxVal = rangesCheckbox.getRanges();
  var c = 'Completada';
  var nc = 'No completada';
  rangesCheckboxVal.forEach(r => {
    var values = r.getValues();
    var dataValidations = r.getDataValidations();
    var { dataValidation, values } = values.reduce((o, [v], i) => {
      if (v.toString() != "" && ![c, nc].includes(v) && !(dataValidations[i][0] && dataValidations[i][0].getCriteriaType() == SpreadsheetApp.DataValidationCriteria.CHECKBOX)) {
        o.dataValidation.push([SpreadsheetApp.newDataValidation().requireCheckbox(c, nc).build()]);
        o.values.push([null]);
      } else if (dataValidations[i][0] && dataValidations[i][0].getCriteriaType() == SpreadsheetApp.DataValidationCriteria.CHECKBOX) {
        o.dataValidation.push([dataValidations[i][0]]);
        o.values.push([v]);
      } else {
        o.dataValidation.push([null]);
        o.values.push([v]);
      }
      return o;
    }, { dataValidation: [], values: [] });
    r.setValues(values).setDataValidations(dataValidation);
  });
}
  • In this script, about the cells of ['F6:F98', 'I6:I98', 'L6:L98', 'O6:O98', 'R6:R98', 'U6:U98', 'X6:X98'], the checkboxes are put into the cells which have not empty, no values of "Completada" and "No completada", and no checkbox.

  • In order to reduce the process cost, in this case, the checkboxes are inserted using setDataValidations.

Note:

  • If you want to change the skipped values, please modify ![c, nc].includes(v).

References:

Added:

From your following reply,

> It doesn't work for me either. The code itself is fine, however what I need is that the cells that contain the value "Completado" become checked checkboxes. Cells containing "No completado" become unchecked checkbox. Cells that are empty or have another value, do not insert checkcbox. With your current code, it does nothing.

> And if I remove the phrase indicating ![c, nc].includes(v), then checkboxes are inserted in the cells with "Completada" and "No completada" value, however, the cells with "Completada" value do not stay checked. Here is a picture of what I need: ibb.co/Fq9ssp8

How about the following sample script?

In your script, you use Completada and No completada. But in your reply, Completado and No completado are used. In this modification, Completada and No completada are used. Please be careful about this.

Sample script:

function checkboxVistaMensual_comparacion() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const targetSheet = ss.getSheetByName('Calendario');
  var rangesCheckbox = targetSheet.getRangeList(['F6:F98', 'I6:I98', 'L6:L98', 'O6:O98', 'R6:R98', 'U6:U98', 'X6:X98']);
  var rangesCheckboxVal = rangesCheckbox.getRanges();
  var c = 'Completada';
  var nc = 'No completada';
  rangesCheckboxVal.forEach(r => {
    var values = r.getValues();
    var dataValidation = values.map(([v]) => [[c, nc].includes(v) ? SpreadsheetApp.newDataValidation().requireCheckbox(c, nc).build() : null]);
    r.setDataValidations(dataValidation);
  });
}
  • By this, the cells with Completada and No completada from ['F6:F98', 'I6:I98', 'L6:L98', 'O6:O98', 'R6:R98', 'U6:U98', 'X6:X98'] are converted to the checkboxes.

huangapple
  • 本文由 发表于 2023年2月24日 05:44:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75550634.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定