28

使用 Google Apps 脚本,有没有办法将 Google 电子表格数组中的值写入范围而无需循环?

我正在考虑类似以下的方法,将一个名称分别放入单元格中A1:A3

function demoWriteFromArray() {

   var employees=["Adam","Barb","Chris"];

   ssActive = SpreadsheetApp.getActiveSheet();

   rgMyRange = ssActive.getRange("A1:A3");

   rgMyRange.setValue(employees)
} 

上面的问题是执行后,A1:A3都包含={"Adam","Barb","Chris"} and display "Adam".

4

9 回答 9

37

Range.setValue() 用于在范围的每个单元格中设置相同的值,而setValues用于将值数组设置到范围内的相应单元格中。请注意,此方法需要一个多维数组,外部数组为行,内部数组为列。因此,在您的情况下,数据应如下所示:

var employees=[["Adam"],["Barb"],["Chris"]];
于 2012-07-19T20:05:00.317 回答
12

最佳答案提供了一种将数组写入 ROW 的良好、紧凑的方式,但写入 COLUMN 有点困难,但由于这是这里的问题,这里有一个快速函数:

function addArrayToSheetColumn(sheet, column, values) {
  const range = [column, "1:", column, values.length].join("");
  const fn = function(v) {
    return [ v ];
  };
  sheet.getRange(range).setValues(values.map(fn));
}

然后在代码中调用该函数的位置,如下所示:

const ss = SpreadsheetApp.getActiveSpreadsheet();
const cache = ss.getSheetByName("_cache_");
const results = ["Adam","Barb","Chris"];
addArrayToSheetColumn(cache, "A", results);
于 2018-12-23T17:37:13.827 回答
9

尽管有点晚了,但有人可能会在某个时候遇到这个答案。我编写了一个将一维数组强制转换为二维数组(矩阵)的函数,这是预期的参数Range.setValues()

// Morphs a 1-d array into a 2-d array for use with Range.setValues([][])
function morphIntoMatrix(array) {

  // Create a new array and set the first row of that array to be the original array
  // This is a sloppy workaround to "morphing" a 1-d array into a 2-d array
  var matrix = new Array();
  matrix[0] = array;

  // "Sanitize" the array by erasing null/"null" values with an empty string ""
  for (var i = 0; i < matrix.length; i ++) {
    for (var j = 0; j < matrix[i].length; j ++) {
      if (matrix[i][j] == null || matrix[i][j] == "null") {
        matrix[i][j] = "";
      }
    }
  }
  return matrix;
}

我不能保证除了基本数据类型之外的任何值都会被保留。清理是必要的,因为 JavaScript 在内部似乎将原始 Array 中的空值替换为null"null"当它被分配为另一个 Array 的元素时。至少,这是我的经验。它虽然有效,但有人可能会发现它很有用。

于 2013-11-26T00:40:02.300 回答
5

我将脚本执行时间提高了 10 倍。它对我有用:

function xabo_api() { 
var sskey = 'KEY-CODE';
var doc = SpreadsheetApp.openById(sskey);    
var conn = Jdbc.getConnection("jdbc:mysql://HOST:PORT/DB", "USER", "PWD");
var stmt = conn.createStatement();

//stmt.setMaxRows(5000);

var rs = stmt.executeQuery("select * from xabo;");
var sheet = doc.setActiveSheet(doc.getSheetByName("xabo laboratories"));

//var cell = doc.getRange('A2');

var row = 0;
var data = [];

while (rs.next()) {
    var rowData = [];
    for (var col = 0; col < rs.getMetaData().getColumnCount(); col++) {
    rowData[col] = (rs.getString(col + 1));
}
data[row] = rowData;
row++;
}

 // My script writes from the second row, as first I use for headers only

 var range = sheet.getRange(2,1,row, col); // check edges or uses a1 notation
 range.setValues(data);

 //   This is what google api doc suggests: It takes 10x more row by row
 //   while (rs.next())
 //   {
 //       for (var col = 0; col < rs.getMetaData().getColumnCount(); col++){
 //         cell.offset(row, col).setValue(rs.getString(col + 1));
 //        }
 //     row++;
 //   } 

 rs.close();
 stmt.close();
 conn.close();
 }
于 2013-10-17T14:43:26.183 回答
4

要包装数组元素以便将它们写入列,您还可以使用 array.forEach()

这个:

var employees=["Adam","Barb","Chris"];

employees.forEach((item,index,array) => array[index] = [item]);

将对您的数组进行以下更改:

["Adam","Barb","Chris"]  -->  [["Adam"],["Barb"],["Chris"]]

有关forEach的更多信息:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

于 2020-11-10T08:14:45.327 回答
0

我在为自己的应用程序研究答案时看到了这个问题。另一种解决方案是使用返回二维数组的自定义函数

这是一个例子。假设“Adam, Barb, Chris; Aaron, Bill, Cindy”是 A1 中的文本。如果您在 B1 中引用自定义函数,则可以使用单独的名称填充 B1:D2 范围。

用 Apps 脚本编写的自定义函数:

function splitNames(names) {
  // you could do any other work necessary here
  var arr = names.split("; ");
  arr[0] = arr[0].split(", ");
  arr[1] = arr[1].split(", ");

  // output should be 2D array where each element of the
  // main array is a range spanning 1 or more columns and
  // one row and each sub array are cells within that range
  return arr;
}

B1 中引用自定义函数的公式: =splitNames(A1)

请注意,如果与 B1 相邻的单元格不为空,则此函数将引发异常。这可以用IFERROR公式处理,也可以在自定义公式中尝试/捕获。

于 2017-12-06T23:20:24.123 回答
0
var employeesRow = ["Adam","Barb","Chris"];    
var employeesCol = employeesRow.map(x => [x]); //where x is your item/element in the array
Logger.log(employeesCol); //expected result [["Adam"],["Barb"],["Chris"]]
于 2021-12-02T17:48:56.690 回答
0

你可以使用推送

var employees=["Adam","Barb","Chris"];
var newarray = [[],[]] ;
newarray[0].push(employees) ;
ssActive = SpreadsheetApp.getActiveSheet();
rgMyRange = ssActive.getRange("A1:A3");
rgMyRange.setValues(newarray)

请注意,您需要将 setValue 更改为 setValues

于 2020-06-20T10:43:18.660 回答
-3

这里有四个功能:(1) 设置值的水平范围 (2) 设置值的垂直范围 (3) 设置值的区域 (4) 复制值的区域并粘贴。

function SetHorizontalRange() {
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var Sheet = Spreadsheet.getActiveSheet();
var row = 1; var numRows = 1;
var column = 1; var numColumns = 3; //("A1:C1")
var Range = Sheet.getRange(row, column, numRows, numColumns)
var values = [[["Adam"],["Barb"],["Chris"]]];


Range.setValues(values)
} 

//////////////////////////////////////////////////////////////////////////////ℱℳ
function SetVerticalRange() {
  var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var Sheet = Spreadsheet.getActiveSheet();
  var row = 1; var numRows = 3; 
  var column = 1; var numColumns = 1; //("A1:A3")
  var Range = Sheet.getRange(row, column, numRows, numColumns)
  var values = [["Adam"],["Barb"],["Chris"]];


  Range.setValues(values)
} 

//////////////////////////////////////////////////////////////////////////////ℱℳ
function SetArea(){
  var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var Sheet = Spreadsheet.getActiveSheet();
  var row = 1; var numRows = 3; 
  var column = 1; var numColumns = 3; //("A1:C3")
  var Range = Sheet.getRange(row, column, numRows, numColumns)
  var values = [[[["Adam"]], [["Barb"]], [["Chris"]]], [[["Barb"]], [["Chris"]], [["Adam"]]], [[["Chris"]], [["Adam"]], [["Barb"]]]];


  Range.setValues(values)
}

//////////////////////////////////////////////////////////////////////////////ℱℳ
function CopyPasteArea(){
  var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var Sheet = Spreadsheet.getActiveSheet();
  var row = 1;  var column = 1;
  var Range = Sheet.getRange(row, column);
  var values = new Array(3);
  for (var y = 0; y < 3; y++) {
    values[y] = new Array(3);
    for (var x = 0; x < 3; x++) {
      values[y][x] = Range.offset(x,y).getValues(); Logger.log(x+' '+y);      
    }
  }


  Sheet.getRange(4, 1, 3, 3).setValues(values); Logger.log(values)
  //https://developers.google.com/apps-script/best_practices
}
于 2013-07-25T14:58:23.977 回答