1

Hello so I am trying to help the workflow at my job. We have to import two files not .txt that come from two different databases. I created an excel macro that imports the two files with a refresh using get external function option. I would delimit them but that's later. Next I would like to go through and delete the cells that have blanks and bad characters in Column A Starting from row A2. I'm really new and haven't had to script in a longtime due to my job. This is what I have and have trying to tweak. Now the loop deletes almost everything!! Please help. Yes I have looked on all of the forums for help and nothing has worked.

Sub DeleteBadRows()
    Dim i As Variant
    Dim RowNbr As Long
    Dim ColNbr As Long
    Dim BadChr() As Variant
    Dim LR As Long

    BadChr = Array("=", "*", ",FEE", "DATE 12/13", ",(", "SMSLIST O", "REQUEST T", "WHERE", "SVC")  'include any characters to trigger deletion of row
    LR = Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row

    For RowNbr = LR To 1 Step -1
        For ColNbr = 1 To Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Column
            For i = LBound(BadChr) To UBound(BadChr)
                If InStr(Cells(RowNbr, ColNbr), BadChr(i)) Then
                Cells(i).EntireRow.Delete

                    Exit For
                End If
            Next i
        Next ColNbr
    Next RowNbr

3 Answers 3

1

What about Rows(LR).Delete instead of Cells(i).EntireRow.Delete ?

Sign up to request clarification or add additional context in comments.

1 Comment

Yup, this is the part of it exactly. I saw the first error, did not see the second :)
0

You are actually deleting the position from the Array, not the row. Thus, you are making two errors.

So try with:

Cells(RowNbr, 1).EntireRow.Delete

Instead of :

Cells(i).EntireRow.Delete

There is a small "tricky trick" in VBA.

When you give 2 parameters to the Cells() then the first is a row and the second is a column. However, if you only give one parameter, then it is a column.

Thus Cells(5) is E1 and not A5 as you are probably expecting. Thus it deletes the first cell from your code almost always.

Furthermore, the way you are looking for the last column is recalculated every time and it can be dangerous. Try to use a variable there:

For ColNbr = 1 To Cells.Find("*", so:=xlByRows, searchdirection:=xlPrevious).Column

12 Comments

To confuse further, Range("A1:A5").Cells(5) is A5.
I tried that and it's still deleting the rows other than the ones defined. It worked before.Could it be that the Array is too large? The data maybe?
@Kera - I suppose that Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Column is supposed to give you the right end column. Give it a try, hardcode it with 100 and let the VBA code run again.
Now I'm getting a Type mismatch at this line of the code: If InStr(Cells(RowNbr, ColNbr), BadChr(i)) Then
@Kera - what are the values of RowNbr and ColNbr at the specific moment, on which you are getting the type missmatch
|
0

So i have put it like this and removed from the array "*" as this meant all rows were being deleted

Option Explicit

Public Sub DeleteBadRows()

    Dim RowNbR As Long
    Dim BadChr() As Variant
    Dim LR As Long
    Dim wb As Workbook
    Dim wsSource As Worksheet
    Dim lastCol As Long

    Set wb = ThisWorkbook
    Set wsSource = wb.Worksheets("Sheet1")

    Dim rngDelete As Range
    BadChr = Array("=", ",FEE", "DATE 12/13", ",(", "SMSLIST O", "REQUEST T", "WHERE", "SVC") 'include any characters to trigger deletion of row

    LR = wsSource.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    lastCol = wsSource.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Column

    For RowNbR = 1 To LR

        If WasFound(wsSource, BadChr, RowNbR) Then

            If Not rngDelete Is Nothing Then

                Set rngDelete = Union(rngDelete, wsSource.Cells.Rows(RowNbR).EntireRow)

            Else
                Set rngDelete = wsSource.Cells.Rows(RowNbR).EntireRow

            End If
        End If


    Next RowNbR

    If Not rngDelete Is Nothing Then rngDelete.EntireRow.Delete
End Sub


Private Function WasFound(ByRef wsSource As Worksheet, ByVal BadChr As Variant, ByVal RowNbR As Long) As Boolean
 Dim i As Long

 WasFound = False

 For i = LBound(BadChr) To UBound(BadChr)

          Dim found As Long

            On Error Resume Next
            found = wsSource.Cells(RowNbR, 1).EntireRow.Find(What:=BadChr(i), LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, MatchCase:=False).Column
            On Error GoTo 0

            If found > 0 Then

                 WasFound = True

                Exit Function
            End If

       Next i

End Function

2 Comments

I tried this code and it seems to work but I think the megbox has to go, lol. This file is big and I'm up to number 180
I took the message box out and it deleted everything except one line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.