在Google电子表格中移动列

时间:2014-01-15 18:08:58

标签: javascript google-apps-script google-sheets

现在我觉得我在这个网站上问了太多问题:),但好像没有问过这个问题。如果他们这样做,请将我链接到那里。

我只想将特定列移动到同一工作表中的另一个位置(在另一列之前或之后)。我看到了隐藏,插入,删除等选项。但是有些东西像移动一样重要,我看不到。

我是否真的需要获取列数据的范围然后复制它,删除列,在我想要的位置插入列,获取范围,然后粘贴数据..?

示例:

Col A  B  C  D  E  F  G  H
    1  2  3  4  5  6  7  8
    9  10 11 12 13 14 15 16

将列B移至G之前说:

Col A  B  C  D  E  F  G  H
    1  3  4  5  6  2  7  8
    9  11 12 13 14 10 15 16

3 个答案:

答案 0 :(得分:3)

这种方法比使用SpreadsheetApp方法快得多。您可以立即获取整张表的副本,在内存中进行修改,然后将修改后的数据写回来。而不是复制/删除/插入/粘贴操作。

我们从moveColumn()函数开始,该函数与ssurendr的答案具有相同的签名。但是,它的工作只是读取电子表格数据,将其传递给一般的javascript函数进行操作,然后将结果写回工作表。

/**
 * Move column in current spreadsheet
 *
 * @param {int}   iniCol  Source column index (1-based)
 * @param {int}   finCol    Destination column index (1-based)
 */
function moveColumn(iniCol, finCol) {
  var dataRange = SpreadsheetApp.getActiveSheet().getDataRange();
  var data = arrayMoveColumn( dataRange.getValues(), iniCol - 1, finCol - 1 );
  dataRange.setValues(data);
}

下一个功能arrayMoveColumn()并非特定于Google电子表格。它将在任何二维数组中移动一列。 Javascript数组从0开始编制索引,而Spreadsheet方法使用1-based索引。我们添加了一些基本的错误检查,虽然它不是万无一失的。

此函数中的主力是Array.splice()方法,用于删除和插入数组中的元素。

/**
 * Move content of a "column" in a 2-d Array.
 *
 * @param {array}  data  Two-dimensional matrix (array with no null values)
 *                       Array content is changed by this function.
 * @param {int}    from  Source column index (0-based)
 * @param {int}    to    Destination column index (0-based)
 *
 * @return {array}       Resulting array (for chaining)
 */
function arrayMoveColumn( data, from, to ) {
  // Parameter error checking
  if ( !( data instanceof Array && data[0] instanceof Array ) ) throw new TypeError( 'need 2d array' );
  if ( from >= data[0].length || to >= data[0].length ) throw new Error( 'index out of bounds' );

  for (var row=0; row<data.length; row++) {
    var temp = data[row].splice(from, 1);  // take 'from'
    data[row].splice(to, 0, temp[0]);      // put  'to'
  }
  return data;
}

答案 1 :(得分:2)

我想除了我之前说的那样,除此之外别无他法。这是我做的一个功能,如果有些人要求同样的东西需要它。您可以轻松修改它以移动行。我是Apps Script的新手,所以代码可能比这更容易。

function moveColumn(iniCol, finCol) {
  // iniCol - Column of interest. (Integer)
  // finCol - Column where you move your initial column in front of.(Integer)
  // Ex:
  // Col A  B  C  D  E
  //     1  2  3  4  5
  //     6  7  8  9  10
  //     11    12 13 14
  // Want to move Column B in between Column D/E.
  // moveColumn(2,4);
  // Col A  B  C  D  E
  //     1  3  4  2  5
  //     6  8  9  7  10
  //     11 12 13    14
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getActiveSheet();
  var lRow = sh.getMaxRows();
  if (finCol > iniCol) {
    sh.insertColumnAfter(finCol);
    var iniRange = sh.getRange(1, iniCol, lRow);
    var finRange = sh.getRange(1, finCol + 1, lRow);
    iniRange.copyTo(finRange, {contentsOnly:true});
    sh.deleteColumn(iniCol);
  }
  else {
    sh.insertColumnAfter(finCol);
    var iniRange = sh.getRange(1, iniCol + 1, lRow);
    var finRange = sh.getRange(1, finCol + 1, lRow);
    iniRange.copyTo(finRange, {contentsOnly:true});
    sh.deleteColumn(iniCol + 1);    
  }
}

我认为理想情况下,我们在前端谷歌电子表格中可以做的任何事情都可以通过编程方式完成。 (比如移动一列或一行。)

答案 2 :(得分:0)

如果有人想要替换两列:(感谢@ssurendr为基础)

function replaceColumn(Col1, Col2) {
// Ex:
// Col A  B  C  D  E
//     1  2  3  4  5
//     6  7  8  9  10
//     11    12 13 14
// Want to replace Column B & D.
// moveColumn(2,4);
// Col A  D  C  B  E
//     1  4  3  2  5
//     6  9  8  7  10
//     11 13 12    14
if (Col2 > Col1) {
  sh.insertColumnAfter(Col1);
  var iniAftRa = sh.getRange(1, Col2+1, lRow); 
  var finRange = sh.getRange(1, Col1, lRow);
  var finColAftRange = sh.getRange(1, Col1+1, lRow);
  finRange.copyTo(finColAftRange, {contentsOnly:true});
  iniAftRa.copyTo(finRange, {contentrsOnly:true});
  finColAftRange.copyTo(iniAftRa, {contentrsOnly:true});
  sh.deleteColumn(Col1 + 1);  
} else {
  sh.insertColumnAfter(Col2);
  var iniAftRa = sh.getRange(1, Col1+1, lRow); 
  var finRange = sh.getRange(1, Col2, lRow);
  var finColAftRange = sh.getRange(1, Col2+1, lRow);
  finRange.copyTo(finColAftRange, {contentsOnly:true});
  iniAftRa.copyTo(finRange, {contentrsOnly:true});
  finColAftRange.copyTo(iniAftRa, {contentrsOnly:true});
  sh.deleteColumn(Col2 + 1);    
}
}