VBA Delete row if - vba

All i want to do is to optimize my current delete row code.
At this stage this step take to much time.
Dim miesiac2 As Integer '--->current month
miesiac2 = Range("b1").Value
Dim LastRow As Long
LastRow = [A65536].End(xlUp).Row
For i = LastRow To 1 Step -1
If Cells(i, 1) = miesiac2 Then Rows(i & ":" & i).EntireRow.Delete
Next i
So... If column A equals current month then EntireRow.Delete
Any idea?

That's something I have built so far:
Option Explicit
Public Sub TestMe()
Application.ScreenUpdating = False
Dim miesiac2 As Long
Dim LastRow As Long
Dim i As Long
Dim rRange As Range
miesiac2 = Range("b1").Value
LastRow = [A65536].End(xlUp).Row 'xl2003
For i = LastRow To 1 Step -1
If Cells(i, 1) = miesiac2 Then
If rRange Is Nothing Then
Set rRange = Rows(i)
Else
Set rRange = Union(rRange, Rows(i))
End If
End If
Next i
If Not rRange Is Nothing Then rRange.Select
Application.ScreenUpdating = True
End Sub
It uses a Union and it selects the rows instead of deleting them. Its for visibility reasons, but you can fix it.
Furthermore, the 65K rows are only in Excel 2003, in later versions the rows are 1Mln+. Last but not least - do not use integer in Excel, its slow and dangerous.

This is what I could cook up in hurry
Sub delete_on_condition()
Dim wb_export As Workbook
Dim wb_export_sheet As Worksheet
Dim arr_raw_dump As Variant
Dim arr_final
Dim findcell As Range
Set wb_export = ThisWorkbook ' CHANGE IT IF REQURIED
Set wb_export_sheet = wb_export.Sheets(1) 'CHANGE IT IF REQUIRED
Dim ctr As Long
ctr = 0
With wb_export_sheet.Range("A1").CurrentRegion ' OR With wb_export_sheet.USEDRANGE
Do
Set findcell = .Find("SOME TEXT")
If ctr = 0 And findcell Is Nothing Then
MsgBox "No data found"
Exit Sub
End If
wb_export_sheet.Rows(findcell.Row).Delete
Set findcell = .Find("SOMETEXT")
ctr = ctr + 1
Loop While Not findcell Is Nothing
End With
End Sub

Related

delete columns based on cell value vba

I have a list of product details in excel, headers in row 2, products details from row 3.
In column C, I have status of either Open or Closed and I want vba codes that can delete the whole range if the list is Open only, hence, no Closed if found. If data has both Closed and Open or just Closed, I don't have to do anything, just leave the data as it is.
This is part of the larger codes I have already written, so that is why I am hoping to achieve this using vba codes.
I am not sure if I need to set my range to column C and how to interpret rng.Cells(q, 1).Value. Right now it looks like my codes just step through and no error but nothing happens. I have provided pic of my test data and results.
Sub test()
Dim Satus As Worksheet
Dim LR1, q As Long
Dim rng As Range
Set Status = Worksheets("Sheet1")
LR1 = Status.Cells(Rows.Count, "B").End(xlUp).Row
Set rng = Status.Range("B2:G" & LR1)
For q = 3 To LR1
If InStr(1, rng.Cells(q, 1).Value, "Closed") = 0 Then
Else
Status.Columns("B:G").EntireColumn.Delete
Status.Range("B2").Value = "No Closed Status"
End If
Next q
End Sub
It's much simpler by directly working with objects and using Excel's native functions:
Option Explicit
Sub Test()
Dim Status As Worksheet
Set Status = Worksheets("Sheet1")
With Status
Dim LR1 As Long
LR1 = .Range("B" & .Rows.Count).End(xlUp).Row
If .Range("C3:C" & LR1).Find("Closed", lookat:=xlWhole) Is Nothing Then
.Range("C3:C" & LR1).EntireRow.Delete
End If
End With
End Sub
Is Nothing is because .Find returns a range object if it's found. If it doesn't find it it will return, essentially, nothing.
It is simple to use Worksheetfunction countif.
Sub test()
Dim Satus As Worksheet
Dim LR1, q As Long
Dim rng As Range, rngDB As Range
Dim cnt As Long
Set Status = Worksheets("Sheet1")
With Status
LR1 = .Cells(Rows.Count, "B").End(xlUp).Row
Set rng = Status.Range("B2:G" & LR1)
Set rngDB = .Range("c3:c" & LR1)
cnt = rngDB.Rows.Count
If WorksheetFunction.CountIf(rngDB, "Open") = cnt Then
rng.EntireColumn.Delete
.Range("B2").Value = "No Closed Status"
.Range("a1") = "Data1 Result"
End If
End With
End Sub
I think this should solve your problem. You can't decide in the for loop a state for a whole column. You have to collect all single states and execute a change afterwards.
Sub test()
Dim Satus As Worksheet
Dim LR1, row As Long
Dim rng As Range
'Dim lOpen As Long
Dim lClosed As Long
Set Status = ThisWorkbook.ActiveSheet
LR1 = Status.Cells(Rows.Count, "B").End(xlUp).row
Set rng = Status.Range("B2:G" & LR1)
rngStart = 2 ' because of header line
rngEnd = rng.Rows.Count - 1 ' likewise
For row = rngStart To rngEnd
Select Case rng.Cells(row, 2).Value
'Case "Open" ' just in case for future use
' lOpend = lOpend + 1
Case "Closed"
lClosed = lClosed + 1
Case Else
End Select
Next row
If lClosed = 0 Then
rng.EntireColumn.Delete ' delete just the data range
Status.Range("B2").Value = "No Closed Status"
End If
End Sub

VBA - Go through Worksheets and end with one sheet with found strings, from all Sheets

I can't get this code to work. I am trying to go through all worksheets in a Excel Book, And when I find a row that contains "Syst" it is supposed to pop up in a list in the worksheet "Systemoversikt"
Sub WorksheetLoop()
MsgBox "Testing"
Dim WS_Count As Integer, j As Integer
WS_Count = ActiveWorkbook.Worksheets.Count
' Begin the loop.
For j = 1 To WS_Count
Dim sh As Worksheet
Dim i As Long
Set sh = ActiveWorkbook.Worksheets(j)
sh.Activate
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
Dim n As Integer
For i = 1 To LastRow
n = 3
Dim systemnummer As String
systemnummer = Left(Cells(i, 1).Value, [4])
If systemnummer = "Syst" Then
Sheets("Systemoversikt").Cells(n, 8).Value = Cells(i, n).Value
n = n + 1
End If
Next i
Next j
End Sub
I think your search and loop method needs improvement. Here's a simplified version. It's not as fast and efficient as using a find function, but I think it gets you what you need.
Sub WorksheetLoop()
Dim SearchWkb As Workbook
Dim DestWkb As Workbook
Set SearchWkb = ActiveWorkbook
Set DestWkb = Workbooks("Punktliste11.xlsm") 'updated!
'Begin loop through sheets
Dim sh As Worksheet
Dim vCell As Range
For Each sh In SearchWkb.Sheets
If sh.Name <> "Systemoversikt" Then
'Look through all activerange cells (this could be done faster but good for illustration)
For Each vCell In sh.UsedRange.Cells
If Left(vCell.Value, 4) = "Syst" Then
DestWkb.Sheets("Systemoversikt").Cells(Rows.Count, 8).End(xlUp).Offset(1, 0).Value = vCell.Value
End If
Next vCell
End If
Next sh
End Sub

Delete special rows in every sheet via VBA

I tried to write some code to search for a word and if this word isn't found in the first an second column I delete the row.
This code runs through every Sheet.
Unfortunately this script takes like forever and Excel stops working. It works for one sheet but even if there are just 2 rows, it takes like 10 seconds.
Maybe you can help me to work on the performance, because I never learned VBA and this code is the best I was able to write.
Option Explicit
Sub dontDeleteRowWithInput()
Dim wksSheet As Worksheet
Dim area As Range, i As Integer, j As Integer
Dim rows As Long
Dim Var As String
Dim bool As Boolean
Dim celltxt As String
Var = InputBox("Input", "Input")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'Loop over every Worksheet in this Workbook
For Each wksSheet In ActiveWorkbook.Worksheets
Set area = wksSheet.UsedRange
rows = area.Rows.Count
'Loop the rows backwards until it reaches row 2 (Row 1 should be ignored)
For j = rows To 2 Step -1
'Search vor the input in Column 1 and 2
For i = 1 To 2 Step 1
'Get the content of the reached cell in string format
celltxt = Cells(j, i).Value
'Compare the saved string with the input
If InStr(celltxt, Var) > 0 Then
'If the input is found in this cell don't delete the row
bool = False
Exit For
End If
'Delete the row if the input wasn't found in its columns
If bool = True Then
Rows(j).Delete
End If
'Reset the bool
bool = True
Next i
Next j
Next wksSheet
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Could you try something simpler like:
Dim wksSheet As Worksheet, i As Integer, j As Integer
Dim lastrow As Long
Dim Var As String
Var = InputBox("Input", "Input")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'Loop over every Worksheet in this Workbook
For Each wksSheet In ThisWorkbook.Worksheets
With wksSheet
lastrow = 0
On Error Resume Next
lastrow = .Cells.Find("*", SearchOrder:=xlByRows, LookIn:=xlValues, SearchDirection:=xlPrevious).Row
If lastrow > 0 And Var <> "" Then
For i = lastrow To 2 Step -1
If InStr(.Cells(i, 1).Text, Var) > 0 Or InStr(.Cells(i, 2).Text, Var) > 0 Then
.rows(i).Delete
End If
Next i
End If
End With
Next
Application.ScreenUpdating = True
Application.DisplayAlerts = True
You can try this, I believe this should work for you. It has not been tested yet.
Sub dontDeleteRowWithInput()
Dim sht As Worksheet
Dim nlast As Long
For Each sht In Sheets
nlast = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
For n = nlast To 1 Step -1
If sht.Cells(n, 1).Value <> "Input" And sht.Cells(n, 2).Value <> "Input" Then
sht.Rows(n).EntireRow.Delete
End If
Next n
Next sht
End Sub
`

Excel VBA Two functions on one array

I need to delete spaces at the beginning, end of string and make string Proper Case.
I have found two scripts:
Sub Function01()
Dim arrData() As Variant
Dim arrReturnData() As Variant
Dim rng As Excel.Range
Dim lRows As Long
Dim lCols As Long
Dim i As Long, j As Long
Range("R1", Range("R1").End(xlDown)).Select
lRows = Selection.Rows.Count
lCols = Selection.Columns.Count
ReDim arrData(1 To lRows, 1 To lCols)
ReDim arrReturnData(1 To lRows, 1 To lCols)
Set rng = Selection
arrData = rng.Value
For j = 1 To lCols
For i = 1 To lRows
arrReturnData(i, j) = Trim(arrData(i, j))
///ADDING HERE(read below)
Next i
Next j
rng.Value = arrReturnData
Set rng = Nothing
End Sub
which is deleting spaces on string and another script:
Sub ChangeCase()
Dim Rng As Range
On Error Resume Next
Err.Clear
Application.EnableEvents = False
For Each Rng In Selection.SpecialCells(xlCellTypeConstants, _
xlTextValues).Cells
If Err.Number = 0 Then
Rng.Value = StrConv(Rng.Text, vbProperCase)
End If
Next Rng
Application.EnableEvents = True
End Sub
Which is making Proper Case of string. Those two scripts are working on ranges to select all not null cells in R column. I need to make function second script in the first one.
Adding this code in first script at (///ADDING HERE) point:
arrReturnData(i, j) = StrConv(arrData(i, j), vbProperCase)
Making my output in Proper Case but with spaces.
Could you guys suggest how to make two script functions in a stroke?
Thank you!
This will do the whole without loops:
Sub Function01()
Dim rng As Range
Set rng = Selection
rng.Value = rng.Parent.Evaluate("INDEX(PROPER(TRIM(" & rng.Address & ")),)")
End Sub
Before:
After:

Need help trimming spaces out of column

I am trying to figure out how to loop through the first column of my worksheet and take out the spaces so I can use VLOOKUP. Not sure how to do it in VBA. Here is what I have:
I can't figure out why it does not go onto the next sheet now? I can't just cycle through all of the sheets since they are different.
Sub trima()
Dim x As Integer
Dim numrows As Long
numrows = Range("A1",Range("A1").End(xlDown)).Rows.Count
Range("A1").Select
For x = 1 To numrows
Application.WorksheetFunction.trim (ActiveCell)
ActiveCell.Offset(1, 0).Select
Next
End Sub
Here you go:
Sub TrimA()
Dim v
v = [transpose(transpose(trim(a1:index(a:a,match("",a:a,-1)))))]
[a1].Resize(UBound(v)) = v
End Sub
UPDATE
If you want to update multiple sheets, you can utilize the above like so:
Sub DoTrims()
Sheet1.Activate: TrimA
Sheet2.Activate: TrimA
'etc.
End If
The Trim function does not work like that.
Instead, try something like:
Sub trima()
Dim numrows As Long
Dim vItem as Variant
Dim i As Long
numrows = Range("A1",Range("A1").End(xlDown)).Rows.Count
Application.ScreenUpdating = False
With ActiveSheet
For i = 1 To numrows
vItem = .Range("A" & i)
If vItem <> vbNullString then .Range("A" & i) = Application.WorksheetFunction.Trim(vItem)
Next
End With
Application.ScreenUpdating = True
End Sub
The following code will loop through ALL worksheets in the Workbook and perform the same trim on values in Column A:
Sub trimA()
Dim ws As Excel.Worksheet
Dim i As Long, numrows As Long
Dim vItem As Variant
Application.ScreenUpdating = False
For Each ws In Worksheets
With ws
numrows = .Range("A1", .Range("A1").End(xlDown)).Rows.Count
For i = 1 To numrows
vItem = .Range("A" & i)
If vItem <> vbNullString Then .Range("A" & i) = Application.WorksheetFunction.Trim(vItem)
Next i
End With
Next
Application.ScreenUpdating = True
End Sub
Using the Range.TextToColumns method should quickly clear all cells containing leading/trailing spaces.
This procedure can quickly convert text-that-look-like-numbers to true numbers as well.
Dim c As Long
With Range("A1").CurrentRegion `<~~ set to the desired range of one or more columns
For c = 1 To .Columns.Count
.Columns(c).TextToColumns Destination:=.Columns(c), _
DataType:=xlFixedWidth, FieldInfo:=Array(0, 1)
Next c
End With
If the cells actually contain non-standard spacing like the non-breaking space (common on data copied from a web page) then other Range.Replace method should be added.