4

在操作(复制/移动)包含合并单元格的范围时,我总是收到错误“您的粘贴与合并的单元格重叠。请取消合并单元格,然后重试”。但是,当尝试使用 取消合并范围内的单元格时Range#breakApart,我收到另一个错误:“无法合并选定的单元格。”,这更加令人困惑,因为我没有尝试合并任何内容,我只是想打破细胞分开。

4

4 回答 4

6

结果breakApart只有当它被调用的范围包含所有合并的单元格时才有效,而不仅仅是合并区域的一部分。

这不会太糟糕。一旦您意识到 API 中无法获取合并单元格的范围,问题就开始了。所以解决这个问题的最好方法(到目前为止我发现)只是轻轻地扩大你的范围,直到没有错误发生:

var breakRange = myRange;
for(;;) {
  try {
    breakRange.breakApart();
    break;
  } catch(e) {
    breakRange = mySheet.getRange(
      breakRange.getRowIndex(),
      breakRange.getColumnIndex(),
      Math.min(
        breakRange.getHeight()+5,
        mySheet.getMaxRows()-breakRange.getRowIndex()+1
      ),
      Math.min(
        breakRange.getWidth()+5,
        mySheet.getMaxColumns()-breakRange.getColumnIndex()+1
      )
    );
  }
}

(我添加了五行/列而不是一个,因为获取范围似乎是一个相当昂贵的过程)。只要您在扩展搜索区域时没有添加其他合并的单元格,这就会很好地工作。

当涉及到电子表格中的合并单元格时,Google Apps Scripts API 从根本上至少在以下方面被破坏:

  1. 无法在工作表/范围中获取合并单元格范围的数组。
  2. 应该有一种方法可以查看哪些单元格已被拆分(breakApart仅返回“用于链接”的原始范围)。这使得无法拆分合并,然后让每个单元格包含原始合并单元格的内容。
  3. 尝试breakApart在仅包含合并单元格的一部分的范围内使用仍应拆分整个合并而不是引发异常。

总而言之,目前的 API 仅适用于脚本作者自己可以完全控制其布局和使用的电子表格。

于 2013-03-15T20:33:35.053 回答
1

此函数拆分与提供的单元格或范围部分相交的合并单元格的范围。它使用表格高级服务来识别给定表格中的所有合并范围,正如 Adam Morris ( @clssrmtechtools ) 在此线程中所建议的那样。

演示电子表格在这里

/** 
* Breaks apart merged cells in range
* @param {sheet} sheet Sheet of range
* @param {range} rangeToSplit Cell or cells that intersect with whole merged range
*/
function breakApartAux(sheet, rangeToSplit) {

  // Current spreadsheet & sheet
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let activeSSId = ss.getId();
  let activeSId = sheet.getSheetId();

  // Get sheet's merges using advanced sheets service
  let merges = Sheets.Spreadsheets.get(activeSSId).sheets.find(s => s.properties.sheetId == activeSId).merges;

  if (merges == undefined) SpreadsheetApp.getUi().alert('No merged cells found in sheet.');
  else {

    // Logger.log(merges);

    // Cells to merge R/C
    let rowS = rangeToSplit.getRow();
    let rowE = rowS + rangeToSplit.getNumRows() - 1;
    let colS = rangeToSplit.getColumn();
    let colE = colS + rangeToSplit.getNumColumns() - 1;

    // Find overlapping merged range
    // Advanced service merged ranges start in 0 and are right-open [..)
    let merge = merges.find(m => {
                            let mRowS = m.startRowIndex + 1;
                            let mRowE = m.endRowIndex;
                            let mColS = m.startColumnIndex + 1;
                            let mColE = m.endColumnIndex;

                            // Check for overlapping
                            return ((rowS >= mRowS && rowS <= mRowE)  || 
                                    (rowE <= mRowE && rowE >= mRowS)  ||
                                    (rowS < mRowS && rowE > mRowE)) &&
                                   ((colS >= mColS && colS <= mColE)  ||
                                    (colE <= mColE && colE >= mColS)  ||
                                    (colS < mColS && colE > mColE));
    })

    // Overlapping range?
    if (merge == undefined) SpreadsheetApp.getUi().alert('No merged cells found in specified range.');
    else {
      // Break apart whole range
      ss.getActiveSheet().getRange(merge.startRowIndex + 1,
                                   merge.startColumnIndex + 1,
                                   merge.endRowIndex - merge.startRowIndex,
                                   merge.endColumnIndex - merge.startColumnIndex).breakApart();
    }
  }

}
于 2020-04-24T13:54:56.090 回答
0

受拉斐尔回答的启发,这是如何取消合并工作表中的所有单元格。这是我用于合并具有相邻空值的单元格的数据导入的内容,即我将单元格 a1 与单元格 b1 取消合并,其中 a1 有一个值而 b1 没有:

function unmergeSheet() {

let mySheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
let myRange = mySheet.getDataRange()
myRange.breakApart();
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
}

更新了 Juuso Nykänen 的建议

于 2020-04-24T06:30:22.417 回答
0

这是我发现的最简单的方法:

function unmerge() {
  var sheetName = 'Sheet1';   // Change!
  var a1Notation = 'A1:B15';  // Change!  
  var range = SpreadsheetApp.getActive().getSheetByName(sheetName).getRange(a1Notation);  
  var mergedRanges = range.getMergedRanges();
  for (var i = 0; i < mergedRanges.length; i++)
  {
    mergedRanges[i].breakApart();
  }
}
于 2020-06-16T06:14:38.017 回答