I need Excel to delete columns as long as the header is NOT "Event Notes."
For related purposes, I found and successfully used the InStr function to find certain headers and delete the columns. But now I just want it to, starting at the end, delete columns until it finds THE EXACT STRING "Event Notes."
So far, I've had it delete EVERYTHING that didn't contain Event Notes; now it's finding "Event Notes Dates" and exiting the For loop.
Thanks a bunch for any assistance!
For iCounter = myWorksheet.Cells.Find(What:="*", LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column To 1 Step -1
If InStr(1, myWorksheet.Cells(1, iCounter).Value, "Event Notes") = 1 Then
Exit For
Else
myWorksheet.Columns(iCounter).EntireColumn.Delete
End If
Next iCounter
following my comment, you should simply compare the range value to the "target" one
As per this little revision of your code
With myWorksheet ' reference your sheet.
For iCounter = .Cells.Find(What:="*", LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlPrevious).Column To 1 Step -1
If .Cells(1, iCounter).Value = "Event Notes" Then
Exit For
Else
.Columns(iCounter).EntireColumn.Delete
End If
Next iCounter
End With
Related
I used record macro to create some code and then I put it in a loop. It works but there is an error in the find function which causes it to only work once. I tried to do something with the error but I am not having any luck having it loop. I've looked a couple of days here and there but I am at a loss. Hope you can help me. Much appreciated.
i = 1
On Error GoTo notfound
Do While Sheet1.Cells(i, 1) <> ""
Columns("J:J").Select
Selection.Find(What:="x", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Rows(ActiveCell.Row).EntireRow.Delete
notfound: msgbox "Finished"
GoTo notfound
Exit Sub
i = i + 1
Loop
I've corrected, completed, formatted and commented your code. This should take you one step closer to what you want to do.
Private Sub Sample()
Dim Crit As Variant ' the criterium to look for
Dim Fnd As Range ' the cell to find
Dim i As Long
' never create an error handler if you don't know which error to exect
' On Error GoTo notfound
i = 1
' the cell can't be "" only its value can do thjat
Do While Sheet1.Cells(i, 1).Value <> ""
Crit = "x"
' Columns("J:J").Select
' don't Select anything, address cells or ranges instead
Set Fnd = Columns("J:J").Find(What:=Crit, _
After:=ActiveCell, _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False)
' where is the 'Activecell'?
' a) it doesn't change while this loop is running
' but it might get deleted by this loop's action
' b) it must be in the range you are searching
' that's why your code will fail most of the time.
' don't Activate anything. Instead address the object you want to deal with.
If Fnd Is Nothing Then
MsgBox "I didn't find """ & Crit & """"
Else
Sheet1.Rows(Fnd.Row).EntireRow.Delete
End If
i = i + 1
Loop
End Sub
This code will look for "x" in column J for as long as there is a value in column A and delete the row where it is found. It's hard to imagine a relationship between the number of entries in column A and the number of "x" in column J but, hopefully, this isn't your problem. Instead, your obvious problem is the cell in which you want to start the search. It definitely isn't ActiveCell but it might be Cells(1, "J"). You can also omit this instruction and VBA will start the search after J1.
You want to LookIn formulas. If there are formulas in column J the Formula will be different from the Value. You may wish to search in xlValues.
I am trying to check whether Row 1 of my active sheet named "Exceptions" contains the text "Control Date" (two spaces) or "Control Date".
My code finds the condition false.
Dim a As Range
Dim exceptions As Worksheet
Set exceptions = ActiveWorkbook.Worksheets("Exceptions")
For Each c In Exceptions.Range("A1:Z1")
If c = "Control Date" Then
Cells.Find(What:="control date", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Else
Cells.Find(What:="Control Date", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
End If
Next c
Example of a worksheet with two spaces in "Control Date"
How to write the condition
As far as checking if the cell value is "Control Date" with a single space or one with two spaces, there are two ways of going about it:
Use the like operator
The like operator makes it easy to compare a string to a basic pattern. In this example, using the wildcard character * (Zero or more characters) will return true regardless of how many spaces are between Control and Date.
If cell.Value2 Like "Control*Date" Then
' Do something with that cell
End If
Use the or operator
Using the or operator ok to use as well, although not a flexible and perhaps a bit more difficult to see what's going on for your specific example.
If cell.Value2 = "Control Date" Or cell.Value2 = "Control Date" Then
' Do something with that cell
End If
Worksheet Codename
Each worksheet has whats called a codename. This is a reference that can be called directly in the code to that specific worksheet by it's name.
To set this name, in the properties window update the name property
So instead of
Dim Exceptions As Worksheet
Set Exceptions = ActiveWorkbook.Worksheets("Exceptions")
For Each cell In Exceptions.Range("A1:Z1")
' Do something...
Next cell
you can call the worksheet reference directly
For Each cell In Exceptions.Range("A1:Z1")
' Do something...
Next cell
Putting it together
Instead of using c for your variable, I like to make my variables easier to read and follow so I used cell.
Also, instead of hard coding your header columns in range, you could loop the cells of the entire first row. This is option suggestion though.
Lastly, be more explicit in what property you are looking for in your Cell. In my example I use .value2 to show I am looking for the value of that cell.
Public Sub Demo()
Dim cell As Range
For Each cell In Exceptions.Rows(1).Cells
If cell.Value2 Like "Control*Date" Then
' Do something with that cell
End If
Next cell
End Sub
Why duplicate the data into a third column? Whenever you need the "combined" date, just go get it, but do not store it twice.
Option Explicit '<<-- always have this
Sub doFindControl()
Dim a As Range
Dim c As Range '<<-- add this
Dim colDate As Long, colNumber As Long, colBlank As Long '<<--add this
Dim exceptions As Worksheet
Set exceptions = ActiveWorkbook.Worksheets("Exceptions")
For Each c In exceptions.Range("A1:Z1")
' first find the 2 key columns
If InStr(c, "Control") > 0 Then
If InStr(c, "Date") > 0 Then
colDate = c.Column
ElseIf InStr(c, "Number") > 0 Then
colNumber = c.Column
End If
' second look for the first blank column for you to put results in
ElseIf c.Text = "" Then
colBlank = c.Column
Exit For ' stop looking after its found
End If
Next c
' now you have the 2 FROM columns, and the TO column
MsgBox (colDate & " " & colNumber & " " & colBlank)
' and you can loop thru all the rest of the rows doing combine
End Sub
Thank you for all the answers! Robert Todar's answer led me to my lightbulb moment, and I can't believe at how simple the answer was. All I had to do was change this code:
Cells.Find(What:="Control Date", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
to:
Cells.Find(What:="Control*Date", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
I have a spreadsheet which contains 4 general lines constant in every quote. Depending on the # of line items in the quote the rows where these 4 general lines occur varies. I am trying to find a code which locates the words "SHOP TICKETS" in column B and then deletes that row and the 3 below it without containing a loop. The loop is not needed and seems to bog it down. I have been at this for 2 days, and I can't seem to find the right code.
I've tried For Each, With, Find, a whole bunch of solutions I have found online, but none seem to work right. except a Dim one but it slowed it down so much it wasn't worth keeping. I'm new/self taught so please be patient with me.
Sub delete
With WorkSheets("Sheet1") 'Change to your sheet
Dim rw as Long
On Error Resume Next
rw = Application.WorksheetFunction.Match("SHOP TICKETS",.Range("B:B"),0)
On Error Goto 0
If rw > 0 Then
.Range(rw & ":" & rw + 3).entirerow.delete
End if
End with
End sub
Cells.Find(What:="SHOP TICKETS", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Set rng = Range(ActiveCell, ActiveCell.Offset(3, 0))
rng.EntireRow.Delete
I got it!! Thanks. Talking it through to a group helped.
I'm really new to VBA, and could do with your help please.
Sheet2 is a long list of data (jobs) where each row in column B contains a unique job reference number.
I want users to input one of these numbers into a cell in Sheet 1 (G11), then the macro searches Sheet2ColumnB for the number, goes across 21 cells in that same row, then enters today's date and time into that cell.
(It then goes back to Sheet1 and says "Job Booked Out" but I think I can do this bit)
I've tried to modify some other code I've found, but get errors in the 4th line, and I have no clue if it works.
Sub CloseJob()
Dim cell As Range
Dim temp As Range
For Each cell In Sheets("Sheet1").UsedRange.cell("G11").Cells
If cell <> "" And cell.Row <> 1 Then
Set temp = Sheets("Sheet2").Columns("B").Find(What:=cell.Value, _
LookIn:=xlFormulas, LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=True)
'if found
If Not temp Is Nothing Then
'if the search_criteria is in the same sheet
cell.Offset(0, 21) = Date
End If
End If
Next
End Sub
Error:
"Run-time error 483. Object doesn't support this property or method"
by your narrative you seem after this:
Sub CloseJob()
Dim temp As Range
Set temp = Sheets("Sheet2").Columns("B").Find(What:=Sheets("Sheet1").Range("G11").Value, _
LookIn:=xlFormulas, LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, MatchCase:=True)
'if found
If Not temp Is Nothing Then temp.Offset(0, 21) = Date
End Sub
notice I changed LookAt:=xlPart to LookAt:=xlWhole for an exact match
Test and I will be able to get connect with like minded peopl
I recently got to work on an old Project of an colleague to get rid of bugs. Main Problem is, that in one Sub he shall count some numbers on sheets. But until i reset, paused and reset the Code, he doesn't count a thing. After some hours i realized, that he doesn't even find the beginning row in the first place, that startrow and endrow are returned as Nothing. (startDate and endDate are fine and filled)
But if I reset, pause and reset the code manually again (over the VBA controls) then it works just fine, even if i change sheets etc. Only if i close and open it up there is this bug again (yes I tried deactivatet the opening makro, didn't help).
Dim startDate As String, endDate As String
For i = 1 To UBound(auftraegeVar, 1)
' Adopt range to be looked in for each order according to user specified months
Set startrow = Worksheets(auftraegeVar(i)).Range("A1:A200").Find(what:=startDate, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)
Set endrow = Worksheets(auftraegeVar(i)).Range("A1:A200").Find(what:=endDate, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)
Next i
Edit:
Here is the module after applying the changes that #shairado suggested. Everything runs fine when startrow and endrow are ranges and with Set as above (except for the fact, that he always set them as nothing [i observed the variables], except i reset,pause and reset the makros). But now (If find returns Nothing, i get the Error 91 on find(bla).row, therefore the if part)
Public Sub HourCounting(auftraegeVar As Variant)
Dim indices As Range
Dim startrow As Integer, endrow As Integer
Dim startDate As String, endDate As String
'Do stuff that works
' Get start and end month in which to look for names
startDate = Worksheets("Main").cmbPastDate.Value
endDate = Worksheets("Main").cmbCurrentDate.Value
' Get start and end month in which to look for names
startDate = CDate(Worksheets("Main").cmbPastDate.Value)
endDate = CDate(Worksheets("Main").cmbCurrentDate.Value)
' ------------------- Search in all the workbooks for names, orders and months -------------------
For i = 1 To UBound(auftraegeVar, 1)
' Adopt range to be looked in for each order according to user specified months
If Worksheets(auftraegeVar(i)).Range("A:A").Find(what:=startDate, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) Is Nothing Then
startrow = 0
Else
startrow = Worksheets(auftraegeVar(i)).Range("A:A").Find(what:=startDate, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).row
End If
If Worksheets(auftraegeVar(i)).Range("A:A").Find(what:=endDate, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False) Is Nothing Then
endrow = 0
Else
endrow = Worksheets(auftraegeVar(i)).Range("A:A").Find(what:=endDate, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).row
End If
' Do stuff in Loops that works
Next i
End Sub
The Worksheet contains at the A1:A200 formulae that returns the first of a certain Month. Its formatted to Display only MMM YY. This is the same structure as my searchTerms (startDate and endDate).
If I try the search manually It works.
Found the Error: Type-Mismatch with the Values in the searched range. Phew. I gonna get myself some coffee. Thanks for helping :)