Google शीट में एक कस्टम फ़ंक्शन द्वारा पुनर्प्राप्त डेटा ताज़ा करें


92

मैंने एक कस्टम Google Apps स्क्रिप्ट लिखी है जो एक idवेब सेवा (एक मूल्य) से जानकारी प्राप्त करेगी और प्राप्त करेगी ।

मैं एक स्प्रेडशीट में इस स्क्रिप्ट का उपयोग करता हूं, और यह ठीक काम करता है। मेरी समस्या यह है कि ये कीमतें बदलती रहती हैं, और मेरी स्प्रेडशीट अपडेट नहीं होती है।

मैं इसे स्क्रिप्ट को फिर से चलाने और कोशिकाओं को अपडेट करने के लिए कैसे बाध्य कर सकता हूं (बिना मैन्युअल रूप से प्रत्येक सेल पर जा रहा है)?


1
हाँ, यहाँ एक स्पष्टीकरण मैंने इस पर किया: stackoverflow.com/questions/9022984/…
हेनरिक जी। अब्रेउ

मैं अपने स्पष्टीकरण को अपने शोध के हिस्से के रूप में पढ़ता हूं। बहुत मददगार, धन्यवाद। मैंने अपने उत्तर की लिंक जोड़ दी।
tbkn23

समान (परिभाषित और तार्किक, लेकिन कभी-कभी दुर्भाग्यपूर्ण) व्यवहार से सामना करने वालों के लिए, Google इश्यू ट्रैकर में इस सुविधा के अनुरोध को जारी रखने में मदद मिल सकती है: जारीकर्ता
टिमोथी जॉन्स

यहाँ एक सरल उत्तर है जो मैंने किया।
एरियल

असली वर्कअराउंड: stackoverflow.com/a/56802017 और stackoverflow.com/a/61946592
TheMaster

जवाबों:


92

ठीक है, ऐसा लगता है कि मेरी समस्या यह थी कि Google अजीब तरीके से व्यवहार करता है - यह स्क्रिप्ट को फिर से नहीं चलाता है जब तक स्क्रिप्ट पैरामीटर समान होते हैं, यह पिछले रन से कैश्ड परिणामों का उपयोग करता है। इसलिए यह एपीआई से फिर से कनेक्ट नहीं होता है और कीमत को फिर से प्राप्त नहीं करता है, यह बस पिछले स्क्रिप्ट परिणाम देता है जिसे कैश किया गया था।

अधिक जानकारी यहां देखें: https://code.google.com/p/google-apps-script-issues/issues/detail?==8

और यहां: डेटा को सारांशित करने के लिए स्क्रिप्ट अद्यतन नहीं

मेरा समाधान मेरी स्क्रिप्ट में एक और पैरामीटर जोड़ना था, जिसका मैं उपयोग भी नहीं करता। अब, जब आप फ़ंक्शन को पिछले कॉल से भिन्न पैरामीटर के साथ कॉल करते हैं, तो उसे स्क्रिप्ट को फिर से चलाना होगा क्योंकि इन मापदंडों के लिए परिणाम कैश में नहीं होगा।

इसलिए जब भी मैं फ़ंक्शन को कॉल करता हूं, तो अतिरिक्त पैरामीटर के लिए मैं "$ A $ 1" पास करता हूं। मैंने रिफ्रेश नामक एक मेनू आइटम भी बनाया, और जब मैं इसे चलाता हूं, तो यह ए 1 में वर्तमान तिथि और समय डालता है, इसलिए स्क्रिप्ट के सभी कॉल $ A $ 1 के साथ दूसरे पैरामीटर के रूप में पुनर्गणना करने होंगे। यहाँ मेरी स्क्रिप्ट से कुछ कोड है:

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Refresh",
    functionName : "refreshLastUpdate"
  }];
  sheet.addMenu("Refresh", entries);
};

function refreshLastUpdate() {
  SpreadsheetApp.getActiveSpreadsheet().getRange('A1').setValue(new Date().toTimeString());
}

function getPrice(itemId, datetime) {
  var headers =
      {
        "method" : "get",
        "contentType" : "application/json",
        headers : {'Cache-Control' : 'max-age=0'}
      };

  var jsonResponse = UrlFetchApp.fetch("http://someURL?item_id=" + itemId, headers);
  var jsonObj = eval( '(' + jsonResponse + ')' );
  return jsonObj.Price;
  SpreadsheetApp.flush();
}   

और जब मैं एक सेल में आईडी 5 के साथ आइटम की कीमत डालना चाहता हूं, तो मैं निम्नलिखित सूत्र का उपयोग करता हूं:

=getPrice(5, $A$1)

जब मैं कीमतों को ताज़ा करना चाहता हूं, तो मैं बस "ताज़ा करें" -> "ताज़ा करें" मेनू आइटम पर क्लिक करता हूं। याद रखें कि onOpen()स्क्रिप्ट बदलने के बाद आपको स्प्रेडशीट को फिर से लोड करना होगा ।


4
एक अतिरिक्त पैरामीटर के रूप में अब () का उपयोग क्यों नहीं किया जा रहा है?
एडवांस्ड

5
आप देखें, जैसे मेरे कार्य का पुनर्मूल्यांकन नहीं किया जाएगा, क्योंकि यह पैरामीटर नहीं बदला है (अर्थात कोशिकाओं के मान), अब () का पुनर्मूल्यांकन नहीं किया जाएगा क्योंकि इसका कोई पैरामीटर नहीं है, इसलिए यह वापसी मूल्य होगा नहीं बदलते हैं और इसलिए मेरे फ़ंक्शन के पैरामीटर नहीं बदलेंगे। इसके अलावा, अब उपयोग करने से () मेरे कार्य का हर समय पुनर्मूल्यांकन करने का कारण बनेगा, जो यह देखते हुए थोड़ा भारी है कि यह कई HTTP कॉल उत्पन्न करता है ...
tbkn23

2
अच्छा मिल गया। इनपुट के रूप में नामित श्रेणियों का उपयोग करते समय मुझे यह समस्या थी। आपके उत्तर का उपयोग करते हुए, मुझे पता चला कि इनपुट की सीमा के ऊपर एक डमी राशि को पास करने के लिए यह अक्सर अच्छा होता है, जैसे कि "सम (बी: डी)" में, जहाँ बीडी की सीमाएँ कस्टम फ़ंक्शन द्वारा देखी जाती हैं। किसी भी सेल को बदलने से राशि बदल जाएगी और ताज़ा करने के लिए कस्टम फ़ंक्शन। वैसे, ऐसा लगता है कि कस्टम फ़ंक्शन को अनदेखा पैरामीटर घोषित करने की आवश्यकता नहीं है।
शॉन हूवर

1
एक शर्म की बात है कि यह अभी भी सबसे अच्छा समाधान है जो मैंने इस समस्या को पाया है। Google के बजाय हमें विशेष फ़ंक्शन कॉल के लिए कैश को अक्षम करने की अनुमति देने के बजाय, हम मनमाने ढंग से बढ़ाते हैं कि कैश में क्या संग्रहीत किया जा रहा है यह सुनिश्चित करने के लिए कि हमें कैश्ड मूल्य नहीं मिलता है ... फिर भी, पोस्ट के लिए धन्यवाद,
ग्रेडफ़ॉक्स


33

मैं जानता हूं कि यह एक पुराना सवाल है। लेकिन इस पद्धति को बदलाव करने के अलावा किसी भी उपयोगकर्ता कार्रवाई की आवश्यकता नहीं है।

मैंने जो किया वह tbkn23 के समान था।

जिस फ़ंक्शन का मैं पुनर्मूल्यांकन करना चाहता हूं, उसमें एक अतिरिक्त अप्रयुक्त पैरामीटर, $ A $ 1 है। तो फ़ंक्शन कॉल है

=myFunction(firstParam, $A$1)

लेकिन कोड में फ़ंक्शन हस्ताक्षर है

function myFunction(firstParam)

एक ताज़ा समारोह होने के बजाय मैंने इस तरह onEdit (e) फ़ंक्शन का उपयोग किया है

function onEdit(e)
{
   SpreadsheetApp.getActiveSheet().getRange('A1').setValue(Math.random());
}

जब भी स्प्रेडशीट में किसी भी सेल को संपादित किया जाता है, तो यह फ़ंक्शन चालू हो जाता है। तो अब आप एक सेल संपादित करते हैं, एक यादृच्छिक संख्या A1 में रखी जाती है, यह पैरामीटर सूची को tbkn23 के रूप में सुझाता है, जिससे कस्टम फ़ंक्शन का पुनर्मूल्यांकन किया जाता है।


5
बहुत अच्छा काम करता है। नीचे है, पूर्ववत करें (ctrl + z) इतिहास गड़बड़ है।
जॉन

1
एक कष्टप्रद के साथ अच्छी चाल
उल्टा

इस उत्तर के साथ छोटे और पांडित्य संबंधी चेतावनी; अविश्वसनीय रूप से असंभावित घटना में Math.random उसी नंबर को लौटाता है, उस अवसर पर यह अपडेट नहीं होगा, क्योंकि वह विशेष संख्या पहले ही कैश हो चुकी है।
वुडी पायने

12

यह बहुत देर हो चुकी है और मुझे नहीं पता कि यह उपयोगी होगा लेकिन वास्तव में यहां सेटिंग है आप अपने आप NOW()अपडेट कर सकते हैं

यहाँ छवि विवरण दर्ज करें


1
NOW()एक अंतर्निहित फ़ंक्शन है, कस्टम फ़ंक्शन नहीं है।
रुबेन

@ बकवास यह है कि अब आप इसमें शामिल कर सकते हैं () किसी भी कस्टम फ़ंक्शन में फ़ंक्शन जिसे आप इसे अपडेट करना चाहते हैं
थाइना

13
इस समय कस्टम फंक्शन की दलीलें नियतात्मक होनी चाहिए, दूसरे शब्दों में, वे तर्क के रूप में अब () नहीं करते हैं। डेवलपर्स
Rubén

3
यदि आप कस्टम फ़ंक्शन के अंदर अब () का उपयोग करने का प्रयास करते हैं तो यह एक त्रुटि फेंकता है
स्टेफानो गियाकॉन

6

यदि आपका कस्टम फ़ंक्शन किसी विशिष्ट कॉलम के अंदर है, तो बस उस कॉलम द्वारा अपनी स्प्रेडशीट ऑर्डर करें।

आदेश देने वाली कार्रवाई डेटा को ताज़ा करने के लिए मजबूर करती है, जो एक बार में उस कॉलम की सभी पंक्तियों के लिए आपके कस्टम फ़ंक्शन को आमंत्रित करती है।


1

यह एक सुपर पुराना धागा हो सकता है लेकिन ऐसा करने के लिए किसी के लिए उपयोगी हो सकता है, जैसा कि मैं अभी था।

Lexi की स्क्रिप्ट के अनुसार काम करना, यह वर्तमान शीट्स के साथ अब काम नहीं करता था, लेकिन अगर मैं अपने फ़ंक्शन में एक पैरामीटर के रूप में डमी चर को जोड़ता हूं (वास्तव में फ़ंक्शन के अंदर इसका उपयोग करने की कोई आवश्यकता नहीं है), यह वास्तव में होगा पृष्ठ को फिर से ताज़ा करने के लिए Google शीट को बाध्य करें।

तो, घोषणा की तरह: फ़ंक्शन myFunction (firstParam, dummy) और फिर इसे कॉल करना जैसा कि सुझाया गया है। मेरे लिए वह काम कर गया।

इसके अलावा, यदि यह आपके सभी चादरों पर एक यादृच्छिक चर के लिए एक उपद्रव है जिसे आप संपादित करते हैं, तो एक शीट तक सीमित करने का एक आसान उपाय इस प्रकार है:

function onEdit(e)
{
  e.source.getSheetByName('THESHEETNAME').getRange('J1').setValue(Math.random());
}

1
@ बकवास यह बहुत समान है लेकिन एक अच्छा उपद्रव के साथ; सक्रिय शीट का उपयोग करने के बजाय यह एक परिभाषित शीट नाम का उपयोग करता है, जो आपके इतिहास को बेहतर
जोनास डी।

1

स्क्रिप्ट तर्क:

  • कस्टम फ़ंक्शंस तब तक अपडेट नहीं होते जब तक कि यह तर्क नहीं बदलता।
  • टेक्स्टफ़ाइंडर का उपयोग करके स्प्रेडशीट में सभी कस्टम फ़ंक्शंस के सभी तर्कों को बदलने के लिए एक ऑनचेंज ट्रिगर बनाएं

स्निपेट:

/*@customfunction*/
function sheetNames(e) {
  return SpreadsheetApp.getActive()
    .getSheets()
    .map(function(sheet) {
      return sheet.getName();
    });
}

/*Create a installable trigger to listen to grid changes on the sheet*/
function onChange(e) {
  if (!/GRID/.test(e.changeType)) return; //Listen only to grid change
  SpreadsheetApp.getActive()
    .createTextFinder('=SHEETNAMES\\([^)]*\\)')
    .matchFormulaText(true)
    .matchCase(false)
    .useRegularExpression(true)
    .replaceAllWith(
      '=SHEETNAMES(' + (Math.floor(Math.random() * 500) + 1) + ')'
    );
}

पढ़ने के लिए:


1

जैसा कि पहले उल्लेख किया:

कस्टम फ़ंक्शंस तब तक अपडेट नहीं होते जब तक कि यह तर्क नहीं बदलता।

संभव समाधान एकल कक्ष में एक चेकबॉक्स बनाना और कस्टम फ़ंक्शन के लिए इस सेल का उपयोग तर्क के रूप में करना है:

  1. एक चेकबॉक्स बनाएँ: नि: शुल्क सेल चुनें [A1], [इन्सर्ट]> [चेकबॉक्स] पर जाएँ
  2. इस सेल को एक तर्क दें: =myFunction(A1)
  3. सूत्र को ताज़ा करने के लिए चेकबॉक्स पर क्लिक करें

-3

यदि आपने एक कस्टम फ़ंक्शन लिखा है और इसे अपनी स्प्रेडशीट में एक सूत्र के रूप में उपयोग किया है, तो हर बार जब आप स्प्रेडशीट खोलते हैं या कोई संदर्भ कक्ष संशोधित किया जाता है, तो फॉर्मूला पुनर्गणित होता है।

यदि आप स्प्रेडशीट को बस घूरते रहना चाहते हैं और इसके मूल्यों को बदलना चाहते हैं, तो एक समयबद्ध ट्रिगर जोड़ने पर विचार करें जो कोशिकाओं को अपडेट करेगा। यहां ट्रिगर्स के बारे में और पढ़ें


10
यह बहुत अच्छा होगा, सिवाय इसके कि यह काम नहीं करता ... पृष्ठ को पुनः लोड करने से मान ताज़ा नहीं होते। इसके अलावा, सेल को हटाना और समान फ़ंक्शन कॉल को फिर से दर्ज करना, अभी भी पुराना मूल्य रखता है। अगर मैं एक ही फ़ंक्शन को किसी अन्य सेल से बिल्कुल कॉल करता हूं, तो यह नया मान दिखाएगा, लेकिन पुराने सेल में नहीं।
tbkn23 12
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.