Google工作表,将活动范围设置为窗口的左上角单元格

时间:2016-08-18 11:55:01

标签: google-apps-script

基本上,我有几张表,其中包含以下设置:

在工作表顶部有一些冻结的标题行,在多行数据下面都有一个日期在A列。以下函数允许我在任何工作表上跳转到“今天”(从技术上讲,最接近的一天)在将来如果没有今天的数据的话。)

function goToToday() {
  var workbook = SpreadsheetApp.getActiveSpreadsheet()
  var currentSheet = workbook.getActiveSheet().getName();
  if (currentSheet !== "Calculations") {
    workbook.getSheetByName(currentSheet).setActiveRange(workbook.getSheetByName(currentSheet).getRange(1,1))
    var today = new Date()
    var rowNumber = 4
    var numOfRows = workbook.getSheetByName(currentSheet).getLastRow() - 3
    var dates = workbook.getSheetByName(currentSheet).getRange(4,1,numOfRows,1).getValues()
    for(i = 0; i < numOfRows; i++) {
      if(dates[i][0] > today) {
        break
      }
      else {
        rowNumber++
      }
    }
workbook.getSheetByName(currentSheet).getRange(rowNumber, 1).activate()
  }
}

让我烦恼的是,如果在运行该函数之前的活动单元格下面返回该函数的“今天”单元格,则该单元格将作为窗口中左上角的单元格返回,这是完美的。但是,如果当前活动单元格高于返回的单元格,则单元格将返回窗口底部附近。如何使函数一致地返回单元格作为窗口的左上角单元格?我认为这与滚动有关..

3 个答案:

答案 0 :(得分:0)

我认为它们不是可以控制滚动的Google Apps脚本中的方法,您可以request a new feature

解决方法(不是最好的方法)是使用hideRows()并立即调用showRows()来使UI“滚动”。假设第一行被冻结的示例:

function myFunction() {
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sheet = ss.getSheets()[0];
 sheet.hideRows(2, 199);
 sheet.showRows(2, 199);
 sheet.getRange(200, 2).activate();
}

答案 1 :(得分:0)

function goToToday() {
  var workbook = SpreadsheetApp.getActiveSpreadsheet(),
      currentSheet = workbook.getActiveSheet();
  if ( currentSheet.getName() !== "Calculations" ) {
    var lastCell = currentSheet.getRange(
           currentSheet.getMaxRows(),getMaxColumns() 
    );
    currentSheet.setActiveRange("A1");
    var today = new Date(),
        rowNumber = 4,
        numOfRows = currentSheet.getLastRow() - 3,
        dates = currentSheet.getRange(4,1,numOfRows,1).getValues();
    for(i = 0; i < numOfRows; i++) {
      if(dates[i][0] > today) {
        break
      }
      else {
        rowNumber++
      }
    }
    currentSheet.setActiveRange(lastcell);
    SpreadsheetApp.flush();
    currentSheet.getRange(rowNumber, 1).activate()
  }
}

我重构了一些函数调用,但主要思想是将活动范围设置为右下角单元格,刷新工作表(应更新UI),然后将活动范围设置为目标。

编辑:在重构OP的代码时,我将调用移至.getName()到条件中,并将表单存储在currentSheet中。这消除了对worksheet.getSheetByName(currentSheet)的多次调用。这里不是什么大问题,但是在更大的脚本中,运行时间会受到影响。而且,IMO,它更容易阅读。

答案 2 :(得分:0)

采用HardScale的解决方案,我得到了这个。我写的不是最好的,而且我确信有很多方法可以帮助你减轻成本。可以这么说,但它确实有效!

function goToToday() {
  var workbook = SpreadsheetApp.getActiveSpreadsheet()
  var currentSheet = workbook.getActiveSheet().getName();
  if (currentSheet !== "Calculations") {
    var lastCell = workbook.getSheetByName(currentSheet).getRange(workbook.getSheetByName(currentSheet).getMaxRows(),workbook.getSheetByName(currentSheet).getMaxColumns());
    workbook.getSheetByName(currentSheet).setActiveRange(workbook.getSheetByName(currentSheet).getRange(1,1))
    var today = new Date()
    var rowNumber = 4
    var numOfRows = workbook.getSheetByName(currentSheet).getLastRow() - 3
    var dates = workbook.getSheetByName(currentSheet).getRange(4,1,numOfRows,1).getValues()
    for(i = 0; i < numOfRows; i++) {
      if(dates[i][0] > today) {
        break
      }
      else {
        rowNumber++
      }
    }
    workbook.getSheetByName(currentSheet).setActiveRange(lastCell);
    SpreadsheetApp.flush();
workbook.getSheetByName(currentSheet).getRange(rowNumber, 1).activate()
  }
}