如何在具有多个标签的电子表格中打开今天的日期

时间:2017-05-04 04:47:49

标签: google-apps-script google-sheets spreadsheet

我有一大群人可以访问一个电子表格。每个人都有一个带有一列日期的选项卡(C列),他们输入每个日期收到的信息。我希望EACH表格在打开标签时跳转到当前日期。下面的脚本有效,但仅适用于第一个选项卡/表,必须为所有其他选项卡手动运行,这不值得。我如何解决这个问题,以便它在每个标签打开后运行?

whatever-search-term site:yrshaikh.com

3 个答案:

答案 0 :(得分:0)

目前在

中没有事件触发器选择工作表

但每个标签都有唯一的链接。如果每个用户都有自己的选项卡,他们可能会将链接保存到个人tad,并且当电子表格打开时脚本将起作用,因为这行:

var sheet = ss.getActiveSheet();

答案 1 :(得分:0)

您无法从脚本中检测工作表选择,但您可以更改用户在电子表格中选择活动工作表的方式。 使用侧边栏可以比通常的选择模式更加用户友好,特别是当您有多张纸时。

下面的代码是我经常使用的侧边栏工具的简化版本。我删除了所有不必要的项目(至少我希望如此!)并集成您的代码以跳转到当前日期。

它使用JQUERY,因为它是一个更大的脚本的一部分,我经常使用它,但我承认它在这个简单的脚本中不是很有用...我只是懒得把它删除:)

整个代码很长但很容易理解。 您也可以从this public copy的副本开始。

enter image description here

code.gs

function onOpen() {
  SpreadsheetApp.getUi()
  .createMenu("Authorize")
  .addItem('Authorize script', 'authorize')
  .addToUi();
  showSidebar();
}

function authorize(){
  showSidebar();
}

function showSidebar() {
  var ui = HtmlService.createTemplateFromFile('Sidebar')
      .evaluate()
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setTitle('Page selection');
  SpreadsheetApp.getUi().showSidebar(ui);
}


function createList(){
  var ssProfs_envois = SpreadsheetApp.getActiveSpreadsheet();
  var list = [];
  var sh, sheetName;
  for(var s=0;s<ssProfs_envois.getNumSheets();s++){
    sh = ssProfs_envois.getSheets()[s];
    sheetName = sh.getName();
    list.push(sheetName);
  }
  var message = ''; 
  var color;
  message+= '<table style="border-collapse:collapse;font-family:arial,sans;font-size:9pt;" border = 1 >';
  message+='<tr valign="top" cellpadding=5>'
  for(var n=0;n<list.length;n++){
      color="#000"
    message+='<tr><td align="center">&nbsp'+(n+1)+'&nbsp</td><td>'+
      '<input type="button" id="button'+n+'" value="'+list[n]+'" style="color:'+color+'; width:200px;font-size:10pt;white-space:normal;" onclick="selectSheet(\''+n+'\')"/></td></tr>';
  }
  message+='</table>';
  return message;
}

function showSheetGS(sheetNumber){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[sheetNumber].activate();
  jumpToDate(sheet);
}

function jumpToDate(sheet) {
  var range = sheet.getRange("A1:A");
  var values = range.getValues();  
  var day = 24*3600*1000;  
  var today = parseInt((new Date().setHours(0,0,0,0))/day);  
  var ssdate; 
  for (var i=0; i<values.length; i++) {
    try {
      ssdate = values[i][0].getTime()/day;
    }
    catch(e) {
    }
    if (ssdate && Math.floor(ssdate) == today) {
      sheet.setActiveRange(range.offset(i,0,1,1));
      break;
    }    
  }
}

Sidebar.html

<?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>

<!-- Below is the HTML code that defines the sidebar element structure. -->
<div class="sidebar branding-below">
<!-- The div-table class is used to make a group of divs behave like a table. -->
<h3>Available tabs,<br><span style="color:#070"> Green typeface = </span>sheet already selected</h3>
  <div id="sidebarList">
  <br><br><br>...wait a moment,<br>list is being created.
  <p>If nothing happens then please authorize the script using the menu.</p> 
  </div>

<!-- Enter sidebar bottom-branding below. -->
  <div class="sidebar bottom">
  <img alt="Add-on logo" class="logo" width="25"
      src="http://insas.cluster006.ovh.net/serge/apps-script_2x.png">
  <span class="gray branding-text">Sheet Select tool<br>&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp© SG 2017</span>
<?!= HtmlService.createHtmlOutputFromFile('SidebarJavaScript').getContent(); ?>

SidebarJavaScript.html

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script>
  /**
   * Run initializations on sidebar load.
   */
populateEncodeLocal();

function populateEncodeLocal(){
   //console.log('populateEncode');
   google.script.run.withSuccessHandler(populateList).createList();
}

function selectSheet(sheetNumber){
  console.log(sheetNumber);
  google.script.run.withSuccessHandler(showSheet(sheetNumber)).showSheetGS(sheetNumber);
}
function showSheet(n){
  console.log("showSheet"+n);
  $('#button'+n).css('font-size','14pt').css('color','#070');
}

function populateList(data){
   //console.log(data);
   $('#sidebarList').html(data);
}
</script>

Stylesheet.html

<!-- This CSS package applies Google styling; it should always be included. -->
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<style>

html, body {
    max-width: 100%;
    overflow-x: hidden;
}

#sidebarList {
  width:270px;
  height:600px;
  overflow:auto;
  }

input[type="button"] {
    height: 23px;
    width: 270px;
    padding-left: 8px;
    line-height: 24px;
}

label {
  font-weight: bold;
}

.branding-below {
  bottom: 3px;
  top: 0px;
  padding-left:0px;
}

.branding-text {
  left: 7px;
  position: relative;
  top: 3px;
}

.logo {
  vertical-align: middle;
}

.width-100 {
  width: 100%;
  box-sizing: border-box;
  -webkit-box-sizing : border-box;‌
  -moz-box-sizing : border-box;
}

#sidebar-value-block,
#dialog-elements {
  background-color: #eee;
  border-color: #eee;
  border-width: 5px;
  border-style: solid;
}

#sidebar-button-bar,
#dialog-button-bar {
  margin-bottom: 10px;
}

.div-table{
  display:table;
  width:280px;
  height:500px;
  background-color:#eee;
  border:1px solid  #666666;*/
  border-spacing:2px;
  font-size:8,5pt;
}
.div-table-row{
  display:table-row;
  width:auto;
  clear:both;
}
.div-table-td, .div-table-th {
  display:table-cell;         
  width:auto;   
  background-color:rgb(230, 230, 230);  
  padding-left:4px;
  padding-right:4px;
}
.div-table-th {
  /*float:left;*/
  font-weight: bold;
}
.div-table-td {
  /*float:right;*/
}
div.ui-datepicker{
padding:0px;
font-size:90%;
 width: 250px;
 heigth: 90px;
  }

th {
  border-bottom: 0px solid #acacac;
  font-weight: normal;
  padding: 1px 1px 0;
  text-align: left;
}

td {
  border-bottom: 0px solid #ebebeb;
  padding: 1px 0;
}


}
</style>

答案 2 :(得分:0)

这有点可能,但很慢。

这个想法是使用触发器onOpen()逐个调用jumpToDate到所有工作表。但是,Google表格在您打开单张纸张时不会同时呈现所有纸张,而只会打开您打开的纸张,而且似乎是最常打开的纸张。当您单击“不受欢迎”工作表选项卡时,您的浏览器需要渲染它,在我的测试中在一个简单的工作表上花费500毫秒。您的大型电子表格可能需要更长时间。

以下是我如何调整您的代码来回答您的问题:

function jumpToDate() {
  /* optional:*/ /*var ui = SpreadsheetApp.getUi();
  var response = ui.alert('Today', 'To scroll to today, please click yes.', ui.ButtonSet.YES_NO);
  if(response == "NO"){return}; */
  
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets(); // this now gets all the sheets
  var numSheets = ss.getNumSheets(); // gets number of sheets
  
  var day = 24*3600*1000;  
  var today = parseInt((new Date().setHours(0,0,0,0))/day);   
  var range;
  var values;  
  var ssdate; 
  
  for (h = 0; h < numSheets; h++) {
    
    range = sheet[h].getRange("C:C"); // note the [h]
    ss.setActiveSheet(sheet[h]);
    Utilities.sleep(500); // without this line, it runs much faster but some sheets don't load.
                          // I recommend that you play around and increase/decrease the 500 number
                    
    values = range.getValues(); 
    
    for (var i=0; i<values.length; i++) {
      try {
        ssdate = values[i][0].getTime()/day;
      }
      catch(e) {
      }
      if (ssdate && Math.floor(ssdate) == today) {
        sheet[h].setActiveRange(range.offset(i,0,1,1)); // note the [h]
        break;
      }    
    }
  }
}

这个选项很可能对您的需求来说太慢了,所以我建议我们以不同的方式解决问题。页面是否真的需要显示我们每天不编辑的所有行?我们经常读它们吗?如果没有,我们可以隐藏那些不使用的行。可以使用hideRows(rowIndex, numRows)方法完成。

  1. 创建在今天之前隐藏所有行的函数hideOld()
  2. 自定义hideOld()以隐藏行(今天 - 10天)
  3. 每天凌晨3:00添加一个运行hideOld()的触发器。