我如何知道是否使用谷歌应用程序脚本合并电子表格单元格

时间:2012-06-14 01:26:18

标签: google-apps-script google-sheets

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


}

9 个答案:

答案 0 :(得分:3)

不可能知道这一点。关于此问题已经开了issue,但它已经很老了,没有任何活动。你应该为它加注星标(跟踪更新和投票的类型)并留下评论,看看你是否能得到一些关注。

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

答案 1 :(得分:3)

<强> range.isPartOfMerge()

似乎.isPartOfMerge()方法was implemented(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

OLD APPROACH

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

如果您尝试使用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不是合并范围的一部分 - 因为它仅使用第一个绑定行/列作为参考来检查下一列。

答案 2 :(得分:2)

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

感谢Henrique提示!

答案 3 :(得分:1)

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

您可以在此处找到它:https://github.com/martinhbramwell/CellMergeWorkAround

我写的是因为我有一个小项目,它依赖于能够将范围从一个电子表格完全克隆到另一个电子表格。显然,我已经加入了我的投票,希望修复这个问题。

(注意:我会将此作为对正确答案的评论添加,但缺少必要的分数。)

答案 4 :(得分: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);  
}

答案 5 :(得分:1)

是的,现在您可以使用 Storyboard sb = this.FindResource("FadeAnim") as Storyboard; Storyboard.SetTarget(sb, this.YourButton); sb.Begin(); 进行检查了。

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

isPartOfMerge

希望有帮助。

答案 6 :(得分:0)

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

示例下载网址:

docs.google.com/feeds/download/spreadsheets/Export?key=* spreadsheetkey *&amp; exportFor mat = html&amp; gid = 3

其中gid是工作表gid编号。   - 需要通过google drive api登录(有关详细信息,请参阅google drive DrEdit Tutorial)

答案 7 :(得分: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;
  }
}

答案 8 :(得分: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;
}

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