VBA looping help

leosmessi786

New Member
Joined
Oct 18, 2021
Messages
9
Office Version
  1. 365
Platform
  1. Windows
Thanks everyone in advance for helping me out really appreciate it. This is an interesting assingment and I've tried a lot of different code but I can't get my head around it.

Basically, the table in sheet 1 is pulling in data from sheet 2 and pasting whatever is an underweight or an overweight(10% more or less relative to benchmark).So for example on the second table for Strategy 1 Sector 3 the portfolio weight is 23% greater than the benchmark weight. so that will be pasted onto the sheet 1 in the table. I do this process manually but am trying to code it. I tried a loop that goes through the data on the second table but I can't get my head around it.

If someone could help me that would be awesome thanks!

Sheet 1:


Portfolio Port %BM %Active %% Over
Guideline
Underweight More Than -10% Relative Benchmark Weight
Strategy 1Sector 328.005.0023.0033.00
Strategy 1Sector 531.005.0026.0036.00
Strategy 5Sector 213.000.0013.0023.00
Overweight 10% Plus the Benchmark Weight
Strategy 2Sector 59.0020.00-11.00-31.00
Strategy 4Sector 20.0012.00-12.00-24.00



Sector 1Sector 2Sector 3Sector 4Sector 5
Strategy 17.008.0028.001.0031.00
Benchmark 15.005.005.005.005.00
Strategy 220.0020.0020.0020.009.00
Benchmark 226.0026.0026.0026.0020.00
Strategy 30.000.000.000.000.00
Benchmark 34.004.004.004.004.00
Strategy 40.000.000.000.000.00
Benchmark 40.0012.000.000.000.00
Strategy 50.0013.000.000.000.00
Benchmark 50.000.000.000.000.00
 

Excel Facts

Is there a shortcut key for strikethrough?
Ctrl+S is used for Save. Ctrl+5 is used for Strikethrough. Why Ctrl+5? When you use hashmarks to count |||| is 4, strike through to mean 5.
Try this:

ABCDEFG
1
2MyDataSector 1Sector 2Sector 3Sector 4Sector 5
3Strategy 17.008.0028.001.0031.00
4Benchmark 15.005.005.005.005.00
5Strategy 220.0020.0020.0020.009.00
6Benchmark 226.0026.0026.0026.0020.00
7Strategy 30.000.000.000.000.00
8Benchmark 34.004.004.004.004.00
9Strategy 40.000.000.000.000.00
10Benchmark 40.0012.000.000.000.00
11Strategy 50.0013.000.000.000.00
12Benchmark 50.000.000.000.000.00
13
14
15PortfolioSectorPort %BM %Active %% Over
16Overweight 10% +
17Strategy 1Sector 328523???
18Strategy 1Sector 531526???
19Strategy 5Sector 213013???
20Underweight 10% +
21Strategy 2Sector 5920-11???
22Strategy 4Sector 2012-12???
Sheet1

MyData: =Sheet1!$B$2:$G$12
PutResultsHere: =Sheet1!$B$16:$G$22

VBA Code:
Sub Test()

    Dim vIn As Variant, vOut(1 To 2) As Variant, vTemp() As Variant
    Dim Count(1 To 2) As Long, i As Long, j As Long, k As Long
    Dim diff As Double
    Const N = 2, T = 10, cols = 6
    
    vIn = Range("MyData").Value2
    ReDim vTemp(1 To (UBound(vIn) - 1) * (UBound(vIn, 2) - 1) / N, 1 To cols)
    vOut(1) = vTemp
    vOut(2) = vTemp
        
    For i = 2 To UBound(vIn) - 1 Step N
        For j = 2 To UBound(vIn, 2)
            If Abs(vIn(i, j) - vIn(i + 1, j)) >= T Then
                k = IIf(vIn(i, j) > vIn(i + 1, j), 1, 2)
                Count(k) = Count(k) + 1
                vOut(k)(Count(k), 1) = vIn(i, 1)
                vOut(k)(Count(k), 2) = vIn(1, j)
                vOut(k)(Count(k), 3) = vIn(i, j)
                vOut(k)(Count(k), 4) = vIn(i + 1, j)
                vOut(k)(Count(k), 5) = vIn(i, j) - vIn(i + 1, j)
                vOut(k)(Count(k), 6) = "???"  'I don't know what this number is
            End If
        Next j
    Next i

    With Range("PutResultsHere")
        .ClearContents
        .Cells(1, 1).Value = "Overweight 10% +"
        .Offset(1).Resize(Count(1), cols).Value = vOut(1)
        With .Offset(Count(1) + 1)
            .Cells(1, 1).Value = "Underweight 10% +"
            .Offset(1).Resize(Count(2), cols).Value = vOut(2)
        End With
        .Resize(Count(1) + Count(2) + 2, cols).Name = "PutResultsHere"
    End With
    
End Sub
 
Upvote 0
Try this:

ABCDEFG
1
2MyDataSector 1Sector 2Sector 3Sector 4Sector 5
3Strategy 17.008.0028.001.0031.00
4Benchmark 15.005.005.005.005.00
5Strategy 220.0020.0020.0020.009.00
6Benchmark 226.0026.0026.0026.0020.00
7Strategy 30.000.000.000.000.00
8Benchmark 34.004.004.004.004.00
9Strategy 40.000.000.000.000.00
10Benchmark 40.0012.000.000.000.00
11Strategy 50.0013.000.000.000.00
12Benchmark 50.000.000.000.000.00
13
14
15PortfolioSectorPort %BM %Active %% Over
16Overweight 10% +
17Strategy 1Sector 328523???
18Strategy 1Sector 531526???
19Strategy 5Sector 213013???
20Underweight 10% +
21Strategy 2Sector 5920-11???
22Strategy 4Sector 2012-12???
Sheet1

MyData: =Sheet1!$B$2:$G$12
PutResultsHere: =Sheet1!$B$16:$G$22

VBA Code:
Sub Test()

    Dim vIn As Variant, vOut(1 To 2) As Variant, vTemp() As Variant
    Dim Count(1 To 2) As Long, i As Long, j As Long, k As Long
    Dim diff As Double
    Const N = 2, T = 10, cols = 6
   
    vIn = Range("MyData").Value2
    ReDim vTemp(1 To (UBound(vIn) - 1) * (UBound(vIn, 2) - 1) / N, 1 To cols)
    vOut(1) = vTemp
    vOut(2) = vTemp
       
    For i = 2 To UBound(vIn) - 1 Step N
        For j = 2 To UBound(vIn, 2)
            If Abs(vIn(i, j) - vIn(i + 1, j)) >= T Then
                k = IIf(vIn(i, j) > vIn(i + 1, j), 1, 2)
                Count(k) = Count(k) + 1
                vOut(k)(Count(k), 1) = vIn(i, 1)
                vOut(k)(Count(k), 2) = vIn(1, j)
                vOut(k)(Count(k), 3) = vIn(i, j)
                vOut(k)(Count(k), 4) = vIn(i + 1, j)
                vOut(k)(Count(k), 5) = vIn(i, j) - vIn(i + 1, j)
                vOut(k)(Count(k), 6) = "???"  'I don't know what this number is
            End If
        Next j
    Next i

    With Range("PutResultsHere")
        .ClearContents
        .Cells(1, 1).Value = "Overweight 10% +"
        .Offset(1).Resize(Count(1), cols).Value = vOut(1)
        With .Offset(Count(1) + 1)
            .Cells(1, 1).Value = "Underweight 10% +"
            .Offset(1).Resize(Count(2), cols).Value = vOut(2)
        End With
        .Resize(Count(1) + Count(2) + 2, cols).Name = "PutResultsHere"
    End With
   
End Sub
thanks a lot for you rreply. wait do u want me to declare the mydata and putresultshere as variables?
 
Upvote 0
Yes, based on the layout in Post #3, my code expects to find:

MyData: =Sheet1!$B$2:$G$12

(Or you could use VBA to determine this dynamically)

The code also expects to find a range called PutResultsHere, which as the name implies, is where you want the output table. A single cell will suffice - the code works out the required size dynamically.
 
Upvote 0
I'm getting an error with this line which is why im asking lol. Where do i put these variable above the sub test () or within the macro or where else




1634761188828.png
 
Upvote 0
thank you so so much. this really helps a lot. you really are a great man. Just one more question sorry about that. But how would I make it so that strategies above 30% on an absolute basis have their own category

I put a picture


1634788719342.png
 
Upvote 0
You could generalise the code like this:

VBA Code:
Sub Test()

    Dim vIn As Variant, vOut() As Variant, vTemp() As Variant
    Dim Count() As Long, i As Long, j As Long, k As Long, counter As Long
    Dim diff As Double
    Dim header() As String
    Const N = 2, cols = 6, M = 3
    ReDim vOut(1 To M)
    ReDim Count(1 To M)
    ReDim header(1 To M)
    header(1) = "Overweight 20% +"
    header(2) = "Overweight 10% +"
    header(3) = "Underweight 10% +"
        
    vIn = Range("MyData").Value2
    ReDim vTemp(1 To (UBound(vIn) - 1) * (UBound(vIn, 2) - 1) / N, 1 To cols)
    For i = 1 To M
        vOut(i) = vTemp
    Next i
        
    For i = 2 To UBound(vIn) - 1 Step N
        For j = 2 To UBound(vIn, 2)
            k = 0
            Select Case vIn(i, j) - vIn(i + 1, j)
            Case Is > 20
                k = 1
            Case Is > 10
                k = 2
            Case Is < -10
                k = 3
            End Select
            If k <> 0 Then
                Count(k) = Count(k) + 1
                vOut(k)(Count(k), 1) = vIn(i, 1)
                vOut(k)(Count(k), 2) = vIn(1, j)
                vOut(k)(Count(k), 3) = vIn(i, j)
                vOut(k)(Count(k), 4) = vIn(i + 1, j)
                vOut(k)(Count(k), 5) = vIn(i, j) - vIn(i + 1, j)
                vOut(k)(Count(k), 6) = "???"  'I don't know what this number is
            End If
        Next j
    Next i

    With Range("PutResultsHere")
        .ClearContents
        .Font.Bold = False
        For i = 1 To M
            With .Offset(counter)
                .Cells(1, 1).Value = header(i)
                .Cells(1, 1).Font.Bold = True
                If Count(i) > 0 Then
                    .Offset(1).Resize(Count(i), cols).Value = vOut(i)
                Else
                    .Offset(1).Cells(1, 1).Value = "n/a"
                    counter = counter + 1
                End If
                counter = counter + Count(i) + 1
            End With
        Next i
        .Resize(counter, cols).Name = "PutResultsHere"
    End With
    
End Sub
 
Upvote 0
hey, thanks for your reply. I said 30% as an absolute value not a relative one. so if a value for a strategy was 30% and lets say the benchmark was 25% it would still show.
 
Upvote 0

Forum statistics

Threads
1,215,209
Messages
6,123,646
Members
449,111
Latest member
ghennedy

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