Я сталкиваюсь с проблемой совместного использования сценария с помощью ряда функций, предназначенных для помощи в манипулировании различными копиями одной и той же исходной электронной таблицы Google (у каждого пользователя есть личная копия).
Каждая копия электронной таблицы имеет собственную ограниченную копию сценария, поэтому, если я улучшу какую-либо функцию, мне придется обновить каждую копию сценария.
Чтобы преодолеть эту проблему, я увидел, что можно вызвать библиотеку из вашего скриптового проекта и поместить все общие функции в эту библиотеку. Некоторые ссылки, которые я прочитал:
Как я могу вызвать свой автономный скрипт в моей таблице? ;
Как использовать скрипт приложений Google в нескольких документах ;
Как передать ограниченный скрипт другому пользователю, чтобы он мог добавить его в свои электронные таблицы? ; Распространение скрипта Google Apps и отправка обновлений ;
https://issuetracker.google.com/issues/36755072
Там вы можете увидеть несколько проблем использования этого подхода:
- Чтобы распространять обновления вашей библиотеки (динамически, без необходимости снова прикасаться к пользовательским листам), ее необходимо включить в сценарии с ограниченным листом, используя режим разработки и предоставляя своим пользователям edit доступ к скрипту вашей библиотеки (если у них есть только доступ к просмотру, они используют статическую версию вашей библиотеки).
- Вам необходимо изменить исходный код, ограниченный листом, чтобы функции вызывались с предшествующим именем, используемым для обозначения вашей библиотеки: libraryname.functionName () - может не быть проблемой, но я упоминаю об этом просто на случай, если кто-то другой получает ошибки из-за этого, как я сделал.
- Из моих тестов у меня сложилось впечатление, что код работает намного медленнее при использовании библиотеки, по сравнению с тем же кодом, вставленным в ограниченный листом скрипт.
Поэтому мне интересно, возможно ли включить код каким-либо другим способом, и я нашел несколько комментариев о , использующих eval () для включения кода javascript из внешнего URL :
импорт внешнего javascript в скрипт приложений Google ;
вставить внешний файл javascript в скрипт приложения Google (Документы Google) ;
https://ctrlq.org/code/20380-load-external-javascript-with-eval
По сути, так говорят:
eval(UrlFetchApp.fetch('http://path.to/external/javascript.js').getContentText());
Мои вопросы:
Я не совсем понимаю, как eval () должен работать в приведенных выше примерах. Он предназначен для запуска из скрипта, который запускается на сервере приложений Google? (поэтому мой включенный файл будет по-прежнему вызывать функции SpreadsheetApp. или DriveApp.)
Если код внутри eval () определяет набор функций, они все еще доступны после завершения eval ()? Можем ли мы вызывать их из событий, управляемых пользователем, например, щелкая пункты меню?
А если мы можем их назвать, следует ли обращаться по-особенному? Я не смог этого сделать
Я мог бы просто загрузить новое меню (определенное в remote.js), используя eval (remote.js).
НО другие функции, определенные в remote.js, больше не доступны для вызовов меню (нажатие на меню вызывает ошибки, такие как Функция сценария не найдена: f1 ).
- Должен ли я, возможно, загрузить все функции каким-либо образом до определения меню? Я попытался определить функцию f1 () в начале, но это не имеет значения относительно функции f2 (), которая находится в конце. Я также попробовал 2 отдельных вызова, 1st eval (remote_functions.js), 2nd eval (remote_menuLoader.js), но это тоже не имело значения (поэтому мой код ниже показывает только один вызов eval, который загружает один пульт. JS с определениями обеих функций и меню, которое будет вызывать их).
Мой код:
Ограниченный скрипт Google для электронных таблиц:
var app = SpreadsheetApp.getActiveSpreadsheet();
function onOpen() {
app.addMenu("LOAD remote menu", [
{name: "eval(remote.js) to load new menu", functionName: "evalRemote"}
]);
}
function evalRemote() {
var remotejs_url="https://drive.google.com/uc?authuser=0&id=1wCjewWFTPdH-Luw53zWh_KHX-RhRhFIn&export=view";
eval(UrlFetchApp.fetch(remotejs_url).getContentText());
var message=remote_onOpen(app);
Browser.msgBox(message);
}
файл remote.js:
function f1() {
Browser.msgBox("you called f1");
}
function remote_onOpen(app) {
var menuName="REMOTE-loaded menu";
app.addMenu(menuName, [
{name: "FUNCTION 1", functionName: "f1"}
,{name: "FUNCTION 2", functionName: "f2"}
]);
return("remote_onOpen(app) function was called;\\n "
+ "A reference to '" + app.getName() + "' was passed \\n"
+ "in order to create this new menu on it:\\n"
+ "'" + menuName + "'\\n\\n"
+ "You should now have 2 new functions available.");
}
function f2() {
Browser.msgBox("you called f2");
}