2012-06-06 49 views
2

我有一個自定義函數定義的提取從字符串地址的一部分:如何在FILTER上使用自定義函數?

/* 
* 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

當一個自定義函數被調用傳遞一個多單元格範圍時,它接收到一個值矩陣(2d數組),如果該範圍是單列還是單行,它並不重要,它總是一個矩陣。你也應該返回一個矩陣。

無論如何,我不會使用自定義功能這一點,因爲已經有本地的電子表格公式:RegexMatchRegexExtractRegexReplace公式。要獲得「if match」行爲,只需將它們包裝在IfError公式中。

+3

例如:'= FILTER( 'Sheet 1'!A:A; VALUE(REGEXEXTRACT('Sheet 1'!B:B;「([0-9] +)N」))> = 450)' – AdamL

+0

感謝您的額外英里AdamL :) –

0

它不起作用,因爲地址是,如果你只傳遞一個單元格作爲一個字符串,一個範圍,一個字符串矩陣。

所以你返回一個字符串,過濾器中使用布爾數組來過濾數據,讓你的過濾器的狀況是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; 
    } 
} 

希望這會有所幫助。

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; 
    } 
} 
相關問題