How can I improve this code to call Google API less times -
i have sync google contacts spreadsheet, have call api may time set values in google spreadsheet, how can overcome problem call google api less times or once ?
var precontacts = group.getcontacts(); var rowno = 2; for(var y = 0; y < precontacts.length; y++) { var fnamecontact = precontacts[y].getgivenname(); var phonenoarray = precontacts[y].getphones(); var phonenocontact = getphonenumbers(phonenoarray); var emailarray = precontacts[y].getemails(); var emailadresscontact = getemailaddresses(emailarray); //var customfieldsarray = precontacts.getcustomfields(); sheettab_bulk_cdb.getrange("j"+rowno).setvalue(emailadresscontact); sheettab_bulk_cdb.getrange("g"+rowno).setvalue(emailadresscontact); sheettab_bulk_cdb.getrange("f"+rowno).setvalue(emailadresscontact); sheettab_bulk_cdb.getrange("a"+rowno).setvalue(emailadresscontact); rowno++; }
the significant optimization available write data spreadsheet using single setvalues()
call instead of many single-cell setvalue()
operations have. read on answer what faster: scriptdb or spreadsheetapp? details.
to take advantage of setvalues()
, though, you'll have re-arrange spreadsheet contact information you're writing contiguous. consider spreadsheet arranged so:
with set up, can collect contact info two-dimensional array, , make single call so:
sheet.getrange(_row_,_col_,data.length,data[0].length).setvalues(data);
... _row_,_col_
top-left corner of range want write data to.
script
here's complete script retrieve contacts group, , populate example spreadsheet. can extended include other contact information.
/** * retrieves contacts group. if groupname isn't passed * parameter, user prompted. */ function getcontactgroup(groupname) { var ss = spreadsheetapp.getactivespreadsheet(); groupname = groupname || browser.inputbox('get contact group', 'group name:', browser.buttons.ok_cancel); if (groupname === 'cancel') { ss.toast('task canceled', 'status', 3); return; } var group = contactsapp.getcontactgroup(groupname); if (!group) { ss.toast('group not found', 'status', 3); return; } else { var data = []; // array hold contact info spreadsheet var contacts = group.getcontacts(); if (contacts.length == 0) { ss.toast('no contacts in group', 'status', 3); return; } else { (var i=0; i<contacts.length; i++) { var contactinfo = [] // build row of contact information contactinfo.push( contacts[i].getfullname() ); contactinfo.push( getphonenumbers(contacts[i].getphones()) ); contactinfo.push( getemailaddresses( contacts[i].getemails()) ); contactinfo.push( contacts[i].getlastupdated() ); // add row data array data.push( contactinfo ); } } } // output contact info spreadsheet in 1 shot. var sheet = ss.getactivesheet(); var headers = 1; // # rows containing headers sheet.getdatarange().offset(headers, 0).clearcontent(); // clear old content sheet.getrange(1+headers,1,data.length,data[0].length).setvalues(data); }; function getphonenumbers( phones ) { // convert array of phones comma-separated string var phonelist = []; (var phone=0; phone < phones.length; phone++) { var phoneentry = phones[phone].getlabel() + ' ' + phones[phone].getphonenumber(); if (phones[phone].isprimary()) { // add primary phone @ front phonelist.unshift(phoneentry); } else { // add other phones @ end phonelist.push(phoneentry); } } return phonelist.join(', '); } function getemailaddresses( emails ) { // convert array of emails comma-separated string var emaillist = []; (var email=0; email < emails.length; email++) { var emailentry = emails[email].getlabel() + ' ' + emails[email].getaddress(); if (emails[email].isprimary()) { // add primary email @ front emaillist.unshift(emailentry); } else { // add other emails @ end emaillist.push(emailentry); } } return emaillist.join(', '); } /** * adds custom menu active spreadsheet */ function onopen() { var sheet = spreadsheetapp.getactivespreadsheet(); var entries = [{ name : "copy contact group sheet", functionname : "getcontactgroup" }]; sheet.addmenu("script center menu", entries); };
script version 2
this isn't efficient previous version, because each column of data written separately. harder maintain , expand upon, because has more code. still simple, more.
the column numbering correct example sheet shown above, need adjusted own spreadsheet.
/** * retrieves contacts group. if groupname isn't passed * parameter, user prompted. * * version 2: version allows columns of contact info * non-contiguous, less efficient version 1. */ function getcontactgroup2(groupname) { var ss = spreadsheetapp.getactivespreadsheet(); groupname = groupname || browser.inputbox('get contact group', 'group name:', browser.buttons.ok_cancel); if (groupname === 'cancel') { ss.toast('task canceled', 'status', 3); return; } var group = contactsapp.getcontactgroup(groupname); if (!group) { ss.toast('group not found', 'status', 3); return; } else { var contactname = []; // arrays hold contact info spreadsheet var contactphone = []; var contactemail = []; var contactlastupdated = []; var contacts = group.getcontacts(); if (contacts.length == 0) { ss.toast('no contacts in group', 'status', 3); return; } else { ss.toast('starting copy', 'status', 3); (var i=0; i<contacts.length; i++) { // record contact information in column arrays contactname.push( [contacts[i].getfullname()] ); contactphone.push( [getphonenumbers(contacts[i].getphones())] ); contactemail.push( [getemailaddresses( contacts[i].getemails())] ); contactlastupdated.push( [contacts[i].getlastupdated()] ); } } } ss.toast('storing sheet', 'status', 3); // output contact info spreadsheet in 1 shot per column. var sheet = ss.getactivesheet(); var headers = 1; // # rows containing headers var columnname = 1, // column numbers receive contact info columnphone = 2, columnemail = 3, columnlastupdated = 4; sheet.getrange(1+headers,columnname,contactname.length,1).setvalues(contactname); sheet.getrange(1+headers,columnphone,contactphone.length,1).setvalues(contactphone); sheet.getrange(1+headers,columnemail,contactemail.length,1).setvalues(contactemail); sheet.getrange(1+headers,columnlastupdated,contactlastupdated.length,1).setvalues(contactlastupdated); ss.toast('operation complete', 'status', 3); };
Comments
Post a Comment