3

我定义了一个自定义函数,它从字符串中提取部分地址:

/*
 * Return the number preceding 'N' in an address
 *    '445 N 400 E' => '445'
 *    '1083 E 500 N' => '500'
 */
function NorthAddress(address) {
  if (!address) return null;
  else {
    var North = new RegExp('([0-9]+)[\\s]+N');
    var match = address.match(North);
    if (match && match.length >= 2) {
      return match[1];
    }
    return null;
  }
}

我想将此函数用作在FILTER(...)存储这些地址的电子表格中调用的条件之一:

=FILTER('Sheet 1'!A:A, NorthAddress('Sheet 1'!B:B) >= 450))

但是,当我NorthAddress这样调用时,它会在 B 列中获取所有值的数组,而我终其一生都找不到任何关于如何处理它的文档。最明显的方法(对我来说)似乎不起作用:遍历数组调用NorthAddress每个值,并返回一个结果数组。

我的函数需要返回什么才能FILTER按预期工作?

4

3 回答 3

4

当调用自定义函数传递多单元格范围时,它会接收一个值矩阵(二维数组),无论该范围是单列还是单行,它始终是一个矩阵。你也应该返回一个矩阵。

无论如何,我不会对此使用自定义函数,因为已经有本机电子表格公式:RegexMatchRegexExtract公式RegexReplace。要获得“如果匹配”行为,只需将它们包装在IfError公式中即可。

于 2012-06-06T11:26:50.217 回答
0

它不起作用,因为地址是,如果您只将一个单元格作为 arg 传递一个字符串、一个范围、一个字符串矩阵。

所以你返回一个字符串, FILTER 使用一个布尔数组来过滤数据,所以你的过滤器的条件是string< number

您只需在返回值时将字符串转换为数字

/*
 * Return the number preceding 'N' in an address
 *    '445 N 400 E' => '445'
 *    '1083 E 500 N' => '500'
 */
function NorthAddress(address) {
  if(typeof address == "string"){
    if (!address) return "#N/A";
    else {
      var North = new RegExp('([0-9]+)[\\s]+N');
      var match = address.match(North);
      if (match && match.length >= 2) {
        return parseInt(match[1]);
      }
      return "#N/A";
    }
  } else {
    var matrix = new Array();
    for(var i = 0; i<address.length; i++){
      matrix[i] = new Array();
      for(var j = 0; j<address[i].length; j++){
        var North = new RegExp('([0-9]+)[\\s]+N');
        var match = address[i][j].match(North);
        if (match && match.length >= 2) {
          matrix[i].push(parseInt(match[1]));
        }
      }
    }
    return matrix;
  }
}

希望这会有所帮助。

于 2012-06-06T11:25:35.843 回答
0

toString()我将其添加为答案,因为我发现如果未调用时在引用的单元格或范围中传递了数值,则自定义函数会返回错误:

function NorthAddress(address) {
  if (!address) return null;
  else {
    if (address.constructor == Array) {
      var result = address;
    }
    else {
      var result = [[address]];
    }
    var north = new RegExp('([0-9]+)[\\s]+N');
    var match;
    for (var i = 0; i < result.length; i++) {
      for (var j = 0; j < result[0].length; j++) {
        match = result[i][j].toString().match(north);
        if (match && match.length >= 2) {
          result[i][j] = parseInt(match[1]);
        }
        else {
          result[i][j] = null;
        }
      }
    }
    return result;
  }
}
于 2012-06-06T11:58:44.307 回答