Delete columns based on header value VBA - vba

I am trying to delete columns that contain the text "Title" from all the Worksheets. (It could be Title A, Title B, etc.)
I wrote the below, but it's not working... Please enlighten me.
Dim wsh As Worksheet
Dim A As Range
For Each wsh In ActiveWorkbook.Worksheets
Do
Set A = Rows(1).Find(What:="Title", LookIn:=xlValues, lookat:=xlPart)
If A Is Nothing Then Exit Do
A.EntireColumn.Delete
Loop
Next wsh

Since you are looking for "Title A" (as well for only "Title") , you can use the Find in 2 ways:
Add the * wild-card to the searched string, and at the third parameter have xlWhole Find(What:="Title*", LookIn:=xlValues, lookat:=xlWhole)
Don't use the * wild-card, and use xlPart .Find(What:="Title", LookIn:=xlValues, lookat:=xlPart)
Code
Option Explicit
Sub RemoveTitle()
Dim wsh As Worksheet
Dim A As Range
For Each wsh In ActiveWorkbook.Worksheets
Do
Set A = wsh.Rows(1).Find(What:="Title", LookIn:=xlValues, lookat:=xlPart)
If Not A Is Nothing Then
A.EntireColumn.Delete
End If
Loop While Not A Is Nothing
Next wsh
End Sub

You are not qualifying your range with a sheet so only the active sheet is searched
Sub x()
Dim wsh As Worksheet
Dim A As Range
For Each wsh In ActiveWorkbook.Worksheets
Do
Set A = wsh.Rows(1).Find(What:="Title", LookIn:=xlValues, lookat:=xlPart)
If A Is Nothing Then Exit Do
A.EntireColumn.Delete
Loop
Next wsh
End Sub

You need to specify the sheet in which you use Find
And add * (wildcard) to include all possibilities
Dim wsh As Worksheet
Dim A As Range
For Each wsh In ActiveWorkbook.Worksheets
Do
Set A = wsh.Rows(1).Find(What:="Title*", LookIn:=xlValues, lookat:=xlPart)
If A Is Nothing Then Exit Do
A.EntireColumn.Delete
Loop
Next wsh

you may want to delete all columns in one shot
Option Explicit
Sub main()
Dim wsh As Worksheet
Dim A As Range, foundTitle As Range
Dim firstAddress As String
For Each wsh In ActiveWorkbook.Worksheets
With wsh.Range("A1", wsh.Cells(1, wsh.Cells.Columns.Count).End(xlToLeft))
Set foundTitle = .Offset(1).Resize(1, 1)
Set A = .Find(What:="Title", LookIn:=xlValues, lookat:=xlPart)
If Not A Is Nothing Then
firstAddress = A.Address
Do
Set foundTitle = Union(foundTitle, A)
Set A = .FindNext(A)
Loop While A.Address <> firstAddress
End If
Set foundTitle = Intersect(foundTitle, .Cells)
If Not foundTitle Is Nothing Then foundTitle.EntireColumn.Delete
End With
Next wsh
End Sub

Related

Object issue in VBA

I am starting out with VBA and have encountered issues with the following code. Ultimately I just want to store the row for use later. Can someone assist me please?
Sub UpdateQuote()
Dim wb As Workbook
Dim ws As Worksheet
Dim FoundCell As Range
Dim FoundRow As Range
Dim FindValue As String
Set wb = ActiveWorkbook
Set ws = ActiveSheet
FindValue = Sheet24.Range("D3")
Set FoundCell = Sheet20.Range("A:A").Find(What:=FindValue)
Set FoundRow = FoundCell.Row
Application.ScreenUpdating = False
MsgBox FoundRow
End Sub

Finding values from another worksheet (a loop in a loop)

I would like to atomatize an excel process using VBA.
The script has to go cell by cell in a selected area on Sheet3. Each cell contains a number or is blank.
The script will go and search for the value of each cell in a specific range on Sheet2. When it finds something the content of the whole row where it was found must go bold.
If it finds nothing it will just procede to the next cell.
After browsing here on stackoverflow and different guides I've managed to put together a script. It has no errors but it doesn't do Anything.
Sub MacroText()
Dim xlRng As Range
Dim rng As Range
Dim xlSht As Worksheet
Dim sht As Worksheet
Dim iLastRow As Integer
Dim iRow As Integer
Dim bFound As Boolean
Dim xCell As Range
Dim xlCell As Range
Dim valueToFind As String
bFound = False
Set sht = ActiveWorkbook.Worksheets("Sheet3")
Set xlSht = ActiveWorkbook.Worksheets("Sheet2")
Set rng = Selection
Set xlRng = ActiveWorkbook.Worksheets("Sheet2").Range("A:A")
iLastRow = xlSht.Range("A1").End(xlDown).Row
Set xlRng = xlSht.Range("A1:A" & iLastRow)
For Each xCell In rng
valueToFind = xCell.Value
For Each xlCell In xlRng
Worksheets("Sheet2").Activate
If xlCell.Value = valueToFind Then
bFound = True
iRow = xlCell.Row
Rows(iRow).Font.Bold = True
End If
If bFound = True Then Exit For
End
Next xlCell
Next xCell
End Sub
I am assuming that it has to be something with positioning within the code but I couldn't find any information for that.
After working on this for 12 hours I would really appreciate your help.
Cheers!
You could use the Find method to achieve this instead of the second loop
Sub MacroText()
Dim xlRng As Range
Dim rng As Range
Dim xlSht As Worksheet
Dim sht As Worksheet
Dim iLastRow As Long
Dim iRow As Long
Dim bFound As Boolean
Dim xCell As Range
Dim xlCell As Range
Dim valueToFind As String
Dim FoundRange As Range
bFound = False
Set sht = ActiveWorkbook.Worksheets("Sheet3")
Set xlSht = ActiveWorkbook.Worksheets("Sheet2")
Set rng = Selection
Set xlRng = ActiveWorkbook.Worksheets("Sheet2").Range("A:A")
iLastRow = xlSht.Range("A1").End(xlDown).Row
Set xlRng = xlSht.Range("A1:A" & iLastRow)
For Each xCell In rng
Set FoundRange = Nothing
Set FoundRange = xlRng.Find(what:=xCell.Value2)
If Not FoundRange Is Nothing Then
FoundRange.EntireRow.Font.Bold = True
End If
Next xCell
End Sub
For Each xlCell In xlRng
Worksheets("Sheet2").Activate
If xlCell.Value = valueToFind Then
xlCell.EntireRow.Font.Bold = True
End If
Next xlCell
I don't know what thing you are not getting, but I assumed that you are not getting desired row as bold. Replace the above code with your's for loop and run.
I didn't tested it, but am uncertain about not working.

Excel VBA Find Method for specific column

VBA find method seems to fail when I am trying to search for the value in specific column.
This code
Sub TargetR()
Dim CLL As Range
Dim TargetRange As Worksheet
Dim R As Range
Set CLL = ThisWorkbook.Worksheets(1).Range("J29")
Set TargetRange = ThisWorkbook.Worksheets(1)
Set R = TargetRange.Cells.Find(CLL.Value)
If Not (R Is Nothing) Then
Debug.Print R.Address
Else: Debug.Print "Empty"
End If
End Sub
works perfectly.
While the search limited by the column with keyword header fails:
Sub Target()
Dim CLL As Range
Dim TargetRange As Worksheet
Dim targetColumn As Range
Dim sColumn As Range
Dim R As Range
Set CLL = ThisWorkbook.Worksheets(1).Range("J29")
Set TargetRange = ThisWorkbook.Worksheets(1)
Set sColumn = TargetRange.Cells.Find("This Column")
Set targetColumn = sColumn.EntireColumn
Set R = targetColumn.Cells.Find(CLL.Value)
If Not (R Is Nothing) Then
Debug.Print R.Address
Else: Debug.Print "Empty"
End If
End Sub
Specifying search direction through xlByColunm does not help
Try the code below (explanation inside the code as comments):
Option Explicit
Sub Target()
Dim CLL As Range
Dim TargetRange As Worksheet
Dim sColumn As Range
Dim R As Range
Set CLL = ThisWorkbook.Worksheets(1).Range("J29")
Set TargetRange = ThisWorkbook.Worksheets(1)
Set sColumn = TargetRange.Cells.Find("This Column")
If Not sColumn Is Nothing Then ' <-- make sure Find was successful
Set R = sColumn.EntireColumn.Find(what:=CLL.Value, LookIn:=xlValues, lookat:=xlWhole)
If Not R Is Nothing Then
Debug.Print R.Address
Else: Debug.Print "Empty"
End If
Else ' Find failed to find "This Column"
MsgBox "Unable to find 'This Column'"
End If
End Sub
As I figured out, Find method do not work correctly if value that needs to be found contained in merged cell, and Find methoud applied only for the leftmost column, that contain part of that merged cell. For my VBA code to work properly, some additional merge check , and subsequent extension of search area was the answer
If sColumn.MergeCells Then
Set sColumn = Column.Resize(,Column.MergeArea.Columns.Count)

Type mismatch error VBA loop through worksheets

I keep getting a type mismatch error and have tried changing the type a few times. I'm just trying to loop through each worksheet and a specified range to see if that word exists in every cell of that range.
Sub CheckWord()
Dim arrVar As Variant
Dim ws As Worksheet
Dim strCheck As Range
Set arrVar = ActiveWorkbook.Worksheets
'MsgBox (arrVar)
For Each ws In arrVar
If ws.Range("C9:G20").Value = "Word" Then
MsgBox (True)
End If
Next ws
End Sub
When you have a range with many columns, it creates an array.
Taking the array into consideration like so:
Sub CheckWord()
Dim arrVar As Variant
Dim ws As Worksheet
Dim strCheck As Range
Set arrVar = ActiveWorkbook.Worksheets
'MsgBox (arrVar)
For Each ws In arrVar
For each col in ws.Range("C9:G20").Cells
if col.Value = "Word" Then
MsgBox (True)
end if
End If
Next ws
End Sub
You can't get the value of ws.Range("C9:G20") and compare it to one string. You've selected multiple cells. If you want to return True when nay one of these cells contains "Word" or when all of them contain "Word" you'll need to iterate over them.
This is an example of how to return whether or not your range contains "Word" anywhere at least once
Function CheckWord()
Dim arrVar As Variant
Dim ws As Worksheet
Set arrVar = ActiveWorkbook.Worksheets
For Each ws In arrVar
Dim c
For Each c In ws.Range("C9:G20").Cells
If c = "Word" Then
CheckWord = True
Exit Function
End If
Next c
Next ws
End Function
Sub CheckWord()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If Not ws.Range("C9:G20").Find(What:="Word", LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False) Is Nothing Then MsgBox "Found in " & ws.Name
Next ws
End Sub

Search for multiple values and select

So far, I have an excel file as such
http://i.stack.imgur.com/zX3xC.png
My problem is that I want to be able to input a number after having the search button pressed and an Input box appears, With the number in the search bar for all numbers that match in the spreadsheet to be selected.
Also as as addition to be able to put in a few numbers (40, 21, 33 separated by commas)
My current code is:
Sub SEARCH_Click()
Dim sh1 As Sheet1
Dim rng As Range
Dim uname As String
Set sh1 = Sheet1: uname = InputBox("Input")
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
With sh1
.AutoFilterMode = False
Set rng = .Range("A4", .Range("A" & .Rows.Count).End(xlUp))
On Error Resume Next
rng.SpecialCells(xlCellTypeVisible).Select
If Err.number <> 0 Then MsgBox "Data not found" _
Else MsgBox "All matching data has been selected"
.AutoFilterMode = False
On Error GoTo 0
End With
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub
I am fairly new to coding so a lot of this has come from internet research etc.
Abandon your AutoFilter method in favor of a Range.Find method. While ultimately possible with a series of .AutoFilters applied to each column, simply collecting the results from a .Find operation with the Union method makes more sense.
Private Sub CommandButton1_Click()
Dim uname As String, sh1 As Worksheet '<~~ there is no var type called Sheet1
Dim v As Long, fnd As Range, rng As Range, addr As String, vals As Variant
Set sh1 = Sheet4
uname = InputBox("Search for...")
vals = Split(Replace(uname, Chr(32), vbNullString) & Chr(44), Chr(44))
ReDim Preserve vals(UBound(vals) - 1)
With sh1
For v = LBound(vals) To UBound(vals)
If IsNumeric(vals(v)) Then vals(v) = Val(vals(v))
Set fnd = .Cells.Find(What:=vals(v), LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchFormat:=False)
If Not fnd Is Nothing Then
addr = fnd.Address
Do
If rng Is Nothing Then
Set rng = fnd
Else
Set rng = Union(rng, fnd)
End If
Set fnd = .Cells.FindNext(after:=fnd)
Loop Until addr = fnd.Address
End If
addr = vbNullString
Set fnd = Nothing
Next v
If Not rng Is Nothing Then rng.Select
End With
End Sub
It is not clear what actions you want to perform after the Range .Select¹ method has been applied. I would suggest that a simple With ... End With statement woudl allow you to continue working on the rng discontiguous Range object without actually selecting it at all.
    
¹ See How to avoid using Select in Excel VBA macros for more methods on getting away from relying on select and activate to accomplish your goals.