Вопрос по google-apps-script, google-sheets – Как узнать, объединяются ли ячейки таблицы с помощью скрипта Google Apps?

8

В электронной таблице документов Google. Если клетки А1 и А2 слились, есть ли способ подтвердить слияние с помощью скрипта Google 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();


}

Ваш Ответ

9   ответов
0


https://code.google.com/p/google-apps-script-issues/issues/detail?id=618

But работает только для активного диапазона

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

я написал небольшой инструмент, который берет большую часть работы осла из создания файла значения ключа всех объединенных ячеек из экспортированного HTML.

Вы можете найти это здесь:https://github.com/martinhbramwell/CellMergeWorkAround

Я написал это, потому что у меня небольшой проект, который зависит от возможности полного клонирования диапазонов из одной электронной таблицы в другую. Очевидно, я добавил свой голос к желанию исправить проблему.

(Примечание: я бы добавил это в качестве комментария к правильному ответу, но у меня не было необходимых пунктов.)

1

isPartOfMerge Проверять.

И для любого желающего получить значение объединенной ячейки:

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

Надеюсь, это поможет.

0

это немного запоздалый ответ, так как я не видел эту проблему для новой версии электронных таблиц Google. Но я все еще использую старую версию электронных таблиц для своего проекта. Так что мне нужно было как-то разобраться.

Мне нужно скопировать формат предыдущего столбца для новых столбцов. Это часть кода ниже:

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

Если невозможно скопировать эти ячейки, просто продолжите поиск других.

3

вопрос открыто относительно этого, но оно довольно старое и не имеет активности. Вы должны пометить его (следить за обновлениями и голосовать за него) и оставить комментарий, чтобы посмотреть, сможете ли вы привлечь к себе внимание.

Но то, что я делаю, когда мне нужно убедиться, что объединенные ячейки соответствуют моим желаниям, - это разбить все на части и снова объединить, просто чтобы быть уверенным. Конечно, это не решение, а просто идея, которая может вам подойти.

Энрике, я нашел решение в конце концов. Так что пометил это как правильный ответ. eddyparkinson
0

лист можно загрузить в формате HTML, включая информацию о слитых ячейках. Не очень хорошее решение, но оно работает.

Пример загрузки URL:

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

где gid - номер листа gid.  - требуется вход через интерфейс API Google Drive (подробности см. в учебнике Google DrEdit).

Да, HTML содержит rowspan и colspan для объединенных ячеек. Легко проверить, используйте указанный выше URL, измените ключ, и он будет загружен, если вы вошли в систему. (Gid не обязателен, он выбирает лист). eddyparkinson
А из HTML можно проверить, какие ячейки слиты? Любое понимание этого (например, они устанавливают размер строки)? Я спрашиваю, так как это был ваш первоначальный вопрос.
3

range.isPartOfMerge()

Кажется.isPartOfMerge() методбыл реализован (11 сентября 2016 г.)

Таким образом, вы можете проверить, объединен ли диапазон как таковой:

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

Публикация здесь другого подхода, который мне нравится больше, чем принятый ответ.

Если вы попытаетесь использовать 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 не является частью объединенного диапазона - потому что он проверяет только следующий столбец, используя в качестве ссылки первую связанную строку / столбец.

Хорошая находка. ... Я предполагаю, что это работает с новыми таблицами стилей, а не со старым стилем. Поскольку код в вопросе уже проверяет эту идею и показывает, что она не работает со старой таблицей стилей, но я не проверял ее с новыми таблицами стилей. eddyparkinson
2

Для таких, как я, которые не знали.breakapart() способ расформирования клеток: https://developers.google.com/apps-script/class_range#breakApart

Спасибо Энрике за отзыв!

Похожие вопросы