如何在Google Apps脚本

时间:2017-07-25 01:31:59

标签: google-apps-script google-sheets gs-conditional-formatting

我需要一种方法来通过运行脚本来删除所有条件格式(我的客户端将使用这个,并且他不想重复删除大量电子表格中每个工作表的条件格式的过程文件)。

有没有办法通过Google Apps脚本执行此操作?我所看到的只是.clearFormat(),遗憾的是它清除了所有格式,其中很多都不应删除(例如,字体颜色,bg颜色,字体,字体粗细,字体旋转,单元格轮廓)

如何以每个电子表格文件只需按一个按钮的方式执行此操作?

6 个答案:

答案 0 :(得分:4)

这可以通过Google Sheets API v4进行,Apps脚本可以通过Advanced Sheets Service访问(请注意,必须在使用前启用它,如链接页面所指示的那样)。这是一个脚本,它删除当前电子表格Sheet1中的所有条件格式规则(您需要循环遍历表格等)。

function clearSheet() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ssId = ss.getId();
  var sheet = ss.getSheetByName("Sheet1");
  var sheetId = sheet.getSheetId(); 
  var format_req = {
    "requests": [{
      "deleteConditionalFormatRule": { 
        "index": 0,
        "sheetId": sheetId
      }
    }]
  };
  var string_req = JSON.stringify(format_req);
  while (true) {
    try {
      Sheets.Spreadsheets.batchUpdate(string_req, ssId);
    }
    catch(e) {
      break;
    }
  }
}

每个条件格式规则都有一个基于0的“索引”。删除索引为0的规则会导致其他索引减少1.因此循环继续删除index = 0规则,直到没有索引为止,并且抛出错误(并且捕获,退出循环)。

这是一种发送请求的奇怪方式:我更愿意发送一个这样的批处理请求:

  var format_req = {
    "requests": [
    {
      "deleteConditionalFormatRule": { 
        "index": 0,
        "sheetId": sheetId
      }
    },
    {
      "deleteConditionalFormatRule": { 
        "index": 1,
        "sheetId": sheetId
      }
    }]
  };

但要做到这一点,必须知道有多少条件格式规则(我不知道怎么会发现)。如果要求删除的规则多于工作表中存在的规则,则整个请求将失败,并且不会删除任何内容。

没有高级服务

使用普通的Apps脚本,最好的可以做到这一点:

  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getRange(1, 1, sheet.getMaxRows(), sheet.getMaxColumns());
  var backgrounds = range.getBackgrounds(); 
  var fontColors = range.getFontColor(); 
  var fontFamilies = range.getFontFamilies();
  // ... other get methods from https://developers.google.com/apps-script/reference/spreadsheet/range 

  // tricky part: modify the backgrounds, replacing the colors used in conditional formatting by white 

  range.clearFormat();
  range.setBackgrounds(backgrounds)
       .setFontColors(fontColors)
       .setFontFamilies(fontFamilies)
    // .set  other things

这里我假设条件格式仅影响单元格背景。如果一个人无法过滤背景颜色(这需要确切知道条件格式规则中使用了什么颜色),条件格式的效果将变为普通的背景颜色,这是非常不可取的......放弃设置可能会更好背景颜色。

答案 1 :(得分:2)

Google Apps脚本现在支持使用clearConditionalFormatRules

删除条件格式
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clearConditionalFormatRules();

https://developers.google.com/apps-script/reference/spreadsheet/sheet#clearconditionalformatrules

答案 2 :(得分:1)

所以在我评论 if ....

之后
  

但要做到这一点,必须知道有多少条件格式规则(我不知道怎么会发现)

决定扩展他的代码:

function get_clear_Formatting() {

 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var ssId = ss.getId();

// 1部分 - 获取活动电子表格中所有工作表的条件格式设置数据

 var params = {
  'fields': "sheets(properties(title,sheetId),conditionalFormats)"
 };

 var getFormatResult = Sheets.Spreadsheets.get(
   ssId,
   params
 );

  var sheets = getFormatResult.sheets;

  var ConditionalFormatIndex = {
      "sheetID" : [],
      "sheetTitle" : [],
      "formatRulesCount" : []
      }

  for (var i = 0; i < sheets.length; i++) {
    ConditionalFormatIndex.sheetID[i]          = sheets[i].properties.sheetId;
    ConditionalFormatIndex.sheetTitle[i]       = sheets[i].properties.title
    ConditionalFormatIndex.formatRulesCount[i] = (sheets[i].conditionalFormats) ?
                                                  sheets[i].conditionalFormats.length :
                                                  0;
  }

// 2部分 - 清除活动电子表格中所有工作表中的所有条件格式

  var ClearFormat_req = []

  for (var i = 0; i < ConditionalFormatIndex.sheetID.length; i++) {
    if ( ConditionalFormatIndex.formatRulesCount[i] ) {
      for (var cf = 0; cf < ConditionalFormatIndex.formatRulesCount[i]; cf++) {

        ClearFormat_req.push(
          {
            "deleteConditionalFormatRule": { 
              "index": 0,
              "sheetId": ConditionalFormatIndex.sheetID[i]
            }
          }); 
      }
    };  
  }

  Sheets.Spreadsheets.batchUpdate({'requests': ClearFormat_req}, ssId);

}

答案 3 :(得分:0)

  1. 复制没有任何条件格式的单元格。
  2. 选择要从中删除条件格式的单元格。
  3. 编辑->特殊粘贴->仅粘贴条件格式。

答案 4 :(得分:0)

有点晚了,但是我找到了一种方法,如果可以的话可以帮助别人。 删除与参数相交的范围上的所有条件格式 然后保持其他所有条件格式不变(实际上是:重建它)。

function test(){

  var sh=shWork;//define your sheet
  var r= sh.getRange("A3:A6");//example
  clearEveryConditionalFormattingOnRange(sh,r)

}

function clearEveryConditionalFormattingOnRange(sh,r){  
  //build a parallel rules at looping on initial rule, in order to rebuild it without unwanted elements

  //get rules
  var rules=sh.getConditionalFormatRules();

  //create new rules
  var a_newRules= new Array();

  //loop on rules
  for (var i=0;i<rules.length;i++){

    //create new currentRanges
    var a_newCurrentRanges=new Array();

    //loop on ranges from rule
    var currentRule=rules[i];
    var currentRanges=currentRule.getRanges();
    for (var j=0;j<currentRanges.length;j++){

      var currentRange=currentRanges[j];
      var testIfIntersect_OK=RangeIntersect(r,currentRange);

      //add this range to a_newCurrentRanges
      if (!testIfIntersect_OK){        
        a_newCurrentRanges.push(currentRange);        
      }//if (testIfIntersect_OK){

    }//for (var j=0;j<currentRanges.length;j++){

    //create then add new rule to a_newRules
    if (a_newCurrentRanges.length>0){

      var a_newRule = SpreadsheetApp.newConditionalFormatRule()
      .whenFormulaSatisfied(currentRule.getBooleanCondition().getCriteriaValues())
      .setBackground(currentRule.getBooleanCondition().getBackground())
      .setRanges(a_newCurrentRanges)
      .build();     
      a_newRules.push(a_newRule);

    }//if (a_newCurrentRanges.length>0){

  }//for (var i=0;i<rules.lengthi++){

  sh.setConditionalFormatRules(a_newRules);

}

//returns true if intersection between range1 and range2
function RangeIntersect(R1, R2) {

  var LR1 = R1.getLastRow();
  var Ro2 = R2.getRow();
  if (LR1 < Ro2) return false;


  var LR2 = R2.getLastRow();
  var Ro1 = R1.getRow();
  if (LR2 < Ro1) return false;

  var LC1 = R1.getLastColumn();
  var C2 = R2.getColumn();
  if (LC1 < C2) return false;

  var LC2 = R2.getLastColumn();
  var C1 = R1.getColumn();
  if (LC2 < C1) return false;

  return true;

}

答案 5 :(得分:0)

我最终根据David Friedman的答案找到了解决方案。该脚本仅从一列(D)中成功删除了条件格式,而其他列中的条件格式则保持不变。

// clearConditionalFormat
// Data must have header row that does NOT have conditional formatting
// Otherwise you must identify some other cell on the sheet that does not 
//                 have conditional formatting

function test(){
var sheetName = "Sheet13";   // replace with your sheet's name
var rangeText = "D3:D";      // replace with the your range
clearConditionalFormat(rangeText,sheetName);
};


function clearConditionalFormat(rangeText,sheetName){
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var rangeText = rangeText.toString().toUpperCase();
var range =  ss.getRange(rangeText).activate();

var rangeTextSplit = rangeText.split(":");               
     // example: returns  AA22 from AA22:AZ37
var rangeFirstLetter = rangeTextSplit[0].replace(/[0-9]+/g, ""); 
    // example: returns  AA from AA22
var rangeRowNum1 = rangeTextSplit[0].replace(/[A-Z]+/g, "")*1; 
    // example: returns the 22 of AA22:AZ37
var rangeHeaderText = rangeFirstLetter + (rangeRowNum1 - 1);

sheet.getRange(rangeHeaderText)
    .copyTo(range,SpreadsheetApp.CopyPasteType
    .PASTE_CONDITIONAL_FORMATTING, false);
 };