VBA - Delete either row above or row below - vba

I have an Excel sheet with the following structure:
What I need to do is delete an entire record if either it's Type A or Type B are = 0. As an example, for record 1, I need to delete A & B because B = 0.
I have the following code:
Sub Loop_Example()
Dim Firstrow As Long
Dim Lastrow As Long
Dim Lrow As Long
Dim CalcMode As Long
Dim ViewMode As Long
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
With ActiveSheet
.Select
ViewMode = ActiveWindow.View
ActiveWindow.View = xlNormalView
.DisplayPageBreaks = False
Firstrow = .UsedRange.Cells(1).Row
Lastrow = .UsedRange.Rows(.UsedRange.Rows.Count).Row
For Lrow = Lastrow To Firstrow Step -1
With .Cells(Lrow, "B")
If Not IsError(.Value) Then
If .Value = "0" Then .EntireRow.Delete
End If
End With
Next Lrow
End With
ActiveWindow.View = ViewMode
With Application
.ScreenUpdating = True
.Calculation = CalcMode
End With
End Sub
Therefore, what I would like to do is add the logic to delete the entire row if the value is 0 and either the row above or below depending on its 'type'.
Thanks.

this should work.
Sub pDeleteRow()
Dim wksData As Worksheet
Dim rngCell As Range
Dim lngCounter As Long
Dim lngTotalCount As Long
Set wksData = Worksheets("Sheet1")
lngTotalCount = wksData.Range("A1").CurrentRegion.Rows.Count
lngCounter = 1
With wksData
While lngCounter <= lngTotalCount
If (UCase(Trim(.Cells(lngCounter, 2))) = "A" Or UCase(Trim(.Cells(lngCounter, 2))) = "B") And UCase(Trim(.Cells(lngCounter, 3))) = "0" Then
.Cells(lngCounter, 1).EntireRow.Delete
lngCounter = lngCounter - 1
lngTotalCount = lngTotalCount - 1
End If
lngCounter = lngCounter + 1
Wend
End With
End Sub

You can Try This:
Sub ConditionalRowDelete()
Set colA = Range("C1", Cells(Rows.Count, "C").End(xlUp))
Set colB = Range("D1", Cells(Rows.Count, "D").End(xlUp))
MsgBox colA.Rows.Count
For i = 1 To colA.Rows.Count
If colB(i) = 0 Then
If colA(i) = "A" Then
'colB(i).Select
With colB(i) 'Selection
Application.Union(.EntireRow, .Offset(1, 0).EntireRow).Delete 'Select
End With
'Selection.EntireRow.Select
'MsgBox "found A"
End If
If colA(i) = "B" Then
'colB(i).Select
With colB(i) 'Selection
Application.Union(.EntireRow, .Offset(-1, 0).EntireRow).Delete 'Select
End With
'MsgBox "found B"
End If
End If
Next
End Sub

Related

Removing blank columns/rows in VBA as part of csv save

I am using the following VBA code to save each individual sheet in a .xlsx workbook into a .csv file.
Whilst the code is working well I would like to adapt the VBA code so blank columns & rows are removed from the .csv files which are being created.
Existing VBA Code:
Public Sub SaveWorksheetsAsCsv()
Dim xWs As Worksheet
Dim xDir As String
Dim folder As FileDialog
Set folder = Application.FileDialog(msoFileDialogFolderPicker)
If folder.Show <> -1 Then Exit Sub
xDir = folder.SelectedItems(1)
For Each xWs In Application.ActiveWorkbook.Worksheets
xWs.SaveAs xDir & "\" & xWs.Name, xlCSV
Next
End Sub
To remove blank rows & columns I was able to get the below JavaScript working in a .hta application, but would like to integrate this same functionality into the above VBA code.
//Remove all blank rows
for(var i = usedRng.Rows.Count; i > 0; i--){
if( xlApp.CountA(usedRng.Rows(i)) == 0 ) usedRng.Rows(i).Delete();
}
//Remove all blank columns
for(var i = usedRng.Columns.Count; i > 0; i--){
if( xlApp.CountA(usedRng.Columns(i)) == 0 ) usedRng.Columns(i).Delete();
}
How can I integrate this row/column removal code into VBA?
Use below sub-routine to delete empty row/column in the spreadsheet
Sub RemoveEmptyRowColumn()
Dim Firstrow As Long
Dim Lastrow As Long
Dim Lrow As Long
Dim CalcMode As Long
Dim ViewMode As Long
CalcMode = Application.Calculation
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
ActiveSheet.Select
ViewMode = ActiveWindow.View
ActiveWindow.View = xlNormalView
ActiveSheet.DisplayPageBreaks = False
Firstrow = ActiveSheet.UsedRange.Cells(1).Row
Lastrow = ActiveSheet.UsedRange.Rows(ActiveSheet.UsedRange.Rows.Count).Row
FirstColumn = ActiveSheet.UsedRange.Cells(1).Column
LastColumn = ActiveSheet.UsedRange.Columns(ActiveSheet.UsedRange.Columns.Count).Column
'------------------
' Delete Empty Rows
'------------------
For Lrow = Lastrow To Firstrow Step -1
For LColumn = LastColumn To FirstColumn Step -1
With ActiveSheet.Cells(Lrow, LColumn)
If Not IsError(.Value) Then
If .Value = "" Then
DeleteRow = "Yes"
Else
DeleteRow = "No"
Exit For
End If
End If
End With
Next LColumn
If DeleteRow = "Yes" Then
ActiveSheet.Cells(Lrow, LColumn + 1).EntireRow.Delete
End If
Next Lrow
'---------------------
' Delete Empty Columns
'---------------------
For LColumn = LastColumn To FirstColumn Step -1
For Lrow = Lastrow To Firstrow Step -1
With ActiveSheet.Cells(Lrow, LColumn)
If Not IsError(.Value) Then
If .Value = "" Then
DeleteColumn = "Yes"
Else
DeleteColumn = "No"
Exit For
End If
End If
End With
Next Lrow
If DeleteColumn = "Yes" Then
ActiveSheet.Cells(Lrow + 1, LColumn).EntireColumn.Delete
End If
Next LColumn
ActiveWindow.View = ViewMode
With Application
.ScreenUpdating = True
.Calculation = CalcMode
End With
End Sub

Removing Rows - Code Too Slow

I have the following which I am using to remove all rows of data where the name in column DX is not a specified name. The code will sort through all rows and delete each row that doesn't contain that specific name. The problem is, it is way too slow.
Any thoughts?
Sub DeleteNonName()
Dim Firstrow As Long
Dim Lastrow As Long
Dim Lrow As Long
Dim CalcMode As Long
Dim ViewMode As Long
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
With ActiveSheet
.Select
ViewMode = ActiveWindow.View
ActiveWindow.View = xlNormalView
.DisplayPageBreaks = False
Firstrow = 2
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
For Lrow = Lastrow To Firstrow Step -1
With .Cells(Lrow, "DX")
If Not IsError(.Value) Then
If InStr(.Value, "Name") = 0 Then .EntireRow.Delete
End If
End With
Next Lrow
End With
ActiveWindow.View = ViewMode
With Application
.ScreenUpdating = True
.Calculation = CalcMode
End With
End Sub
Sub DeleteName()
With ActiveSheet
.AutoFilterMode = False
With Range("DX1", Range("DX" & Rows.Count).End(xlUp))
.AutoFilter 1, "Name"
On Error Resume Next
.Offset(1).SpecialCells(12).EntireRow.Delete
End With
.AutoFilterMode = False
End With
Selection.AutoFilter
End Sub

Splitting multi value cells in Excel into rows

I encountered a problem in excel, I'm planning to split a multi-valued cell into rows through VBA.
This is my current table
Then I'm trying to make it like this
Thank you
This will do what you want. I'm assuming your 'Emails' column is column B and you start on row 1.
Option Explicit
Const ANALYSIS_ROW As String = "B"
Const DATA_START_ROW As Long = 1
Sub ReplicateData()
Dim iRow As Long
Dim LastRow As Long
Dim ws As Worksheet
Dim iSplit() As String
Dim iIndex As Long
Dim iSize As Long
'Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With ThisWorkbook
.Worksheets("Sheet1").Copy After:=.Worksheets("Sheet1")
Set ws = ActiveSheet
End With
With ws
LastRow = .Cells(.Rows.Count, ANALYSIS_ROW).End(xlUp).Row
End With
For iRow = LastRow To DATA_START_ROW Step -1
iSplit = Split(ws.Cells(iRow, ANALYSIS_ROW).Value2, ",")
iSize = UBound(iSplit) - LBound(iSplit) + 1
If iSize = 1 Then GoTo Continue
ws.Rows(iRow).Copy
ws.Rows(iRow).Resize(iSize - 1).Insert
For iIndex = LBound(iSplit) To UBound(iSplit)
ws.Cells(iRow, ANALYSIS_ROW).Offset(iIndex).Value2 = iSplit(iIndex)
Next iIndex
Continue:
Next iRow
Application.CutCopyMode = False
Application.Calculation = xlCalculationAutomatic
'Application.ScreenUpdating = True
End Sub

Need Alternate Code for For Loop

I'm using below code in vba but it taking too much time to run. Report have 8 sheets and 450+ rows should be check in each sheet.
Sub forloop()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual
lr = Cells(Rows.Count, 3).End(xlUp).Row - 1
For s = 1 To Sheets.Count
For x = lr To 1 Step -1
If Cells(x, 2) <> "" Then
Cells(x, 2).EntireRow.Delete
Next x
Next s
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.Calculation = xlCalculationAutomatic
End Sub
Could you please suggest me any alternate method to run fast.
dim wb as workbook, sht as worksheet, lr as long, r as long
set wb = workbook.open(wbPathHere)
for each sht in wb.worksheets
lr = sht.cells(sht.rows.count, 3).End(xlUp).row - 1
for r = lr to 1 step-1
if sht.cells(r, 2) <> "" Then sht.cells(r, 2).entirerow.delete
next r
next sht

Excel VBA- Toggle row highlighting with each click of a macro

I have a macro that highlights a row if there is anything blank text in a specific column. This macro is used to highlight areas where a user needs to direct attention. I want to be able to unhighlight those rows after changes have been made, by clicking the same macro button.
How do I do this?
This is the current macro:
Sub Macro13()
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
With ActiveSheet
.Select
ViewMode = ActiveWindow.View
ActiveWindow.View = xlNormalView
.DisplayPageBreaks = False
Firstrow = 2
LastRow = .Cells(.Rows.Count, "M").End(xlUp).Row
For Lrow = LastRow To Firstrow Step -1
With .Cells(Lrow, "M")
If .Value = "" Then
.EntireRow.Interior.ColorIndex = 3
End If
End With
Next Lrow
End With
ActiveWindow.View = ViewMode
With Application
.ScreenUpdating = True
.Calculation = CalcMode
End With
End Sub
My idea was to, at the beginning of the macro, check to see if any row was highlighted red. If so, run a new loop that iterates through all columns, removing the cell highlighting, and then after that loop is done, break out of the macro. This is ugly and riddled with errors, though.
Sub Macro13() 'Checks for Incorrect Countries
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
With ActiveSheet
.Select
ViewMode = ActiveWindow.View
ActiveWindow.View = xlNormalView
.DisplayPageBreaks = False
Firstrow = 2
LastRow = .Cells(.Rows.Count, "M").End(xlUp).Row
FirstrowA = 2
LastRowA = .Cells(.Rows.Count, "M").End(xlUp).Row
For Lrow = LastRow To Firstrow Step -1
With .Cells(Lrow, "M")
If .EntireRow.Interior.ColorIndex = 3 Then
For LrowA = LastRowA To FirstrowA Step -1
.EntireRow.Interior.ColorIndex = xlColorIndexNone
Next LrowA
End
Exit Sub
End If
If .Value = "" Then
.EntireRow.Interior.ColorIndex = 3
End If
End With
Next Lrow
End With
ActiveWindow.View = ViewMode
With Application
.ScreenUpdating = True
.Calculation = CalcMode
End With
End Sub
This should do the trick for you. I've added a loop that looks for any formatting before it starts highlighting blanks. If if finds something red, it clears the whole sheet of red formatting and raises a flag (Tracker = True). When the flag is raised, the macro will not
format blank cells' rows as red. I tested it and it worked for me.
Sub Macro13()
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
With ActiveSheet
.Select
ViewMode = ActiveWindow.View
ActiveWindow.View = xlNormalView
.DisplayPageBreaks = False
Firstrow = 2
LastRow = .Cells(.Rows.Count, "M").End(xlUp).Row
Dim Tracker As Boolean
Tracker = False
For Lrow = LastRow To Firstrow Step -1
If .Cells(Lrow, "M").EntireRow.Interior.ColorIndex = 3 Then
.Cells.Interior.ColorIndex = 0
Tracker = True
Exit For
End If
Next Lrow
If Tracker = False Then
For Lrow = LastRow To Firstrow Step -1
With .Cells(Lrow, "M")
If .Value = "" Then
.EntireRow.Interior.ColorIndex = 3
End If
End With
Next Lrow
End If
End With
ActiveWindow.View = ViewMode
With Application
.ScreenUpdating = True
.Calculation = CalcMode
End With
End Sub
I've had a similar issue before and conditional formating didn't work well for me. I used something similar to this:
Sub CheckAndHighlight(area As Range, Optional ByVal searchValue As String = "")
Application.ScreenUpdating = False
Dim r As Range
For Each r In area
r.EntireRow.Interior.ColorIndex = 0
If r.Value = searchValue Then
r.EntireRow.Interior.ColorIndex = 3
End If
Next
Application.ScreenUpdating = True
End Sub