set sum formula in excel using vba - excel

Working on a excel macros where I am trying to add the cell values from above cells to calculate total value. This is what my data looks like
Here I want to add above cell values for each column to calculate the sum. To accomplish this i have written a macro as follows.
For cl = 2 To 5
Worksheets(5).Cells(4, cl).Formula = "=SUM(B4:B6)"
Next cl
This should set the formula to each cell in a row till 5 columns.
But it sets the same formula on all cells in a row it should get change according to column. How to set sum formula for each cell for corresponding column ?

Not sure I quite understand your code. You seem to be writing into row 4, but you also want to sum from row 4 to row 6. That will create a circular reference.
Let's assume the formula is written into row 3 instead. You will want to use the R1C1 reference style to make the cells to sum relative to the current cells.
A trick to learn what reference to use is:
Get a new worksheet, enter =SUM(B4:B6) into cell B3 and copy to the right.
Then click File > Options > Formulas and select R1C1 Reference Style.
Now inspect the formulas in the sheet. You will see this: =SUM(R[1]C:R[3]C)
This is what you need in the macro.
For cl = 2 To 5
Worksheets(5).Cells(3, cl).FormulaR1C1 = "=SUM(R[1]C:R[3]C)"
Next cl

some more details to R1C1 and R[1]C[1] style in formulas.
As far as I know R[1]C[1] creates a relative reference and R1C1 creates a absolute reference. But keep in mind that the figures for R[x] and C[y] are an offset to the cell which contains the formula.
That means if you want to show the sum of A1:B4 in C5 the code has to be like this:
Worksheets(5).Cells(5, 3).FormulaR1C1 = "=SUM(R[-4]C[-2]:R[-1]C[-1])"
If you want to the same but ending up with an absolute reference is aht to look like this.
Worksheets(5).Cells(5, 3).FormulaR1C1 = "=SUM(R1C1:R4C2)"

You can use very simple formula like below:
Sub sum_month()
Sheets("13").Activate
Range("D2").Formula = "=SUM(A1+A2+A3)"
End Sub
And next just hold and drag the cell to fill up another rows automatically.

For your case, you can use this:
For cl = 2 To 5
ColName = Left(Cells(1, cl).Address(0, 0), (Cells(1, cl).Column < 27) + 2)
ValueSum = "=SUM(" & ColName & "4:" & ColName & "6)"
Worksheets(5).Cells(4, cl).Formula = ValueSum
Next

Try something like this.
For cl = 2 To 5
ColName = Left(Cells(1, cl).Address(False, False), 1 - (cl > 26))
Worksheets(5).Cells(4, cl).Formula = "=SUM(" & ColName & "4:" & ColName & "6)"
Next cl

I think you can just reference the whole formula range and Excel will be smart enough to adjust the columns.
With no loop:
Worksheets(5).Cells(4, cl).resize(1,4).Formula = "=SUM(B4:B6)"

Related

How to copy the number if contains certain number (first 4 digit) to another column - EXCEL VBA

I'm trying to search on the specific column(E), and if matched with the first 4 digit, I would like to copy the number to a different column.
Column E is where i would like to paste all the random number(dynamic)
Column A/B/C is static where i would add 4 digits from time to time.
Column I/J/K is where is would like to paste the result.
PS:
I'm doing it manually and would really appreciate if someone can help me out with the automation hence no code is provided. :(
Having ExcelO365 means you may use FILTER(). Therefor try the below:
Formula in I2:
=FILTER($E:$E,ISNUMBER(MATCH(--LEFT($E:$E,4),A:A,0)))
Drag right to K2. Now, this is dynamic and will change accordingly upon data entry in column E:E, or changing values in A:C.
this is the code to execute on sheet 1, it goes through the entire column E and validates through the formula of counting if in each of the first three columns and assigns the value found in the corresponding columns.
Sub macro()
Dim Static_Data As String
Dim Sht As Worksheet
Set Sht = ThisWorkbook.Sheets("Hoja1")
Active_row = 2
Do While Sht.Range("E" & Active_row).Value <> ""
Static_Data = Sht.Range("E" & Active_row).Value
For i = 1 To 3
If Application.WorksheetFunction.CountIf(Sht.Columns(i), Mid(Static_Data, 1, 4)) > 0 Then
Sht.Cells(Sht.Cells(Rows.Count, i + 8).End(xlUp).Row + 1, i + 8).Value = Static_Data
End If
Next i
Active_row = Active_row + 1
Loop
End Sub
For Excel versions that don't support FILTER or as an alternative you can use standard formulas for this.
If you use columns F-H as helper columns (and these columns can be hidden) then the formula in F2 will be:
=IF(NOT(ISERROR(VLOOKUP(VALUE(LEFT($E2,4)),A$2:A$100,1,FALSE)))=TRUE,$E2,"")
The formula can then be copied across and down. This will find your matches.
In order to then remove the blanks from the data you can use the following formula in I2 and again copy across and down. Depending on how many numbers you want to add in, you may want to extend the range A$2:A$100 in the top formula and F$2:F$100 in the bottom formula
=IFERROR(INDEX(F$2:F$100,AGGREGATE(15,6,(ROW(F$2:F$100)-ROW(F$2)+1)/(F$2:F$100<>""),ROWS(I$2:I2))),"")

Is Microsoft's forced implicit intersection operator neutering my formula in Excel VBA?

I am using a formula to indent text in column "D" based on values in column "C" and have been using it in VBA to format worksheets. It looks like this: =setindent(D2,C2). Until recently, it has worked well, but now it doesn't. It looks like Microsoft has started to force "implicit intersection operators" into formulas (adding the #: =#setindent(D2,C2). It seems to have neutered my formula where it returns "#Value!". If I open one of the cells with the formula in edit mode and then hit "Enter" it changes to a number and the formula works on the targeted cell text. How do I resolve this in VBA?
Here is the formula:
Function SetIndent(z As Range, ByVal Level As Long) As Variant
Dim celldent As Range
SetIndent = IIf(Level < 0, "Min is 0!", IIf(Level > 10, "Max is 10!", Level))
If Level < 0 Then Level = 0 Else If Level > 10 Then Level = 10
For Each celldent In z
With celldent
If Level - .IndentLevel Then .InsertIndent Level - .IndentLevel
End With
Next celldent
End Function
. . . and here is the VBA copying the formula
'Format the Name (Column D) to indent per the Outline Level value in Column C
'See Module 16 for the Function: SetIndent
Range("AB2").Select
ActiveCell.Formula = "=SetIndent(D2,C2)"
Range("AB2").Copy Range("$AB$3:AB" & lastRow)
' Range("$AB2:AB" & lastRow).Clear
Thanks,
Tim
Try to enter the formulae directly into the entire range using .Formula2 instead of .Formula
Range("AB2:AB" & lastRow).Formula2 = "=SetIndent(D2,C2)"
So you can avoid unnecessary selecting/activating, too.
Furthermore I'd recommend to fully qualify your range references, e.g. via Sheet1.Range("AB2:AB" & lastRow).Formula2 using the worksheet's Code(Name) or ThisWorkbook.Worksheets("Sheet1")... using the Excel sheet's name string identifyer :-)

Fill series with irregular gaps in between

I have a set of data in which when there is value in column B then i need to fill corresponding column A with number series 1,2,3... Is this possible in VBA??
I filled the below formula in VBA but it will return 1 in all cases... while I need 1,2,3 etc.
Range("I22").Select
ActiveCell.FormulaR1C1 = "=IF((NOT(ISBLANK(RC27))),""1"","" "")"
This should also do the trick:
=IF(LEN($AA22),COUNTIF($AA$22:AA22,"<>"&""),"")
You can paste the following formula in Column A. This will work.
=IF(B2="","",MAX($A$1:A1)+1)
Try using count formula? You'd want a variable to store the location....
Copy and paste this:
Dim rng as range
rng = Range("I22")
rng.FormulaR1C1= "=IF(ISBLANK(RC27), """", COUNT(" & Range("A1").Address(True, True, xlR1C1) & ":RC27))"
Then replace A1 with the top cell of the column you want to count, and I22 with the cell that the formula goes in.
Try this code, please:
Range("I22").Formula = "=IF((NOT(ISBLANK($AA22))),IF(I21="""",1,I21+1),"""")"
It will increment the I21 value, if any. If nothing, it will write 1 (not "1"), like start of iteration...

Paste absolute references in a formula but increase by 1

I have a spreadsheet that has formulas spread over the sheet (averaging around five cells between them).
I want to copy a formula from say A1 and paste it into cell A6 but have the formula only increment the cell reference by 1.
For example:
=IF(ISBLANK(sheet1!$a$2),"",sheet1!$a$2)
And paste this into cell A7 but have the absolute reference now be
=IF(ISBLANK(sheet1!$a$3),"",sheet1!$a$3)
There are about 200 of these to add to the sheet so I'd rather not manually edit each one.
Use INDEX on column A and some maths to create the stagger.
=IF(ISBLANK(INDEX(Sheet1!$A:$A, INT((ROW(1:1)-1)/5)+1)), "", INDEX(Sheet1!$A:$A, INT((ROW(1:1)-1)/5)+1))
I suppose that INT could be replaced by ROUND for a 'fuzzy' stagger 'averaging around 5 cells between them'.
Other possibilities for incrementing the stagger could be COUNT, COUNTA, COUNTIF or even COUNTIFS but you haven't provided enough information to base any concrete suggestions upon beyond generalities.
Try using the Indirect in that way :
=IF(ISBLANK(INDIRECT("Sheet1!$A$" & ROW()+1)),"",INDIRECT("Sheet1!$A$" & ROW()+1))
If you like using VBA you can use this simple loop
Sub Test()
Dim r As Long
For r = 1 To Cells(Rows.Count, 1).End(xlUp).Row Step 6
Cells(r, 1).Formula = "=IF(ISBLANK(Sheet1!$A$" & r + 1 & "),"""",Sheet1!$A$" & r + 1 & ")"
Next r
End Sub

Use CELL on an array to return string made of types of the cells

Lets say we have 5000 rows with random values (blanks, numbers, characters). I need to show type of all the cells in these 5000 rows in a single cell using a formula. Is it actually possible? I've tried to CONCATENATE(CELL("type";array)) and ctrl+shift+enter but it didn't work (it returns the type of the first cell in the array).
If you want to know, this is for finding a cell with text rather than values or blanks in a very big file. Maybe you have a better solution.
Thanks in advance.
UPD: thanks for macros but I can't use them in this workbook, I need a formula-solution.
UPD: I've got how to do it with conditional formatting => new rule => use a formula to determine... => use ISTEXT('first cell of the range') formula
But still, is it possible to create the formula?
The best way to go about this is to use MACROs
Here is my sample code:
Sub Button2_Click()
numRows = 10 ' Number fo rows to loop through, in your case 5000
'loop through each cell located in column 1
'Check its type
'Concatenate each one in 1 cell on the 8th column
For i = 1 To numRows
Sheet1.Cells(1, 8).Value = Sheet1.Cells(1, 8).Value & TypeName(Sheet1.Cells(i, 1).Value) & ","
Next i
End Sub
You can adapt this small user defined function to your needs.
Say we are looking at cells in the first row, from A1 through D1 and we want to concatenate their types into a single cell. Enter the following UDF() in a standard module:
Public Function KonKaType(rIN As Range) As String
Dim r As Range
For Each r In rIN
s = "cell(""type""," & r.Address(0, 0) & ")"
KonKaType = KonKaType & Evaluate(s)
Next r
End Function
and then in the worksheet cell E1 enter:
=KonKaType(A1:D1)

Resources