How to write a average formula in excel vba - vba

I am trying to calculate average, but i am getting an run-time error. Here is my code..
lastrowcell = Range("B1", Range("B1").End(xlDown)).Rows.Count
Range("F1").Value = "High+Low/2"
For n = 2 To lastrowcell
Range(Cells(n, 6)).Formula = "=average(" & Range(Cells(n, 2), Cells(n, 3)).Address(False, False) & ")"
Next
Can anyone show what I did wrong.
Thanks in advance...

You don't need to loop, Excel is smart enough to fill the entire thing in one go:
lastrowcell = Range("B1", Range("B1").End(xlDown)).Rows.Count
Range("F1").Value = "High+Low/2"
Range("F6:F" & LastRow).Formula = "=AVERAGE(B6:C6)"
The 6 will be incremented in each row
If you want the last row though, its always better to come from the bottom up unless you are specifically looking for the first blank:
lastrowcell = Range("B" & Rows.Count).end(xlup).row

Range(Cells(n, 6))
is not correct syntax for Range property. When there is only one parameter, it should be string. Instead you can use:
Cells(n, 6)
or
Range("F" & n).

Related

substract using activecell.offset

my lastrow is (315) - in the below code i need help in the last line (i am trying to do (sum of col H) - (sum of col J) by using activecell-offset in col k
''Totals''
Range("K" & LastRow).Offset(5, 0).Formula = "=activecell.offset(0,-3)-activecell.offset(0-1)"
I don't know how your last row becomes 315 and you have data on the 320 but you are looking for this:
Range("K" & LastRow).Offset(5, 0).Value = ActiveCell.offset(0,-3) - ActiveCell.offset(0-1)
Range("K" & LastRow).Offset(5, 0).Formula = "=" & ActiveCell.Offset(0, -3).Address & "-" & ActiveCell.Offset(0 - 1).Address
This would work, but is not pretty. An alternative would be a static VBA solution such as Damian's answer.
Furthermore, I would advise you to refer to the correct workbook and -sheet. If you were to omit this, the VBA code would always refer to the active workbook/-sheet, something you often don't want.
E.g.
With Workbooks(REF).Sheets(REF)
.Range("K" & LastRow).Offset(5, 0).Formula = "=" & ActiveCell.Offset(0, -3).Address & "-" & ActiveCell.Offset(0 - 1).Address
End With
Next to that, referring to the active cell is also asking for trouble. Perhaps you are better off with referring to better defined ranges, such as
With Workbooks(REF).Sheets(REF)
.Range("K" & LastRow).Offset(5, 0).Formula = "=" & .Cells(LastRow + 4, "K").Address & "-" & .Cells(LastRow, "J").Offset(0 - 1).Address 'Ranges randomly chosen
End With
EDIT
Formulas are dynamic. In other words, their results change dynamically with values/ranges they refer to. Unless you code a Worksheet_Change event, the calculation below will not update if you change the values for which the sum is calculated. However, you don't always need calculations to be dynamic, so pick what you need. I am assuming your columns have headers.
With Workbooks(REF).Sheets(REF)
LastRow = .Cells(.Rows.Count, "K").End(xlUp).Row
LROWJ = .Cells(.Rows.Count, "J").End(xlUp).Row
LROWH = .Cells(.Rows.Count, "H").End(xlUp).Row
.Range("K" & LastRow).Value = Application.Sum(.Range("H2:H" & LROWH)) - Application.Sum(.Range("J2:J" & LROWJ))
End With

How to refer to a range with two variables

I'm putting together a report and can't figure out the syntax for referring to a range with two variable rows. This is what I currently have.
.Cells(mrow, 4).Value = Application.Sum(Range("D3:D" & brow - 1))
brow is a variable row that I've defined earlier in the code.
Instead of referring to D3:d(brow), how can I refer to D(arow):D(brow) in this range? I can't figure out where to place the quotes.
Thanks!
.Cells(mrow, 4).Value = Application.Sum(.Range("D" & arow & ":D" & brow - 1))
Or
.Cells(mrow, 4).Value = Application.Sum(,Range(.Cells(arow,4),.Cells(brow-1,4)))

Splitting cell with multiple data into multiple rows in more than 1 column

I have a sheet with multiple data in 1 cell this happen in a couple of columns. What I need to do is split the cell into individual rows while still keep the details from the other columns
Screen 1 shows the data i got
http://imageshack.com/a/img845/1783/wxc8.png (Screen 1)
Screen 2 is what i wish the macro to output.
http://imageshack.com/a/img842/7356/7yra.png (screen 2)
The macro i found and edited in only allows me to split 1 column and i can't get the editing of the range right. the columns that needs to be split is "J" "K" "N" and "O". The columns "A"- "I" and "L""M" just needs to copy their content to the new row.
Thank you in advance for the help.
Here the Macro im using
Sub Splt1()
Dim LR As Long, i As Long
Dim X As Variant
Application.ScreenUpdating = False
LR = Range("J" & Rows.Count).End(xlUp).Row
Columns("J").Insert
For i = LR To 1 Step -1
With Range("K" & i)
If InStr(.Value, Chr(10)) = 0 Then
.Offset(, -1).Value = .Value
Else
X = Split(.Value, Chr(10))
.Offset(1).Resize(UBound(X)).EntireRow.Insert
.Offset(, -1).Resize(UBound(X) - LBound(X) + 1).Value = Application.Transpose(X)
End If
End With
Next i
Columns("K").Delete
LR = Range("J" & Rows.Count).End(xlUp).Row
With Range("L1:M" & LR)
On Error Resume Next
.SpecialCells(xlCellTypeBlanks).FormulaR1C1 = "=R[-1]C"
On Error GoTo 0
.Value = .Value
End With
Application.ScreenUpdating = True
End Sub
The problem appears to be the with operator. It constrains your selection. Try reformulating your macro without the with and refer to the the ranges direct. For example, replace your first for loop with something like this:
For i = LR To 1 Step -1
If InStr(Range("K" & i).Value, Chr(10)) = 0 Then
Range("K" & i).Offset(, -1).Value = Range("K" & i).Value
'Range("J" ...
'Range("N" ...
'Range("O" ...
Else
K_collection = Split(Range("K" & i).Value, Chr(10))
Range("K" & i).Offset(1).Resize(UBound(K_collection)).EntireRow.Insert
Range("K" & i).Offset(, -1).Resize(UBound(K_collection) - LBound(K_collection) + 1).Value = Application.Transpose(K_collection)
'J_collection = Split(Range("J"...
'N_collection = Split(Range("N"...
'O_collection = Split(Range("O"...
End If
Next i
In general I avoid with because it tends to obscure the visual pattern of code.
You might also consider eliminating the .INSERT and .DELETE columns, and overwrite directly to the cells. When working with more than one at a time, it becomes hard to keep track which column is temporary and which one is the source. But that all depends on your preference.
Copying values for the other columns should be easy compared to this.

1004: Application defined error when trying to examine cell contents

I am trying to loop through the rows in my sheet, adding cells B-F of the current row to a range to be copied to another sheet. The cells in the row (B-F) should only be added to the range if the value in column G is "Active" and if the value in column C has a value (not empty/nothing/null/!#VALUE...)
I've tried several ways around it, but I keep getting 1004: App/Object defined error off the first If statement
The msgbox shows me the range is valid, I've tried qualifying to the tiniest detail and also using Cells() instead of .range to no avail.
MsgBox (ActiveWorkbook.Worksheets("Staging").range("G" & Cells(rows.Count, 5).End(xlUp).Row).Value)
For i = Cells(rows.Count, 5).End(xlUp).Row To i = 1 Step -1
If ActiveWorkbook.Worksheets("Staging").Cells("G" & i).Value = "Active" Then
If Not IsError(ActiveWorkbook.Worksheets("Staging").range("C" & i)) Then
Set selectRange = range("B" & i & ":F" & i)
Set copyRange = Union2(copyRange, selectRange)
Else
'Do Nothing
End If
Else
'Do Nothing
End If
Next
Am I just missing something simple here? I've been banging my head over this for hours now.
...and for you eagle eyes out there, Union2 isn't a typo, just a user defined function to avoid not being able to join ranges set to "Nothing"
Try the following:
Change the second line to
For i = Cells(rows.Count, 5).End(xlUp).Row To 1 Step -1
Change the third line to
If ActiveWorkbook.Worksheets("Staging").Range("G" & i).Value = "Active" Then
To start change:
If ActiveWorkbook.Worksheets("Staging").Cells("G" & i).Value = "Active" Then
To
If ActiveWorkbook.Worksheets("Staging").Range("G" & i).Value = "Active" Then
Or
If ActiveWorkbook.Worksheets("Staging").Cells(i , 7).Value = "Active" Then
You also need to fully qualify all your ranges as alot of your ranges are pointing to the active sheet and NOT "staging" Unless it is the active sheet, but just to be sure you should use the following code:
With ActiveWorkbook.Worksheets("Staging")
MsgBox (.Range("G" & .Cells(.Rows.Count, 5).End(xlUp).Row).Value)
For i = .Cells(.Rows.Count, 5).End(xlUp).Row To 1 Step -1
If .Range("G" & i).Value = "Active" Then
If Not IsError(.Range("C" & i)) Then
Set SelectRange = .Range("B" & i & ":F" & i)
Set copyRange = Union(copyRange, SelectRange)
Else
'Do Nothing
End If
Else
'Do Nothing
End If
Next
End With
Also You are using copyRange in this scope without it being declared, I am assuming you are assigning it to a range earlier in your code but if not please make sure to do that.
This is wrong:
ActiveWorkbook.Worksheets("Staging").Cells("G" & i).Value
You can use these:
ActiveWorkbook.Worksheets("Staging").Cells(i, 6)
ActiveWorkbook.Worksheets("Staging").range(cells(i, 6), cells(i, 6)).value
ActiveWorkbook.Worksheets("Staging").range("G" + strings.trim(str(i))).value
I was getting the below Error:
Go to Home -> Select the cell for which you are getting Error-> Use clear all funtion to clear the method.
I executed the script again and it started working fine.

Moving a Do Until function across columns in excel vba

I'm pretty new to VBA and having trouble creating a quick macro used to move blocks of numbers around.
What I am trying to create is a button that when pressed:
Moves the contents of (i,5) to E63
The cells from (i, 16) down to F67:F110
Dependant on whether Row 10 contains "Low" or "High" moves three cells from the set
N106:N109 to the cells (i12:i14) [Where i is the column reference).
The Range sections of code are what accomplish this and they are working fine, the problem I am having is with my Do.Until row and with the reference Column(i)
Does anyone know how this could work? Thanks
UPDATE
So thanks to the help of Siddharth I've been able to fix all but one bit, which is the lines where there is a string in the Range function. The reason I am not using .Formula here but Paste instead is that otherwise all of the cells A12:A14 to Z12:Z14 will equal the same thing which isn't correct. On the other parts that doesn't matter. I am getting a type 13 mismatch error on these lines.
Sub Columntest()
Dim i As Integer
i = 5
Do Until Cells(5, i).Value = ""
If Cells(10, i).Value = "Low" Then
Range("E63").Formula = Cells(5, i)
Range("F67:F110").Formula = Cells(16, i)
Range("O106:O108").Copy
Range("=" & Columns(i) & "12").PasteSpecial Paste:=xlPasteValues
End If
If Cells(10, i).Value = "High" Then
Range("E63").Formula = Cells(5, i)
Range("F67:F110").Formula = Cells(16, i)
Range("N106:N108").Copy
Range(Columns(i) & "12").PasteSpecial Paste:=xlPasteValues
End If
i = i + 1
Loop
End Sub
The type mismatch is because you are trying to concatenate a column object and a string in the range reference:
Range("=" & Columns(i) & "12").PasteSpecial Paste:=xlPasteValues
Try using this instead:
Cells(12, i).PasteSpecial Paste:=xlPasteValues