Diagonal Sum in excel table via VBA code

spgexcel

New Member
Joined
Mar 16, 2016
Messages
29
Office Version
  1. 365
Platform
  1. Windows
Hello,
Hope you are all good.
I am having a trouble with a diagonal sum vba code. Not sure what wrong I am doing.
1st will explain what I am trying to do.
In the image attached herewith is a table. (A9:F13)

  • Rows A10, A11, A12 should multiply with their respective curve from the curve library and sum them diagonally.
  • The multiplication should occur with the correct row and column values, ensuring the diagonal sum is cumulative.

Key Requirements:

  1. Row 10: A10 * Curve(ABC, M1)
  2. Row 11: A11 * Curve(CDE, M1) + A10 * Curve(CDE, M2)
  3. Row 12: A12 * Curve(CDE, M1) + A11 * Curve(CDE, M2) + A10 * Curve(CDE, M3)
I am expecting a result as in 2nd table (A15:F18)

The VBA incorrectly references to $A10 in 2nd row whereas it should reference to $A10.
Formula text table is also mentioned for reference.
Output column is where diagonal sum is expected. Have color coded the output column and table cell to show what cells are summed up to get output result.

Here is my vba code.

VBA Code:
Sub CalculateDiagonalSum()

    Dim ws As Worksheet
    Dim lastRow As Long
    Dim i As Long, j As Long
    Dim result As Double
    Dim numberValue As Double, curveValue As Double
    Dim curveRow As Range
    Dim curveColIndex As Integer
    Dim curveName As String
    Dim rowOffset As Integer
    
 
    Set ws = ThisWorkbook.Sheets("Sheet1")
    
  
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    

    ws.Range("F10:F" & lastRow).ClearContents

    For i = 10 To lastRow
        result = 0
        curveName = ws.Cells(i, "B").Value
        
     
        Set curveRow = ws.Range("B4:B6").Find(What:=curveName, LookIn:=xlValues, LookAt:=xlWhole)
        
        If Not curveRow Is Nothing Then
     
            For j = 0 To i - 10
                rowOffset = i - j
                numberValue = ws.Cells(rowOffset, "A").Value
                curveColIndex = 3 + j
                
                If curveColIndex <= 5 Then
                    curveValue = ws.Cells(curveRow.Row, curveColIndex).Value
                    result = result + (numberValue * curveValue)
                End If
            Next j
        End If

        ws.Cells(i, "F").Value = result
    Next i
    
End Sub

Hoping to resolve this as this is an example table. I am trying to do away the need of creating a big table in my model and just do a vba based diagonal sum. My model has huge table.
Hope you can help me with it.



Thanks

Sumant
 

Attachments

  • Screenshot 2024-08-16 104255.png
    Screenshot 2024-08-16 104255.png
    32.3 KB · Views: 15

Excel Facts

What is =ROMAN(40) in Excel?
The Roman numeral for 40 is XL. Bill "MrExcel" Jelen's 40th book was called MrExcel XL.
See if this works for you. My numbers came out slightly different - for example value at C10 on your sheet comes to 75.98 instead of 76.25 as in your example, but my manual calculation of 58*131%=75.98. Perhaps there's some additional decimals in your percentages that I can't see?

VBA Code:
Sub CalculateDiagonalSum()
    Dim ws As Worksheet
    Dim Result As Double
    Dim lastrow As Long, i As Long, j As Long, k As Long
    Dim CurveArr, OutputArr
    '
    Set ws = ThisWorkbook.Sheets("Sheet1")
    lastrow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    CurveArr = ws.Range("C5:E6")
    ws.Range("F10:F" & lastrow).ClearContents
    OutputArr = ws.Range("A10:F" & lastrow)
    For i = LBound(OutputArr, 1) To UBound(OutputArr, 1)
        For j = 3 To 5
            Select Case OutputArr(i, 2)
                Case "ABC"
                    OutputArr(i, j) = OutputArr(i, 1) * CurveArr(1, j - 2)
                Case "CDE"
                    OutputArr(i, j) = OutputArr(i, 1) * CurveArr(2, j - 2)
                Case Else
                    MsgBox "Error"
                    Exit Sub
            End Select
        Next j
    Next i
    '
    For i = UBound(OutputArr, 1) To LBound(OutputArr, 1) Step -1
        k = 0
        For j = 3 To i + 2
            OutputArr(i, UBound(OutputArr, 2)) = OutputArr(i, UBound(OutputArr, 2)) + OutputArr(i - k, j)
            k = k + 1
        Next j
    Next
    '
    Range("A15").Resize(UBound(OutputArr, 1), UBound(OutputArr, 2)) = OutputArr
End Sub
 
Upvote 1
See if this works for you. My numbers came out slightly different - for example value at C10 on your sheet comes to 75.98 instead of 76.25 as in your example, but my manual calculation of 58*131%=75.98. Perhaps there's some additional decimals in your percentages that I can't see?

VBA Code:
Sub CalculateDiagonalSum()
    Dim ws As Worksheet
    Dim Result As Double
    Dim lastrow As Long, i As Long, j As Long, k As Long
    Dim CurveArr, OutputArr
    '
    Set ws = ThisWorkbook.Sheets("Sheet1")
    lastrow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    CurveArr = ws.Range("C5:E6")
    ws.Range("F10:F" & lastrow).ClearContents
    OutputArr = ws.Range("A10:F" & lastrow)
    For i = LBound(OutputArr, 1) To UBound(OutputArr, 1)
        For j = 3 To 5
            Select Case OutputArr(i, 2)
                Case "ABC"
                    OutputArr(i, j) = OutputArr(i, 1) * CurveArr(1, j - 2)
                Case "CDE"
                    OutputArr(i, j) = OutputArr(i, 1) * CurveArr(2, j - 2)
                Case Else
                    MsgBox "Error"
                    Exit Sub
            End Select
        Next j
    Next i
    '
    For i = UBound(OutputArr, 1) To LBound(OutputArr, 1) Step -1
        k = 0
        For j = 3 To i + 2
            OutputArr(i, UBound(OutputArr, 2)) = OutputArr(i, UBound(OutputArr, 2)) + OutputArr(i - k, j)
            k = k + 1
        Next j
    Next
    '
    Range("A15").Resize(UBound(OutputArr, 1), UBound(OutputArr, 2)) = OutputArr
End Sub
@myall_blues : Awesome, This is exactly what I wanted.. I can not thank you enough. And yes it was a matter of decimals. In my workbook I get exact result..
 
Upvote 0
Hi @myall_blues ,

I modified the code a bit to do away the hard coding of the curve names,

VBA Code:
Sub CalculateDiagonalSumNew()
    Dim ws As Worksheet
    Dim Result As Double
    Dim lastrow As Long, i As Long, j As Long, k As Long
    Dim CurveArr As Variant, OutputArr As Variant
    Dim CurveName As String
    Dim CurveRow As Long
   
    ' Set the worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")
   
    ' Get the last row
    lastrow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
   
    ws.Range("F10:F" & lastrow).ClearContents
   
   
    ' Load curve library and output data into arrays
    CurveArr = ws.Range("C5:E7").Value
    OutputArr = ws.Range("A10:F" & lastrow).Value
       
 
    For i = LBound(OutputArr, 1) To UBound(OutputArr, 1)
        CurveName = OutputArr(i, 2)
        CurveRow = 0
       
    For j = 1 To UBound(CurveArr, 1)
            If ws.Cells(4 + j, 2).Value = CurveName Then
                CurveRow = j
                Exit For
            End If
        Next j
       
        ' If no match is found, show an error
        If CurveRow = 0 Then
            MsgBox "Error: Curve name '" & CurveName & "' not found in curve library."
            Exit Sub
        End If
       
For j = 3 To 5
            OutputArr(i, j) = OutputArr(i, 1) * CurveArr(CurveRow, j - 2)
        Next j
    Next i
   
    ' Calculate the diagonal sum
    For i = UBound(OutputArr, 1) To LBound(OutputArr, 1) Step -1
        k = 0
        For j = 3 To i + 2
            OutputArr(i, UBound(OutputArr, 2)) = OutputArr(i, UBound(OutputArr, 2)) + OutputArr(i - k, j)
            k = k + 1
        Next j
    Next
       
    ' Output only the final results to F10:F12
    For i = LBound(OutputArr, 1) To UBound(OutputArr, 1)
        ws.Cells(i + 9, 6).Value = OutputArr(i, UBound(OutputArr, 2))
    Next i
   

End Sub

It works fine. But the moment I try to change the range of output to c column it messes up the things. Tried to debug but gives weird results.

Basically, my original sheet has big table of curve library and long list of numbers to multiply and do the diagonal sum of.
Please refer to the attached excel sheet. I hit the run button, and get the curve not found error while it is there in the curve library.

Here is actual data lets say:

Curve NameM1M2M3M4M5M6M7M8M9M10M11M12M13M14M15M16M17M18M19M20M21M22M23M24
AB
131%​
124%​
116%​
75%​
60%​
40%​
30%​
24%​
20%​
17%​
17%​
15%​
13%​
13%​
12%​
12%​
12%​
11%​
10%​
9%​
8%​
8%​
8%​
8%​
BC
133%​
117%​
104%​
65%​
51%​
48%​
40%​
30%​
28%​
24%​
21%​
18%​
15%​
14%​
13%​
12%​
12%​
11%​
10%​
9%​
8%​
8%​
7%​
7%​
CD
133%​
107%​
95%​
61%​
51%​
42%​
35%​
29%​
25%​
22%​
20%​
17%​
13%​
9%​
8%​
7%​
6%​
6%​
5%​
5%​
4%​
4%​
4%​
4%​
DE
133%​
103%​
99%​
69%​
62%​
48%​
38%​
31%​
25%​
21%​
19%​
17%​
16%​
13%​
11%​
11%​
11%​
11%​
10%​
10%​
8%​
9%​
9%​
7%​
EF
133%​
113%​
101%​
70%​
57%​
47%​
37%​
30%​
22%​
17%​
16%​
14%​
13%​
11%​
9%​
9%​
9%​
9%​
8%​
9%​
7%​
8%​
8%​
6%​
GH
133%​
114%​
102%​
64%​
53%​
44%​
36%​
31%​
26%​
23%​
21%​
18%​
13%​
10%​
8%​
7%​
6%​
6%​
5%​
5%​
4%​
4%​
3%​
3%​
IJ
133%​
111%​
102%​
67%​
56%​
45%​
36%​
29%​
21%​
17%​
15%​
14%​
13%​
10%​
9%​
9%​
9%​
9%​
8%​
8%​
7%​
7%​
7%​
5%​
JK
133%​
95%​
86%​
61%​
51%​
41%​
32%​
26%​
19%​
15%​
14%​
12%​
11%​
9%​
8%​
8%​
8%​
8%​
7%​
7%​
6%​
7%​
7%​
5%​
LM
133%​
112%​
104%​
73%​
61%​
49%​
39%​
32%​
22%​
18%​
17%​
15%​
14%​
11%​
10%​
9%​
9%​
9%​
8%​
9%​
7%​
8%​
8%​
6%​
NO
133%​
108%​
96%​
62%​
51%​
43%​
35%​
30%​
25%​
22%​
20%​
17%​
13%​
10%​
8%​
7%​
6%​
6%​
6%​
5%​
5%​
4%​
4%​
4%​
PQ
133%​
113%​
104%​
67%​
56%​
42%​
33%​
27%​
26%​
21%​
19%​
18%​
16%​
11%​
10%​
8%​
7%​
7%​
7%​
7%​
5%​
6%​
6%​
6%​
RS
133%​
113%​
100%​
62%​
49%​
46%​
38%​
29%​
27%​
23%​
20%​
18%​
14%​
14%​
12%​
12%​
11%​
11%​
10%​
9%​
8%​
7%​
7%​
7%​
TU
133%​
116%​
96%​
68%​
54%​
50%​
42%​
32%​
29%​
25%​
22%​
19%​
16%​
15%​
14%​
13%​
12%​
12%​
11%​
10%​
9%​
8%​
8%​
7%​
VW
133%​
115%​
103%​
64%​
50%​
47%​
39%​
30%​
28%​
23%​
21%​
18%​
15%​
14%​
13%​
12%​
12%​
11%​
10%​
9%​
8%​
8%​
7%​
7%​
XY
100%​
84%​
75%​
69%​
56%​
52%​
43%​
35%​
25%​
22%​
14%​
10%​
10%​
10%​
8%​
8%​
7%​
6%​
5%​
4%​
3%​
2%​
1%​
1%​
ZA
133%​
116%​
102%​
62%​
50%​
39%​
32%​
25%​
23%​
19%​
17%​
15%​
9%​
7%​
5%​
4%​
2%​
2%​
2%​
2%​
2%​
2%​
2%​
2%​
ZB
133%​
110%​
96%​
60%​
49%​
39%​
33%​
27%​
22%​
19%​
16%​
14%​
13%​
12%​
11%​
10%​
9%​
9%​
6%​
4%​
4%​
4%​
4%​
4%​
ZC
133%​
119%​
106%​
72%​
65%​
54%​
44%​
38%​
33%​
30%​
25%​
23%​
19%​
13%​
9%​
8%​
7%​
7%​
5%​
3%​
3%​
3%​
3%​
3%​
ZD
133%​
112%​
97%​
62%​
50%​
42%​
32%​
29%​
24%​
22%​
18%​
16%​
12%​
9%​
6%​
5%​
5%​
5%​
3%​
2%​
2%​
2%​
2%​
2%​
ZE
133%​
108%​
99%​
63%​
54%​
41%​
34%​
25%​
20%​
16%​
15%​
13%​
11%​
11%​
9%​
9%​
9%​
7%​
5%​
6%​
5%​
3%​
2%​
2%​
ZF
133%​
114%​
102%​
66%​
58%​
48%​
37%​
31%​
23%​
19%​
14%​
11%​
9%​
10%​
9%​
6%​
3%​
2%​
3%​
1%​
3%​
3%​
3%​
3%​
ZG
133%​
101%​
94%​
61%​
49%​
42%​
35%​
31%​
26%​
23%​
19%​
15%​
13%​
11%​
9%​
6%​
7%​
6%​
4%​
2%​
1%​
2%​
1%​
2%​
ZH
133%​
113%​
103%​
67%​
54%​
47%​
38%​
34%​
29%​
25%​
21%​
16%​
14%​
12%​
9%​
7%​
8%​
7%​
4%​
2%​
1%​
2%​
1%​
3%​
ZI
133%​
117%​
104%​
69%​
55%​
52%​
44%​
34%​
32%​
28%​
25%​
22%​
19%​
18%​
17%​
16%​
16%​
15%​
14%​
13%​
12%​
12%​
11%​
11%​
ZK
133%​
124%​
110%​
68%​
54%​
51%​
42%​
32%​
30%​
25%​
22%​
19%​
16%​
15%​
14%​
13%​
12%​
12%​
11%​
10%​
9%​
8%​
8%​
7%​
ZL
133%​
109%​
96%​
60%​
47%​
44%​
37%​
28%​
26%​
22%​
19%​
17%​
14%​
13%​
12%​
11%​
11%​
10%​
9%​
9%​
8%​
7%​
7%​
7%​
ZM
133%​
102%​
91%​
56%​
45%​
42%​
35%​
27%​
25%​
21%​
18%​
16%​
13%​
12%​
11%​
11%​
10%​
10%​
9%​
8%​
7%​
7%​
6%​
6%​
ZN
133%​
92%​
81%​
51%​
40%​
37%​
31%​
24%​
22%​
18%​
16%​
14%​
12%​
11%​
10%​
10%​
9%​
9%​
8%​
7%​
6%​
6%​
6%​
6%​

NumberCurveOutput
0.00​
PQ
0.00​
RS
0.00​
TU
0.00​
VW
0.00​
XY
58.58​
ZA
31.70​
ZB
25.21​
ZC
44.23​
ZD
31.91​
ZE
23.68​
ZF
38.67​
ZG
16.54​
ZH
29.79​
ZI
37.78​
ZK
41.75​
ZL
33.38​
ZM
32.92​
ZN
72.87​
AB
58.81​
BC
84.17​
CD
96.53​
DE
121.68​
EF
96.47​
GH
127.91​
IJ
162.97​
JK
154.86​
LM
105.88​
NO
123.19​
PQ
129.65​
RS
141.00​
TU
169.10​
VW
166.30​
XY
120.73​
ZA
153.66​
ZB
141.23​
ZC
160.52​
ZD
133.15​
ZE
125.28​
ZF
110.03​
ZG
108.36​
ZH
159.77​
ZI
138.81​
ZK
152.85​
ZL
159.16​
ZM
188.25​
ZN
151.74​
AB
145.25​
BC
152.52​
CD
195.17​
DE
140.51​
EF
172.04​
GH
138.66​
IJ
205.03​
JK
192.77​
LM
201.36​
NO
204.44​
PQ
269.43​
RS
212.78​
TU
216.02​
VW
255.27​
XY
218.41​
ZA
215.95​
ZB
202.22​
ZC
204.31​
ZD
198.54​
ZE
225.21​
ZF
250.65​
ZG
251.08​
ZH
232.51​
ZI
245.50​
ZK
232.29​
ZL
243.87​
ZM
249.74​
ZN
258.12​
AB
264.19​
BC
271.38​
CD
278.19​
DE
285.30​
EF
289.59​
GH
293.59​
IJ
296.28​
JK
298.92​
LM
301.21​
NO
303.79​
PQ
307.35​
RS
310.86​
TU
314.51​
VW
318.13​
XY
318.13​
ZA
316.98​
ZB
315.83​
ZC
314.67​
ZD
311.12​
ZE
307.79​
ZF
304.95​
ZG
302.51​
ZH
300.36​
ZI
298.45​
ZK
296.71​
ZL
295.12​
ZM
293.64​
ZN
292.24​
AB
287.36​
BC
282.53​
CD
277.74​
DE
272.99​
EF
268.26​
GH
263.55​
IJ
258.85​
JK
254.17​
LM
249.49​
NO
242.06​
PQ
241.79​
RS
234.11​
TU
209.11​
VW
202.04​
XY
196.31​
ZA
189.00​
ZB
181.73​
ZC
174.50​
ZD
167.30​
ZE
160.12​
ZF
152.97​
ZG
143.59​
ZH
138.73​
ZI
130.41​
ZK
122.78​
ZL
115.78​
ZM
110.40​
ZN
105.53​
AB
101.12​
BC
97.14​
CD
93.53​
DE
90.26​
EF
87.31​
GH
82.88​
IJ
78.83​
JK
75.41​
LM
72.51​
NO
70.05​
PQ
67.98​
RS
66.22​
TU
64.73​
VW
63.47​
XY
62.41​
ZA
61.50​
ZB
60.74​
ZC
60.74​
ZD


1723961147809.png


for this I have edited the vba like this

VBA Code:
Sub CalculateDiagonalSumNew()
    Dim ws As Worksheet
    Dim Result As Double
    Dim lastrow As Long, i As Long, j As Long, k As Long
    Dim CurveArr As Variant, OutputArr As Variant
    Dim CurveName As String
    Dim CurveRow As Long
    
    ' Set the worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")
    
    ' Get the last row
    lastrow = 184
    
    ws.Range("C36:C" & lastrow).ClearContents
    
    
    ' Load curve library and output data into arrays
    CurveArr = ws.Range("C5:AA32").Value
    OutputArr = ws.Range("A36:C" & lastrow).Value
    
    
    For i = LBound(OutputArr, 1) To UBound(OutputArr, 1)
        CurveName = OutputArr(i, 2)
        CurveRow = 0
        
        ' Match the curve name with the curve library row
        For j = 1 To UBound(CurveArr, 1)
            If ws.Cells(4 + j, 2).Value = CurveName Then
                CurveRow = j
                Exit For
            End If
        Next j
        
        ' If error
        
        If CurveRow = 0 Then
            MsgBox "Error: Curve name '" & CurveName & "' not found in curve library."
            Exit Sub
        End If
        
        For j = 3 To 3
            OutputArr(i, j) = OutputArr(i, 1) * CurveArr(CurveRow, j - 2)
        Next j
    Next i
    
    ' Calculate the diagonal sum
    For i = UBound(OutputArr, 1) To LBound(OutputArr, 1) Step -1
        k = 0
        For j = 3 To i + 2
            OutputArr(i, UBound(OutputArr, 2)) = OutputArr(i, UBound(OutputArr, 2)) + OutputArr(i - k, j)
            k = k + 1
        Next j
    Next
        
    ' Output
    For i = LBound(OutputArr, 1) To UBound(OutputArr, 1)
        ws.Cells(i + 9, 6).Value = OutputArr(i, UBound(OutputArr, 2))
    Next i
    
End Sub

I know the table is too long to be pasted here in actual . Apologies for that.
Can you help one more time please?
 
Upvote 0
But the moment I try to change the range of output to c column it messes up the things.
Can you clarify what you mean by this, specifically the 'output to c column'?

Also if it's possible for you to download and use XL2BB to post data and curve array that would make life a lot easier.
 
Upvote 0
Hi
I've been working on this with some success with your initial test data, but I've come up against a problem when I move to the full dataset that needs some input from yourself.
Let me see if I can explain it for you.
Your test dataset is a square array - i.e. there are three columns in the curve array and three rows in the data array, so the output column calculates for n=1,2,3 and all is well.
For your full dataset, there are 24 columns and 149 rows. For the sake of demonstration I've scaled that back to 3 columns (24/8) and 18 rows (approx 149/8) in the dataset below, but the number of rows is irrelevant here as long as it is greater than the number of columns.
As you can see I can calculate the first total as just R1C1, the second as R2C1+R1C2, and the third as R3C1+R2C2+R1C3 but then what? How should the total be calculated for the fourth row onward?

diagonalsum.xlsm
ABCDEFGHIJKLM
1
2
3
4Curve libraryM1M2M3Output
5AB1.311.241.1658.58ZA76.739872.639267.952876.7398
6BC1.331.171.0431.7ZB42.16137.08932.968114.8002
7CD1.331.070.9525.21ZC33.529326.974723.9495138.5711
8DE1.331.030.9944.23ZD58.825945.556943.7877??
9EF1.331.131.0131.91ZE42.440336.058332.2291
10GH1.331.141.0223.68ZF31.494426.995224.1536
11IJ1.331.111.0238.67ZG51.431142.923739.4434
12JK1.330.950.8616.54ZH21.998215.71314.2244
13LM1.331.121.0429.79ZI39.620733.364830.9816
14NO1.331.080.9637.78ZK50.247440.802436.2688
15PQ1.331.131.0441.75ZL55.527547.177543.42
16RS1.331.13133.38ZM44.395437.719433.38
17TU1.331.160.9632.92ZN43.783638.187231.6032
18VW1.331.151.0372.87AB96.917183.800575.0561
19XY10.840.7558.81BC58.8149.400444.1075
20ZA1.331.161.0284.17CD111.946197.637285.8534
21ZB1.331.10.9696.53DE128.3849106.18392.6688
22ZC1.331.191.06121.68EF161.8344144.7992128.9808
23ZD1.331.120.9796.47GH128.3051108.046493.5759
24
Sheet3
 
Upvote 0
Hi,

Apologies for the scattered data I provided. I am posting the XL2BB version of data here.
Here is what I am trying to do.
My actual model has curve library of 24 months long. It could stretch up to 60 months as well.
By c column as output I mean the vba will paste the output in c column. earlier the code pasted the same in column F.
Also, 3 x 3 grid in earlier was just an example as I thought i would extend the code to larger pool of the table.

As you can see in cells starting from D36:AA55 I have pulled the respective curve using index match from curve library and multiplied by the respective number in column A.
For example: row 36: D36 onwards the formula is =INDEX(D$5:D$32,MATCH($B36,$C$5:$C$32,0),1)*$A36
So this creates a grid form which I am doing diagonal sum. For ease, I have color coded the same till 41 row. It should keep on extending as each row progresses.
In the example, my row ends at 55 but in my model the number rows are more than 100. I want to do away the grid portion. and let th vba do the job of grid + diagonal sum.

Trial.xlsm
CDEFGHIJKLMNOPQRSTUVWXYZAA
4Curve NameM1M2M3M4M5M6M7M8M9M10M11M12M13M14M15M16M17M18M19M20M21M22M23M24
5AB131%124%116%75%60%40%30%24%20%17%17%15%13%13%12%12%12%11%10%9%8%8%8%8%
6BC133%117%104%65%51%48%40%30%28%24%21%18%15%14%13%12%12%11%10%9%8%8%7%7%
7CD133%107%95%61%51%42%35%29%25%22%20%17%13%9%8%7%6%6%5%5%4%4%4%4%
8DE133%103%99%69%62%48%38%31%25%21%19%17%16%13%11%11%11%11%10%10%8%9%9%7%
9EF133%113%101%70%57%47%37%30%22%17%16%14%13%11%9%9%9%9%8%9%7%8%8%6%
10GH133%114%102%64%53%44%36%31%26%23%21%18%13%10%8%7%6%6%5%5%4%4%3%3%
11IJ133%111%102%67%56%45%36%29%21%17%15%14%13%10%9%9%9%9%8%8%7%7%7%5%
12JK133%95%86%61%51%41%32%26%19%15%14%12%11%9%8%8%8%8%7%7%6%7%7%5%
13LM133%112%104%73%61%49%39%32%22%18%17%15%14%11%10%9%9%9%8%9%7%8%8%6%
14NO133%108%96%62%51%43%35%30%25%22%20%17%13%10%8%7%6%6%6%5%5%4%4%4%
15PQ133%113%104%67%56%42%33%27%26%21%19%18%16%11%10%8%7%7%7%7%5%6%6%6%
16RS133%113%100%62%49%46%38%29%27%23%20%18%14%14%12%12%11%11%10%9%8%7%7%7%
17TU133%116%96%68%54%50%42%32%29%25%22%19%16%15%14%13%12%12%11%10%9%8%8%7%
18VW133%115%103%64%50%47%39%30%28%23%21%18%15%14%13%12%12%11%10%9%8%8%7%7%
19XY100%84%75%69%56%52%43%35%25%22%14%10%10%10%8%8%7%6%5%4%3%2%1%1%
20ZA133%116%102%62%50%39%32%25%23%19%17%15%9%7%5%4%2%2%2%2%2%2%2%2%
21ZB133%110%96%60%49%39%33%27%22%19%16%14%13%12%11%10%9%9%6%4%4%4%4%4%
22ZC133%119%106%72%65%54%44%38%33%30%25%23%19%13%9%8%7%7%5%3%3%3%3%3%
23ZD133%112%97%62%50%42%32%29%24%22%18%16%12%9%6%5%5%5%3%2%2%2%2%2%
24ZE133%108%99%63%54%41%34%25%20%16%15%13%11%11%9%9%9%7%5%6%5%3%2%2%
25ZF133%114%102%66%58%48%37%31%23%19%14%11%9%10%9%6%3%2%3%1%3%3%3%3%
26ZG133%101%94%61%49%42%35%31%26%23%19%15%13%11%9%6%7%6%4%2%1%2%1%2%
27ZH133%113%103%67%54%47%38%34%29%25%21%16%14%12%9%7%8%7%4%2%1%2%1%3%
28ZI133%117%104%69%55%52%44%34%32%28%25%22%19%18%17%16%16%15%14%13%12%12%11%11%
29ZK133%124%110%68%54%51%42%32%30%25%22%19%16%15%14%13%12%12%11%10%9%8%8%7%
30ZL133%109%96%60%47%44%37%28%26%22%19%17%14%13%12%11%11%10%9%9%8%7%7%7%
31ZM133%102%91%56%45%42%35%27%25%21%18%16%13%12%11%11%10%10%9%8%7%7%6%6%
32ZN133%92%81%51%40%37%31%24%22%18%16%14%12%11%10%10%9%9%8%7%6%6%6%6%
Sheet1
 
Upvote 0
It would not let me paste both tables in one message.
Here is the grid table I mentioned above.

Trial.xlsm
ABCDEFGHIJKLMNOPQRSTUVWXYZAA
35NumberCurveOutputM1M2M3M4M5M6M7M8M9M10M11M12M13M14M15M16M17M18M19M20M21M22M23M24
3658.58ZA78.106026178.167.859.536292319151311108.75.53.82.92.21.41.21.41111.21.2
3731.70ZB110.03065642.33530.4191612108.576.14.94.543.73.43.22.82.821.31.21.41.21.2
3825.21ZC128.14598333.630.126.7181614119.68.47.66.25.84.73.32.421.81.81.30.80.80.90.80.8
3944.23ZD155.6963825949.4432722191413119.68.17.15.53.82.82.42.12.11.510.910.90.9
4031.91ZE166.93545342.634.631.62017131186.45.24.74.13.53.52.92.92.82.11.71.91.51.10.60.6
4123.68ZF165.49390431.62724.21614118.77.45.44.63.42.72.12.42.11.40.70.50.60.30.60.60.60.6
4238.67ZG51.638.936.32419161412108.87.25.84.94.23.32.42.82.41.50.60.50.60.51
4316.54ZH2218.717.1118.97.76.35.64.74.13.42.72.321.61.11.31.10.70.30.20.30.20.4
4429.79ZI39.734.930.920161513109.68.27.46.65.65.454.94.74.54.23.93.63.53.43.3
4537.78ZK50.446.841.42620191612119.48.37.35.95.65.14.94.74.54.13.73.33.12.92.8
4641.75ZL55.745.540.22520191512119.18.17.15.85.554.84.64.33.93.63.232.82.7
4733.38ZM44.534.230.2191514128.98.26.96.15.34.34.13.83.63.43.332.72.42.22.12.1
4832.92ZN43.930.226.7171312107.87.26.15.44.73.83.63.33.232.92.62.42.121.91.8
4972.87AB95.890.284.25544292217151312119.79.68.88.48.487.36.65.85.55.55.6
5058.81BC78.469613830282318171412118.78.37.67.26.96.665.44.84.54.34.1
5184.17CD11289.879.8514336292521181714117.96.865.454.64.33.83.63.23.1
5296.53DE12999.995.16660473730252018161512111010109.39.98.18.88.96.4
53121.68EF1621381238570584537262119171613111111119.9118.79.39.56.8
5496.47GH12911098.2625142352925222017139.4876.25.75.24.64.13.93.33.1
55127.91IJ17114213186725846372621191816131111111110118.79.49.66.8
Sheet1
Cell Formulas
RangeFormula
D36:AA55D36=INDEX(D$5:D$32,MATCH($B36,$C$5:$C$32,0),1)*$A36
C36C36=D36
C37C37=D37+E36
C38C38=D38+E37+F36
C39C39=D39+E38+F37+G36
C40C40=D40+E39+F38+G37+H36
C41C41=D41+E40+F39+G38+H37+I36
 
Upvote 0
OK try this code. Your most recent data upload and this code gives these results. Also confirmed with original 3x3 data set.

diagonalsum.xlsm
ABC
6558.57952ZA78.10603
6631.70395ZB110.0307
6725.20828ZC128.146
6844.22953ZD155.6964
6931.91293ZE166.9355
7023.67512ZF165.4939
7138.66976ZG184.9713
7216.53599ZH166.1203
7329.78681ZI179.0532
7437.77586ZK195.0572
7541.74604ZL222.7101
7633.38444ZM225.6996
7732.9209ZN221.2691
7872.86617AB267.7836
7958.80931BC309.4164
8084.16651CD377.0919
8196.52769DE426.6578
82121.6822EF502.3579
8396.47499GH540.5092
84127.9136IJ621.2475
8596.52769DE641.0556
86121.6822EF675.1928
8796.47499GH685.0759
88127.9136IJ742.1439
Sheet2


VBA Code:
Sub CalculateDiagonalSum()
    Dim ws As Worksheet
    Dim Result As Double
    Dim lastrow As Long, i As Long, j As Long, k As Long
    Dim maxCurves As Long, maxOutput As Long, maxArrays As Long
    Dim CurveName As String
    Dim CurveArr, OutputArr
    '
    ' Set worksheet
    '
    Set ws = ThisWorkbook.Sheets("Sheet2")
    '
    ' Get last row
    '
    lastrow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
    '
    ' Load curve library and data into arrays
    '
    CurveArr = ws.Range("C5:aa32")
    ws.Range("c35:c" & lastrow).ClearContents
    OutputArr = ws.Range("a36:b" & lastrow)
    '
    ' Get maximum dimensions of arrays - the smaller of which becomes the
    ' maximum possible diagonal sum that can be calculated.
    '
    maxCurves = UBound(CurveArr, 2) - 1
    maxOutput = UBound(OutputArr, 1)
    maxArrays = maxCurves
    If maxOutput < maxCurves Then
        maxArrays = maxOutput
    End If
    '
    ' Redim the output array to accomodate the intermediate calculations
    ' Redim the curve array to get same number of columns as output array
    ' (minus output column)
    '
    ReDim Preserve OutputArr(1 To UBound(OutputArr, 1), 1 To UBound(CurveArr, 2) + 2)
    ReDim Preserve CurveArr(1 To UBound(CurveArr, 1), 1 To UBound(CurveArr, 2) + 2)
    For i = LBound(CurveArr, 1) To UBound(CurveArr, 1)
        For j = UBound(CurveArr, 2) - 1 To LBound(CurveArr, 2) Step -1
            CurveArr(i, j + 1) = CurveArr(i, j)
        Next j
    Next i '
    ' For each row of the output array
    '
    For i = LBound(OutputArr, 1) To UBound(OutputArr, 1)
        CurveName = OutputArr(i, 2)
        '
        ' For each row of the curve array
        '
        For j = LBound(CurveArr, 1) To UBound(CurveArr, 1)
            '
            ' If the curvename is found multiply by the array values
            '
            If CurveName = CurveArr(j, 1) Then
                For k = LBound(CurveArr, 2) + 2 To UBound(CurveArr, 2)
                    OutputArr(i, k) = OutputArr(i, 1) * CurveArr(j, k)
                Next k
            End If
        Next j
    Next i
    '
    ' Work out the diagonal sums
    '
    For i = maxArrays To LBound(OutputArr, 1) Step -1
        k = 0
        For j = LBound(OutputArr, 2) + 2 To i + 2
            OutputArr(i, UBound(OutputArr, 2)) = OutputArr(i, UBound(OutputArr, 2)) + _
            OutputArr(i - k, j)
            k = k + 1
        Next j
    Next
    '
    ' Output to desired location
    ' First write reference data
    '
    Range("A65").Resize(UBound(OutputArr, 1), 2) = OutputArr
    '
    ' Then write last array column
    '
    For i = LBound(OutputArr, 1) To UBound(OutputArr, 1)
        Cells(i + 64, 3).Value = OutputArr(i, UBound(OutputArr, 2))
    Next i
End Sub
 
Upvote 0
Solution

Forum statistics

Threads
1,224,868
Messages
6,181,483
Members
453,046
Latest member
Excelvbaexpert

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