A1 gösterimini kullanmadan Google Apps komut dosyası özel işlevinde geçiş aralığı


10

Google Apps komut dosyasında yeniyim ve hücreler arka plan rengi gibi belirli ölçütleri karşıladığında hücre değerlerini toplayan bir e-tablo için bir işlev oluşturmak istiyorum. Dahası, aralığı bir dizi olarak iletmek ve aşağıdaki nedenden dolayı A1 gösterimini kullanmak istemiyorum .

Burada A1 notasyonunu kullanan bir fonksiyon buldum . Sorun, belirli bir hücreye sahip olduğumda

=sumWhereBackgroundColorIs("white", "A1:A10")

ve değeri sağ bitişik hücreye kopyalarım sonuç yine olacak

= sumWhereBackgroundColorIs ("beyaz", "A1: A10" )

ben isterken

= sumWhereBackgroundColorIs ("beyaz", "B1: B10" )

Aksi takdirde giriş argümanını her zaman manuel olarak değiştirmem ve bu işlevi yaygın olarak kullanmam gerektiğinden bundan kaçınmak istiyorum.

Bu yüzden kullanarak bir dizi değer olarak bir aralık geçirerek denedim

=sumIfBgColor(#ffffff, A1:A10)


function sumIfBgColor(color, range){
    var x = 0;
    for(var i = 0; i < range.length; i++){
      for(var j = 0; j < range[i].length; j++){

        var cell = getCell();

        if(cell.getBackgroundColor() == color)
          x += parseFloat(range[i][j]);
      }
    }
    return x;
}

ama sahip olduğumdan başlayarak hücreyi (yani Range türünün nesnesini) nasıl alacağımı bilmiyorum.


Bir API çağrısı kullanılmadan bu mümkün değildir. Bu durumda A1 notation,.
Jacob Jan Tuinstra

Bunu söylemekten nefret ediyorum, ama bulduğun senaryo çok etkili değil. Birkaç satırda, fark önemli olmayabilir, ancak 100 gibi daha fazla satırınız varsa, işlem süresindeki fark çok büyüktür. Hazırladığım komut dosyası 30 kat daha hızlı, çünkü yalnızca üç API çağrısı kullanıyor. Bulduğunuz komut dosyası, yaklaşık 100 satır kullanır. 300 API çağrısı. Örneğime bakın. Verilen sayılar milisaniyedir.
Jacob Jan Tuinstra


1
şunu kullanmayı deneyin: = sumWhereBackgroundColorIs ("beyaz", ADRES (SATIR (A1), SÜTUN (A10), 4) & ":" & ADRES (SATIR (A10), SÜTUN (A10), 4))
gezici

Yanıtlar:


8

@ Jacob'un imkansızlık iddiasına göre, ben bunu reddediyorum ... (ama gelişmiş hız için teşekkürler)

kullanarak:

=sumIfBgColor("#ffffff", A1:A10, COLUMN(A1), ROW(A1))

Aşağıdaki işlevlerle istediğinizi yapabilirsiniz.

/**
 * Sums cell values in a range if they have the given background color
 * 
 * @param  {String} color    Hex string of color eg ("#ffffff")
 * @param  {Array.Array} range    Values of the desired range
 * @param  {int} startcol The column of the range
 * @param  {int} startrow The first row of the range
 * 
 * @return {int}          Sum of all cell values matching the condition
 */
function sumIfBgColor(color, range, startcol, startrow){
  // convert from int to ALPHANUMERIC - thanks to 
  // Daniel at http://stackoverflow.com/a/3145054/2828136
  var col_id = String.fromCharCode(64 + startcol);
  var endrow = startrow + range.length - 1
  // build the range string, then get the background colours
  var range_string = col_id + startrow + ":" + col_id + endrow
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var getColors = ss.getRange(range_string).getBackgrounds();

  var x = 0;
  for(var i = 0; i < range.length; i++) {
    for(var j = 0; j < range[0].length; j++) {
      // Sometimes the cell background is eg 'white' rather than '#ffffff'.
      // I don't know why - I think it's a bug.
      // so we remove that inconsistency with colourNameToHex
      // courtesy of Greg at http://stackoverflow.com/a/1573141/2828136
      if(colourNameToHex(getColors[i][j].toString()) == color) {
        x += range[i][j];
      }
    }
  }
  return x;
}

/**
 * Takes a colour string and returns it to a hex string. If a non-matching string is
 * passed, it will return the argument as is - for this situation it means that a
 * hex string can be passed to it and be returned as is. This is not for production.
 * 
 * @param  {string} color    Must be either a colour name or hex string of color eg ("#ffffff")
 * 
 * @return {object|string}          hex string of color eg ("#ffffff") or the argument given.
 */
function colourNameToHex(colour)
{
    var colours = {"aliceblue":"#f0f8ff","antiquewhite":"#faebd7","aqua":"#00ffff","aquamarine":"#7fffd4","azure":"#f0ffff",
    "beige":"#f5f5dc","bisque":"#ffe4c4","black":"#000000","blanchedalmond":"#ffebcd","blue":"#0000ff","blueviolet":"#8a2be2","brown":"#a52a2a","burlywood":"#deb887",
    "cadetblue":"#5f9ea0","chartreuse":"#7fff00","chocolate":"#d2691e","coral":"#ff7f50","cornflowerblue":"#6495ed","cornsilk":"#fff8dc","crimson":"#dc143c","cyan":"#00ffff",
    "darkblue":"#00008b","darkcyan":"#008b8b","darkgoldenrod":"#b8860b","darkgray":"#a9a9a9","darkgreen":"#006400","darkkhaki":"#bdb76b","darkmagenta":"#8b008b","darkolivegreen":"#556b2f",
    "darkorange":"#ff8c00","darkorchid":"#9932cc","darkred":"#8b0000","darksalmon":"#e9967a","darkseagreen":"#8fbc8f","darkslateblue":"#483d8b","darkslategray":"#2f4f4f","darkturquoise":"#00ced1",
    "darkviolet":"#9400d3","deeppink":"#ff1493","deepskyblue":"#00bfff","dimgray":"#696969","dodgerblue":"#1e90ff",
    "firebrick":"#b22222","floralwhite":"#fffaf0","forestgreen":"#228b22","fuchsia":"#ff00ff",
    "gainsboro":"#dcdcdc","ghostwhite":"#f8f8ff","gold":"#ffd700","goldenrod":"#daa520","gray":"#808080","green":"#008000","greenyellow":"#adff2f",
    "honeydew":"#f0fff0","hotpink":"#ff69b4",
    "indianred ":"#cd5c5c","indigo ":"#4b0082","ivory":"#fffff0","khaki":"#f0e68c",
    "lavender":"#e6e6fa","lavenderblush":"#fff0f5","lawngreen":"#7cfc00","lemonchiffon":"#fffacd","lightblue":"#add8e6","lightcoral":"#f08080","lightcyan":"#e0ffff","lightgoldenrodyellow":"#fafad2",
    "lightgrey":"#d3d3d3","lightgreen":"#90ee90","lightpink":"#ffb6c1","lightsalmon":"#ffa07a","lightseagreen":"#20b2aa","lightskyblue":"#87cefa","lightslategray":"#778899","lightsteelblue":"#b0c4de",
    "lightyellow":"#ffffe0","lime":"#00ff00","limegreen":"#32cd32","linen":"#faf0e6",
    "magenta":"#ff00ff","maroon":"#800000","mediumaquamarine":"#66cdaa","mediumblue":"#0000cd","mediumorchid":"#ba55d3","mediumpurple":"#9370d8","mediumseagreen":"#3cb371","mediumslateblue":"#7b68ee",
    "mediumspringgreen":"#00fa9a","mediumturquoise":"#48d1cc","mediumvioletred":"#c71585","midnightblue":"#191970","mintcream":"#f5fffa","mistyrose":"#ffe4e1","moccasin":"#ffe4b5",
    "navajowhite":"#ffdead","navy":"#000080",
    "oldlace":"#fdf5e6","olive":"#808000","olivedrab":"#6b8e23","orange":"#ffa500","orangered":"#ff4500","orchid":"#da70d6",
    "palegoldenrod":"#eee8aa","palegreen":"#98fb98","paleturquoise":"#afeeee","palevioletred":"#d87093","papayawhip":"#ffefd5","peachpuff":"#ffdab9","peru":"#cd853f","pink":"#ffc0cb","plum":"#dda0dd","powderblue":"#b0e0e6","purple":"#800080",
    "red":"#ff0000","rosybrown":"#bc8f8f","royalblue":"#4169e1",
    "saddlebrown":"#8b4513","salmon":"#fa8072","sandybrown":"#f4a460","seagreen":"#2e8b57","seashell":"#fff5ee","sienna":"#a0522d","silver":"#c0c0c0","skyblue":"#87ceeb","slateblue":"#6a5acd","slategray":"#708090","snow":"#fffafa","springgreen":"#00ff7f","steelblue":"#4682b4",
    "tan":"#d2b48c","teal":"#008080","thistle":"#d8bfd8","tomato":"#ff6347","turquoise":"#40e0d0",
    "violet":"#ee82ee",
    "wheat":"#f5deb3","white":"#ffffff","whitesmoke":"#f5f5f5",
    "yellow":"#ffff00","yellowgreen":"#9acd32"};

    if (typeof colours[colour.toLowerCase()] != 'undefined')
        return colours[colour.toLowerCase()];

    return colour;
}

1
Sadece denedim ve işe yarıyor. Web Uygulamalarında bu cevaba sahip olmak çok güzel.
Jacob Jan Tuinstra

2
Bunları test ediyorum, biliyorsun. ;-)
Tom Horwood

Teşekkürler fıstık - sadece eski cevabımı okuyordum ve biraz renk yardımcı olacağını düşündüm (sanırım olsa olmayacak). Üzgünüm not defteri tarzı cevapları okumak zorunda herkes :-)
Tom Horwood

2

Başvuru: http://igoogledrive.blogspot.com/2015/11/google-spreadsheet-sum-of-colored-cells.html

Parametreleri özel işleve dize olarak iletmek yerine aşağıdaki komut dosyası girdi olarak aralık alır:

/**
* @param {string} color String as background color to be searched for in sumRange
* @param {range} sumRange Range to be evaluated
* @return {number}
* @customfunction
*/

function sumColoredCells(color,sumRange) {
  var activeRange = SpreadsheetApp.getActiveRange();
  var activeSheet = activeRange.getSheet();
  var formula = activeRange.getFormula();
  var rangeA1Notation = formula.match(/\,(.*)\)/).pop();
  var range = activeSheet.getRange(rangeA1Notation);
  var bg = range.getBackgrounds();
  var values = range.getValues();
  var total = 0;

  for(var i=0;i<bg.length;i++)
    for(var j=0;j<bg[0].length;j++)
      if( bg[i][j] == color )
        total=total+(values[i][j]*1);
  return total;
};

Aşağıdaki ekran görüntüsüne bir göz atın:

resim açıklamasını buraya girin


1

Aşağıdaki küçük senaryo hile yapacak.

kod

function sumIfBgColor(color, range){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var getColors = ss.getRange(range).getBackgrounds();
  var getValues = ss.getRange(range).getValues(), x = 0;
  for(var i = 0; i < getValues.length; i++) {
    for(var j = 0; j < getValues[0].length; j++) {
      if(getColors[i][j].toString() == color) {
        x += getValues[i][j];
      }
    }
  }
  return x;
}

Açıklaması

İlk olarak, aktif e-tablo belirlenir. Ardından, aralığa dayalı olarak hem değerler hem de renkler getirilir. Değerler renkler ve sonuçta toplamı yinelemek için kullanılacaktır.

kullanım

resim açıklamasını buraya girin

Misal

Sizin için bir örnek dosya oluşturdum: Arka plana dayalı toplam


1
Bu işlev işe yarıyor, ancak A1 gösterimi ile çağırmanız gerekiyor, yani bir hücreye yazma = sumIfBgColor (#ffffff, "A1: A10") Bu, yukarıda yazdığım gereksinimlere uymuyor, yani formülü hücreler arasında kopyalayıp yapıştırırken İçeriği manuel olarak düzenlemem gerekecek
Ganswer

@ganswer Sorunuza yaptığım yorumda bunun mümkün olmadığını söylemiştim. Sahip olduğunuz kod A1 gösterimi ile veya A1 gösterimi olmadan çalışmamış olmalıdır. Bu yüzden bir senaryo yazdım.
Jacob Jan Tuinstra

üzgünüm yorumunuzu okumadım. Çok kötü haber! Yani yolu yok ... A1 gösterimini kullanamıyorum, e-tablomun düzenini tamamen değiştirmek zorunda kalacağım. teşekkürler
Ganswer

@ganswer Cevabımı yararlı buldunuz mu?
Jacob Jan Tuinstra

1
iyi bir seçenek ama zaten A1 notasyonu ile çalışan benzer bir fonksiyonum vardı. Lütfen cevabınızı en üstte, aradığım şeyin mümkün olmadığını söyleyen bir yorum da dahil olmak üzere yanıtınızı değiştirin, böylece cevabınızı çözüm olarak kabul edebilirim
Ganswer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.