谷歌表格脚本| 全局变量在 html 侧边栏/模态窗口后失去其值

Phi*_*hil 0 javascript google-apps-script

大家好,我有一个团队假期日历。用户按字母“v”来设置假期日期,假期日期存储在外部工作表中(用于其他目的,因此我不能简单地在同一电子表格中拥有单独的工作表)。

问题是,假期日期可以是“付费”或“银行”(以便稍后记入)。我使用模态 Html 窗口询问用户假期是两者中的哪一个。但是,我在打开 html 模式窗口之前设置的全局变量失去了它们的值。我需要这些全局变量来存储原始条目的行和列(因为用户在键入“v”后单击单元格会更改 getActiveCell() 的值。

应该发生什么:

  1. 用户输入“v”
  2. 弹出 html 窗口“这是什么假期类型?银行假期还是付费假期?
  3. 代码将假期日期输入外部电子表格。
  4. 代码将“已付款”或“已银行”值输入到外部电子表格中。

我可以让它进行到上面的步骤 3,但是,全局变量正在丢失其值,并且无法确定用户最初单击的单元格。

步骤1

步骤1

第2步

第2步

var selectedDateRangeRow;
var selectedDateRangeColumn;

function onEdit(e) {
  if (sheet.getRange("AH2").getValue() == true && sheet.getActiveCell().getValue() == "V") {
    selectedDateRangeRow = sheet.getActiveCell().getRow();
    selectedDateRangeColumn = sheet.getActiveCell().getColumn();
    ShowVacationMenu();
  }
}

function ShowVacationMenu() {
  var html = HtmlService.createHtmlOutputFromFile('VacationType').setTitle("New Vacation Date");
  SpreadsheetApp.getUi().showModalDialog(html, "Select Vacation Type");
}

function AddDateToOverTimeSheet(selectedVacationType) {
  Browser.msgBox(selectedDateRangeRow);     //This global value returns empty/null.
}
Run Code Online (Sandbox Code Playgroud)

html 文件:

<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
Run Code Online (Sandbox Code Playgroud)
<div class="container">

    <form action="#" name="vacation">
        <p>
            <input name="vacationType" type="radio" id="banked" value="Banked">
            <label for="banked">Banked</label>
        </p>
        <p>
            <input name="vacationType" type="radio" id="paid" value="Paid">
            <label for="paid">Paid</label>
        </p>
    </form>

    <p>
        <button id="submitBtn" class="btn waves-effect waves-light">Submit
  <i class="material-icons right">send</i>
</button>
    </p>
</div>

<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

<script>
    // 1. Find and store the element we want to listen to events on.
var submitButton = document.getElementById("submitBtn");

// 2. Create script function to run.
var onButtonClick = function() {
    if(document.forms.vacation.vacationType.value == ""){
      M.toast({html: 'Please select an option'});
    }else{

      //Create Array to store selected details
      var data=[
        document.forms.vacation.vacationType.value
       // exampe-of-new-item (no semicolon needed)
      ];

    google.script.run.AddDateToOverTimeSheet(data);
    google.script.host.close();
    };
};

// 3. Add the event listener for the element and function
submitButton.addEventListener("click", onButtonClick);
</script>
Run Code Online (Sandbox Code Playgroud)

更新:我现在使用“属性服务”在 GAS 和 html 之间传递变量,如下所示:

function SelectVacationType(){

var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('CALENDAR_SHEET_ID', calendarSheetID);
userProperties.setProperty('PERSON_NAME', personName);
userProperties.setProperty('R', r);

  //Show Vacation Type Selector Window.
  ShowVacationMenu();

}


function ShowVacationMenu() {

var html = HtmlService.createHtmlOutputFromFile('VacationType').setTitle("New Vacation Date");
SpreadsheetApp.getUi().showModalDialog(html, "Select Vacation Type");
}



function ImportData(data) {
//Retrieve First letter of first array item in 'data'
var selectedVacationType = data[0][0];

var userProperties = PropertiesService.getUserProperties();
var calendarSheetID = userProperties.getProperty('CALENDAR_SHEET_ID');
var personName = userProperties.getProperty('PERSON_NAME');
var r = userProperties.getProperty('R');

//open EXTERNAL Calendar sheet and go to the current person's sheet.
var calendarSheet = SpreadsheetApp.openById(calendarSheetID).getSheetByName(personName);
calendarSheet.getRange(r, 7).setValue(selectedVacationType); //<- this doesn't seem to work.

}
Run Code Online (Sandbox Code Playgroud)

dou*_*ary 5

全局变量会丢失,因为google.script.run调用在新实例中执行服务器端脚本,而新实例不知道原始服务器端实例的状态。

当流程在客户端启动时,您可以通过以下方式维护状态:在客户端 HTML/JavaScript 代码中创建一个对象,将其通过google.script.run()对服务器端 Apps 脚本代码的调用传递,然后将可能修改的对象返回到客户端成功处理程序。请参阅HTML 服务:参数和返回值。请注意,Date对象不会在往返过程中保留下来,必须以文本字符串或其他方式编码。

当流程在服务器端启动时,您可以通过模板化 HTML中的 scriptlet 将值传递给客户端。

如果出于某种原因需要在服务器端实例之间共享状态,您可以使用属性服务,或者只需在所有实例都知道其位置的电子表格单元格中写入和读取数据。