Display formula in cell (average function) - excel

I have some data:
For each column, I want to calculate the average of the most current year. In the example below, I want to calculate it for 2020, so rows 164, 165 and 166. The result should appear in row 163.
However, I want not just the result, I want the formula so the user can see what is being calculated, but I can't. Maybe relevant: I'm using German Excel. I tried using .FormulaLocal and MITTELWERT(German for AVERAGE) but I think I'm making a different kind of mistake. With both .Formula and .FormulaLocal I'm getting a run time error 13 (type) in the line with the .Formula.
Sub FormulaLeased(ByVal fRow As Long, ByVal lCol As Long, ws As Worksheet)
Dim i As Long
Dim iCol As Long
'manually setting values for this example:
fRow = 164
lCol = 7
Set ws = ActiveSheet
With ws
Select Case Mid(.Cells(fRow, "A").Value, 4, 2) 'Determining the most recent quarter
Case "12"
i = 3
Case "09"
i = 2
Case "06"
i = 1
Case "03"
i = 0
End Select
For iCol = 2 To lCol
'---works, but only shows the result, not the forumla:
'.Cells(fRow - 1, iCol).Value = Application.WorksheetFunction.Average(.Range(.Cells(fRow, iCol), .Cells(fRow + i, iCol)))
'---results in type error:
.Cells(fRow - 1, iCol).Formula = "= Application.WorksheetFunction.Average(" & .Range(.Cells(fRow, iCol).Address(False, False) & ":" & .Cells(fRow + i, iCol).Address(False, False)) & ")"
'---trying to use .FormulaLocal -> Type error
'.Cells(fRow - 1, iCol).FormulaLocal = "= MITTELWERT(" & .Range(.Cells(fRow, iCol).Address(False, False) & ":" & .Cells(fRow + i, iCol).Address(False, False)) & ")"
Next iCol
End With
End Sub

Application.WorksheetFunction does not work with .Formula or .FormulaLocal. The .Formula needs the English formula as you would write it in the cell, and .FormulaLocal needs the localized formula (German) as you would write it in the cell.
So this approach was the one to go:
.Cells(fRow - 1, iCol).FormulaLocal = "= MITTELWERT(" & .Range(.Cells(fRow, iCol).Address(False, False) & ":" & .Cells(fRow + i, iCol).Address(False, False)) & ")"
but needs to be changed to
.Cells(fRow - 1, iCol).FormulaLocal = "=MITTELWERT(" & .Cells(fRow, iCol).Address(False, False) & ":" & .Cells(fRow + i, iCol).Address(False, False) & ")"
there is no Range needed just the addresses of the 2 cells.
Note that this code will only work if you run it in a German Excel because MITTELWERT will not be translated to other localizations. If you plan that your code should run on a French Excel too, then you would need to use the English formula and .Formula. This will translate to any localization and therefore work in all Excel versions. I highly recommend to use .Formula and translate them yourself into English (https://excel-translator.de might help):
.Cells(fRow - 1, iCol).Formula = "=AVERAGE(" & .Cells(fRow, iCol).Address(False, False) & ":" & .Cells(fRow + i, iCol).Address(False, False) & ")"

Related

vba excel conditional formatting - invalid Procedure call or argument

I have an Excel sheet in which I want to add an Conditional Formula by VBA. While I'm trying to do so, Excel is throwing "Invalid procedure call or argument" and I can't find why.
The problem is with exactly this line:
Set cf = shG.Range("E" & (i - 3) & ":AI" & (i - 2)).FormatConditions.Add(type:=xlExpression, Formula1:="=OR(ISNUMBER(SEARCH(""holiday"",E$" & i & ")),ISNUMBER(SEARCH(""l4"",E$" & i & ")))")
What it should do?
It should change font color to white for 1st and 2nd rows in case if 4th row will contain "holiday" or "l4"
Full Sub:
Sub AddCondForm(shG As Worksheet)
Dim r As Range
Dim cf
Set r = shRoles.Cells(2, 1)
Do
For i = 8 To 204 Step 4
If Not IsEmpty(shRoles.Cells(r.row, 2)) Then
Set cf = shG.Range("E" & i & ":AI" & i).FormatConditions.Add(type:=xlTextString, String:=r.Value, _
TextOperator:=xlBeginsWith)
Else
Set cf = shG.Range("E" & i & ":AI" & i).FormatConditions.Add(type:=xlCellValue, Operator:=xlEqual, _
Formula1:=r.Value)
End If
cf.Interior.Color = r.Next.Next.Next.Interior.Color
cf.Font.Color = r.Next.Next.Next.Font.Color
cf.SetFirstPriority
'HERE IS PROBLEM
Set cf = shG.Range("E" & (i - 3) & ":AI" & (i - 2)).FormatConditions.Add(type:=xlExpression, Formula1:="=OR(ISNUMBER(SEARCH(""holiday"",E$" & i & ")),ISNUMBER(SEARCH(""l4"",E$" & i & ")))")
'END OF PROBLEM
cf.Font.ColorIndex = 2
'Coloring C Column
Set cf = shG.Range("C" & (i - 3) & ":C" & i).FormatConditions.Add(type:=xlExpression, Formula1:="=$A$" & i - 3 & "=1")
cf.Interior.ThemeColor = xlThemeColorAccent6
Set cf = shG.Range("C" & (i - 3) & ":C" & i).FormatConditions.Add(type:=xlExpression, Formula1:="=$A$" & i - 3 & "=3/4")
cf.Interior.ThemeColor = xlThemeColorAccent6
cf.Interior.TintAndShade = 0.2
Set cf = shG.Range("C" & (i - 3) & ":C" & i).FormatConditions.Add(type:=xlExpression, Formula1:="=$A$" & i - 3 & "=1/2")
cf.Interior.ThemeColor = xlThemeColorAccent6
cf.Interior.TintAndShade = 0.4
Set cf = shG.Range("C" & (i - 3) & ":C" & i).FormatConditions.Add(type:=xlExpression, Formula1:="=$A$" & i - 3 & "=1/4")
cf.Interior.ThemeColor = xlThemeColorAccent6
cf.Interior.TintAndShade = 0.6
Next
Set r = shRoles.Cells(r.row + 1, 1)
Loop Until IsEmpty(r.Value)
End Sub
PS. I checked the formula itself and it seems working properly. Other lines are also working well. Only this one and I don't know why :'(
If you're not English user, this may be important for you.
In case of FormatCondition.Add you need to add formula exactly the same as if you were entering it manually. So if separator in your language is not a comma, like in Poland (we have semicolon) you would have to use that separator and translate your formulas to that language.
In my case it means I had to change formula to
=LUB(CZY.LICZBA(SZUKAJ.TEKST(""holiday"";E$" & i & "));CZY.LICZBA(SZUKAJ.TEKST(""l4"";E$" & i & ")))"

Is there a simple way to set 2 Variable into Range Function

I want to add two variable into my vba's range function.
For exemple I would like to set a range like this but I don't know if it is possible :
Range("BY" & FirstVariable &":BY" & SecondVariable)
In order to use WorksheetFunction. Median Method :
Application.Median(Range("BY" & FirstVariable &":BY" & SecondVariable))
I tried this :
Range("BY" & ActiveCell.Row - CptM & ":BY" & ActiveCell.Row)
Where CptM is a Number
But I got the error : "Execution code 91: Object Variable Or Bloc Variable With not defined.
What i want to do :
I am using a For Loop to Browse J Column and to check Value Of J Cells
For Cpt = 4 To Cells(Rows.Count, 10).End(xlUp).Row
MyString= Cells(Cpt - 1, 10).Value
If Cells(Cpt, 10).Value = MyString Then
CptM = CptM + 1
End If
If Cells(Cpt, 10).Value <> Metier Then
MyVar= Application.Median(Range("BY" & ActiveCell.Row - CptM & ":BY" & ActiveCell.Row))
Cells(Cpt, 81).Value = MyVar
CptM = 0
End If
Next Cpt
There i except to get the Median of the range R1 , R2 ect ...
Thanks for your time and consideration.
This will work:
Application.Median(Range("BY" & ActiveCell.Row - CptM & ":BY" & ActiveCell.Row))
You can put this as a value in any variable.
The problem was due to ActiveCell.Row because i didn't have Active Cells.
To handle this i just used Cpt in stead of ActiveCell.Row
The full line code is :
Application.Median(Range("BY" & Cpt - CptM & ":BY" & Cpt))

VBA Formula creation uses the name of the Variable rather than the value

Im trying to create a code which will allow me to pull the average of 6 rows from a sheet called 'Raw Data' and dump it into a cell in a different worksheet, and then pull the average of the next 6 rows from 'Raw Data' and so on.
E.G. average('RawData'! A1:A6) in a new sheet A1
then
average('Raw Data'! A7:A12) In new sheet A2
etc.
So far I have managed to make the code loop in a way that I want however Im having trouble writing the actual formula in new sheet A1 and A2.
so far I have tried:
Dim address13 As String
address13 = "'Raw Data'" & "!" & Cells(start_row, RPM1300).Address & ":" & _
Cells(end_row, RPM1300).Address
ActiveCell.Offset(0, -4).Select
'1300
ActiveCell.Formula = "=Average(""" & address13 & """)"
However this returns the correct formula but with "" around it - rendering it useless.
I have also tried:
Sheets("Raw Data").Select
Dim address9 As Range
Set address9 = Range(Cells(start_row, RPM900).Address(), Cells(end_row, RPM900).Address())
Sheets("New Sheet").Select
rCell.Activate
ActiveCell.Offset(0, -5).Select
ActiveCell.Formula = "=Average(address9)"
However this just returns the name of the variable address9 in the formula rather than the actual range.
Note that RPM1300, RPM900, start_row, end_row and rCell are all variables in order for the code to loop and paste into the correct places.
Any help would be greatly apreciated
Try replacing your line:
ActiveCell.Formula = "=Average(""" & address13 & """)"
With:
ActiveCell.Formula = "=AVERAGE(" & address13 & ")"
The reason: the variable address13 is already defined as a String, that's why you don't need the extra " inside the brackets.
Code (use your first method:)
Dim address13 As String
address13 = "'Raw Data'!" & Cells(start_row, RPM1300).Address & ":" & _
Cells(end_row, RPM1300).Address
ActiveCell.Offset(0, -4).Select
ActiveCell.Formula = "=AVERAGE(" & address13 & ")"
Note: Try avoid using Select and ActiveCell , instead use referenced Ranges and Worksheets.
For instance, let's say you start from Cell A1, and you want this formula to be in Cell A5, you can use:
Range("A1").Offset(4, 0).Formula = "=AVERAGE(" & address13 & ")"
It is probably a bug in your version of Excel. Instead of
ActiveCell.Formula = "=Average(""" & address13 & """)"
try using
ActiveCell.Formula = '=Average("' & address13 & '")'
(single quotes around strings with double quotes and using only 1 double quote then).
Instead of
ActiveCell.Formula = "=Average(""" & address13 & """)"
Try
ActiveCell.Formula = "=Average("& chr(34) & address13 & chr(34) & ")"
At least here chr(34) returns the quotes you want. This may be tweaked if needed. Just change the number inside the ( )
Try using this:
Sub CellValue()
Dim adr As String
Dim sht As String
sht = "'Raw Data'"
adr = "A1:A3"
ActiveCell.Formula = "=AVERAGE(" & sht & "!" & adr & ")"
End Sub
Hope it helps :)
This formula will give you the same result and you'd be able to autofill it by dragging the cell handle.
=AVERAGE(OFFSET('Raw Data'!$A$2,ROW(A1)*6-7,0,6,1))
Filling in both formulas
Sub FillFormulas()
Const BASE_FORMULA = "=AVERAGE('Raw Data'!#Address)"
Dim lastRow As Long, x As Long
Dim Formulas
With Worksheets("Raw Data")
lastRow = .Range("A" & .Rows.Count).End(xlUp).Row / 6
End With
ReDim Formulas(1 To lastRow, 1 To 1)
With Worksheets("New Sheet")
For x = 1 To lastRow
Formulas(x, 1) = Replace(BASE_FORMULA, "#Address", .Cells((x * 6) - 5, 1).Resize(6).Address)
Next
.Range("A1").Resize(lastRow).Formula = Formulas
.Range("C1").Resize(lastRow).Formula = "=AVERAGE(OFFSET('Raw Data'!$A$2,ROW(A1)*6-7,0,6,1))"
End With
End Sub

VBA sum loops in Formula Arrays

If I have defined named ranges for some blocks - say for example, 2 by 2 blocks named Apple1, Apple2, Apple3, Apple4
and I want to create a Total Block being the sum of the above (in excel, the formula array formula would be {Apple1 + Apple2 + Apple3 + Apple4}
With the FormulaArray command - am I on the right lines in my thought process below?
For i = 1 to 2
range("Total").formulaarray = "=" & "Apple" & i
next i
I've not understand why you need FormulaArray for such task, but you can use this:
Sub test()
Dim i%, Apples$
For i = 1 To 4
Apples = Apples & "+SUM(Apple" & i & ")"
Next i
[Total].FormulaArray = "=" & Mid(Apples, 2, Len(Apples))
End Sub
After my experiment, I find the behavior of FormulaArray is more complicated.
sub test()
dim i as long, Apples1 as variant, Apples2 as variant
for i = 1 to 3
Apples1 = Apples1 & "Apple" & i & "+"
Apples2 = Apples2 & "Apple" & i & ","
next i
range("total1").FormulaArray = "=sum(" & left(Apples1, len(Apples1)-1) & ")"
range("total2").FormulaArray = "=sum(" & Apples2 & ")"
range("total3").FormulaArray = "=" & left(Apples1, len(Apples1)-1)
end sub
the outcome is
If any cells in Apple1, Apple2 or Apple3 are string, the outcome is

Paste formula in a range without autofill

I'm trying to put a formula into a range of cells without using autofill. I had it working with autofill before but want to change it and can't seem to get it to work. Can someone tell me what I'm doing wrong? Unable to set the FormulaArray property of the Range cHere is what I have:
With ActiveSheet.ListObjects(1)
Cells(1, .ListColumns.Count - 5).Value = "STUDENT POINTS"
Range(Cells(3, .ListColumns.Count - 5), Cells(.ListRows.Count + 1, .ListColumns.Count - 5)).FormulaArray = "=IF(SUM(" & Range("E3").Address(False, True) & ":" & Cells(3, intTotalItems + 4).Address(False, True) & ")>0,SUM(" & Range("E3").Address(False, True) & ":" & Cells(3, intTotalItems + 4).Address(False, True) & "),"""")"
'rngAssignment.Offset(2, intTotalItems + 1).AutoFill Destination:=Range(rngAssignment.Offset(2, intTotalItems + 1), rngAssignment.Offset(2, intTotalItems + 1).End(xlDown))
End With
Note: The fourth line is commented out. I used that line for the previous way.
Thanks!
I've had a go at this. You have an undefined symbol
intTotalItems
If I try to substitute something in for that and also for variable
lColCountMinusFive
then the code works and the formula array functions. Admittedly, I did pull your code apart whilst debugging and defined some interim variables...
Sub T()
Dim intTotalItems
Dim lColCountMinusFive As Long
With ActiveSheet.ListObjects(1)
lColCountMinusFive = 1 'Meaden .ListColumns.Count - 5
Cells(1, lColCountMinusFive).Value = "STUDENT POINTS"
Dim rngToFill As Excel.Range
Set rngToFill = Range(Cells(3, lColCountMinusFive), Cells(.ListRows.Count + 1, lColCountMinusFive))
Dim sSum As String
sSum = Range("E3").Address(False, True) & ":" & Cells(3, intTotalItems + 4).Address(False, True)
rngToFill.FormulaArray = _
"=IF(SUM(" & sSum & ")>0,SUM(" & sSum & "),"""")"
End With
End Sub
What was the error message (if one)?

Resources