【问题标题】:Cleaning up and trying to consolidate an on edit code清理并尝试合并编辑代码
【发布时间】:2020-07-21 15:07:29
【问题描述】:

这有很多我认为是冗余的代码。虽然我正在努力更多地了解它是如何工作的,但我是一个初学者,我从零碎阅读的内容开始制作这些内容,以便在此处获得这个半可行的文档:

https://docs.google.com/spreadsheets/d/1FqZNZX3zGRscG6teizjEFjmJMLKQmMLRCi6BmUL2T34/edit?usp=sharing

主工作表将其他工作表组合成自身,并根据其他选项卡中的条目自动更新。

问题 1:

var s = SpreadsheetApp.getActiveSheet();
var r = s.getActiveCell();
var nextCell = r.offset(0,-1 );


 
//Movement SECTION
  if( s.getName() == "Movement" )  
    {
      if( r.getColumn() == 2 )   
      {nextCell.setValue("Spacing");}                        
    }
//Defense SECTION
  if( s.getName() == "Defensive" ) 
    {
      if( r.getColumn() == 2 ) { 
        nextCell.setValue("Defense");}
    }
  
//Offense SECTION
  if( s.getName() == "Offensive" ) 
    {
      if( r.getColumn() == 2 )  
      {nextCell.setValue("Offense");}
    }

 //erases category if the exercise is blank
  if(s.getName() == "Movement" | s.getName() == "Defensive" | s.getName() == "Offensive") 
    {
      if( r.getColumn() == 2 )
        {if (r.isBlank() | r == "")
        {nextCell.clearContent()
        }
        }
    }

有没有更简洁的方法来组合所有这些部分?目的是在编辑时,第一列将根据选项卡反映一个类别。我目前计划将 A 列锁定并隐藏,这样在实际标签中就不那么碍眼了。

(额外问题:有没有办法自动将类别添加到主表上的查询中?[单元格是 B4])

问题 2:
是使用受保护的范围更快,还是执行一个脚本来防止更改某些范围并推送一个窗口来解释该做什么会更好?

【问题讨论】:

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


    【解决方案1】:

    我将在下面回答您的“奖励积分”问题,但首先:

    我在这样的一些函数中使用 JSON 来简化逻辑并使其更具可读性。另外,我切换了逻辑,因此它首先检查空白单元格,这样它就不会在删除内容之前不必要地执行写入

    function onEdit(e){
    //checkAll(e) 
    var s = SpreadsheetApp.getActiveSheet();
    var r = s.getActiveCell();
    var nextCell = r.offset(0,-1 );
    var sheetname = s.getName();
    var column = r.getColumn();
    
    var check =
         {
           Movement: "Spacing",
           Defensive: "Defense",
           Offensive: "Offense" //if you add more sheets just add them here
         }
    
    
    if(r.isBlank() && check[sheetname] && column == 2) { // !r.getValue() is not necessary, I believe.
        nextCell.clearContent()
    } else if(check[sheetname] && column == 2) {
        nextCell.setValue(check[sheetname])    
    }
    
    }
    

    接下来,在上述操作生效之前,您将不得不进入您的脚本并编辑/隔离您的 onEdit(e) 函数。目前它包裹了另一个函数,然后“Location.gs”文件中的所有内容根本没有包裹在函数中并且抛出错误。我没有尝试错误检查该部分或弄清楚它在做什么。

    现在,最后,解决您的“积分”问题,您可以通过一种仅使用 google 表格、一些胶带和强力胶而不使用 google 脚本的方式来完成此任务:

    编辑:

    好的,所以我尝试了一种更简单的方法,它不涉及任何胶带和强力胶。只需将查询中的公式替换为以下嵌套查询:

    =query({{query(Movement!B3:C,"select 'Space',B,C where B != ''")};{query(Defensive!B3:C,"select 'Defensive',B,C where B !=''")};{query(Offensive!B3:C,"select 'Offensive',B,C where B !=''")}},"select * where Col2 !=''")
    

    这很短,简单,根本不涉及任何隐藏的工作表,我认为它相对容易理解。就性能而言,这也应该很轻松。


    下面的这个答案有效(但没有那么优雅)

    1. 在此工作簿和 A 列中从第 1 行到第 100 行(或者您认为最多可以有多少行)创建一个新工作表,在每一行中输入“进攻性”。在 B 列中输入“防御性” " 在每一行中,在 C 列中,在每一行中输入“空格”。我在这里有一个示例:copied example sheet 在“标签”表中。

    2. 接下来,在您有查询的单元格中,输入以下内容(作为参考,上面的表格我称为“标签”:

    =query({{array_constrain(Labels!A1:A100,counta(Movement!B3:B),1),filter(Movement!B3:C,Movement!B3:B<>"")};{array_constrain(Labels!B1:B100,counta(Offensive!B3:B),1),filter(Offensive!B3:C,Offensive!B3:B<>"")};{array_constrain(Labels!C1:C100,counta(Defensive!B3:B),1),filter(Defensive!B3:C,Defensive!B3:B<>"")}},"select *")
    

    这应该适用于您想要做的事情,而不必为工作表名称设置一列。上面引用的工作表中的示例是一个工作示例。

    【讨论】:

    • 这太棒了!!!显着减少了滞后。我有位置代码来搜索第一个和最后一个类别条目,然后使用这些值在每个导入的选项卡的开头制作一个“勾选所有框”。我回去做了一些额外的清理工作!我这样做是为了在打开时删除编辑选项卡上所有多余的行。 ...但我不了解复选框,所以我不知道如何删除主表中为空的行保存复选框。计算应该总计的“行”,然后以某种方式插入复选框是否理想?
    • 我不知道制作新的脚本文件是否有帮助,但我将位置和代码分开,因为有很多针对术语和特定单元格的索引。脚本方面的新手,所以我只是为所有内容创建变量,然后为我需要的东西向后工作。
    • @KuukuuOmoi 我使用的复选框的最佳解决方案是使用公式=$C4="" 进入复选框列的条件格式并将文本颜色设置为白色,在您的情况下,将条件格式设置为C4:C540 范围(您也可以执行C4:C。这就是您如何使一个单元格的条件依赖于另一个单元格中的值。它们仍然存在(尽管如果您不小心检查了一个谷歌会显示“点击了不可见的复选框”的警告,并询问您是否是故意的。
    • @KuukuuOmoi 我继续并在您的电子表格上进行了更改 - 因为它看起来好像您可能正在使用电子表格作为您的实时版本,我建议您停止编辑它,在至少,有链接的人,但可能应该限制它。
    • @KuukuuOmoi,你介意接受这个答案吗?
    【解决方案2】:

    我想是这样的:

    function onEdit(e) {
      const sh=e.range.getSheet();
      const shts=["Movement","Defensive","Offensive"];
      const vals=["Spacing","Defense","Offense"]; 
      const idx=shts.indexOf(sh.getName());
      if(idx!=-1 && e.range.columnStart==2 && e.range.getValue()!='') e.range.offset(0,-1).setValue(vals[idx]);
      if(idx!=-1 && e.range.columnStart==2 && e.range.getValue()=='') e.range.offset(0,-1).setValue('');
    }
    

    【讨论】:

    • 肯定清理了类别的输入,但是当我删除单元格或在空间中不输入任何内容时,它不再将其删除
    • 所以它需要一些调试。我没有你的数据。可以调试吗?
    • 我只是在删除之前添加了我使用的那个,我认为它在空白处注册“进入”并以不同的方式点击“退格/删除”,所以有 |或情况兼而有之
    • 仍然无法通过删除、退格或在空单元格上输入来擦除
    猜你喜欢
    • 2023-02-25
    • 2016-09-24
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多