我怎么知道,如果电子表格单元格使用合并谷歌Apps脚本(How do I know if sprea

2019-06-25 11:59发布

在谷歌文档电子表格。 如果单元格A1和A2合并,是否有以确认他们是合并的方式,使用谷歌Apps脚本?

有气体合并功能https://developers.google.com/apps-script/class_range#merge

但没有功能或示例演示了如何检查是否细胞被合并。

的GetValues等刚刚返回该小区的空字符串。 例如,这是行不通的。

function testMerge() {

  var spreadsheet = SpreadsheetApp.openById('Z3ppTjxNUE........'); 
  var sheet = spreadsheet.getSheets()[0];
  var range = sheet.getRange("A3:A4");
  var values = range.getValues();
  var formulas = range.getFormulasR1C1();
  var formulasA1 = range.getFormulas();

  range = sheet.getRange("A4");
  range.setValue("a");

  range = sheet.getRange("A3:A4");
  var values2 = range.getValues();
  var formulas2 = range.getFormulasR1C1();
  var formulasA12 = range.getFormulas();


  var count = range.getHeight();


}

Answer 1:

range.isPartOfMerge()

It seems the .isPartOfMerge() method was implemented (11 sept 2016).

So you can check if a range is merged as such:

function testMerge() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Sheet1");
  var range = sheet.getRange(1,1,2); // example for cells A1 and A2
  Logger.log(range.isPartOfMerge());
}

Docs https://developers.google.com/apps-script/reference/spreadsheet/range#ispartofmerge


OLD APPROACH

Posting here another approach that I like more than the accepted answer.

If you try to use GAS to store a value in a cell of a merged range, except the first cell, it will not store it.

As such, we can exploit this and attempt to store the value and check if it was stored, using a function similar to this one:

  function isMerged(range){
  try {
    range.getDataSourceUrl()
  } catch (err) {
    throw "isMerged function only works with valid GAS Range objects"
  }
  var sheet = range.getSheet();
  var rangeData = range.getValues();

  var testValue = "testing merge";

  if (rangeData.length == 1 && rangeData[0].length == 1) return false; // we have a single cell. Can't possible be merged :)

  if (rangeData.length == 1) {
    // We have a single row. Which means we're testing a row with multiple columns
    var mainCell=range.getA1Notation().split(":")[0];
    var rowNumber= sheet.getRange(mainCell).getRow();
    var nextColNumber = sheet.getRange(mainCell).getColumn()+1;
    var row = rangeData[0];
    var oldValue = row[1]; // for testing purposes, we're chosing the next possible column

    sheet.getRange(rowNumber,nextColNumber).setValue(testValue);
    if (sheet.getRange(rowNumber,nextColNumber).getValue() !== testValue) {
      return true;
    } else {
      sheet.getRange(rowNumber,nextColNumber).setValue(oldValue);
      return false;
    };
  } else if (rangeData[0].length == 1) {
    // We have multiple rows and a single column.
    var mainCell=range.getA1Notation().split(":")[0];
    var nextRowNumber= sheet.getRange(mainCell).getRow()+1;
    var colNumber = sheet.getRange(mainCell).getColumn();
    var oldValue = rangeData[1][0]; // for testing purposes, we're chosing the next possible row

    sheet.getRange(nextRowNumber,colNumber).setValue(testValue);
    if (sheet.getRange(nextRowNumber,colNumber).getValue() !== testValue) {
      return true;
    } else {
      sheet.getRange(nextRowNumber,colNumber).setValue(oldValue);
      return false;
    };
  } else {
    // We have multiple rows and multiple columns
    var mainCell=range.getA1Notation().split(":")[0];
    var nextRowNumber= sheet.getRange(mainCell).getRow()+1;
    var nextColNumber = sheet.getRange(mainCell).getColumn()+1;
    var oldValue = rangeData[1][1]; // for testing purposes, we're chosing the next possible row and next possible column

    sheet.getRange(nextRowNumber,nextColNumber).setValue(testValue);
    if (sheet.getRange(nextRowNumber,nextColNumber).getValue() !== testValue) {
      return true;
    } else {
      sheet.getRange(nextRowNumber,nextColNumber).setValue(oldValue);
      return false;
    };
  }

  // if none of these checks worked, something's fishy. Either way, return false
  return false
}

I've ran a series of quick tests and it returned true/false accordingly, but there is a limitation that I didn't have time to cover: If you had a merged range like "A1:F1" and you checked the range "A1:G1" (so, one more column), it will return true, even if G1 is not part of the merged range - because it checks only the next column using as reference the first bound row/column.



Answer 2:

这是不可能知道。 有已经是一个问题,关于这个打开,但它是很老,没有活性。 你应该加上星号(跟踪更新和亲切的选它的),并发表评论,看看你能得到一些关注。

但是,当我需要,以确保合并单元格如我希望他们是打散的一切,再次合并,只是要确定我做什么。 当然,这不是一个解决方案,只是一个想法,可能适合你。



Answer 3:

对于那些像我谁不知道.breakapart()方法来取消合并单元格: https://developers.google.com/apps-script/class_range#breakApart

感谢恩里克的小费!



Answer 4:

如果有人在这里需要一个变通对于这个问题,我写了一个小工具,它最繁琐的工作中做出了从出口HTML所有的合并单元格的键值文件。

你可以在这里找到它: https://github.com/martinhbramwell/CellMergeWorkAround

我写的,因为我有一个小项目,取决于是否能够完全复制的范围从一个电子表格到另一个。 很显然,我已经加入我的投票,希望固定的问题。

(注:我会加入这个作为正确答案评论,但缺乏必要的点。)



Answer 5:

似乎有一种变通方法利用这样的合并单元格总是返回一个白色背景的事实。 下面的代码似乎对我的工作; 我会很感激,如果任何人都可以证实。

function testMerged() {
  var WHITE = '#ffffff';
  var NON_WHITE = '#fffffe';
  var range = SpreadsheetApp.getActiveSheet().getDataRange();
  range.setBackground(NON_WHITE);
  range.getBackgrounds().forEach(function (row, rowNum) {
    row.forEach(function (col, colNum) {
      if (col === WHITE) { Logger.log('Cell merged at row ' + rowNum + ' col ' + colNum); }
    });
  });
  range.setBackground(WHITE);  
}


Answer 6:

是的,现在你可以使用isPartOfMerge检查。

而对于任何人希望得到的合并单元格的值:

var value = (cell.isPartOfMerge() ? cell.getMergedRanges()[0].getCell(1,1) : cell).getValue();

希望它能帮助。



Answer 7:

下载为HTML:您可以下载的薄片以HTML,这将包括在合并单元格信息。 没有一个很好的解决方案,但它的工作原理。

例如下载网址:

docs.google.com/feeds/download/spreadsheets/Export?key=* spreadsheetkey * exportFor垫= HTML&GID = 3

其中GID是片材GID号。 - 登录名是否通过谷歌驱动API要求(见谷歌驱动DrEdit教程了解详细信息)



Answer 8:

发现了这个解决方案,张贴在这里:
https://code.google.com/p/google-apps-script-issues/issues/detail?id=618

只适用于有效范围

// This is my function to test the active range is merged or not and return
// true or false by passing active range to it
function ismerge() {
  var spread = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spread.getActiveSheet();
  var last_row = sheet.getActiveRange().getLastRow();
  var last_col = sheet.getActiveRange().getLastColumn();

  Logger.log("Last row: %s", last_row);
  var active_row = sheet.getActiveRange().getRow();
  var active_col = sheet.getActiveRange().getColumn();
  Logger.log("Row: %s", active_row);
  if ( (last_row == active_row) && (last_col == active_col) ) {
    Logger.log("Cell not merged");
    return false;
  }
  else {
    Logger.log("Cell merged");
    return true;
  }
}


Answer 9:

也许这是一个有点晚了,因为答案我没有看到这个问题的谷歌电子表格的新版本。 但是,我仍然使用老版本的电子表格为我的项目。 所以,我需要以某种方式看着办吧。

我需要复制前一列的格式为新列。 这是下面的代码部分:

      // trying to find first column with week day (white background)
      var background = '';
      for(var columnIndex = 3; columnIndex<=columnLetters.length; columnIndex++){
        background = sheet.getRange(1, columnIndex).getBackground();
        if(background == 'white' || background == ''){
          tmpRange = columnLetters[columnIndex]+':'+columnLetters[columnIndex];
          Logger.log('tmpRange: '+tmpRange);
          // workaround to be able to copy format if there is some merged cells
          try{
            Logger.log('try');
            // copy format of previous column
            sheet.getRange(tmpRange).copyTo(
              sheet.getRange('B1'), {formatOnly:true}
            );
          }catch(e) {
            Logger.log('continue');
            continue;
          }
          Logger.log('break');
          break;
        }
      }

所以,在这里最重要的部分是:

try{
  Logger.log('try');
  // copy format of previous column
  sheet.getRange(tmpRange).copyTo(
    sheet.getRange('B1'), {formatOnly:true}
  );
}catch(e) {
  Logger.log('continue');
  continue;
}

如果这是不可能复制这些细胞,它只是继续寻找别人。



文章来源: How do I know if spreadsheet cells are merged using google apps script