मेरे पास लगभग 160 उप शीट वाली एक Google शीट है। सभी प्रश्न "सभी" शीट में हैं और बी कॉलम वास्तविक स्प्रेडशीट नाम है जहां उन्हें होना चाहिए। निम्नलिखित कोड "सभी" स्प्रेडशीट से डेटा पढ़ रहा है और उन्हें वांछित स्प्रेडशीट की अंतिम पंक्ति में पूरी तरह से भेज रहा है लेकिन इसमें बहुत लंबा समय लग रहा है! शायद इसलिए कि इसमें बहुत सारी सबशीट हैं और बार-बार getSheetByName का उपयोग कर रही हैं। अब मैंने सभी सब शीट्स के नाम और आईडी को 'शीट्स' और 'शीटआईडी' एरेज़ में एक ही बार में स्टोर कर लिया है। मैं rangeValues[j][1] और sheetNames[k][0] के बीच तुलना करने की सोच रहा हूं। स्प्रेडशीट का कोड और स्क्रीनशॉट नीचे दिया गया है।

क्या यह एक उपयुक्त तरीका है? कृपया स्क्रिप्ट को तेजी से चलाने में मेरी मदद करें!

var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("All");
var rangeData = sheet.getDataRange();
var lastRow = rangeData.getLastRow();
var searchRange = sheet.getRange(1,1, lastRow, 8);
var curr_sheet;

function send() {
  var rangeValues = searchRange.getValues();
  var sheetNames = new Array();
  var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  for (var i=0 ; i<sheets.length ; i++) sheetNames.push( [ sheets[i].getName() ] );
  //Logger.log (sheetNames.length);
  
  var sheetID = new Array();
  var sheetIDs = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  for (var i=0 ; i<sheetIDs.length ; i++) sheetID.push( [ sheetIDs[i].getSheetId() ] );
  //Logger.log (sheetID.length);

  for ( j = 0 ; j < lastRow; j++)
  {
      for ( k = 0 ; k < sheetNames.length ; k++) //
        {
          if (rangeValues[j][1] === sheetNames[k][0])
            {
              
              var targetSheet = ss.getSheetByName(sheetNames[k][0]); // This line is working but taking very long to complete
              var targetSheet = ss.getSheetByID(sheetIDs[k][0]); // This line is not code just to show what I'm thinking to do.
              
              targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, 8).setValues([rangeValues[j]]);
            }
         }
   }
}

enter image description here

2
Imtiaz 4 जुलाई 2020, 02:38

2 जवाब

सबसे बढ़िया उत्तर

मुझे विश्वास है कि आपका लक्ष्य इस प्रकार है।

  • आप अपनी स्क्रिप्ट की प्रक्रिया लागत को कम करना चाहते हैं।

संशोधन बिंदु:

  • कक्षा स्प्रैडशीट में getSheetByID की कोई विधि नहीं है। इसके द्वारा, मुझे लगता है कि आपके मामले में, निम्न स्क्रिप्ट को हटाया जा सकता है।

      var sheetID = new Array();
      var sheetIDs = SpreadsheetApp.getActiveSpreadsheet().getSheets();
      for (var i=0 ; i<sheetIDs.length ; i++) sheetID.push( [ sheetIDs[i].getSheetId() ] );
    
  • आपकी स्क्रिप्ट में, getSheetByName और getRange(###).setValues(###) लूप में उपयोग किए जाते हैं। और साथ ही, जब शीट एक ही शीट होती है, तब भी प्रत्येक पंक्ति को लूप में setValues का उपयोग करके प्रत्येक पंक्ति में रखा जाता है। इस मामले में, प्रक्रिया लागत अधिक होगी। मुझे लगता है कि ये स्थिति आपके मुद्दे का कारण हो सकती है।

  • सौभाग्य से, आपकी स्थिति में, सभी पत्रक एक ही स्प्रेडशीट में हैं। इसलिए आपकी स्क्रिप्ट की प्रक्रिया लागत को कम करने के लिए, मैं शीट्स एपीआई का उपयोग करके प्रत्येक शीट पर मान डालने का प्रस्ताव करना चाहूंगा। संशोधित लिपि का प्रवाह इस प्रकार है।

    1. स्प्रेडशीट और मान प्राप्त करें। <उल>
    2. यह स्क्रिप्ट आपकी स्क्रिप्ट से है।
  • स्प्रेडशीट में सभी पत्रक प्राप्त करें।
  • जांचें कि कॉलम "बी" से शीट के नाम मौजूद हैं या नहीं।
  • शीट्स एपीआई का उपयोग करके प्रत्येक शीट पर डालने के लिए ऑब्जेक्ट बनाएं।
  • बनाई गई वस्तु का उपयोग करके स्प्रेडशीट्स.वैल्यूज.बैचअपडेट ऑफ शीट्स एपीआई की विधि का अनुरोध करें।
  • जब उपरोक्त बिंदु आपकी लिपि में परिलक्षित होते हैं, तो यह निम्नानुसार हो जाता है।

    संशोधित स्क्रिप्ट:

    कृपया निम्नलिखित स्क्रिप्ट को कॉपी और पेस्ट करें। और, कृपया उन्नत Google सेवाओं पर शीट एपीआई सक्षम करें। और फिर, कृपया स्क्रिप्ट चलाएँ।

    function send() {
      // 1. Retrieve Spreadsheet and values. This script is from your script.
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getSheetByName("All");
      var rangeData = sheet.getDataRange();
      var lastRow = rangeData.getLastRow();
      var searchRange = sheet.getRange(1,1, lastRow, 8);
      var curr_sheet;
      var rangeValues = searchRange.getValues();
      
      // 2. Retrieve all sheets in the Spreadsheet.
      var sheets = ss.getSheets().reduce((o, e) => Object.assign(o, {[e.getSheetName()]: e}), {});
      
      // 3. Check whether the sheet names from the column "B" are existing.
      // 4. Create the object for putting to each sheet using Sheets API.
      var data = rangeValues.reduce((o, e) => {
        if (sheets[e[1]]) {
          if (o[e[1]]) {
            o[e[1]].values.push(e);
          } else {
            o[e[1]] = {range: `'${e[1]}'!A${sheets[e[1]].getLastRow() + 1}`, values: [e]};
          }
        }
        return o;
      }, {});
      
      // 5. Request the method of spreadsheets.values.batchUpdate of Sheets API using the created object.
      Sheets.Spreadsheets.Values.batchUpdate({data: Object.values(data), valueInputOption: "USER_ENTERED"}, ss.getId());
    }
    

    ध्यान दें:

    • इस स्थिति में, जब आप स्क्रिप्ट चलाते हैं, तो एक API कॉल का उपयोग किया जाता है। क्योंकि स्प्रैडशीट्स.वैल्यूज़.बैचअपडेट की विधि का उपयोग किया जाता है।
    • मेरे वातावरण में, जब मैंने एक नमूना स्प्रेडशीट का उपयोग करके उपरोक्त स्क्रिप्ट और आपकी स्क्रिप्ट का परीक्षण किया, तो मैं आपकी स्क्रिप्ट से लगभग 70% की प्रक्रिया लागत में कमी की पुष्टि कर सका।

    सन्दर्भ:

    1
    Tanaike 4 जुलाई 2020, 05:33

    ये कोशिश करें:

    बहुत तेज होना चाहिए

    function send() {
      var ss=SpreadsheetApp.getActive();
      var sh=ss.getSheetByName("All");
      var rg=sh.getRange(1,1,sh.getLastRow(),8);
      var v=rg.getValues();
      var names=[];
      var sheets=ss.getSheets();
      sheets.forEach(function(sh,i){names.push(sh.getName());});
      v.forEach(function(r){
        let idx=names.indexOf(r[1]);//column2
        if(idx!=-1) {
          sheets[idx].getRange(sheets[idx].getLastRow()+1,1,1,8).setValues([r]);
        }   
      });
    }
    
    0
    Cooper 4 जुलाई 2020, 03:26