Saya telah menulis Skrip Google Apps khusus yang akan menerima id
dan mengambil informasi dari layanan web (harga).
Saya menggunakan skrip ini dalam spreadsheet, dan berfungsi dengan baik. Masalah saya adalah harga ini berubah, dan spreadsheet saya tidak diperbarui.
Bagaimana saya bisa memaksanya untuk menjalankan kembali skrip dan memperbarui sel (tanpa memeriksa setiap sel secara manual)?
google-apps-script
google-sheets
custom-function
tbkn23.dll
sumber
sumber
Jawaban:
Oke, sepertinya masalah saya adalah Google berperilaku aneh - tidak menjalankan ulang skrip selama parameter skrip serupa, ia menggunakan hasil yang di-cache dari proses sebelumnya. Oleh karena itu, ia tidak terhubung kembali ke API dan tidak mengambil kembali harga, ia hanya mengembalikan hasil skrip sebelumnya yang di-cache.
Lihat info lebih lanjut di sini: https://code.google.com/p/google-apps-script-issues/issues/detail?id=888
dan di sini: Skrip untuk meringkas data yang tidak diperbarui
Solusi saya adalah menambahkan parameter lain ke skrip saya, yang bahkan tidak saya gunakan. Sekarang, ketika Anda memanggil fungsi dengan parameter yang berbeda dari panggilan sebelumnya, itu harus menjalankan kembali skrip karena hasil untuk parameter ini tidak akan ada di cache.
Jadi setiap kali saya memanggil fungsi tersebut, untuk parameter tambahan saya mengirimkan "$ A $ 1". Saya juga membuat item menu yang disebut refresh, dan ketika saya menjalankannya, itu menempatkan tanggal dan waktu saat ini di A1, maka semua panggilan ke skrip dengan $ A $ 1 sebagai parameter kedua harus dihitung ulang. Berikut beberapa kode dari skrip saya:
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(); }
Dan ketika saya ingin memasukkan harga item dengan ID 5 di sel, saya menggunakan rumus berikut:
=getPrice(5, $A$1)
Ketika saya ingin menyegarkan harga, saya cukup mengklik item menu "Refresh" -> "Refresh". Ingatlah bahwa Anda perlu memuat ulang spreadsheet setelah Anda mengubah
onOpen()
skrip.sumber
Saya tahu ini adalah pertanyaan lama. Tetapi metode ini tidak memerlukan tindakan pengguna apa pun kecuali melakukan perubahan.
Apa yang saya lakukan mirip dengan tbkn23.
Fungsi yang ingin saya evaluasi ulang memiliki parameter ekstra yang tidak digunakan, $ A $ 1. Jadi panggilan fungsinya adalah
=myFunction(firstParam, $A$1)
Tapi di dalam kode, tandatangan fungsinya adalah
function myFunction(firstParam)
Alih-alih memiliki fungsi Refresh, saya telah menggunakan fungsi onEdit (e) seperti ini
function onEdit(e) { SpreadsheetApp.getActiveSheet().getRange('A1').setValue(Math.random()); }
Fungsi ini dipicu setiap kali ada sel dalam spreadsheet yang diedit. Jadi sekarang Anda mengedit sel, nomor acak ditempatkan di A1, ini menyegarkan daftar parameter seperti yang disarankan tbkn23, menyebabkan fungsi kustom dievaluasi ulang.
sumber
Ini sangat terlambat dan saya tidak tahu itu akan berguna tetapi sebenarnya ada pengaturan di sini Anda dapat melakukan
NOW()
pembaruan secara otomatissumber
NOW()
adalah fungsi bawaan, bukan fungsi khusus.Jika fungsi kustom Anda berada di dalam kolom tertentu, cukup urutkan spreadsheet Anda dengan kolom tersebut.
Tindakan pengurutan memaksa penyegaran data, yang memanggil fungsi kustom Anda untuk semua baris kolom itu sekaligus.
sumber
Ini mungkin utas yang sangat lama tetapi mungkin berguna bagi seseorang yang mencoba melakukan ini, seperti yang saya lakukan sekarang.
Bekerja dari skrip Lexi apa adanya, sepertinya tidak berfungsi lagi dengan Sheets saat ini, tetapi jika saya menambahkan variabel dummy ke dalam fungsi saya sebagai parameter (tidak perlu benar-benar menggunakannya di dalam fungsi), itu memang akan paksa lembar google untuk menyegarkan halaman lagi.
Jadi, deklarasi seperti: function myFunction (firstParam, dummy) dan kemudian memanggilnya akan seperti yang telah disarankan. Itu berhasil untuk saya.
Selain itu, jika variabel acak muncul di semua sheet yang Anda edit, cara mudah untuk membatasi ke satu sheet adalah sebagai berikut:
function onEdit(e) { e.source.getSheetByName('THESHEETNAME').getRange('J1').setValue(Math.random()); }
sumber
Logika Skrip:
Potongan:
/*@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) + ')' ); }
Untuk membaca:
sumber
Seperti disebutkan sebelumnya:
Solusi yang mungkin adalah membuat kotak centang dalam satu sel dan menggunakan sel ini sebagai argumen untuk fungsi kustom:
=myFunction(A1)
sumber
Jika Anda telah menulis fungsi kustom dan menggunakannya di spreadsheet Anda sebagai rumus, maka setiap kali Anda membuka spreadsheet atau sel referensi apa pun yang diubah, rumus tersebut dihitung ulang.
Jika Anda ingin terus menatap spreadsheet dan ingin nilainya berubah, pertimbangkan untuk menambahkan pemicu berjangka waktu yang akan memperbarui sel. Baca lebih lanjut tentang pemicu di sini
sumber