16

在 Google 文档电子表格中。如果单元格 A1 和 A2 被合并,有没有办法使用谷歌应用脚​​本来确认它们是否被合并?

GAS 中有一个合并功能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();


}
4

9 回答 9

11

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

对于任何想要获得合并单元格的值的人:

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

希望它有所帮助。

于 2019-01-14T07:50:36.347 回答
7

range.isPartOfMerge()

似乎该.isPartOfMerge()方法已实施(2016 年 9 月 11 日)。

所以你可以检查一个范围是否像这样合并:

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());
}

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


旧方法

在这里发布另一种我更喜欢的方法,而不是接受的答案。

如果您尝试使用 GAS 将值存储在合并范围的单元格中,除了第一个单元格,它不会存储它。

因此,我们可以利用这一点并尝试存储该值并检查它是否已存储,使用类似于此的函数:

  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
}

我已经进行了一系列快速测试并相应地返回了true/ false,但是有一个我没有时间介绍的限制:如果您有一个合并的范围,"A1:F1"并且您检查了范围"A1:G1"(所以,还有一列),true即使 G1 不是合并范围的一部分,它也会返回- 因为它仅使用第一个绑定行/列作为参考来检查下一列。

于 2015-10-08T14:14:18.273 回答
3

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

感谢 Henrique 的提示!

于 2012-08-22T18:45:41.050 回答
2

这是不可能知道的。已经有一个关于这个的问题打开了,但它已经很老了,没有任何活动。你应该给它加星标(以跟踪更新和投票)并发表评论,看看你是否能得到一些关注。

但是,当我需要确保合并的单元格符合我的要求时,我所做的就是将所有内容分开并再次合并,以确保确定。当然,这不是一个解决方案,只是一个可能也适合您的想法。

于 2012-06-14T04:14:59.163 回答
1

如果这里有人需要解决这个问题,我编写了一个小工具,它可以将大部分工作从导出的 HTML 中制作所有合并单元格的键值文件中解脱出来。

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

我写它是因为我有一个小项目,它依赖于能够完全克隆从一个电子表格到另一个电子表格的范围。显然,我已经投票赞成解决这个问题。

(注意:我会将其添加为正确答案的评论,但缺少必要的要点。)

于 2013-08-22T09:21:53.267 回答
1

似乎有一种解决方法可以利用合并单元格总是返回白色背景这一事实。下面的代码似乎对我有用;如果有人可以确认,我将不胜感激。

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);  
}
于 2015-03-25T08:49:35.283 回答
0

下载为 HTML:您可以将工作表下载为 HTML,这将包括合并的单元格信息。不是一个好的解决方案,但它有效。

示例下载地址:

docs.google.com/feeds/download/spreadsheets/Export?key=*电子表格 密钥 *&exportFor‌​mat=html&gid=3

其中 gid 是工作表 gid 编号。- 需要通过 google drive api 登录(详见 google drive DrEdit 教程)

于 2013-03-05T02:59:26.657 回答
0

找到了这个解决方案,发布在这里:
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;
  }
}
于 2013-06-03T07:43:44.497 回答
0

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

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

      // 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;
}

如果无法复制这些单元格,它只会继续搜索其他单元格。

于 2015-04-07T08:44:33.273 回答