首页 文章

Google Apps脚本根据其他工作表的数据生成和填充工作表

提问于
浏览
0

我维护一个跟踪蛋糕订单的电子表格工作簿 . 跟踪表(名为CakeOrders)上的列 Headers (A-H)如下:

(A1) 取件日期, (B1) 客户名称, (C1) 电话号码, (D1) 蛋糕上的文字, (E1) 蛋糕味, (F1) 结霜味, (G1) 水果馅, (H1) 链接到PO

这些 Headers 下方的每行数据对应一个新的采购订单(PO),其中包含唯一的日期,客户名称等.View CakeOrders sheet here.

在同一工作簿中的第二个工作表(名为Admin)上,我有一个运行匹配函数的表,以查找CakeOrders上每个列 Headers 的Column# . 这是设置的,这样我的脚本(调用这些列#s)将保持准确,即使我最终重新排列或添加Columns和新 Headers 到CakeOrders表 - 由于匹配函数,脚本将始终引用相应的列在管理表上 . View the Admin sheet here.

我目前有一个脚本设置,允许我直接从此电子表格生成新的格式化电子表格(设计为空白PO) . 脚本根据所选行中的数据命名新工作表(或PO),并在列H中添加指向新PO的链接 .

我想扩展这个脚本,以便它根据其原始行中的信息填充新PO上的选择单元格 .

有没有人知道一个脚本,它允许我使用来自另一个特定行的数据填充新电子表格的特定单元格?

谢谢!

下面是我当前的脚本,它创建一个新的电子表格,其名称基于行内容,将新工作表存储在特定文件夹中,并包含指向原始行中电子表格的链接 .

function onOpen() { 
  var ss = SpreadsheetApp.getActiveSpreadsheet(); 
  var customMenu = [{name: "Create PO", functionName: "Create"}]; 
   ss.addMenu("Create PO", customMenu); 
};

function Create() {
  var sheet = SpreadsheetApp.getActive().getSheetByName("Admin"); 
  var folderID = sheet.getRange("B2").getValue(); //These are column numbers
  var templateID = sheet.getRange("B3").getValue(); 
  var pickupDate = sheet.getRange("B4").getValue(); 
  var clientName = sheet.getRange("B5").getValue();
  var textOnCake = sheet.getRange("B6").getValue(); 
  var cakeFlavor = sheet.getRange("B7").getValue(); 
  var frostingFlavor = sheet.getRange("B8").getValue(); 
  var fruitFilling = sheet.getRange("B9").getValue(); 
  var POColumn = sheet.getRange("B10").getValue(); 

  var ss = SpreadsheetApp.getActiveSheet(); // Back to CakeOrders sheet
  var cell = ss.getActiveCell(); 
  var row = cell.getRow(); //User has to pick the correct row

  if (row <= 1){ 
   Browser.msgBox("Cannot create new document within the header. Please select the row to which you'd like to add a new PO doc and run the script again.");
    return; 
  }

  try{

  var pickupDateValue = Utilities.formatDate(ss.getRange(row,pickupDate).getValue(), "America/Chicago", "MMddYY"); 
  } 
  catch(e) { 
  var pickupDateValue = ss.getRange(row,pickupDate).getValue();    
  }

  var clientNameValue = ss.getRange(row,clientName).getValue();//getting the actual values now using column numbers from admin sheet
  var textOnCakeValue = ss.getRange(row,textOnCake).getValue(); 
  var cakeFlavorValue = ss.getRange(row,cakeFlavor).getValue(); 
  var frostingFlavorValue = ss.getRange(row,frostingFlavor).getValue(); 
  var fruitFillingValue = ss.getRange(row,fruitFilling).getValue(); 
  var POColumnValue = ss.getRange(row,POColumn).getValue(); 

    if (POColumnValue != ""){ 
   Browser.msgBox("There is already content in the PO column. Please clear the contents and try again.");
    return; 
  }


  if (clientNameValue == "" || textOnCakeValue == "" || cakeFlavor == "" || frostingFlavor == ""|| fruitFilling == ""){ 
   Browser.msgBox("Client Name, Text On Cake, Cake Flavor, Frosting Flavor, and Fruit Filling are required. Please enter a value in each of these columns and then try again.");
    return; 
  }

  var docName = "PO." + pickupDateValue + "." + clientNameValue;   

  var template = DriveApp.getFileById(templateID);  
  var destFolder = DriveApp.getFolderById(folderID); 

  var newDocID = template.makeCopy(docName, destFolder).getId(); 
  var docLink = "https://docs.google.com/spreadsheets/d/" + newDocID; 
  ss.getRange(row,POColumn).setValue(docLink);
}

2 回答

  • 0

    感谢Cooper的帮助 . 根据我的情况,我找到的最佳解决方案是编写绑定到PO模板的第二个脚本(及其重复项) .

    绑定到CakeOrders数据库的第一个脚本继续按原样运行:触发后,它会创建PO模板的副本,根据原始行值对其进行命名,将其存储在指定的文件夹中,并将URL存储到数据库中的PO .

    我添加到PO模板(下面)的脚本允许用户填充基于原始行值的主体 .

    function onOpen() { 
    var spreadsheet = SpreadsheetApp.getActive(); 
    var menuItems = [ {name: 'Fill from Cake Order Form', functionName: 'FillInOrder'}]; 
    spreadsheet.addMenu('Fill In Order', menuItems); 
        } 
    //Creates drop down
    
    function FillInOrder() { 
    var orderSheet = SpreadsheetApp.openByUrl( 'https://docs.google.com/spreadsheets/d/1jX0bT2suuA-4nrYyXNrA5s9gtqxV7hmcgxeb5zUxOeQ/edit#gid=0'); 
    var cakeOrders = orderSheet.getSheetByName('CakeOrders') 
    var orderRow = Browser.inputBox('Fill from CakeOrders', 'Please enter the row number of the order to use' + ' (for example, "2"):', Browser.Buttons.OK_CANCEL); 
    if (orderRow == 'cancel') { return; } var rowNumber = Number(orderRow); if (isNaN(rowNumber) || rowNumber < 2 || rowNumber > cakeOrders.getLastRow()) { 
    Browser.msgBox('Error', Utilities.formatString('Row "%s" is not valid.', orderRow), Browser.Buttons.OK); 
    return; 
        } 
    //Prompts user for row
    var pickupDate = cakeOrders.getRange(rowNumber,1).getValue(); 
    var clientName = cakeOrders.getRange(rowNumber,2).getValue(); 
    var textOnCake = cakeOrders.getRange(rowNumber,3).getValue(); 
    
    var clientSheet = SpreadsheetApp.getActive().getSheetByName("Client"); 
    
    //Gets values from source database
    
    clientSheet.getRange("B8").setValue(pickupDate); 
    clientSheet.getRange("B4").setValue(clientName); 
    clientSheet.getRange("B12").setValue(textOnCake); 
    }
    //Sets values in new PO
    
  • 0

    首先让我说,我并不是说这是唯一的,甚至是最好的方法 . 这就是我做的方式 . 在我生命的大部分时间里,我一直作为一个独立的程序员工作,所以我几乎总是这样做 .

    我可能会修改列 Headers ,使它们成为单个单词Camel Code,并将它们用作关联数组的键 . 因此,当我从一行获取数据时,我从表中构建一个如下所示的数组:

    PickupDate  ClientName    Phone         CakeText             CakeFlavor     FrostingFlavor  FruitFilling    LinktoPO
    4/15/2017   Bart Simpson  123-456-7899  Your Wierd Bart      Dessert Cactus Frozen Spinach  Tomato  
    4/16/2017   Bugs Bunny    987-654-3210  Happy Birthdays Bugs Carrot         Carrot          Carrots
    

    对于看起来像这样的数组:

    var rowA = {PickupData:'4/16/2017',ClientName:'Bugs Bunny',Phone:'987-654-3210',CakeText:'Happy Birthday Bugs',CakeFlavor:'Carrot',FrostingFlavor:'Carrot', FruitFilling:'Carrots',LinkToPO:''}
    

    现在,当您进入PO表单填写数据时,您将能够输入如下数据:

    rowA[PickupData] 
    rowA[ClientName] etc...
    

    键来自列 Headers ,值来自您自己的行 . 所以列的顺序并不重要 . 稍后您可以通过更改列的名称来更改变量的名称 .

    您可以使用file.setContent('string')将其他信息作为字符串存储在文件中,然后使用file.getBlob() . getDataAsString() . split(delimiter)将其拆分并使用您选择的任何分隔符将其拆分 . 我经常选择一些你永远不会想到的奇怪的东西,如'| @@@ |' .

    你的最后一个问题是“有没有人知道一个脚本,它允许我用另一个特定行的数据填充新电子表格的特定单元格?”这是对此的回答 . 对不起,我无法为你提供更多帮助 .

    function copyToNewSS()
    {
      var dstlocdict = {PickupDate:'A1',ClientName:'B2',Phone:'C3',CakeText:'D4',CakeFlavor:'E5',FrostingFlavor:'F6',FruitFilling:'G7',LinktoPO:'H8'}
      var srcss = SpreadsheetApp.getActiveSpreadsheet();
      var srcsht = srcss.getActiveSheet();
      var dstss = SpreadsheetApp.openById('Insert ID of Destination Spreadsheet');
      var dstsht = dstss.getSheetByName('PO');
      var srcrow = srcsht.getActiveCell().getRow();
      if((srcrow - 1)==0 || srcrow > srcsht.getLastRow()){SpreadsheetApp.getUi().alert('Error: Invalid Data Row');return;}
      var srcdatR = srcsht.getDataRange();
      var srcdatA = srcdatR.getValues();
      var srcdatdict = {};
      var srcnumcols = srcsht.getLastColumn();
      var s = '{';
      for(var i = 0;i < srcdatA[srcrow - 1].length; i++)
      {
        srcdatdict[srcdatA[0][i]]= srcdatA[srcrow-1][i];
        if(i>0)s += ', ';
        s += srcdatA[0][i] + ':' + srcdatA[srcrow-1][i];
      }
      myUtilities.dispStatus('Source Data Dictionary for Row ' + srcrow , s, 800, 400)  
      for(var key in srcdatdict)
      {
        dstsht.getRange(dstlocdict[key]).setValue(srcdatdict[key]); 
      }
    }
    

相关问题