Vượt qua phạm vi trong chức năng tùy chỉnh tập lệnh của Google Apps mà không cần sử dụng ký hiệu A1


10

Tôi chưa quen với tập lệnh Google Apps và tôi muốn tạo một hàm cho bảng tính tính tổng các giá trị ô khi các ô đáp ứng các tiêu chí nhất định, chẳng hạn như màu nền. Hơn nữa, tôi muốn vượt qua phạm vi dưới dạng một mảng và không sử dụng ký hiệu A1 vì lý do sau.

Tôi tìm thấy một hàm sử dụng ký hiệu A1 ở đây . Vấn đề là khi tôi có nó trên một ô đã cho

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

và tôi sao chép giá trị sang ô bên phải, kết quả sẽ lại

= sumWhereBackgroundColorIs ("trắng", "A1: A10" )

trong khi tôi muốn có

= sumWhereBackgroundColorIs ("trắng", "B1: B10" )

mặt khác, tôi luôn luôn sửa đổi thủ công đối số đầu vào và tôi muốn tránh điều này vì tôi đã sử dụng rộng rãi chức năng này.

Do đó, tôi đã thử bằng cách chuyển một phạm vi dưới dạng một mảng các giá trị bằng cách sử dụng

=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;
}

nhưng tôi không biết làm thế nào để lấy ô (tức là đối tượng của Phạm vi loại) bắt đầu từ những gì tôi có.


Điều đó là không thể, nếu không sử dụng lệnh gọi API. Nếu điều đó xảy ra, bạn cần sử dụng A1 notation.
Jacob Jan Tuinstra

Tôi ghét phải nói nó, nhưng kịch bản bạn tìm thấy không hiệu quả lắm. Trên một vài hàng, sự khác biệt có thể không đáng kể, nhưng nếu bạn có nhiều hàng hơn, giả sử 100, thì sự khác biệt về thời gian xử lý là rất lớn. Kịch bản tôi đã chuẩn bị nhanh hơn 30 lần, vì nó chỉ sử dụng ba lệnh gọi API. Kịch bản bạn tìm thấy sử dụng cho 100 hàng, xấp xỉ. 300 cuộc gọi API. Xem ví dụ của tôi. Các số đã cho, là mili giây.
Jacob Jan Tuinstra

Điều này có thể hữu ích: webapps.stackexchange.com/a/58179/12075
sanmai

1
cố gắng sử dụng này: = sumWhereBackgroundColorIs ( "trắng", ADDRESS (ROW (A1), COLUMN (A10), 4) & ":" & ADDRESS (ROW (A10), COLUMN (A10), 4))
Roamer

Câu trả lời:


8

Đối với yêu cầu không thể của Jacob, tôi bác bỏ nó vì thế ... (nhưng cảm ơn vì tốc độ được cải thiện)

sử dụng:

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

với các chức năng sau đây sẽ làm những gì bạn muốn.

/**
 * 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
Chỉ cần thử nó và nó hoạt động. Rất tốt để có câu trả lời này trên Ứng dụng web.
Jacob Jan Tuinstra

2
Tôi biết kiểm tra những thứ này, bạn biết đấy. ;-)
Tom Horwood

Cảm ơn pnuts - chỉ đọc qua câu trả lời cũ của tôi và nghĩ rằng một chút màu sắc có thể giúp ích (tôi đoán nó sẽ không xảy ra mặc dù). Xin lỗi tất cả những người phải đọc câu trả lời kiểu notepad :-)
Tom Horwood

2

Tham khảo: http://igoogledrive.blogspot.com/2015/11/google-s Lansheet-sum-

of- colored-cells.html Thay vì truyền tham số dưới dạng chuỗi cho hàm tùy chỉnh, tập lệnh sau lấy đầu vào làm phạm vi:

/**
* @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;
};

Hãy nhìn vào ảnh chụp màn hình sau:

nhập mô tả hình ảnh ở đây


1

Các kịch bản nhỏ sau đây sẽ thực hiện các mẹo.

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;
}

Giải thích

Đầu tiên, bảng tính hoạt động được xác định. Sau đó, cả giá trị và màu sắc, dựa trên phạm vi, được tìm nạp. Các giá trị sẽ được sử dụng để lặp qua các màu và cuối cùng là tổng.

Sử dụng

nhập mô tả hình ảnh ở đây

Thí dụ

Tôi đã tạo một tệp ví dụ cho bạn: Tổng hợp dựa trên Nền


1
Hàm này hoạt động nhưng bạn phải gọi nó bằng ký hiệu A1, tức là viết trên một ô = sum IfBgColor (#ffffff, "A1: A10") Điều này không phù hợp với các yêu cầu tôi đã viết ở trên, cụ thể là trong khi sao chép và dán công thức giữa các ô Tôi sẽ phải chỉnh sửa nội dung theo cách thủ công
Ganswer

@ganswer Trong nhận xét của tôi cho câu hỏi của bạn, tôi đã đề cập đến điều đó là không thể. Mã bạn không nên làm việc có hoặc không có ký hiệu A1. Vì vậy, tôi đã viết một kịch bản mà.
Jacob Jan Tuinstra

xin lỗi tôi không đọc bình luận của bạn Tin xấu quá! Vì vậy, không có cách nào..Tôi không thể sử dụng ký hiệu A1, tôi sẽ phải thay đổi hoàn toàn bố cục của bảng tính. cảm ơn
Ganswer

@ganswer Bạn có thấy câu trả lời của tôi hữu ích không?
Jacob Jan Tuinstra

1
đó là một lựa chọn tốt nhưng tôi đã có một chức năng tương tự hoạt động với ký hiệu A1. Vui lòng sửa đổi câu trả lời của bạn, bao gồm ở đầu một nhận xét nói rằng những gì tôi tìm kiếm là không thể, để tôi có thể chấp nhận câu trả lời của bạn dưới dạng giải pháp
Ganswer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.