Search code examples
formulalibreoffice-calc

Compare cell against series of cell pairs


I'm trying to make a LibreOffice spreadsheet formula that populates a column based on another input column, comparing each input with a series of range pairs defined in another sheet and finally outputting a symbol based on matched criteria. I have a series of ranges that specify a - output, and another series that corresponds to +, but not all inputs will fall into a category. I am using this trinary output later for another expression, which I already have in place.

My question becomes: how can I test input against each range pair without spelling out the cell coordinates for each individual cell (ie OR(AND(">= $A$1", "< $B$1"), AND(">=$A$2", "<$B$2"), ...))? Ideally I could just specify an array to compare against like $A$1:$B$4. Writing it in a python macro would work, too, since I don't plan on sharing this file.

I wrote a really quick list comp in python to illustrate what I'm after. This snippet would be one half, such as testing - qualification, and these values may be fed into a condition that outputs the symbol:

>>> def cmp(f, r):
...     return r[0] <= f < r[1]
>>> f = (1, 2, 3)
>>> ranges = ((2, 5), (4, 6), (3, 8))
>>> [any([cmp(i, r) for r in ranges]) for i in f]
[False, True, True]

Here is a small test example with real input and real ranges.


Solution

  • Change the range pairs so that they are in two columns starting from A13. Be sure that they are in sorted order (Data -> Sort).

    A           B           C
    ~~~~~~~~    ~~~~~~~~    ~
    145.1000    145.5000    -
    146.0000    146.4000    +
    146.6000    147.0000    -
    147.0000    147.4000    +
    147.6000    148.0000    -
    440.0000    445.0000    +
    

    In each row, specify whether it is negative or positive. To do this, I entered the following formula in C13 and filled down. If the range pairs are not consistent enough then enter values for C13 and below manually.

    =IF(ISODD(ROW());"-";"+")
    

    Now, enter the following formula in cell C3 and fill down.

    =IFNA(IF(
        VLOOKUP(A3;A$13:C$18;2;1) >= A3;
        VLOOKUP(A3;A$13:C$18;3;1);
        "None");"None")
    

    The formula finds the closest pair and then checks if the number is inside that range or not. For better testing, I would also suggest using 145.7000 as input, which should result in no shift if I understood the question correctly.

    The results in column C:

    -
    +
    None
    None
    

    Documentation: VLOOKUP, IFNA, ROW.

    EDIT:

    The following formula produces correct results for the example data you gave, and it works for anything between 144.0 and 148.0.

    =IFNA(VLOOKUP(A3;A$13:C$18;3;1); "None")
    

    However, 150.0 produces - and 550.0 produces +. If that is not what you want, then use the formula above that has two VLOOKUP expressions.