Range(Cell.Find("Price tag"), Range(Cells.Find("Price tag")).End(xlDown)) - excel

I want to find where 'price tag' is on the sheet, and follow that column to select all way down.
I have wrote
Range(Cells.Find("Price tag"), Range(Cells.Find("Price Tag")).End(xlDown))
but I got [range method of object _global failed] message.
What is wrong with the code, and how can I fix it?

Using the Find Method
If the searched value is not found, the result will be Nothing, so it is safest to use a range variable with the Find method, and then test the variable against Nothing.
Option Explicit
Sub Test()
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim ColumnRange As Range
Dim fCell As Range ' simplified due to assuming it is never in cell `A1`
Set fCell = ws.Cells.Find("Price Tag", , xlFormulas, xlWhole, xlByRows)
' Decide what to do if found or not.
If fCell Is Nothing Then
MsgBox "'Price Tag' not found.", vbCritical
Exit Sub
Else
Set ColumnRange = ws.Range(fCell, fCell.End(xlDown))
MsgBox "'Price Tag' was found in cell '" & fCell.Address(0, 0) _
& "' and the address of your range is '" _
& ColumnRange.Address(0, 0) & "'.", vbInformation
End If
' But usually you know in which row...
With ws.Rows(1)
Set fCell = .Find("Price Tag", .Cells(.Cells.Count), xlFormulas, xlWhole)
End With
' or in which column it is:
With ws.Columns("A")
Set fCell = .Find("Price Tag", .Cells(.Cells.Count), xlFormulas, xlWhole)
End With
End Sub

This function will extend the selections for you.
Public Function DataCells(Source As Range) As Range
Dim ColUsedRange As Range
Dim Col As Range
Dim RowCount As Long
For Each Col In Source.Columns
Set ColUsedRange = Range(Col, Col.EntireColumn.Cells(Source.Parent.Rows.Count).End(xlUp))
If RowCount < ColUsedRange.Rows.Count Then RowCount = ColUsedRange.Rows.Count
Next
Set DataCells = Source.Resize(RowCount)
End Function
Usage
Sub Test()
Dim Target As Range
Set Target = Cells.Find("Price tag")
If Not Target Is Nothing Then
Set Target = DataCells(Target)
Application.Goto Target
End If
End Sub

Related

VBA Help to find a column based on header value and cupy it to an other worksheet

I have this basic code to find the needed coumns in a table and copy them to an other worksheet. My problem is that every time I want to modify it to not to copy&paste the header it returns error. This is my code:
Sub CopyColumns()
Dim wsSource, wsResult As Worksheet
Dim Name, UniqueId, OperatingStatus As Long
Set wsSource = ThisWorkbook.Sheets("Source")
Set wsResult = ThisWorkbook.Sheets("Result")
Name = wsSource.Rows(1).Find("#BASEDATA#name").Column
UniqueId = wsSource.Rows(1).Find("#BASEDATA#uniqueId").Column
OperatingStatus = wsSource.Rows(1).Find("#BASEDATA#operatingStatus").Column
If Name <> 0 Then
wsSource.Columns(Name).Copy Destination:=wsResult.Columns(3)
End If
If UniqueId <> 0 Then
wsSource.Columns(UniqueId).Copy Destination:=wsResult.Columns(4)
End If
If OperatingStatus <> 0 Then
wsSource.Columns(OperatingStatus).Copy Destination:=wsResult.Columns(1)
End If
End Sub
Any ideas how to solve it?
I tried is to copy like this using offset:
If targetColName <> 0 Then
wsSource.Columns(targetColName).Offset(1, 0).Resize(wsSource.Rows.Count - 1).Copy _ Destination:=wsResult.Columns(3).Offset(1, 0)
It gives Error: Application-defined ot object-defined error
Thanks!
offset and resize not working
You can break out the "copy column if found" into a separate sub:
Sub CopyColumns()
Dim wsSource, wsResult As Worksheet
Set wsSource = ThisWorkbook.Sheets("Source")
Set wsResult = ThisWorkbook.Sheets("Result")
CopyIfExists wsSource.Rows(1), "#BASEDATA#name", wsResult, 3
CopyIfExists wsSource.Rows(1), "#BASEDATA#uniqueId", wsResult, 4
CopyIfExists wsSource.Rows(1), "#BASEDATA#operatingStatus", wsResult, 1
End Sub
'Look for `colName` in `headerRow`, and if found copy the whole
' column to column `destColNum` on `destSheet`
Sub CopyIfExists(headerRow As Range, colName As String, destSheet As Worksheet, destColNum As Long)
Dim f As Range
Set f = headerRow.Find(what:=colName, lookat:=xlWhole) 'or xlPart
If Not f Is Nothing Then
f.EntireColumn.Copy destSheet.Cells(1, destColNum)
End If
End Sub
When using find, you should check you got a match before trying to do anything with the matched cell.
Copy Columns
Option Explicit
Sub CopyColumnsToResult()
Dim sColNames(): sColNames = Array("#BASEDATA#name", _
"#BASEDATA#uniqueId", "#BASEDATA#operatingStatus")
Dim dCols(): dCols = Array(3, 4, 1)
Dim sws As Worksheet: Set sws = ThisWorkbook.Sheets("Source")
Dim shrg As Range: Set shrg = sws.Rows(1)
Dim slCell As Range: Set slCell = shrg.Cells(shrg.Cells.Count) ' last cell
Dim dws As Worksheet: Set dws = ThisWorkbook.Sheets("Result")
Dim shCell As Range, c As Long
For c = LBound(sColNames) To UBound(sColNames)
Set shCell = shrg.Find(sColNames(c), slCell, xlFormulas, xlWhole)
If Not shCell Is Nothing Then ' header cell found
sws.Columns(shCell.Column).Copy dws.Columns(dCols(c))
End If
Next c
MsgBox "Columns copied.", vbInformation
End Sub

change the range of function automatically when rows are added

[1
I wrote =sum(A2:A11) in cell A1, and I wrote random numbers in A2:A11. Then I deleted some rows and then the A1 cell's range changed automatically. But I don't understand why the range does not change automatically when I add new rows and intert new values. How can I make it change automatically? Do I have to use vba to do this?
A Worksheet Change Event: Monitor Change in Column's Data
I personally would go with JvdV's suggestion in the comments.
On each manual change of a cell, e.g. in column A, it will check the formula
=SUM(A2:ALastRow) in cell A1 and if it is not correct it will overwrite it with the correct one.
You can use this for multiple non-adjacent columns e.g. "A,C:D,E".
Nothing needs to be run. Just copy the code into the appropriate sheet module e.g. Sheet1 and exit the Visual Basic Editor.
Sheet Module e.g. Sheet1 (not Standard Module e.g. Module1)
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
UpdateFirstRowFormula Target, "A"
End Sub
Private Sub UpdateFirstRowFormula( _
ByVal Target As Range, _
ByVal ColumnList As String)
On Error GoTo ClearError
Dim ws As Worksheet: Set ws = Target.Worksheet
Dim Cols() As String: Cols = Split(ColumnList, ",")
Application.EnableEvents = False
Dim irg As Range, arg As Range, crg As Range, lCell As Range
Dim n As Long
Dim Formula As String
For n = 0 To UBound(Cols)
With ws.Columns(Cols(n))
With .Resize(.Rows.Count - 1).Offset(1)
Set irg = Intersect(.Cells, Target.EntireColumn)
End With
End With
If Not irg Is Nothing Then
For Each arg In irg.Areas
For Each crg In arg.Columns
Set lCell = crg.Find("*", , xlFormulas, , , xlPrevious)
If Not lCell Is Nothing Then
Formula = "=SUM(" & crg.Cells(1).Address(0, 0) & ":" _
& lCell.Address(0, 0) & ")"
With crg.Cells(1).Offset(-1)
If .Formula <> Formula Then .Formula = Formula
End With
End If
Next crg
Next arg
Set irg = Nothing
End If
Next n
SafeExit:
If Not Application.EnableEvents Then Application.EnableEvents = True
Exit Sub
ClearError:
Debug.Print "Run-time error '" & Err.Number & "': " & Err.Description
Resume SafeExit
End Sub
Use a nested function as below:
=SUM(OFFSET(A2,,,COUNTA(A2:A26)))

How to locate the last row of cells in a range which matches using VBA?

There is one column in a table where names of factories are shown but I only need the data for a specific factory name(let's say factory "Australia").
My idea is to locate the first and last rows which match because the data for the same factory are always presented in a consecutive manner. In this way, I can get the range of cells which match up to my search.
Locating the first matched row position is quite easy but I get stuck in getting the last matched row position.
Here is the code regarding this section:
Sub Search()
Dim sh As Worksheet
Dim searchStr As String
Dim lastRow As Long, firstRow as Long
Dim tableRange As range
Set sh = Worksheets("Total order")
searchStr = "Australia"
Set tableRange = sh.range("B:B").Find(what:=searchStr, LookIn:=xlValues, lookat:=xlWhole)
firstRow = tableRange.Row
End Sub
An example of the table dealt with:
Refer to the Range from the Cell of the First to the Cell of the Last Occurrence of a String in a Column
A Side Note
The Range.Find method is kind of tricky. For example, you may not be aware that in your code the search starts from cell B2 (which is even preferable in this case), and using xlValues may result in undesired results if rows are hidden (probably not important).
Usage
Using the function, according to the screenshot, you could (after searchStr = "Australia") use:
Set tableRange = refRangeFirstLast(sh.Columns("B"), searchStr)
to refer to the range B4:B7, or use:
Set tableRange = refRangeFirstLast(sh.Columns("B"), searchStr).Offset(, -1).Resize(, 4)
to refer to the range A4:D7.
The Code
Function refRangeFirstLast( _
ByVal ColumnRange As Range, _
ByVal SearchString As String) _
As Range
If Not ColumnRange Is Nothing Then
With ColumnRange
Dim FirstCell As Range: Set FirstCell = _
.Find(SearchString, .Cells(.Cells.Count), xlFormulas, xlWhole)
If Not FirstCell Is Nothing Then
Dim LastCell As Range: Set LastCell = _
.Find(SearchString, , xlFormulas, xlWhole, , xlPrevious)
Set refRangeFirstLast = .Worksheet.Range(FirstCell, LastCell)
End If
End With
End If
End Function
Sub refRangeFirstLastTEST()
Const SearchString As String = "Australia"
Dim ColumnRange As Range
Set ColumnRange = ThisWorkbook.Worksheets("Total order").Columns("B")
Dim rg As Range: Set rg = refRangeFirstLast(ColumnRange, SearchString)
If Not rg Is Nothing Then
Debug.Print rg.Address
Else
MsgBox "The reference could not be created.", vbExclamation, "Fail?"
End If
End Sub

How do I get the Cell Address from a Variable VBA

I created a variable oldPassword which is populated using a VLookup.
I am trying to get now the cell address from that result but nothing seem to work.
Dim oldPassword As String
oldPassword = Application.WorksheetFunction.VLookup(Me.ComboBox1.Value, Worksheets("Employees").Range("A:B"), 2, False)
You should break the task into steps
Get a reference to the cell containing the search value
Use that reference to get the required value and address
Sub Demo
Din rSearch As Range
Dim rUser as Range
Dim rPassword As Range
Dim idx As Variant
Set rSearch = Worksheets("Employees").Range("A:B")
idx = Application.Match(Me.ComboBox1.Value, rSearch.Columns(1), 0)
If Not IsError(idx) Then
Set rUser = rSearch.Cells(idx, 1)
Set rPassword = rUser.Cells(1, 2)
' get the result
oldPassword = rPassword.Value2
' get the address
Debug.Print rPassword.Address
End If
End Sub
I would prefer using .Find as #Andreas suggested but then that is my personal preference.
Option Explicit
Sub Sample()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Employees")
Dim aCell As Range
Set aCell = ws.Columns(1).Find(What:=ComboBox1.Value, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
Dim oldPassword As String
If Not aCell Is Nothing Then
With aCell.Offset(, 1)
'~~> Do what you want with that cell
oldPassword = .Value2
MsgBox .Address
End With
Else '<~~ Optional
MsgBox ComboBox1.Value & " not found!"
End If
End Sub

VBA Syntax finding the last occupied cell in the column

How do I make this work? I'm trying to make the code identify the last used cell in column C and go to it. I am having trouble with the last part which is selecting the cell in rng1
Sub jupiter3()
Dim ws As Worksheet
Dim rng1 As Range
Set ws = Sheets("Belmont")
Set rng1 = ws.Columns("c").Find("*", ws.[c1], xlValues, , xlByRows, xlPrevious)
If Not rng1 Is Nothing Then
MsgBox "last cell is " & rng1.Address(0, 0)
Else
MsgBox ws.Name & " columns A:B are empty", vbCritical
End If
Range("rng1.address(0, 0)").Select
End Sub
the easiest way for me would be to use this one line of code
Sheets("Belmont").Range("C" & Sheets("Belmont").Range("C" & Rows.Count).End(xlUp).Row).Select
but if you want to modify yours then
Sub jupiter3()
Dim ws As Worksheet
Dim rng1 As Range
Set ws = Sheets("Belmont")
Set rng1 = ws.Columns("c").Find("*", ws.[c1], xlValues, , xlByRows, xlPrevious)
If Not rng1 Is Nothing Then
MsgBox "last cell is " & rng1.Address(0, 0)
rng1.Select
Else
MsgBox ws.Name & " columns A:B are empty", vbCritical
End If
End Sub
Changing Range("rng1.address(0, 0)").Select to rng1.Select or Range(rng1.address).Select
The rng1 variable is defined as a range which is interpreted by the language in a way in which it doesn't fit into range().select You want to define a string variable and do it like this.
replace Range("rng.address(0,0)").Select with
Dim zen as String
zen=rng.address(0,0)
range(zen).select

Resources