To start, the best way to learn VBA is to start the macro recorder, do what you want in the GUI and then look at the resulting code. I would recommend doing that as much as possible.
To paste your value in cell N3, use
Range("N3").Value = Minimum 'Or whatever you want to paste
In the code you provided, you never copied anything. If you have the value you want selected, you can use
Selection.Copy
to copy it and then paste as you did in your code. In your range, you can use Range("C:C") to select the entire column instead of going to row 65536. This should get your code working. As a note, I probably wouldn't bother making Movedown its own function. It's one line, so you could just use it explicitly.
I have not tested this code, but if it was working other than the pasting portion, this should fix it. If you're not sure where it's having trouble, try using
MsgBox c 'or any text or variable name
This will give you a dialog box showing the value of your variable at the point you added the MsgBox line. This is often helpful to determine if your variable isn't being set properly or if there is an issue with pasting or displaying it.
Hope this helps! Good luck!
EDIT:
Here's code that should do what you want. I commented heavily, so hopefully it's clear what is happening, but let me know if not. The basic idea is there's a For loop that is checking the current value of the cell in Column C against the cell just below it and if they match, it increments a variable and keeps track of how many of the same value are in a row. As soon as it finds cells that don't match, it finds the minimum of the range of the current cell (in Column D) through the first cell that matched (which is why we were keeping track of how many matched in a row.)
I didn't explain earlier, but if you didn't know the single apostrophe is a line comment character in VBA. That means anything appearing after the apostrophe is not read by the program and is just for humans to keep track of what is happening.
Private Sub findMin()
Dim lastRow As Integer
Dim i As Integer
Dim comp1 As Integer
Dim comp2 As Integer
Dim rngCount As Integer
Dim minimum As Integer
lastRow = WorksheetFunction.CountA(Range("C:C")) 'Find the last row with data
rngCount = 0
For i = 1 To lastRow
comp1 = ActiveSheet.Cells(i, 3).Value 'Set comp1 equal to the Value of the cell in Column C at the current row in the For loop
comp2 = ActiveSheet.Cells(i + 1, 3).Value 'Set comp2 equal to the value of the cell just below it
If comp1 <> comp2 Then 'If the values are different, i.e. we've found the last item in a series of matches
minimum = Application.WorksheetFunction.Min(Range(Cells(i, 4), Cells(i - rngCount, 4))) 'Find the minimum of the range of cells from Row i in Column D to Row i - rngCount (which is were our series of matches began)
Cells(i, 14).Value = minimum 'Paste the found minimum in Column N, Row i
rngCount = 0 'Because the values no longer match, reset our counter
Else 'If the values are the same
rngCount = rngCount + 1 'increment our range counter until the values do not match
End If
Next i
End Sub
A few notes in addition to what I said above about best practices: Avoid using Select unless you have a good reason to use it. There's a number of reasons why and some lengthy discussions about it on this site and others, but for now suffice it to say that it adds length and possible confusion that is unnecessary. Cells(1,1).Select: Selection.Value = variableA
is the same as Cells(1,1).Value = variableA1
. I would also avoid using Copy and Paste for similar reasons when you can use .Value =
. This is clearer to read and has fewer chances for things to go wrong or not work as you intended. I would also recommend that you comment your code heavily, especially if you are having trouble and paste it here. This will help others better understand what you were trying to do. Even if it works fine, it is a good idea to comment in case you need to change it months later or someone else needs to read it. It's a good habit to get in.
EDIT 2:
This should be what you're looking for. I tried to comment the changes I made, so hopefully it makes sense. As far as the If statement in For j goes, you had it set to check if cell j matched the cell above it and if it was different from the cell below it. However, in Column N, the first For loop only puts code on cells where the value is different. Whenever the value is the same, the corresponding cell in Column N is blank. So checking to see if Column N has a positive value in it will catch cells with data and ignore blank cells. You could also only check if the next cell is different. If you check this on every single cell, it can safely be assumed that the previous cell was the same. This is what I did in the first For loop.
Private Sub findMin()
Dim lastRow As Integer
Dim i As Integer
Dim comp1 As Integer
Dim comp2 As Integer
Dim rngCount As Integer
Dim minimum As Integer
Dim comp3 As Integer
Dim comp4 As Integer
Dim lastRowNotional As Integer
Dim j As Integer
Dim offset1 As Integer
Dim summation As Double 'I don't know how many items you are summing or how large they are, but if it's too large Integer won't work. I needed to use Double for the sample data I made up
lastRowDate = WorksheetFunction.CountA(Range("G:G")) 'Find the last row with data
lastRowNotional = WorksheetFunction.CountA(Range("L:L")) 'Unless Columns G and L are different lengths, there is not a need to have a second variable
rngCount = 0
For i = 1 To lastRowDate
comp1 = ActiveSheet.Cells(i, 7).Value 'Set comp1 equal to the Value of the cell in Column C at the current row in the For loop
comp2 = ActiveSheet.Cells(i + 1, 7).Value 'Set comp2 equal to the value of the cell just below it
If comp1 <> comp2 Then 'If the values are different, i.e. we've found the last item in a series of matches
minimum = Application.WorksheetFunction.Min(Range(Cells(i, 12), Cells(i - rngCount, 12)))
Cells(i, 14).Value = minimum 'Paste the found minimum in Column N, Row i
rngCount = 0 'Because the values no longer match, reset our counter
Else: comp1 = comp2 'If the values are the same
rngCount = rngCount + 1 'increment our range counter until the values do not match
End If
Next i
'I moved this whole For loop outside the other one so that it doesn't try to run for every new i
'Also, you had i inside this loop, but your loop counter is j. This is an easy mistake to make when using a lot of For loops
For j = 1 To lastRowDate 'We want to only check as many rows in Column N as we output, which is equal to lastRowDate
comp3 = ActiveSheet.Cells(j, 14).Value 'I added the .Value here
If Cells(j, 14).Value > 0 Then 'This will throw an error when it tries to find the cell above row 1. Be careful of using row - 1 on functions that include the first row
'Just checking to see if the cell's value is greater than zero should suffice
summation = Application.WorksheetFunction.Sum(Range(Cells(j, 12), Cells(j - rngCount, 12)))
Cells(j, 15).Value = summation 'I moved this to paste in Column O. Otherwise it would paste over the minimum we just found, defeating the purpose of finding the minimum
rngCount = 0 ' Don't forget to reset your counter here.....
Else
rngCount = rngCount + 1 '... or increment it here
End If
Next j 'Be sure to include Next j to move the loop forward
End Sub