Ищу помощь в пользовательской функции, возвращающей двумерный массив, который может переполниться - PullRequest
0 голосов
/ 24 января 2020

Чтобы свести к минимуму количество вызовов, я пытаюсь использовать один вызов функции и заполнить диапазон (несколькими ячейками). Моя функция 'getTotal' ниже работает нормально, но я застрял в 'У вас нет разрешения на вызов setValue'. Диапазон, который я пытаюсь заполнить, - это C4: C12 (см. Прикрепленный экран), и я передаю функцию = getTotal (A4: A12, B4: B12) в функцию. Функция вызывается из C16.

Мы не можем вызвать setValue из пользовательской функции, но я не уверен, смогу ли я вернуть двумерный массив, который может переполниться в C4: C12. Документация и ответы здесь не помогли мне, поэтому я ищу помощь.

enter image description here

function getTotal(oSetVal, vRange) {

  if (Array.isArray(oSetVal[0]) && Array.isArray(vRange[0])) {
    var asp = SpreadsheetApp.getActiveSpreadsheet();
    if (!asp) {
      return;
    }
    var as = asp.getActiveSheet();
    var ss = asp.getSheetByName("Data")
    if (!ss) {
      return;
    }
    if (Array.isArray(oSetVal[0]) && Array.isArray(vRange[0])) {
        var activeCol = as.getActiveCell().getColumn();
        var numCol = activeCol-1
        var textCol = activeCol-2
        var drRow = as.getActiveCell().getRow()-4;
        var textRowStart = drRow - 15;
        var cSource = ss.getRange(3, 2, 5000, 1).getValues();
        var cKcal = ss.getRange(3, 4, 5000, 1).getValues();
        var vEnergy = 0;

        if (textRowStart < 3){
            textRowStart = 3;
        }
        var textRowEnd = drRow
        var textSource = as.getRange(textRowStart, textCol, textRowEnd, 1)
        var numSource = as.getRange(textRowStart, numCol, textRowEnd, 1)
        var numSource = as.getRange(textRowStart, numCol, textRowEnd, 1)
        var setSource = as.getRange(textRowStart, activeCol, textRowEnd, 1)
        for (var k = 1; k <= textRowEnd-textRowStart; k++) {
            var tVal = textSource.getCell(k,1).getValue();
            var nVal = numSource.getCell(k,1).getValue();
            if (tVal.length > 0 && isNumericVal(nVal)) {
                for (var i = 0; i < cSource.length; i++) {
                    if(cSource[i][0] == tVal){
                        var ckl = cKcal[i][0];
                        var vEn = parseFloat((ckl * nVal / 100))
                        vEn = +vEn.toFixed(1)
                        vEnergy = vEnergy + vEn
                        setSource.getCell(k,1).setValue(vEn); 
                    }
                }
            }
        }
    }

  return vEnergy
  }
}

Спасибо

Ответы [ 2 ]

0 голосов
/ 24 января 2020

Если вы хотите продолжать использовать пользовательскую функцию:

Вам нужно использовать return values вместо setValues(). Вы не можете устанавливать значение произвольных ячеек из пользовательской формулы.

Также, как указано @ Cooper"Вы можете вернуть двумерный массив, но он может только переполниться вниз и направо. Не вверх и влево ". То есть вы не можете переполнить вверх, но только вниз.

Это означает, что вам нужно вызывать вашу функцию из ячейки C4 , а не из C16 * 1016. *.

Чтобы изменить формулу и включить переполнение, вам нужно создать 2D-массив требуемых размеров.

В вашем случае 1 столбец и 9 строк зададут все vEn ценности. Вы также можете использовать 13 строк, если хотите установить vEn и vEnergy в один go.

. Проверьте здесь , чтобы узнать, как это сделать.

Применение образца к вашему делу:

В начале своей функции вы можете определить: var myArray = [];

, а затем заменить внутреннюю часть вашего на l oop (setSource.getCell(k,1).setValue(vEn);) с

myArray[k] = [];
myArray[k].push(vEn);

И, наконец, замените return vEnergy на:

myArray[12].push(vEnergy);
return myArray;

Я не проверял ваш код, поскольку у меня нет доступа к «Данные», но я надеюсь, что мой ответ поможет вам изменить код нужным вам способом.

0 голосов
/ 24 января 2020

Пользовательская функция не может влиять на ячейки, отличные от тех, для которых она возвращает значение. Другими словами, пользовательская функция не может редактировать произвольные ячейки, только ячейки, из которых она вызывается, и соседние ячейки. Чтобы редактировать произвольные ячейки, используйте пользовательское меню для запуска функции.

Вы можете вернуть двумерный массив, но он может только переполняться вниз и вправо. Не вверх и влево.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...