1

我想将我的所有代码外包给一个库,但是我正在使用 ScriptProperties 为使用该代码的每个电子表格设置和获取持久的全局变量(如“模式”:“编辑”或“数据”)。

根据规范,不可能有一个库写入托管脚本 ScriptProperties:https ://developers.google.com/apps-script/guide_libraries#scoping

脚本属性(**):在库中创建时,所有包括脚本在内的所有脚本都可以看到相同的实例。

** 这意味着库拥有自己的资源/功能实例,并且所有使用该库的脚本共享并有权访问同一实例。

因此,这使得使用单个代码库为每个电子表格设置全局变量成为不可能。

与 ScriptProperties 结合使用库的这个缺点是否有解决方法或解决方案?

谢谢,一切顺利

马里奥

4

4 回答 4

1

解决方案是将托管 ScriptProperties 的实例传递给库,即类似的东西

function test() {
  var props = ScriptProperties.getProperties();
  MyLib.func1(props);
}

MyLib.gs

function func1(props) {
  var mode = props["mode"];
  //  ...
}

如果托管脚本处理多个电子表格,则可以使用电子表格 id 作为属性键的一部分,例如,有两个电子表格 idsXYZ000XYZ001. 托管脚本包含一系列属性

  • XYZ000.mode=normal
  • XYZ001.mode=extended

托管脚本接受一个活动的电子表格 ID,并将其与属性一起传递给库方法。

一个复杂的解决方案是拥有一个电子表格的设置类,在托管脚本属性中存储每个处理的电子表格的设置类的 JSON 字符串表示,使用电子表格 id 从属性加载电子表格设置并传递设置实例去图书馆。这是一个示例代码。

function Settings(mode) {
  this.mode = mode;
};

function setDefaultSettings() {
  var ID0 = "XYZ000";
  var SettingID0 = new Settings("normal");
  ScriptProperties.setProperty(ID0, SettingID0);
}

function test() {
  var props = ScriptProperties.getProperty("XYZ000");
  MyLib.func1(props);
}
于 2012-10-02T09:22:00.040 回答
0

这是我尝试解决此问题的方法...

我将所有属性存储在库中,然后在库中使用 getter 和 setter 函数,以便调用电子表格轻松访问这些值。

使用调用电子表格的 id 为属性名称创建复合键。函数返回一个带有全键(复合)、“裸”键和返回给调用者的值(验证、错误检查等)的对象。

图书馆.gs

二传手

function setLibPropForSpreadsheet(key, keyValue)
{
var theCaller = SpreadsheetApp.getActiveSpreadsheet().getId();
  var fullKey = theCaller + '-' + key;
  ScriptProperties.setProperty(fullKey, keyValue)
  var theResult = new Object();
  theResult.value = keyValue;
  theResult.key = key;
  theResult.fullKey = fullKey;
  return(theResult);
}

吸气剂

function getLibPropForSpreadsheet(key){
 var theCaller = SpreadsheetApp.getActiveSpreadsheet().getId();
  var fullKey = theCaller + '-' + key;
  return(ScriptProperties.getProperty(fullKey));
}

然后,您可以在调用电子表格脚本中使用这些函数:

电子表格.gs

function setIt() {
var test =  getData.setLibPropForSpreadsheet("thesetting", "the value")
    Logger.log(test)
}

function getIt(){
 Logger.log(getData.getLibPropForSpreadSheet("thesetting"))
  }
于 2012-10-02T17:24:52.860 回答
0

或者也许编码更优雅,更可重用......

还包括在多个用户使用电子表格时很有用的功能,并且他们每个人都需要有自己的设置。

/**
 *Returns a script property from the library file to a calling script

 * @param {string} key The name of the scriptProperty property to return.
* @return {string} the string value of the key passed
 */

function getLibraryProperty(key) {
  return ScriptProperties.getProperty(key);
}

/**
 *Returns the appropriate library property for the calling spreadsheet.
 * @param {string} key The name of the scriptProperty property to return.
* @return {string} the string value for the key passed

 */

function getLibPropForSpreadsheet(key){
  return(ScriptProperties.getProperty(setkey_(key).fullKey));

}
/**
 *Returns the appropriate library property for the calling spreadsheet by user
 * @param {string} key The name of the scriptProperty property to return.
 * @return {Object.<string,string>} Object containing the key, full key, and value
 */
function getLibPropForSSUser(key){
  return(ScriptProperties.getProperty(setkey_(key).fullUserKey));
}
/**
 *Returns the appropriate library property for the calling spreadsheet.
 * @param {string} key The name of the scriptProperty property to return.
 * @return {Object.<string,string>} the string value of the key passed
 */
function setLibPropForSpreadsheet(key, keyValue)
{
  return(setLibProp_(key, setkey_(key).fullKey, keyValue));
}

function setLibPropForSSUser(key, keyValue)
{
    return(setLibProp_(key, setkey_(key).fullUserKey, keyValue));
}

function setLibProp_(key, fullKey, keyValue){
  ScriptProperties.setProperty(fullKey,keyValue)
  var theResult = new Object();
  theResult.value = keyValue;
  theResult.key = key;
  theResult.fullKey = fullKey;
  return(theResult);
} 

function setkey_(key){
var theCaller = SpreadsheetApp.getActiveSpreadsheet().getId();
 var theUser = Session.getEffectiveUser().getEmail();
 var fullUserKey = theCaller + '-' +theUser+ '-' + key;
 var fullKey = theCaller + '-' + key; 
  var theKeys = new Object();
  theKeys.fullUserKey = fullUserKey;
  theKeys.fullKey = fullKey;
  return(theKeys);
}
于 2012-10-02T18:54:17.990 回答
0

如果有人在 2020 年提出要求,那么传递您想要从库中管理的属性实例要容易得多。所以,你只需在onOpen方法或一个名为initialiceLib的方法中执行此操作,该方法在加载脚本时为库设置初始配置。

在图书馆:

var scriptProperties_;
/**
* Assign local document instance of property to a variable
* @param {Properties} properties - Instance of local document properties
*/
function setScriptProperties(properties) {       
   scriptProperties_ = properties;
}

//in some random function
function someFunction() {
   var someProperty = scriptProperties_.getProperty("propertyKey");
}

在本地脚本中:

function initialiceLib() {
   LibraryAlias.setScriptProperties(PropertiesService.getScriptProperties());
}

此示例是关于与库共享本地脚本属性。您可以更改文档属性(用户属性已共享)。

如果您不想启动任何库配置,而只想在库脚本属性中管理文档或其他脚本的所有属性,当然您可以在库中实现一个函数来使用 de 设置属性文档 ID 作为前缀,例如,使每个文档的每个键都是唯一的。

于 2020-11-16T11:05:52.860 回答