Formula that can determine the pair of values that gives the smallest difference

mramono

New Member
Joined
Mar 1, 2017
Messages
25
Hi

I have values in five different cells scattered across my excel sheet and I want to find the pair of those values that gives the smallest difference.

Assuming I have the value in a1, b1, c1, d1 and e1

Then I test the difference as follows

E.g. a1-b1 = 0.50
a1-d1 = 0.53
b1-c1 = 0.49
c1-d1 = 0.31
a1-e1 = 0.48
b1-e1 = 0.45
c1-e1 = 0.32
d1-e1 = 0.53

looking at the answers in column a2, such that a2 equals the formula that gives the smallest answer (In this case the formula in a2 must select c1-d1 because the answer is 0.31 which is the smallest of all the answers. The point is if the values in a1,b1,c1,d1,e1 changes respectively, the formula in a2 will be different as the smallest answer would have changed also for the pairs of values tested.

I will appreciate suggestion how to figure out such an excel function (in a2 for instance)
 
OK well my solution clearly doesn't return the address of the cells the produce the minimum result, and I agree that doing that in a single formula would be challenging.

If I had to deal with this problem myself, I would use helper columns to work out the difference for each of the 8 combinations.
That way you could see, not only which combination of tests give the minimum results, but also how close the other combinations are to the minimum.
That might be useful information.
 
Upvote 0

Excel Facts

Convert text numbers to real numbers
Select a column containing text numbers. Press Alt+D E F to quickly convert text to numbers. Faster than "Convert to Number"
If I had to deal with this problem myself, I would use helper columns to work out the difference for each of the 8 combinations.
If they want a non-VBA approach, I would DEFINITELY recommend that.

However, if they are able to use VBA, you usually don't need helper columns.
 
Upvote 0
So, you mean it will always be columns P, AB, AO, BA, and BN? Is that what you are saying?

Is this going to run on just one row at a time, and do you want the macro to run against a bunch of rows at once?
How should we communicate to the macro which rows to run on (we can do the selected rows, input for rows, or hard-code rows)?

Yes, colums will always be P, AB, AO, BA, BN and answer in BZ (but the columns next to them should also do the same). Meaning CA will work on Q, AC, AP, BB, and BO. That means answer in CA, which is to the right of BZ should use respective columns to the right of P, AB, AO, BA, BN respectively (Q, AC, AP, BB, and BO). And that should be the case for answers in BP up to BX respectively.

I'll like it to run a bunch of rows at once, I think hard-code rows will work fine.
 
Upvote 0
Hmmm, your columns do not seem to be evenly spaced out.
Code:
Column P = column 16
Column AB = column 28
Column AO = column 41
Column BA = column 53
Column BN = column 66
This would be much easier if they were all evenly spaced out (some as 12 apart, some are 13 apart).

I think this can get really messy, even in VBA.
Please explicitly tell us ALL the different sets of columns that need to be compared, and all the rows you want included in this.
 
Upvote 0
Hmmm, your columns do not seem to be evenly spaced out.
Code:
Column P = column 16
Column AB = column 28
Column AO = column 41
Column BA = column 53
Column BN = column 66
This would be much easier if they were all evenly spaced out (some as 12 apart, some are 13 apart).

I think this can get really messy, even in VBA.
Please explicitly tell us ALL the different sets of columns that need to be compared, and all the rows you want included in this.

I have put the data more or less as it appears on my spreadsheet, from column B to BW

Column B and AA are repeats, column N and AM are also repeats from a different laboratory, Column AZ is umpire lab. The final results are in column BL. With the data below then:

BL1720 = either (B1720+N1720)/2 or (AA1720+AM1720)/2 or (B1720+AM1720)/2 or (N1720+AA1720)/2 or (B1720+AZ1720)/2 or (N1720+AZ1720)/2 or (AA1720+AZ1720)/2 or (AM1720+AZ1720)/2

and the choice of the answer that appears in column BL is based on which of the following gives the smallest answer or difference {(B1720-N1720)/min(B1720,N1720), (AA1720-AM1720)/min(AA1720,AM1720), (B1720-AM1720)/min(B1720,AM1720), (N1720-AA1720)/min(N1720,AA1720), (B1720-AZ1720)/min(B1720,AZ1720), (N1720-AZ1720)/min(N1720,AZ1720), (AA1720-AZ1720)/min(AA1720,AZ1720), (AM1720-AZ1720)/min(AM1720,AZ1720)}



BCDEFGHIJKLMNOPQRSTUVWXYZAAABACADAEAFAGAHAIAJAKALAMANAOAPAQARASATAUAVAWAXAYAZBABBBCBDBEBFBGBHBIBJBKBLBMBNBOBPBQBRBSBTBUBVBW
1PtPdRhAu3PGM RuIrCuNiCr2O3CoPtPdRhAu3PGMRuIrCuNiCr2O3SCoPtPdRhAu3PGMRuIrCuNiCr2O3CoPtPdRhAu3PGMRuIrCuNiCr2O3SCoPtPdRhAuRuIrCuNiCr2O3SCoPtPdRhAu3PGMRuIrCuNiCr2O3SCo
261.8026.358.062.3598.56 12.994.000.731.570.7248.0021.507.341.3978.239.752.450.772.100.5561.8026.358.062.3598.5612.994.000.731.570.7242.7021.905.982.4574.3910.503.540.972.530.5547.4622.347.011.3910.452.490.621.5447.7321.927.181.3978.2110.102.470.751.560.64
361.8026.358.062.3598.56 12.994.000.731.570.7248.0021.507.341.3978.239.752.450.772.100.5561.8026.358.062.3598.5612.994.000.731.570.7242.7021.905.982.4574.3910.503.540.972.530.5547.4622.347.011.3910.452.490.621.5447.7321.927.181.3978.2110.102.470.751.560.64
461.8026.358.062.3598.56 12.994.000.731.570.7248.0021.507.341.3978.239.752.450.772.100.5561.8026.358.062.3598.5612.994.000.731.570.7242.7021.905.982.4574.3910.503.540.972.530.5547.4622.347.011.3910.452.490.621.5447.7321.927.181.3978.2110.102.470.751.560.64
544.9120.106.270.7672.04 9.102.770.501.231.1447.6022.006.570.7676.9310.602.650.621.740.8244.9120.106.270.7672.049.102.770.501.231.1448.9022.607.190.8079.4910.602.601.322.250.8222.547.1510.050.461.1846.2622.276.420.7675.7010.332.710.481.200.98

<tbody>
</tbody>

<tbody>
</tbody>


The answers in BL are the correct answers i'm looking for, but i had to do manual and rigorous checks to get them. The idea is to get the same answers automatically.
 
Upvote 0
No, I am looking for specifics.

When I say different sets of columns, here is what I mean.
- You said to compare columns P, AB, AO, BA, and BN. That is ONE set. What are all the other sets (what exactly are all the other 5 columns sets we want to compare)? Just list out all the other 5 columns sets.

Regarding all the rows we need to compare, how is the macro to know which rows?
In your example, you used row 1720. What are all the other rows?
Will it always be the same?
- If "Yes", what exactly are those rows?
- If "No", how can the code figure out which rows to run against?
 
Upvote 0
No, I am looking for specifics.

When I say different sets of columns, here is what I mean.
- You said to compare columns P, AB, AO, BA, and BN. That is ONE set. What are all the other sets (what exactly are all the other 5 columns sets we want to compare)? Just list out all the other 5 columns sets.

Regarding all the rows we need to compare, how is the macro to know which rows?
In your example, you used row 1720. What are all the other rows?
Will it always be the same?
- If "Yes", what exactly are those rows?
- If "No", how can the code figure out which rows to run against?

For simplicity so that you can be able to use the data I provided above, i have shifted the data such that: Column P is now B, AB is now N, AO is now AA, column BA is now AM, column BN is now AZ, and column BZ is now BL.

below is how set of columns are arranged.

I forgot to change the row number, in my original example the row number was 1720 but with the shifting now the row is row 2


BCDEGHIJ
NOPQSTUV
AAABACADAFAGAHAI
AMANAOAPARASATAU
AZBABBBCBDBEBFBG
BLBMBNBOBQBRBSBT (ANS)

<colgroup><col span="4"><col><col><col span="2"></colgroup><tbody>
</tbody>

The formula in row 2, row 3, row 4 and row 5 are exactly the same. The idea is once i have formulas populated in say in row 2 I can just copy the formula down to row 5.
BL, BM, BN, BO, BR, BS and BT contains the answer for each set respectively.
 
Upvote 0
Try this:
Code:
Sub MyMinDiff()

    Dim diff As Double
    Dim minDiff As Double
    Dim frml As String
    Dim cols As Variant
    Dim i As Integer
    Dim j As Integer
    Dim rows As Long
    Dim cloop As Long
    
    Application.ScreenUpdating = False
    
'   Set array of initial columns (numerical equivalents of B, N, AA, AL, and AZ)
    cols = Array(2, 14, 27, 39, 52)
    
'   Loop through rows 2 through 5
    For rows = 2 To 5
'       Run through 8 different sets per row
        For cloop = 0 To 7
            minDiff = 999999999
            For i = LBound(cols) To UBound(cols)
                For j = LBound(cols) To UBound(cols)
                    If (i <> j) And (Cells(rows, cols(i) + cloop) >= Cells(rows, cols(j) + cloop)) Then
                        diff = Cells(rows, cols(i) + cloop) - Cells(rows, cols(j) + cloop)
                        If diff < minDiff Then
                            minDiff = diff
                            frml = "=" & Cells(rows, cols(i) + cloop).Address(0, 0) & "-" & Cells(rows, cols(j) + cloop).Address(0, 0)
                        End If
                    End If
                Next j
            Next i
            Cells(rows, cloop + 64).Formula = frml
        Next cloop
    Next rows

    Application.ScreenUpdating = True
    
    MsgBox "Process complete!"

End Sub
Note that the calculations are being done in the VBA, and the formula returning the smallest values is being returned.
So to expand this to more rows, you CANNOT simply just copy the formulas it creates down. You need to edit the VBA code (change the 5 to the new last row).
 
Upvote 0
Try this:
Code:
Sub MyMinDiff()

    Dim diff As Double
    Dim minDiff As Double
    Dim frml As String
    Dim cols As Variant
    Dim i As Integer
    Dim j As Integer
    Dim rows As Long
    Dim cloop As Long
    
    Application.ScreenUpdating = False
    
'   Set array of initial columns (numerical equivalents of B, N, AA, AL, and AZ)
    cols = Array(2, 14, 27, 39, 52)
    
'   Loop through rows 2 through 5
    For rows = 2 To 5
'       Run through 8 different sets per row
        For cloop = 0 To 7
            minDiff = 999999999
            For i = LBound(cols) To UBound(cols)
                For j = LBound(cols) To UBound(cols)
                    If (i <> j) And (Cells(rows, cols(i) + cloop) >= Cells(rows, cols(j) + cloop)) Then
                        diff = Cells(rows, cols(i) + cloop) - Cells(rows, cols(j) + cloop)
                        If diff < minDiff Then
                            minDiff = diff
                            frml = "=" & Cells(rows, cols(i) + cloop).Address(0, 0) & "-" & Cells(rows, cols(j) + cloop).Address(0, 0)
                        End If
                    End If
                Next j
            Next i
            Cells(rows, cloop + 64).Formula = frml
        Next cloop
    Next rows

    Application.ScreenUpdating = True
    
    MsgBox "Process complete!"

End Sub
Note that the calculations are being done in the VBA, and the formula returning the smallest values is being returned.
So to expand this to more rows, you CANNOT simply just copy the formulas it creates down. You need to edit the VBA code (change the 5 to the new last row).

Hi Joe4,

Thanks for your help still.

I may be doing something wrong, I just copy and pasted the code in the VB Microsoft Excel Objects>Thisworkbook, saved and ran the macro. I'm getting and error message "Run-time error 13"

Unfortunately with my handicapped understanding and usage of VB, I have no idea how to resolve the error or what is that i should do to avoid it.
 
Upvote 0
No, do not put the code in the "ThisWorkbook" module.

In the VBAProject window on the left-side of the VBA Editor, right-click on your file name, select Insert -> Module, and it should insert a Module named "Module1". Place the code in that module.
 
Last edited:
Upvote 0

Forum statistics

Threads
1,215,006
Messages
6,122,666
Members
449,091
Latest member
peppernaut

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top