简体   繁体   English

谷歌表格脚本:为命名范围内的每个单元格获取 A1Notation

[英]Google Sheets Script: Get A1Notation For Each Cell In Named Range

The function I'm working on does an optimisation of the force required by a rudder foil (stabilator) on an America's Cup AC75 yacht, to balance the longitudinal moments of the sail forces.我正在研究的 function 优化了美洲杯 AC75 游艇上舵翼(稳定器)所需的力,以平衡帆力的纵向力矩。 This is done by altering the angle of the stabilator, from initially providing an upward (positive) force, then as sail forces increase, the stabilator has to create a downward (negative) force.这是通过改变稳定器的角度来完成的,从最初提供向上(正)力,然后随着帆力增加,稳定器必须产生向下(负)力。

The stabilator angles are in a column, and when it is changed, other calculations work out if it balances the sail forces.稳定器角度在一个列中,当它改变时,如果它平衡了帆力,其他计算就会起作用。 If it doesn't, there is a "Delta" column that indicates a value whether the rudder foil needs to provide more/less force, via it's angle.如果不是,则有一个“Delta”列,指示方向舵箔是否需要通过其角度提供更多/更少力的值。

I tried using Named Ranges for the column of Angles, and another for Delta.我尝试对 Angles 列使用 Named Ranges,对 Delta 列使用另一个。 The code should iterate through adding a bit more (or less) angle to the stabilator, and each time, check the Delta.代码应该通过向稳定器添加更多(或更少)角度进行迭代,并且每次都检查 Delta。 My code is wrong.我的代码是错误的。

What I need to do is get the Angle value of one Angle cell, incrementally increase/decrease it, then setValue of that cell.我需要做的是获取一个角度单元格的角度值,逐步增加/减少它,然后设置该单元格的值。 Next is to getValue of the corresponding Delta cell, to see if I'm at Zero (plus/minus a small amount).接下来是获取相应 Delta 单元格的值,看看我是否为零(加/减少量)。 If not, via a while loop, I increase/decrease the Angle again, setValue, recheck the Delta, and so on.如果不是,通过while循环,我再次增加/减少角度,设置值,重新检查增量,等等。

My problem is that I do not know how to get the A1Notation of each cell in the Named Ranges as I iterate through it, so that I can repeatedly getValue and setValue for just the single cell at a time?我的问题是,当我遍历命名范围时,我不知道如何获取命名范围中每个单元格的 A1Notation,这样我就可以一次只为单个单元格重复 getValue 和 setValue 吗?

function c_Optimise_Stabilator() {
// Author: Max Hugen
// Date: 20102-12-07
// Purpose: Attempt to optimise Stab Angle to balance with Stab Target Force

/* WARNING: This function may eventually cause a circular reference, so ensure there is an "escape".
 *          May occur if other optimisation functions are also run?
 * OPTIMISATION: Try in this order:
 *          1. Optimise Transverse Moments 
 *          2. Optimise Stabilator 
 *          3. Check, and if necessary, rerun Optimise Transverse Moments 
 *          4. Check, and if necessary, rerun Optimise Stabilator
 *             If Optimise Stabilator returns all Angles OK, we're good!
*/

  const ui = SpreadsheetApp.getUi();
  const ss = SpreadsheetApp.getActiveSpreadsheet();

//  var target_sheet = "Analysis";
//  var sheet = ss.getSheetByName("Analysis");
  var msg = ""; // gather input for Logger
  var s = "";   // short info for testing alerts, then added to msg
  var log = true; // whether to output msg to the Logger

  // angle range
  const maxAngle = 2.0, minAngle = -0.2, incAngle = 0.1;
  //limits
  var maxLoopIterations=10;  // to avoid excessive iterations
  var minDelta=0.02;          // to limit the minimum size of Delta tested
  // counters
  var i=0, loopIterations=0;
  // Original and New Vals
  var originalAngle=0.0, newAngle=0.0, originalDelta=0.0, newDelta=0.0;

  // ranges used in getRange - variable here, for testing. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/* 
  var sAngle = "Optimise_Stab_Angle";
  var sDelta = "Optimise_Stab_Delta";
 
  var sAngle = "Analysis!AF14:AG14";   // 1 rows (but only 2 cols now) - failing
  var sDelta = "Analysis!AM14:AM14";
*/  
  var sAngle = "Analysis!AF10:AG13";   // 4 rows
  var sDelta = "Analysis!AM10:AM13";

  var rAngle = ss.getRange(sAngle);
  var dAngle = rAngle.getValues();
  var rDelta = ss.getRange(sDelta);
  var dDelta = rDelta.getValues();
  
  originalAngle = Math.round(dAngle[i][1]*1000)/1000;
  originalDelta = Math.round(dDelta[i][0]*1000)/1000;

  var iLen = rAngle.getNumRows();

  for(i=0; i<iLen; i++){
    s = "";

    newAngle = originalAngle;
    s += "    Vb: " + dAngle[i][0] + "; Original Angle: " + originalAngle + "; originalDelta: " + originalDelta + "\r\n";

    // if stabilator force is below target (negative Delta), increase stab angle unless at maxAngle.
    if ( Math.abs(Math.round(dDelta[i][0]*100)/100) > minDelta && originalAngle < maxAngle) {

      loopIterations = 1; 
      while (newAngle <= maxAngle) {
        try {
          if ( newAngle == maxAngle ) {
            s += "                 MAX.ANGLE: newDelta" + newDelta + "; originalDelta: " + originalDelta;
            break;
          }
          // Have to update the Delta range, to check if Delta still too high/low
          var rDelta = ss.getRange(sDelta);
          var dDelta = rDelta.getValues();
          newDelta = Math.round(dDelta[i][0]*1000)/1000;
          
          if ( Math.abs(Math.round(newDelta*100)/100) < minDelta ) {
            s += "                 COMPLETED: newDelta" + newDelta + "; originalDelta: " + originalDelta;
            break;
          }
          if ( loopIterations > maxLoopIterations ) {
            s += "                 EXCEEDED maxLoopIterations of " + maxLoopIterations;
            break;
          }
        } catch(err) {
          Logger.log (c_ErrorToString (err) + "\n" + "Vb: " + dAngle[i][0]);
        }
        newAngle += incAngle;  // for some reason, this may STILL produce a number like 1.400000003 (example only)
        newAngle = Math.round(newAngle*1000)/1000;
        
        // set the new angle
        dAngle[i][1] = newAngle;
        // update the iteration count
        loopIterations ++
      } 
    }
    
    // if stabilator force is above target (positive Delta), decrease stab angle unless at minAngle.
    else if ( Math.abs(Math.round(dDelta[i][0]*100)/100) > minDelta && originalAngle > minAngle) {
      loopIterations = 1; 
      
      while (newAngle >= minAngle) {

        try {
          if ( newAngle == minAngle ) {
            s += "                 MIN.ANGLE: newDelta" + newDelta + "; originalDelta: " + originalDelta;
            break;
          }
          // Have to update the Delta range, to check if Delta still too high/low
          var rDelta = ss.getRange(sDelta);
          var dDelta = rDelta.getValues();
          newDelta = Math.round(dDelta[i][0]*1000)/1000;
          
          if ( Math.abs(Math.round(newDelta*100)/100) < minDelta ) {
            s += "                 COMPLETED: newDelta" + newDelta + "; originalDelta: " + originalDelta;
            break;
          }
          if ( loopIterations > maxLoopIterations ) {
            s += "                 EXCEEDED maxLoopIterations of " + maxLoopIterations;
            break;
          }
        } catch(err) {
          Logger.log (c_ErrorToString (err) + "\n" + "Vb: " + dAngle[i][0]);
        }

        newAngle -= incAngle;  // for some reason, this may STILL produce a number like 1.400000003 (example only)
        newAngle = Math.round(newAngle*1000)/1000;
        
        // set the new angle
        dAngle[i][1] = newAngle;
        // update the iteration count
        loopIterations ++
      } 
    }
    
    msg += s + "\r\n";
  }
  rAngle.setValues(dAngle);
  
  msg = "c_Optimise_Stabilator \r\n" + msg
  Logger.log(msg);
  ui.alert(msg);
}

Found the way to get the cell A1Notation, use getCell() on the range, then getA1Notation.找到获取单元格 A1Notation 的方法,在范围上使用 getCell(),然后使用 getA1Notation。

cellA1 = range.getCell(1, 1).getA1Notation();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM