Cannot Delete Cells if they contain value VBA - excel

I have a file that has a bunch of Cells in the A column (1500) that look like this:
Perfect Imperfection;"Kevin Gates";"Luca Brasi 2: Gangsta Grillz";1
or
Perfect Imperfection;"Kevin Gates";"Luca Brasi 2: Gangsta Grillz";0
I am trying to delete cells that end in ;1
Note that some song titles have a 1 in them, and others take the form of:
Perfect Imperfection;;;1
I'm using the following code from a different Stack Overflow post that I have edited slightly:
Sub DeleteRowsWithX()
maxRow = ActiveSheet.UsedRange.Rows.Count
MsgBox (maxRow)
For i = 1 To maxRow
Do While (StrComp(ActiveSheet.Cells(i, 1).Text, ";1", vbTextCompare) = 0)
Rows(i).Select
Selection.Delete Shift:=xlUp
MsgBox ("Deleted")
Loop
Next
End Sub
If it helps, here are some examples of the file:
Perfect Imperfection;"Kevin Gates";"Luca Brasi 2: Gangsta Grillz";1
Perfect Strangers;"Lil Wayne";"Tha Carter V";1
Perplexing Pegasus;"Rae Sremmurd";;1
Phone Numbers Wiz Khalifa;;;0
Piano Man;"Billy Joel";;1
Picasso Baby Jay Z;;;0
Pick Up the Phone ft Young Thug Travis Scott;;;0
Picture;"Kid Rock";;1
Pillowtalk Conor Maynard;;;1
Pimp Juice;Nelly;Nellyville;1
Pinball Wizard;"The Who";;1
Pink Toes Childish Gambino;;;1
Which should look like:
Phone Numbers Wiz Khalifa;;;0
Picasso Baby Jay Z;;;0
Pick Up the Phone ft Young Thug Travis Scott;;;0
However, nothing is deleting. Can anybody advise? NOTE -- this not need to be done in VBA, I just want to delete rows that end in 1

Requirements: Delete entire row of values in column 1 that end with ";1"
For this kind of requirements suggest the use of AutoFilter and SpecialCells to delete all the target rows at once.
Try this:
Sub AutoFilter_To_DeleteRows()
With ActiveSheet
Application.Goto .Cells(1), 1
Rem Add a temporary header to avoid indiscriminate deletion of the first row.
.Cells(1).EntireRow.Insert
.Cells(1).Value2 = "Temporary Header"
Rem Filter values ending with ";1"
.Columns(1).AutoFilter Field:=1, Criteria1:="=*;1"
Rem Delete all resulting rows
.Columns(1).SpecialCells(xlCellTypeVisible).EntireRow.Delete
End With
End Sub

Keeping the answer close to the code that you have written.
You need to loop from the bottom of your list to the top. That way when rows are deleted, you do not skip rows. This can be done in your For loop by starting with the bottom of the list and moving backwards to the first row using Step -1.
The Right function can be used to test the last two characters of the cell value to see if they match to ;1.
The Do While can be removed.
The MsgBox's have been expanded to provide more detail when testing. They can be commented out once you are happy with the way the code is running.
Sub DeleteRowsWithX()
maxRow = ActiveSheet.UsedRange.Rows.Count
MsgBox "No. of Rows: " & maxRow
For i = maxRow To 1 Step -1
ValOfCell = ActiveSheet.Cells(i, 1).Value2
If Right(ValOfCell, 2) = ";1" Then
Rows(i).Delete Shift:=xlUp
MsgBox "Row: " & i & vbCrLf & "Value: " & ValOfCell & vbCrLf & "has been deleted."
End If
Next
End Sub

Jerry, I could not get StrComp to work the way I wanted, so I used Mid & Len to accomplish what you need. This will work since all the song titles end with ";?". Also, I did not add to the code, but consider doing everything you can to not use the Select method - this can lead to complications.
Sub DeleteRowsWithX()
Dim maxrow As Integer
Dim i As Integer
maxrow = ActiveSheet.UsedRange.Rows.Count
For i = 1 To maxrow
Do While Mid(Cells(i, 1).Text, Len(Cells(i, 1).Text) - 1, 2) = ";1"
Rows(i).Select
Selection.Delete Shift:=xlUp
MsgBox ("Deleted")
Loop
Next
End Sub

Related

Insert New Row with Sequential Number after criteria is met

I will admit to being a terrible at code, and have always struggled with Macros... forgive my ignorance.
What I am working on building is a part number index that will create a new sequential number within a numerical series after a macro-button is pressed.
I'd like each button to scan between a range [i.e. 11-0000 (MIN) and 11-9999 (MAX)] and select the max value cell that exists. At that selection point insert an entire new row below with the next + 1 sequential number in the "B" column.
I have my button creating the table row as I would like, however I need help in defining the ".select(=Max(B:B))" and as I understand Max will also limit the # of line items it queries?
I have also been playing with .Range("B" & Rows.CountLarge) with little to no success.
Ideally the 11-**** button [as seen in the screen cap] should insert a sequential number below the highlighted row.
Maybe I'm way over my head, but any guidance even in approach or fundamental structure of the code would help be greatly appreciated!
Private Sub CommandButton1_Click()
Sheets("ENGINEERING-PART NUMBERS").Range("B" & Rows.CountLarge).End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveCell.EntireRow.Insert Shift:=xlDown
ActiveCell.Value = "=ActiveCell + 1"
End Sub
Screen Cap of Spread Sheet
Perhaps there is a simpler solution that I've overlooked, but the below will work.
Insert a module into your workbook and add this code:
Public Sub AddNextPartNumber(ByVal FirstCellInColumn As Range, Optional ByVal PartMask As Variant = "")
Dim Temp As Variant, x As Long, MaxValueFound(1 To 2) As Variant
'Some error checking
If PartMask = "" Then
MsgBox "No part mask supplied", vbCritical
Exit Sub
ElseIf Not PartMask Like "*[#]" Then
MsgBox "Invalid part mask supplied; must end in ""#"".", vbCritical
Exit Sub
ElseIf PartMask Like "*[#]*[!#]*[#]" Then
MsgBox "Invalid part mask supplied; ""#"" must be continuous only.", vbCritical
Exit Sub
End If
'Get the column of data into an array
With FirstCellInColumn.Parent
Temp = .Range(FirstCellInColumn, .Cells(.Rows.Count, FirstCellInColumn.Column).End(xlUp))
End With
'Search through the array and find the largest matching value
For x = 1 To UBound(Temp, 1)
If Temp(x, 1) Like PartMask Then
If MaxValueFound(1) < Temp(x, 1) Then
MaxValueFound(1) = Temp(x, 1)
MaxValueFound(2) = x
End If
End If
Next x
'Output new part number
If MaxValueFound(2) = 0 Then
'This part mask doesn't exist, enter one with 0's at the end of the list
With FirstCellInColumn.Offset(x - 1, 0)
.Value = Replace(PartMask, "#", 0)
.Select
End With
Else
'Get the length of the number to output
Dim NumberMask As String, NumFormatLength As Long
NumFormatLength = Len(PartMask) - Len(Replace(PartMask, "#", ""))
NumberMask = String(NumFormatLength, "#")
'Determine the new part number
MaxValueFound(1) = Replace(MaxValueFound(1), Replace(PartMask, NumberMask, ""), "")
MaxValueFound(1) = Replace(PartMask, NumberMask, "") & Format((MaxValueFound(1) * 1) + 1, String(NumFormatLength, "0"))
'Insert row, add new part number and select new cell
FirstCellInColumn.Offset(MaxValueFound(2), 0).EntireRow.Insert
With FirstCellInColumn.Offset(MaxValueFound(2), 0)
.Value = MaxValueFound(1)
.Select
End With
End If
End Sub
Then, for each button, you write the code like this:
Private Sub CommandButton1_Click()
'this is the code for the [ADD 11-****] button
AddNextPartNumber Me.Range("B16"), "11-####"
End Sub
Private Sub CommandButton2_Click()
'this is the code for the [ADD 22-****] button
AddNextPartNumber Me.Range("B16"), "22-####"
End Sub
This has been written assuming that inserting a new row onto your sheet won't affect other data and that adding new data to the bottom of the table without inserting a row also won't affect other data.
Assuming you're working with a table, by default it should auto-resize to include new data added to the last row.
Good luck learning the ropes. Hopefully my comments help you understand how what I wrote works.

Need to exclude a word (or number of characters) in my code

I am trying to create a Module that will format an excel spreadsheet for my team at work. There is one column that will contain the word "CPT" and various CPT codes with descriptions.
I need to delete all text (CPT description) after the 5 digit CPT code but alsp keep the word CPT in other cells.
For example: Column S, Row 6 contains only the word "CPT" (not in quotations)
Then Column S, Row 7 contains the text "99217 Observation Care Discharge"
This setup repeats several times throughout Column S.
I would like for Row 6 to stay the same as it is ("CPT") but in Row 7 i only want to keep "99217"
Unfortunately, this is not possible to do by hand as there are several people who will need this macro and our spreadsheets can have this wording repeated hundreds of times in this column with different CPT codes and descriptions.
I have tried various If/Then statements, If/Then/Else
Sub CPTcolumn()
Dim celltxt As String
celltxt = ActiveSheet.Range("S6" & Rows.Count).End(xlUp).Text
Dim LR As Long, i As Long
LR = Range("S6" & Rows.Count).End(xlUp).Row
For i = 1 To LR
If InStr(1, celltxt, "CPT") Then
Next i
Else
With Range("S6" & i)
.Value = Left(.Value, InStr(.Value, " "))
End With
Next i
End If
End Sub
When i try to run it I get Various "Compile Errors"
I would do this differently.
Given:
The cell to be modified will be the cell under a cell that contains CPT
in the algorithm below, we look for CPT all caps and only that contents. Easily modified if that is not the case.
Since you write " a five digit code", we need only extract the first five characters.
IF you might have some cells that contain CPT where the cell underneath does not contain a CPT code, then we'd also have to check the contents of the cell beneath to see if it looked like a CPT code.
So we just use the Range.Find method:
Sub CPT()
Dim WS As Worksheet, R As Range, C As Range
Dim sfirstAddress As String
Set WS = Worksheets("sheet4")
With WS.Cells
Set R = .Find(what:="CPT", LookIn:=xlValues, lookat:=xlWhole, _
MatchCase:=True)
If Not R Is Nothing Then
sfirstAddress = R.Address
Set C = R.Offset(1, 0)
C.Value = Left(C.Value, 5)
Do
Set R = .FindNext(R)
If Not R.Address = sfirstAddress Then
Set C = R.Offset(1, 0)
C.Value = Left(C.Value, 5)
End If
Loop Until R.Address = sfirstAddress
End If
End With
End Sub
If this sequence is guaranteed to only be in Column S, we can change
With WS.Cells
to With WS.Columns(19).Cells
and that might speed things up a bit.
You may also speed things up by adding turning off ScreenUpdating and Calculation while this runs.
Your first error will occur here:
ActiveSheet.Range("S6" & Rows.Count).End(xlUp).Text
Because you're trying to retrieve text from the last used range starting .End(xlUp) at Range("S61048576"), which is roughly 58 times the row limit in Excel. You might change Range("S6" & Rows.Count) to Range("S" & Rows.Count)
Your second error will occur here:
LR = Range("S6" & Rows.Count).End(xlUp).Row
Which will be the same error.
The third error will occur here:
For i = 1 To LR
If InStr(1, celltxt, "CPT") Then
Next i
You cannot nest half of an If-End If block in a For-Next loop, or vice-versa and you've done both. If you want to iterate and perform an If-End If each iteration, you need to contain the If-End If within the For-Next like
For i = 1 To LR
If InStr(1, celltxt, "CPT") Then
'Is the purpose here to do nothing???
Else
With Range("S" & i)
.Value = Left(.Value, InStr(.Value, " "))
End With
End If
Next i
EDIT:
For technical accuracy, your first error would actually be your broken up For-Next and If-End If, as you wouldn't even be able to compile to execute the code to run into the other two errors.
You can simply use the Mid function in the worksheet.
As I understood from your question that you need to separate numbers and put them in other cells, is this true?
To do this, you can write this function in cell R6 like this
=Mid(S6,1,5)
Then press enter and drag the function down and you will find that all the cells containing numbers and texts have been retained numbers in them

Excel VBA For Loop Optimization - Exit when j = 2

I'm trying to optimize code that will delete rows that meet certain criteria. I have working code, but the following code creates 7 seconds of wait time to execute:
Dim j As Long
For j = 2 To Rows.Count
If (Range("J" & j).Value <> "") Then
Range("A" & j & ":R" & j).Select
Selection.Delete Shift:=xlUp
End If
Next j
The following code runs instantly; however, I can't get it to work once j = 2. What code needs to be added to stop the loop before it deletes the column headers in row 1?
' Delete rows where column J is not blank
For j = Range("J" & Rows.Count).End(xlUp).Row To 1 Step -1
If (Range("J" & j).Value <> "") Then
Range("A" & j & ":R" & j).Select
Selection.Delete Shift:=xlUp
End If
Next j
As mentioned in the comments, you should looking backward for deletions. If you do the deletions from row#2 to the last row, there might be some rows should be deleted but remained there. Take this for example, assuming we are going to delete row#3 and row#4. If we do it forward, the row#4 becomes to new row#3 after deleting old row#3. And the next row to be checked is row#4, that is the original row#5. So the data in row#4 is actually in row#3 now and it'll never be deleted.
However, when your data is quite massive, the deletions would take so many resource that it drags down the speed. It would be better to find all the ranges to be deleted and delete them at once in the end. We can do it by Union method. And this can also prevent the problem mentioned before, so we can do it forward as other loops.
Lastly, you can avoid selecting ranges since it is not so efficient. Range().Delete can simply delete the range and without selecting it.
The code would be like this.
'pseudo code
Sub deletion()
For i = 2 To lastrow
If shouldBeDeleted Then
If deletingRng Is Nothing Then
Set deletingRng = Cells(i, X)
Else
Set deletingRng = Union(deletingRng, Cells(i, X)
End If
End If
Next i
deletingRng.Delete Shift:=xlUp
End Sub

SIMPLE Delete line from cell?

Hello I'm trying to delete all the rows where in column B the members value is over 1000.
I tried this step by step and tried first getting rid of all the unecessary data from B cells and leave just the line with the members.
I noticed there are 5 lines and the members line is the 6'th one. I searched for hours and I still don't get it HOW TO DELETE THE FIRST 5 LINES. Could you please offer me a hand of help? Im sure its soo easy but I cant find it.
I have this:
Option Explicit
Sub Delete5TextLines()
Dim c As Range, s
Application.ScreenUpdating = False
For Each c In Range("B1", Range("B" & Rows.Count).End(xlUp))
**********
Next c
Application.ScreenUpdating = True
End Sub
this is the .csv file:
http://we.tl/vNcyfg9Wus
Alright, this is not very elegant, but the first thing that I came up with, that kinda works.
use this formula to delete the last word in your bulk of text ("members")
Assuming your text is in A1:
=LEFT(A1,FIND("|",SUBSTITUTE(A1," ","|",LEN(A1)-LEN(SUBSTITUTE(A1," ",""))))-1)
This formula gets you the last word of a text, in this case the number of members (because we deleted the word "members)
Assuming you put the formula above in A2
=IF(ISERR(FIND(" ",A2)),"",RIGHT(A2,LEN(A2)-FIND("*",SUBSTITUTE(A2," ","*",LEN(A2)-LEN(SUBSTITUTE(A2," ",""))))))
Now you should have extracted the number of members. If this value is <5000 you can delete the row with a vba loop that should look like this:
Sub deleteRowsAfterMembers
Dim i as Integer
i = ThisWorkbook.Sheets(1).Rows.Count
While i > 0 Do
If (CellWithMemberCount).Value < 5000 Then
ThisWorkbook.Sheets(1).Rows(i).Delete
End If
i = i-1
Loop
End Sub
That'll (hopefully) do it.
Whenever you delete entire rows using a loop, you should start at the bottom of the range and work the loop upwards.
EDIT#1:
Assuming that there are at least five lines within a cell and the lines are separated by Chr(10) then this will remove the first 5 lines:
Sub marine()
ary = Split(ActiveCell.Value, Chr(10))
t = ""
For i = 5 To UBound(ary)
t = t & Chr(10) & ary(i)
Next i
If Len(t) > 1 Then
t = Mid(t, 2)
Else
t = ""
End If
ActiveCell.Value = t
End Sub

Need to delete irrelevant rows in a spreadsheet

Why does the following code not delete irrelevant rows in my spreadsheet?
Sub Macro1Format()
'
' Macro1Format Macro
'
Dim i As Integer
i = 0
Do While (Range("A1").Value <> "Project ID") And (i < 100)
Range("1:1").Delete
i = i + 1
Loop
End Sub
I'll take a stab that you would like something like:
Sub Macro1Format()
Dim i As Integer
i = 99
For i = 99 To 1 Step -1
If Range("A" & i).Value <> "Project ID" Then
Range(i & ":" & i).Delete
End If
Next
End Sub
You seem to have confused 1 with i but also when deleting rows it may be best to start from the bottom up since the row count changes as a consequence of any row deletion. There were also some syntax problems.

Resources