GAS库和ScriptProperties:将属性保存到包括脚本(不是库)的方法

时间:2012-10-02 08:37:28

标签: google-apps-script

我想将所有代码外包给库,但是我使用ScriptProperties为每个使用代码的电子表格设置并获取持久的全局变量(如“mode”:“edit”或“data”)。

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

  

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

     

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

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

是否有针对图书馆与ScriptProperties结合的这一缺点的解决方法或解决方案?

谢谢,一切顺利

马里奥

4 个答案:

答案 0 :(得分:1)

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

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

<强> MyLib.gs

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

如果托管脚本处理多个电子表格,则可以使用电子表格ID作为属性键的一部分,例如,有两个带有ID XYZ000XYZ001的电子表格。托管脚本包含属性的coupe

  • 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);
}

答案 1 :(得分:0)

以下是我试图解决此问题的方法......

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

使用调用电子表格的id为属性名称创建复合键。函数返回一个对象,其中包含fullkey(复合),“bare”键以及返回给调用者的值(验证,错误检查等)。

<强> library.gs

setter

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));
}

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

<强> spreadsheet.gs

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

function getIt(){
 Logger.log(getData.getLibPropForSpreadSheet("thesetting"))
  }

答案 2 :(得分: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);
}

答案 3 :(得分: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为前缀的属性,例如,使每个文档的每个键都是唯一的。