查看命名范围并将值打印到新工作表

时间:2013-03-19 19:29:40

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

我对JavaScript比较陌生,所以请耐心等待。

我在google电子表格中有一个座位表,用于标记通过指定范围坐在两个相邻单元格中的人员的桌号和姓名。我希望我的代码循环遍历所有命名范围,并获取桌面编号和人员的值,并将其吐入两列中的新工作表 - 一列中的桌面编号和另一列中的用户名。我遇到的一个主要问题是一些桌面编号/用户范围是垂直的(例如:desk_1 = Sheet1!F6:F7,其中F6是桌面编号,F7是用户),有些范围是水平的(例如:desk_2 = Sheet1! G2:H2其中G2是用户,H2是桌号)所以我不确定如何从多个方向搜索。这是我的一些代码,目前无法正常工作。任何建议将不胜感激!!

enter code here
function findSeats() {
var sheet = SpreadsheetApp.getActiveSheet();
var wbk = SpreadsheetApp.getActiveSpreadsheet(); 

var rng_convention = "desk_"; 
var desk_name = rng_convention; 

var users = new Array();

for ( var i = 0; i <= 1000; i++) { 
  desk_name = rng_convention; 
  desk_name = desk_name + i; 

  var rng = wbk.getRangeByName(desk_name); 

if( !rng ) { 
  continue; }
else { 
  var vals = rng.getValues(); 
  var k = 0; 

  if(vals.length == 1) {
    //look left right horizontally for user
    if(vals[0][0] == i) { 
      // create a user for this named range. 
      var user = new Object(); 

      user.name = vals[0][1]; 
      user.position = vals[0][0]; 
      users[k] = user; 
      k++;
    }
    else { 
      //look right left horizontally for user
      if (vals [0][1] == i){
      // create the user for this named range. 
      var user = new Object();

      user.name = vals[0][0]; 
      user.position = vals[0][1]; 
      users[k] = user; 
      k++;
      }
    }
  } 
/*      else {
    /* something is wrong, I need to look up-down, and then down up for users */
  }
 } 
return users; 

};

1 个答案:

答案 0 :(得分:2)

你肯定是在正确的轨道上。你唯一真正的错误是你在循环中设置var k = 0,但试图在同一循环中增加它。结果是你只得到一个用户。

您希望能够确定桌面/用户配对是水平还是垂直排列。要做到这一点,你要检查length返回的二维数组的.getValues(),这样做效果很好。没问题。

在你的问题中,你提到了桌面/用户对的两种安排,但是在你的代码中你会关注四个,因为在你编码的水平方向上,你正在寻找桌面的位置数字,并假设名称在相反的单元格中。这是有效的,只要桌面编号始终与范围名称匹配即可。 (您可以检查该值是否为number。)

所以,这是我为使这项工作所做的改变。

  • 首先,完全摆脱k,并依靠push()构建users数组 - 更简单,更不容易出错。
  • 我将用户对象创建移动到if-then-else块之外,该块用于测试方向,并同时设置桌面编号。 (无需从电子表格中读取该值,因为它已经是循环值。)
  • 我完成了垂直方向的处理,镜像了清理过的水平处理。 (你知道......你可以进一步优化它,但它会失去清晰度。)
  • 添加评论,整理缩进! (实际上,就像我检查代码一样。)

这是生成的功能代码。

function findSeats() {
  var wbk = SpreadsheetApp.getActiveSpreadsheet(); 

  var rng_convention = "desk_"; 
  var desk_name = rng_convention; 

  var users = new Array();

  for ( var i = 0; i <= 1000; i++) { 
    desk_name = rng_convention + i; 

    var rng = wbk.getRangeByName(desk_name); 

    if ( !rng ) { 
      // No matching range name
      continue; 
    }
    else { 
      var vals = rng.getValues(); 

      // create a user for this named range. 
      var user = new Object(); 
      user.position = i; 

      var valsLength = vals.length;
      // Check orientation of the range:
      //    Horizontal...  vals.length == 1 (row)
      //    Vertical means vals.length == 2 (rows)
      if(vals.length == 1) {
        // Check whether we have desk / user, or user / desk
        if(vals[0][0] == i) { 
          // desk / user
          user.name = vals[0][1]; 
        }
        else { 
          // user / desk
          user.name = vals[0][0]; 
        }
      }
      else {
        // vals.length == 2
        // Check whether we have desk / user, or user / desk
        if(vals[0][0] == i) { 
          // desk / user
          user.name = vals[1][0]; 
        }
        else { 
          // user / desk
          user.name = vals[0][0]; 
        }
      }

      // Add this user to our array
      users.push(user);
    }
  }
  // Return array of user objects
  return users; 
};

样本数据

sample data

调试输出

debug output

编辑:在电子表格中记录所有收集的数据

要回答后续问题,可以直截了当地收集所有收集到的桌面和用户信息到电子表格中。要准备.setValues()函数,我们需要将对象转换为二维数组,这很容易。或者,可以重构先前的代码以首先生成数组。

以下是我们如何执行转换,并将所有数据写入工作表。如果命名工作表不存在,我们将首先创建它 - 否则,我们将只替换以前的内容。

// Record all desk / user data to a (new) sheet
function recordAllDeskUsers() {
  var users = findSeats();
  var userArray = new Array();
  userArray.push(["Desk #","User Name"]);

  for (var i in users) {
    var thisUser = [users[i].position,users[i].name];
    userArray.push(thisUser);
  }

  // Open the target sheet - if it doesn't exist, insert it.
  var userSheetName = "All Desks";
  var userSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(userSheetName);
  if (!userSheet) {
    SpreadsheetApp.getActiveSpreadsheet().insertSheet(userSheetName)
    userSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(userSheetName);
  }

  // Clear the sheet, then write our collected values to it.
  userSheet.clear();
  userSheet.getRange(1, 1, userArray.length, userArray[0].length).setValues(userArray);
}