How to find a specific cell and make it the ActiveCell - vba

I am writing a VBA code that will open a specific worksheet in my workbook in Excel, and then find the cell in Column A that has the value "TOTAL". This then must be set as the ActiveCell, so that the rest of my macro can perform actions on the row containing this cell.
I want it so that when the user runs the macro, this cell is specifically chosen right off the bat. The position of this cell will change after the macro is run, so I need it to work no matter what cell this value is in. Everytime the macro runs, a new row is added above the row containing "TOTAL" and therefore the position of this cell is ever-changing.
So far I have come up with this, just from readin through forums. It still doesn't work, but I'm new to this language and I can't determine where the error is.
Sub Macro2()
Dim C As Range
Worksheets("Project Total").Select
With Selection
C = .Find("TOTAL", After:=Range("A2"), MatchCase:=True)
End With
End Sub

Try this:
Sub Macro2()
Dim cl As Range
With Worksheets("Project Total").Cells
Set cl = .Find("TOTAL", After:=.Range("A2"), LookIn:=xlValues)
If Not cl Is Nothing Then
cl.Select
End If
End With
End Sub

Try this:
Sub activateCellContainingTOTAL()
'Go to the worksheet
Worsheets("Project Total").Activate
'Start going down column A to see if you find the total
dim loopBool as Boolean
loopBool = True
Worksheets("Project Total").Range("A1").Activate
Do While loopBool=True
if Activecell.value = "TOTAL" then
loop = false
else
activecell.offset(1, 0).Activate
end if
loop
End sub

Sub Getvaluesfromeachcolumns()
Dim loopcounter As Integer
Dim loopcounter1 As Integer
Dim dumvalue As String
Dim rrange As Range
dumvalue = Activecell.value 'you can replace your cell reference or any value which you want to search. also you can use input method.'
loopcounter1 = Range("A1:C1").Count
For loopcounter = 1 To loopcounter1
Cells(1, loopcounter).Select
Range(ActiveCell.Address).Select ' to know the active cell and address
Set rrange = Range(ActiveCell.Address, ActiveCell.End(xlDown)).Find(dumvalue)
rrange.Select
Next loopcounter
End Sub

Related

Loop Through Non Blank Cells

I just want to know how to loop through the non blank cells on Column A. What I'm trying to do is copy the contents on [A1:B1] to be added on top of each non blank cells on Column A. So far I have counted the non blank cells on column A but I'm stuck. I know that an Offset function should be used for this.
Here's my code so far:
Dim NonBlank as Long
NonBlank = WorksheetFunction.CountA(Worksheet(1).[A:A])
For i = 1 to NonBlank
[A1:B1].Copy Offset(1,0). "I'm stuck here"
Next i
If you are trying to fill the headers for each Product, try this...
Sub FillHeaders()
Dim lr As Long
Dim Rng As Range
lr = ActiveSheet.UsedRange.Rows.Count
Application.ScreenUpdating = False
On Error Resume Next
Range("A1:B1").Copy
For Each Rng In Range("A3:A" & lr).SpecialCells(xlCellTypeConstants, 2).Areas
If Rng.Cells(1).Value <> Range("A1").Value Then
Rng.Cells(1).Offset(-1, 0).PasteSpecial xlPasteAll
End If
Next Rng
Application.CutCopyMode = 0
Application.ScreenUpdating = True
End Sub
As example to simulate the effect of Ctrl-Down from Cell A1 and display the Address, Value in the Immediate Window:
Sub HopToNextNonBlankCellBelow()
Dim oRng As Range
Set oRng = Range("A1")
Debug.Print "Cell Address", "Cell Value"
Do
Set oRng = oRng.End(xlDown)
If Not IsEmpty(oRng) Then Debug.Print oRng.Address(0, 0), oRng.Value
Loop Until oRng.Row = Rows.Count
Set oRng = Nothing
End Sub
Try this... I've (probably) overcounted the rows at 1000, but it likely won't make a difference with your performance. If you wanted to be more precise, there are hundreds of articles on how to find the last row of a range. As for the Offset function, it references a cell in relation to the one we're looping through. In the example below, the code is saying cell.offset(0,1) which means one cell to the right of the cell we are currently looping through. A clearer (less loopy!) example would be if you typed: Range("A10").offset(0,1) it would be the same as typing Range("B10")
Dim Cell As Range
For Each Cell In Range("A2:A1000").Cells
If Not IsEmpty(Cell) Then
Cell.Offset(0, 1).Value = Cell.Value
End If
Next Cell

Looping through a column to move cells with font size 10 down one row

I have section title cells set at 10 pt font while all other data is set at 9 point font in column A. I am trying to write a vba macro to loop through column A to move each title cell down one row(because the csv leaves a blank cell below them) then move on to the next title cell in the column. Here is my attempt but I'm not sure what I'm doing wrong here.
Sub FontSpacing()
Dim Fnt As Range
For Each Fnt In Range("A8:A5000")
If Fnt.Font.Size = "10" Then
ActiveCell.Cut Destination:=ActiveCell.Offset(",1")
End If
Next
Try this
Sub FontSpacing()
Dim r As Range
For Each r In ThisWorkbook.Worksheets("Sheet1").Range("A8:A5000")
If r.Font.Size = 10 Then
r.Offset(1,0).Value = r.Value
r.Value = vbNullString
End If
Next r
End Sub
The issues:
Offset(",1") shouldn't have the speech marks. I.e. it should be Offset(0,1). In fact, if you want to paste to the row below, then it should be Offset(1,0).
Avoid using ActiveCell. It's not the cell that is looping through your range, it's just the cell that was active on the worksheet when you ran the sub.
Fnt is a bad name for a range, it's probably the reason you got confused. When declaring (dimensioning) a range, try to give it a name that makes it clear you're working with a range.
Extra:
Fully qualify your range reference to avoid an implicit reference to the ActiveSheet e.g. ThisWorkbook.Worksheets("Sheet1").Range("A1").
Avoid cutting an pasting by setting the Value directly
Your indentation is out, which makes it look like a complete Sub, but it's missing the End Sub.
Not sure if you meant 1 Row below or 1 Column right so:
To shift 1 Column:
Sub FontSpacing()
Dim rng As Range, cell As Range
Set rng = Range("A1:A5000")
For Each cell In rng
If cell.Font.Size = "10" Then
cell.Offset(0, 1).Value = cell.Value
cell.Clear
End If
Next
End Sub
To shift 1 Row:
Sub FontSpacing()
Dim rng As Range, cell As Range
Set rng = Range("A1:A5000")
For Each cell In rng
If cell.Font.Size = "10" Then
a = cell.Row + 1
Rows(a & ":" & a).Insert Shift:=xlDown, CopyOrigin:=1
cell.Offset(1, 0).Value = cell.Value
cell.Offset(1, 0).Font.Size = "11"
cell.Clear
End If
Next
End Sub

How to avoid using select in VBA for variable cell ranges?

I have heard of the dislike for using .select in VBA for excel macros, but I am wondering how my particular goal can be achieved without its use? For example, say there is a cell(used as a header) with the value "Commodity". Beneath it, all cells need to have a VLookup function. However, on each and every iteration of the macro, the column will shift (as new columns are added) and new rows will be added (so that newly added rows will need to have the function added as well). How is it possible to consistently locate this Commodity column and find its lowest unfilled row? It is very simple to do using select:
Do Until ActiveCell.Value = "Commodity"
Activecell.offset(0,1).select
loop
Do Until ActiveCell.Value = ""
ActiveCell.offset(1,0).select
loop
Obviously, I would prefer to avoid using this type of syntax, but I do not know how to get around it. All answers I have seen regarding the avoidance of select appear to set, for example, rng = Cell(x,y) or something, but they are always known-location cells. I do not know how to do this without utilizing select to check cell values.
First find the column that your Sting is located, then count the rows beside it, set your range and enter the formula.
Sub FindColumn()
Dim f As Range, c As Integer
Dim LstRw As Long, rng As Range
Set f = Rows(1).Find(what:="Commodity", lookat:=xlWhole)
If Not f Is Nothing Then
c = f.Column
Else: MsgBox "Not Found"
Exit sub
End If
LstRw = Cells(Rows.Count, c - 1).End(xlUp).Row
Set rng = Range(Cells(2, c), Cells(LstRw, c))
rng = "My Formula"
End Sub
Here are two iterate rows to based on the ActiveCell.
Sub Examples()
Dim Target As Range
Dim x As Long
Set Target = ActiveCell
Do Until Target.Value = "Commodity"
Set Target = Target.Offset(0, 1)
Loop
Do Until ActiveCell.Offset(x, 1).Value = ""
x = x + 1
Loop
End Sub
Assuming the wanted header IS there, you can use this function:
Function FindLowestUnfilledCell(headerRow As Range, header As String) As Range
With headerRow.Find(What:=header, lookat:=xlWhole, LookIn:=xlValues, MatchCase:=False) '<--| look for header in passed row
Set FindLowestUnfilledCell = headerRow.Parent.Cells(headerRow.Parent.Rows.Count, .Column).End(xlUp)
End With
End Function
to be used by your main sub as follows
Sub main()
FindLowestUnfilledCell(Rows(1), "Commodity").Formula = "myformula"
End Sub
should the absence of the wanted header be handled, the same function gets a little longer like follows
Function FindLowestUnfilledCell(headerRow As Range, header As String) As Range
Dim r As Range
Set r = headerRow.Find(What:=header, lookat:=xlWhole, LookIn:=xlValues, MatchCase:=False) '<--| look for "Commodity" in row 1
If Not r Is Nothing Then Set FindLowestUnfilledCell = headerRow.Parent.Cells(headerRow.Parent.Rows.Count, r.Column).End(xlUp)
End Function
and its exploitation would consequently take into account the possibility of not founding the wanted header:
Sub main()
Dim lowestUnfilledRange As Range
Set lowestUnfilledRange = FindLowestUnfilledCell(Rows(1), "Commodity")
If Not lowestUnfilledRange Is Nothing Then lowestUnfilledRange.Formula = "myformula"
End Sub
I want to simplify the answer a bit. For example
Set r = ActiveCell
MsgBox r.Address ' $A$1
Columns("A").Insert ' insert column before the first column
MsgBox r.Address ' $B$1
so you can change your code to
Dim cell As Range ' optional
Set cell = ActiveCell
While cell = "Commodity"
Set cell = cell(, 2) ' similar to Set cell = cell.Resize(1,1).Offset(, 1)
Wend
While cell = ""
Set cell = cell(, 2)
Wend

Remove Duplicates from Random Cells using Excel VBA

I have an excel sheet where I've duplicate values in difference cells. BUT the catch here is all those cells are not adjacent to one another. I'll randomly select those cells manually from the sheets & want to remove the duplicates.
In below screenshot I've selected random cells with value "test". I would like to remove the duplicates from selected cells.
Apologies : Adding possible scenario. Need only first occurrence of any repetitive cells. Remove remaining occurrences. It means it should give A1=TEST & B6=WEST. all other cell values should be removed.
Assuming that you have already made the random selection:
Sub dural()
Dim v As Variant, r As Range
v = ActiveCell.Text
addy = ActiveCell.Address
For Each r In Selection
If Not addy = r.Address Then
If r.Value = v Then
r.ClearContents
End If
End If
Next r
End Sub
Just for fun, here's a non-looping version. It does wipe out the ActiveCell's value and then reassign it, which worked in all situations in my limited testing:
Sub RemoveAllSelectionCellsExceptActiveCell()
Dim ActiveCellValue As Variant
ActiveCellValue = ActiveCell.Formula
Selection.Clear
ActiveCell.Formula = ActiveCellValue
End Sub
EDIT: Response to your edited question
This relies on the fact that adding a duplicate to a collection generates an error. If that happens, the cell in question is added to a range of cells to delete. Note that it will treat a cell with "=2" as different from a cell with "2":
Sub RemoveAllSelectionCellsExceptActiveCell2()
Dim cell As Excel.Range
Dim collDupes As Collection
Dim DupeCells As Excel.Range
Set collDupes = New Collection
For Each cell In Selection.Cells
On Error Resume Next
collDupes.Add cell.Formula, cell.Formula
If Err.Number <> 0 Then
If DupeCells Is Nothing Then
Set DupeCells = cell
Else
Set DupeCells = Union(DupeCells, cell)
End If
End If
On Error GoTo 0
Next cell
DupeCells.Clear
End Sub
And another...
If you want to clear the cells' contents and formatting and leave the cursor in the ActiveCell with no selected cells highlighting.
Note, when you make your selection, it will be the last cell visited that is the ActiveCell whose contents will remain, and remain selected.
Option Explicit
Sub remSelDup()
Dim ac As Range, c As Range
Set ac = ActiveCell
For Each c In Selection
If c = ac And c.Address <> ac.Address Then
c.Clear
End If
Next c
ac.Select
End Sub
There should be more than a few Find/FindNext examples on this site but here's another one.
Dim fnd As Range, fcl As Range, searchTerm As Variant
With ActiveSheet
Set fcl = ActiveCell
searchTerm = fcl.Value
Set fnd = .Cells.Find(What:=searchTerm, After:=fcl, LookIn:=xlValues, LookAt:= _
xlWhole, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False)
Do While fcl.Address <> fnd.Address
fnd.ClearContents
Set fnd = .Cells.FindNext(After:=fcl)
Loop
End With

VBA dynamic loop macro

I am trying to build a loop macro is visual basic which takes cells from a range in one worksheet and places them in to specific cells in other worksheet directed by the worksheet's tab name in a parallel range. The ranges need to be variable - with more or less data as directed.
This is the code which currently works for one cell:
Sub Ticker_input()
Dim wsname As String
wsname = ActiveCell.Value
Worksheets("Summary").Range("Tab_name").Select
Worksheets(wsname).Range("CapIQ_ticker").Value = ActiveCell.Offset(0, 1)
End Sub
I need to turn this into a loop macro.
Help would be greatly appreciated.
There are multiple ways to do loops in VBA. This is one way that could apply to your situation:
Sub Ticker_input()
On Error Resume Next
Application.ScreenUpdating = False
Dim wsname As String
Dim rTabNames As Range, c As Range
Set rTabNames = Worksheets("Summary").Range("Tab_name")
For Each c In rTabNames
If c.Value <> "" Then
wsname = c.Value
Worksheets(wsname).Range("CapIQ_ticker").Value = c.Offset(0, 1).Value
End If
Next
Application.ScreenUpdating = True
End Sub
Just make sure your named range "Tab_name" is the entire range of cells that could contain sheet names (for example, if you list your sheet names in A, have "Tab_name" be referring to that entire column), as opposed to one cell.
I'm not exactly sure what you are trying to accomplish, but below is an example of looping through a named range. It is dnyamic in the fact that it will loop through the named range and if you reset the size of the named range it will only loop through those cells.
~ hope this helps.
Sub loopRnage()
'create your variable outside the loop
Dim wsname
'tell the loop the range you want to loop through
For Each cell In ThisWorkbook.Sheets("Stocks").Range("symbols")
'set the variable to the current cell
wsname = cell.Value
Worksheets("Summary").Range("Tab_name").Select
'use the variable to set the target name
Worksheets(wsname).Range("CapIQ_ticker").Value = cell.Offset(0, 1)
Next cell
End Sub