如何从 for() 循环中获取特定行。它应该停止时继续循环

Posted

技术标签:

【中文标题】如何从 for() 循环中获取特定行。它应该停止时继续循环【英文标题】:How to get a specific row out of a for() loop. It keeps looping when it should stop 【发布时间】:2019-06-03 19:54:19 【问题描述】:

我有一个这样的循环:

for (var i = 0; i < Sheet1Data.length; i++) 

当它等于特定行时,我试图获取 i,该行必须是两个不同电子表格上的两个值不匹配的行,我得到这样的结果。

 var s1data = Sheet1Data[i][0];
 var s2data = Sheet2Data[i][0];
if (s1data != s2data)
      var falseRow = i+1

工作表数据是工作表范围的所有值。因此,当 if 函数使用循环倒计时时,它看起来像:

0: Aang=Aang

1:科拉=科拉

2: Sakka!=Toph -> var falseRow = 2+1=3

我添加加 1 的原因是将数字从整个 0=第一行事物更改为其他函数理解的整数.. 当它获得该错误行时,它会根据在工作表中找到的值的位置来选择对其进行处理。例如:”; ;”表示电子表格中的变化。

0: 昂; ;安安

1:科拉; ;科拉

2:萨卡; ;顶部

3:托普; ;(空格)

它使用另一个循环来查找这些值在另一张表中的位置

   var s1falseRowARange = s1.getRange(falseRow,1,1,1);
   var s1falseRowAName = s1falseRowARange.getValues();
for (var j = 0; j < Sheet1Data.length; j++) 
   var s1dataj = Sheet1Data[j][0];
   var s2dataj = Sheet2Data[j][0];
   if(s1falseRowAName == s2dataj)
      var s2trueRow = j+1;


它也这样做,但对于 sheet2。所以它会找到 Toph 在 Sheet 2 中的位置,即第 4 行,所以

var s1trueRow =j+1;//or 4

但是Sheet2中没有Sakka?所以它确定他不在那里使用

  if(falseRow > s2trueRow) 
    var fm2t = 'true';
  
  else if(falseRow < s2trueRow) 
    var fl2t = 'true';
  
    var s2Rowfound = 'true';

  else if(j+1 == s2LastRow && s2Rowfound != 'true')
     s2.insertRows(falseRow);
     s2.getRange(falseRow,1,1,1).setValue(s1data)
  
function insertCell(cellRange) 
  var sos = SpreadsheetApp.openById("Sheet1");
  var sas = SpreadsheetApp.setActiveSpreadsheet(sos);
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s1 = ss.getActiveSheet();
  s1.getRange(cellRange).insertCells(SpreadsheetApp.Dimension.ROWS);


function deleteCell(cellRange)
  var sos = SpreadsheetApp.openById("Sheet1");
  var sas = SpreadsheetApp.setActiveSpreadsheet(sos);
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s1 = ss.getActiveSheet();
  s1.getRange(cellRange).deleteCells(SpreadsheetApp.Dimension.ROWS);

Var s2Rowfound 永远不会等于 true。所以它确定他在 sheet2 上不存在并将他添加到 sheet 2。

这是我的问题终于出现的地方! falseRow 等于循环值 i。因此,当它添加这一新行时,循环函数可能仍在处理意外,这在将 Sakka 添加到列表后会导致这样的事件:

0: 昂; ;安安

1:科拉; ;科拉

2:萨卡; ;萨卡

3:托普; ;(空格)

4:(空格); ;顶部

它在下一行插入了一个不应该插入的行。这与 falseRow 作为循环变量 i 有关。而且它不仅仅是添加行,它还删除了行(我有一种情况,如果它在 sheet1 上不存在,它会删除该行)。有时它会正常工作,但有时它会在循环之后添加或删除行。如何让它在删除或添加行之前不继续循环以防止发生这种双重添加或双重删除?

编辑: 好的,所以我对它进行了更多测试。似乎问题可能更多在于deleteCell()insertCell()insertRows() 函数。有一些小问题,它会无缘无故地重复。我可能不得不提出另一个比循环更多地围绕这个问题的问题。但如果这里有人有任何想法,我会给你更多的背景知识。

if(j+1 == s1LastRow && fnot1t == 'true' && 'F3' != 'RUNNING')
          s1.getRange('F3').setValue('RUNNING');

我尝试了很多方法,例如在函数开头将 Cell 设置为“RUNNING”并将其设置回“”。当它完成那部分时。为了防止它自己赛车。这至少给了我一个好处,即拥有一个关于该功能当时正在做什么的视觉指示器。

          var falseRow = falseRowC.getRow();
          s1.getRange('F4').setValue(falseRow);
          var F4 = s1.getRange('F4').getValue();
          s2.deleteRow(F4);

然后我尝试将 falseRow 转换为其他类型的变量,以使其尽可能远离“i”,并认为这就是导致错误的原因。这甚至将行写入一个单元格并获取该单元格的值来代替我需要更改的行。

          s1.getRange('C'+F4).deleteCells(SpreadsheetApp.Dimension.ROWS);
          Logger.log('Delete row '+F4+' from Mirror Sheet.');
          s1.getRange('F3').setValue('');
        

这里是 F3 单元格变回空的地方,表示此过程已完成并被允许从头开始执行该过程。你还看到deleteCells函数在这里,那么如果它只写一次并且这个函数在RUNNING指示灯关闭之前不能再次运行,它怎么能执行两次呢?这就是问题。

        else if(j+1 == s1LastRow && fnot2t == 'true' && fl1t == 'true' && 'F3' != 'RUNNING') 
          s1.getRange('F3').setValue('RUNNING');
          var falseRow = falseRowC.getRow();
          s1.getRange('F4').setValue(falseRow);
          var F4 = s1.getRange('F4').getValue();
          s1.getRange('C' + F4).insertCells(SpreadsheetApp.Dimension.ROWS);
          s1.getRange('C' + F4).setValue('HOME');
          var SRange = s1.getRange(F4,1,1,2);
          var A1Range = SRange.getA1Notation();
          var SData = SRange.getValues();
          s2.insertRows(F4);
          s2.getRange(A1Range).setValues(SData);
          s1.getRange('F3').setValue('');
        

这是相同的过程,但是当它添加行时。同样的问题。使 F3 = RUNNING 以防止它运行此 insertRows 进程。但由于某种原因,它添加了多行。

【问题讨论】:

我不清楚。所有名称都出现在两张纸上是否很重要,还是定位也很重要?为什么要插入单元格而不是附加行?对我来说,仅找出缺少的名称,附加该名称,然后按名称对两个页面进行排序会更有意义。这会为您简化吗? Sheet1 和 Sheet2 的大小是否始终相同? 您的数据从哪一行开始? 你能分享一下数据表吗? @J.G.所有名称都需要出现在两张纸上。这是因为一张纸是人们看的那张纸,而第二张纸只是在那里显示第一张纸发生了什么变化。表 1 上有一个 C 列,它是使用差异的同一行进行编辑的,并且它是由人更改的,所以我不能让它附加在它上面,因为这会重置它,这是我不想要的。 C列需要跟随它所属的人,无论是向上还是向下。这就是为什么删除和添加必须精确的原因。我让它找到正确的行,问题是它删除或添加了这些行。 【参考方案1】:

根据getValues() 方法(下面的链接)的文档,它“返回一个二维值数组,先按行索引,然后按列索引。”因此,当您将它与 s2dataj 进行比较时,它是一个单一的值,它可能会给您带来问题。由于您在调用s1.getRange(falseRow,1,1,1) 时设置了范围以获取单个单元格,因此我相信您的检查应该是:

if(s1falseRowAName[0][0] == s2dataj)
      var s2trueRow = j+1;

getValues() 文档链接:https://developers.google.com/apps-script/reference/spreadsheet/range#getvalues

【讨论】:

我做了更改,不幸的是同样的问题仍然存在。它双重添加一行或双重删除一行。我得出的结论可能与 insertRow 和 insert Cell 函数更相关。

以上是关于如何从 for() 循环中获取特定行。它应该停止时继续循环的主要内容,如果未能解决你的问题,请参考以下文章

如何定义何时停止和开始 for /f 批量循环

单击仅使用 JavaScript 从 JSON 获取的表数据中的按钮时引用特定行

在 for 循环中使用切换

如果if条件满足,如何跳转到for循环中的特定位置?

如何从 Mediainfo 获取特定信息

如何从一系列循环元素中获取点击元素?