通过应用程序脚本合并单元格时,如何解决此“错误:您必须选择合并范围中的所有单元格才能合并或取消合并它们。”?

问题描述 投票:0回答:1

当多行在相应的列中具有相同的值时,我尝试使用应用程序脚本合并 Google 表格中的单元格,我将它们合并到一列。

就像我通过检查第二列的值(索引 1)来合并其余相应列值一样。如果该列的多行具有相同的值,我想将其余的列值合并到这些行的一个值中。

虽然我无法正确实现该功能,但它的合并功能至少正在执行。但是如果我添加一些新行并尝试执行它,它会抛出这个

Error: You must select all cells in a merged range to merge or unmerge them.

这是原始数据: 原始数据

我想要的结果: 预期结果

但是在应用程序脚本中执行以下函数后,我在第一次执行时得到了这个,之后每次执行都会出现标题为错误的错误! 结果受损

function mergeCustomerOrderRows() {
  const spreadsheetId = "GOOGLE_SHEET_ID";
  const sheetName = "SHEET_NAME";
  const mergeColumns = [0, 1, 2, 3, 4]; // I don't want 'Product ID'(index 5) to be merged

  try {
    const spreadsheet = SpreadsheetApp.openById(spreadsheetId);
    const sheet = spreadsheet.getSheetByName(sheetName);

    if (!sheet) throw new Error(`Sheet "${sheetName}" not found.`);

    const dataRange = sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn());
    const data = dataRange.getValues();
    
    let startRowIndex = 1;
    for (let i = 1; i < data.length; i++) {
      if (data[i][1] === data[i - 1][1]) continue;

      if (startRowIndex < i) {
        mergeColumns.forEach(colIndex => {
          const range = sheet.getRange(startRowIndex + 1, colIndex + 1, i - startRowIndex, 1);
          range.merge();
        });
      }
      startRowIndex = i;
    }

    if (startRowIndex < data.length) {
      mergeColumns.forEach(colIndex => {
        const range = sheet.getRange(startRowIndex+1, colIndex+1, data.length - startRowIndex, 1);
        range.merge();
      });
    }

    SpreadsheetApp.flush();
    Logger.log("Merging completed based on the first column match.");
    return ContentService.createTextOutput("Merged cells successfully based on first column condition");
  } catch (error) {
    Logger.log(`Error: ${error.message}`);
    return ContentService.createTextOutput(`Error: ${error.message}`);
  }
}

哪些改变可以让它按照我想要的方式工作?

google-sheets google-apps-script
1个回答
0
投票

在你的展示脚本中,作为一个简单的修改,下面的修改怎么样?

来自:

const range = sheet.getRange(startRowIndex + 1, colIndex + 1, i - startRowIndex, 1);

致:

const range = sheet.getRange(startRowIndex + 2, colIndex + 1, i - startRowIndex, 1);

注:

作为另一种方法,下面的示例脚本怎么样?

function mergeCustomerOrderRows() {
  const spreadsheetId = "GOOGLE_SHEET_ID";
  const sheetName = "SHEET_NAME";
  const mergeColumns = ["A", "B", "C", "D", "E"];
  const checkCol = 2; // Column "B". This is from your script.

  try {
    const sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName);
    const values = sheet.getDataRange().getValues();
    let temp = "";
    let tempAr = [];
    const ar = [];
    for (let i = 0; i < values.length; i++) {
      const v = values[i][checkCol - 1];
      const row = i + 1;
      if (v == temp) {
        tempAr.push(row);
      } else {
        if (tempAr.length > 0) {
          ar.push(tempAr);
        }
        tempAr = [row];
        temp = v;
      }
    }
    ar.filter(r => r.length > 1).map(r => {
      const start = r.shift();
      const end = r.pop();
      mergeColumns.forEach(m => sheet.getRange(`${m}${start}:${m}${end}`).merge());
    });

    SpreadsheetApp.flush(); // I thought that this line might not be required to be used.
    Logger.log("Merging completed based on the first column match.");
    return ContentService.createTextOutput("Merged cells successfully based on first column condition");
  } catch (error) {
    Logger.log(`Error: ${error.message}`);
    return ContentService.createTextOutput(`Error: ${error.message}`);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.