Incrementing the row and Deleting a row using vba IN EXCEL - vba

Range("H25")
The above statement selects the 25th row of H column.Now The thing I want to know is,
How do i increment the row putting H constant?
yeah I have seen these on the google $h24 where column stays constant and row keeps on incrementing.
But i have to increment it from H25 to the end I dont know where does H column end. how do i make that?We can declare a variable right using VBA and incremenet it?
I was thinkin to put it like these Range("Hvariablename")?
The actual Task I need to do is I have to check rows from H25 to the end and get their values to my VBA and make some calcutaions then right it back to them Im stucked at incrementing the rows.And could anyone please let me know the macro to delete a row from the vba itself?Thank you

I believe you can provide some further details about how this range is supposed to looks like. When you mean "have to check rows from H25 to the end and" what's the END here?
If you're manually copying the formula down, it will automatically goes until the last row with values in column G. Is that your case? I'm not assuming the H rows below row 25 already have some values. Is this the case?
If you use as END the last row with values in column G, you can use Selection.AutoFill.
If you already have values in column H and want to go through them, you can define a dynamic range and loop through it in VBA.
To define a dynamic range: Add a new range, based in this formula (you may need to adapt it according to your needs, obviously)
=OFFSET(Sheet1!$H$25,0,0,COUNTA(Sheet1!$H:$H),1)
And then, in VBA, go through it.
Sub TEST()
Dim oCell As Excel.Range
Dim oRange As Excel.Range
Set oRange = [TestRange]
For Each oCell In oRange
Debug.Print oCell.VALUE
Next oCell
End Sub
In time: To delete an entire row in Excel, you'll use
Sheets(1).Rows(25).EntireRow.Delete

A Do While() Loop sounds like what you might need.
Do While(cells(row,col)<>"")
'Some code to be executed on cell(row,col)
Loop
Or you could do the same thing with for loop
and find the last cell using lastRow=Cells("H24").End(xlDown).Row. (It is the same thing as pressing Ctrl+Down. so if there are empty cells between cell H25 and the end you will need to account for that).
Either way I'd definitely look into using the R1C1 cell reference style for moving through cells instead of the A1 style. You moving through lettered columns is much more difficult than numbered columns. Also you should keep in mind that the "last row" in Excel 2007 is a very high number and looping all the way until the end can take a lot longer than looping until the last important cell.
I hope that's on the right track.

Related

Loop and Add Range in a place holder

Hello,
First of all, thanks for everyone who's helped me with my previous concern. I have another loop issue though. What I'm trying to do is store a certain range on a place holder and use for Charts. My code loops through column A to check cells that contain Product/URL and if found, will offset to the next column and will store the range highlighted on a place holder.
What I was able to do so far is to just select the cell with content in-line with cell with Product/URL. Here's my code so far.
Dim ProdCell as Range
For Each ProdCell in [A:A].SpecialCells(xlCellTypeConstants)
If Not IsEmpty(Prodcell) and Prodcell.Cells.Value = [A1] Then
ProdCell.Offset(0,1).Cells.End(xlToRight).Select
End if
Next ProdCell
I believe that if I can find a way to highlight the range using VBA coding, I will be able to loop through it. Please help.

How to do a summation only within specific cells via VBA

In reference to the picture below, I would like to loop through a certain column (Column D in this case) until I hit a specific cell (Yellow cells in this case). In my final spreadsheet I have multiple yellow cells that I would like to target. Once I hit a yellow cell, I would like to start a simple summation of the values one cell to the left of the yellow (Column C). I would like to keep summing the values until I hit a blank cell, which would indicate the end of the set.
Please let me know if you need any more clarification!
Here's some code that should get the job done. However you are going to have to adapt it to however you want to use it.
Dim Summation as Double
For Each Target in Range("D:D")
If Target.Interior.ColorValue = 6 Then
Summation = Summation + Target.Offset(0, -1).Value
End If
Next Target
I hope this helps. However, don't forget about FreeMan's suggestions about good question asking and using the macro recorder!

Posting a date column in Excel VBA

I'm stuck on what should be a very simple question, which is frustrating me greatly.
Essentially, I'm sorting through many files and manipulating them, but am stuck on this: how do I add in a column with something like the date in every cell down to the end of where the other columns have data?
Say that there are 5 other columns with length of 20 each. What code would I use to make column 6 have a certain value with a length of 20? The length varies with each sheet I work on, and this has been the problem.
In a program like MATLAB, I could just denote this by putting something like F1:end, but finding the answer for Excel is driving me crazy!
Any help would be greatly appreciated.
You could programmatically do this in vb to detect the bottom row with a value in, though it sounds as though you might be after a more straight forwards working solution.
Type a value in the top row, and with the cell selected you should see a square in the bottom right of the cell, double click it to fill to the end of the used range.
In VBA you would typically look from the bottom up to find the last non-blank cell in a column. With this, you can get the .Row to concatenate into a Range object definition. Example:
with activesheet
.range("F1:F" & .cells(rows.count, 5).end(xlup).row) = Format(Now, "dd-mmm-yyyy hh:mm")
end with
This will fill column F from the first row to the cell in column F that is next to the last non-blank value in column E.
Sub Tester()
With ActiveSheet
.Range(.Range("E1"), _
.Cells(Rows.Count, "E").End(xlUp)).Offset(0, 1).Value = Date
End With
End Sub

Keeping column formulas in a table header

Is it possible to have the formulas that I need applied on columns be saved or applied to a column header or some kind of metadata so that as and when I add new rows to my Excel table the Formulas get applied to the columns?
Scenarion:
I am creating a template Table, which will have no rows at first.
On a separate sheet (or same sheet for that matter) once the user selects the number of rows to be generated in the table, I dynamically add rows to the table using VBA.
The idea is I may not have any rows in the table at beginning OR user may have deleted rows manually.
When I programmatically add new rows, I want the Formulas applied on the cells as well. Most of the formulas I am using are either of the three types:
Structured table reference, Excel functions like SUM, AVERAGE etc and custom function names.
Updated:
Here is what I have tried:
1> tried applying the formula to the header itself.
Result: The header it self changes with #REF! error. I think the behavior is correct. So it's a no-go option.
2> Tried creating one row and apply the formula to the row. That works, but the problem is, I do not want a dummy row to begin with.
3> Using VBA code to add row to the table using
ActiveWorkbook.Worksheets("Sheet3").ListObjects("Table2").ListRows.Add AlwaysInsert:=True
inside a for loop.
The new rows retain the visual style sheets, but does not seem to retain the formulas. Just blank cells.
Could the fomrmulas be in header cell commnets?
And then with VBA add the formula for the current row:
Sub test()
Dim headerCells As Range
Set headerCells = Range("B2:E2")
OnNewRow 3, headerCells
End Sub
Sub OnNewRow(newRow As Integer, headerCells As Range)
Dim headerCell As Range, targetCell As Range, formulaFromComment As String
For Each headerCell In headerCells
formulaFromComment = GetFormulaFromComment(headerCell)
If (formulaFromComment = "") Then _
GoTo NextHeaderCell
Set targetCell = Intersect(headerCells.Worksheet.Rows(newRow), _
headerCell.EntireColumn)
AddFormula newRow, targetCell, formulaFromComment
NextHeaderCell:
Next
End Sub
Sub AddFormula( _
newRow As Integer, _
targetCell As Range, _
formula As String)
formula = Replace(formula, "{ROW}", newRow)
targetCell.formula = formula
End Sub
Function GetFormulaFromComment(headerCells As Range) As String
' TODO
GetFormulaFromComment = "=SUM($C${ROW}:$E${ROW})"
End Function
Just use tables.
If you highlight cells and choose Insert Table from the ribbon, it doesn't just give you formatting and filters. It also, if you build them the right way, stores column formulas once per column instead of once per cell. Also, the formulas are more readable!
For formulas, you can't use cell addresses if you want it to be a single column formula unless they are absolute. (E.g. $A$1, not A1.) Instead, you use [ColumnTitle] for the entire column (where "ColumnTitle" is the actual title of that column) and [#ColumnTitle] for the column value in the same row. So if "Cost" was the title of column B, "RunningTotal" was the title of column C and your formula for C6 was therefore =B6+C5, you'd instead use a formula of =[#Cost]+OFFSET([#RunningTotal],-1,0)] which is longer but much easier to read/maintain/debug, and if you change a column title then the formulas change too! No VBA required. Given this, plus being able change columns for the entire columns at once, plus being able to refer to other columns in other tables without worrying about cell addresses (e.g. MAX(Table1[Cost])), plus being able to style the tables so easily, plus the integration with Power-Query, and VBA support. (See learn.microsoft.com.) Whether VBA or otherwise, add a row to your table and the columns with a single column formulas will automatically carry over into the new row.
Not sure about Table templates or VBA but perhaps there is another option by using =ARRAYFORMULA()
For example, say you had a header row and 3 columns and wanted your last column to be the product of the first two. In cell C2 you could enter the following:
=ARRAYFORMULA(A2:A*B2:B)
This has three benefits:
Skips the first row completely
Effectively applies the formula to every row which is useful if you later decide to insert a row (your question)
Only one location to modify the formula for every single row
Although, it may not be immediately obvious where how/where the cells are being calculated. (hint: ctrl+~ may help)

For each cell in a range, if a value in a seperate range is found in the next cell do stuff

This Macro I have built works but I am hoping for a faster version or a Formula that will do the same in less time.
What I Have:
For Each cell In Range("Table_Query_1[[#Data],[Reason2]]")
For Each PossibleValue In Range("F2", Range("F2").End(xlDown))
If Len(cell) = 0 Then
If (InStr(UCase(cell.Offset(0, 1)), UCase(PossibleValue)) <> 0) Then
cell.Value = PossibleValue.Value
End If
Else
Exit For
End If
Next
If Len(cell) = 0 Then
cell.Value = cell.Offset(0, -1)
End If
Next
The only other way I could get anything to work way with the following Array Formula
=IF(ISNA(MATCH($F$3:$F$10,[#Extra Info],0)),[#Reason],$F$3:$F$10)
but this doesn't work for Partial matches as in the case of Row 4 and 9. I also have my doubts that this array formula would be that much faster then a vba macro along with the fact it would also require more upkeep with the test values range (F2:f3) in this case as I would have to constantly update that formula OR I wouild have to make the original range like F2:F100 witch would cause it to take that much longer.
So, what i'd like is if ANY value in my range of values (F2:F3 in this case), Is found inside of the Extra Info Column on the current Row , Then Reason2 of that row (Offset(0, -1)) equals the Value that was matched. But if nothing is found then just use the Reason in that row(Offset(0,1)).
And the second Issue is that I need the Macro to Run After the QueryTable refreshes but if I set it as a Cell Change Event on a cell the is in the query that will change, the macro runs and finishes before the Final querytable is imported and sorted.
Solved!
This is post the comment that I posted above which had the initial formula.
=IF(COUNT(FIND($F$2:$F$3,C1)),"What Will Go Here",A1)
The below tells you what has to go in place of "What Will Go Here"
Put this formula in cell B2. Note that this is an Array Formula. You will have to press CTRL + SHIFT + ENTER after you enter the formula.
=IF(COUNT(FIND($F$2:$F$4,C2)),INDEX($F$2:$F$4,MATCH(SUM(IF(ISNUMBER(--FIND($F$2:$F$4,C2,1)),--FIND($F$2:$F$4,C2,1))),FIND($F$2:$F$4,C2,1),0),0),A2)
Screenshot
Explanation:
FIND($F$2:$F$4,C2,1) when used with an array returns an array. To check the values you can highlight it and press F9 and it will tell you the position at which the match is found. See this screenshot
So it tells us that it found the match at the 3rd position in 4532. It yet doesn't tell us with what did it find a match.
Now the next step is to retrieve the position of that number from the array. So in the above example it will be position 2 and to find that position we will use MATCH() and to use MATCH we will need that 3
So to retrieve 3 from the array we use this formula
=SUM(IF(ISNUMBER(--FIND($F$2:$F$4,C2,1)),--FIND($F$2:$F$4,C2,1)))
Now we have that 3 so we will use it in Match to find the position in the Possible Value
=MATCH(SUM(IF(ISNUMBER(--FIND($F$2:$F$4,C2,1)),--FIND($F$2:$F$4,C2,1))),FIND($F$2:$F$4,C2,1),0)
This will give us 2
Now we know the position of the number in the Possible Value. To find that number we will use INDEX
=INDEX($F$2:$F$4,MATCH(SUM(IF(ISNUMBER(--FIND($F$2:$F$4,C2,1)),--FIND($F$2:$F$4,C2,1))),FIND($F$2:$F$4,C2,1),0),0)
SAMPLE Workbook
http://wikisend.com/download/280280/Sample.xlsx
This is a solution I came across that does not have to be Array Entered and seems to run faster then Siddharth Rout's solution. I am using the formula
=IFERROR(LOOKUP(1E+100,SEARCH($F$2:$F$4,C2),$F$2:$F$4),A2)
Where I am looking for any word in C2 that is in the range F2:F4. If none found it will throw an ERROR and in that situation I know nothing was found and simply return the original reason.
Not shown in the picture I also turn F2:F4 into a named range called Reasons and change the formula too:
=IFERROR(LOOKUP(1E+100,SEARCH(Reasons,C2),Reasons),A2)