0

I have a range of cells in one row. I want to test if they all do not have content.

I found If Not IsError(Application.Match(ValueToSearchFor, RangeToSearchIn, 0)) Then

I fixed the ranges to be more like my needs:

If Not IsError(Application.Match("", rRng.Offset(lOffset).Range(Cells(1, 1), Cells(1, rRng.Columns.Count)), 0)) Then

It didn't jump into my conditional statement.

I tried the opposite:

If Not IsError(Application.Match("<>", rRng.Offset(lOffset).Range(Cells(1, 1), Cells(1, rRng.Columns.Count)), 0)) Then

It didn't hit my conditional statement.

I checked that a range existed:

rRng.Offset(lCorrection).Range(Cells(1, 1), Cells(1, rRng.Columns.Count)).Select

The correct range is selected.

I believe the condition "" or "<>" are correct input, its simpler than put in a cell reference.
What about the looping, is there something I missed?

11
  • I'd use FIND, but looking at the formula - rRng.Offset(lOffset).Range is looking at whatever sheet and range that rRng is set to, but within that range you're using just Cells(1,1) which is pointing to cell A1 on whatever sheet is currently active. It should be something like rRng.Cells(1,1), or maybe rRng.Offset(lOffset).Range(rRng.Offset(lOffset).Cells(1,1),.... Commented Mar 17 at 10:31
  • Thanks! I try to use a range, and it should in a way work the same as a table. I would like to ask for Header Row or Total Row. In this situation, I dont know if the range is set up with a Total row. When someone is asks for a TotalRow, i offset it down Rows.count and then need to find if any of the columns have data. Reason why it should simulate Table, is that it should cover old code that not use table Commented Mar 17 at 11:14
  • I understand! rRng is the Range associated withe the input data. Cell(1,1), i thought supposed to be the first cell in the range, but maybe I need to use rRng.Cell(1,1) Commented Mar 17 at 11:25
  • I've tested, and found out that we should start with rRng, and when we specify which cells in the range it should start with Cells(1,1) that is the first cell in the range of that row. Then it should follow still first/the same row and columns like range with. Dim lCorrection As Long: lCorrection = rRng.Rows.Count rRng.Offset(lCorrection).Range(Cells(1, 1), Cells(1, rRng.Columns.Count)).Select This represents the row below the range and Column with Commented Mar 17 at 11:51
  • 1
    You need to explain accurately which condition you need. The options usually are just the following: Is any cell blank? (one or more are blank), Is no cell blank?, and Are all cells blank?. Which one is it? Sharing the complete code would help a lot. Commented Mar 17 at 13:23

4 Answers 4

1

You can also use CountIf in a way similar to that you tried to use Match :

MsgBox Application.CountIf(rRng.Offset(lOffset), "<>")  ' counts non-empty cells
MsgBox Application.CountIf(rRng.Offset(lOffset), "")    ' counts empty cells
Sign up to request clarification or add additional context in comments.

Comments

0
main()
 set og_NameRng = rRng
 If CorrectRangeForHeaderRows(rRng) Then
   If CorrectForTotalRow(rRng) Then
    Set og_Rng = rRng
          bFound = True
    End If
 End If
Private Function CorrectRangeForHeaderRows(ByRef rRng As Range) As Boolean
  rRng.Select
  Dim lCorrection As Long: lCorrection = 0
  Dim vVar As Variant

  ActiveSheet.rRng.Offset(-(lCorrection + 1)).Range(Cells(1, 1), Cells(1,          ActiveSheet.rRng.Columns.Count)).Select

  vVar = Application.Match("", ActiveSheet.rRng.Offset(-(lCorrection + 1)).Range(Cells(1, 1), Cells(1, ActiveSheet.rRng.Columns.Count)), 0) 

  If Not IsError(Application.Match("", ActiveSheet.rRng.Offset(-(lCorrection + 1)).Range(Cells(1, 1), Cells(1, ActiveSheet.rRng.Columns.Count)), 0)) Then _
    Debug.Print vVar
  CorrectRangeForHeaderRows = True
  Set rRng = rRng.Resize(lCorrection)
End Function
Private Function CorrectForTotalRow(ByRef rRng As Range) As Boolean
  'The problem is that the position we want to search for do not have content in first Column but later
  rRng.Select
  Dim lCorrection As Long: lCorrection = rRng.Rows.Count
  Dim vVar As Variant
    
  ActiveSheet.rRng.Offset(lCorrection - 1).Range(Cells(1, 1), Cells(1, ActiveSheet.rRng.Columns.Count)).Select

  vVar = Application.Match("", ActiveSheet.rRng.Offset(lCorrection - 1).Range(Cells(1, 1), Cells(1, ActiveSheet.rRng.Columns.Count)), 0)

  If Not IsError(Application.Match("", ActiveSheet.rRng.Offset(lCorrection - 1).Range(Cells(1, 1), Cells(1, rRng.Columns.Count)), 0)) Then _
    Debug.Print vVar
  Set rRng = rRng.Resize(lCorrection)
  rRng.Select
  CorrectForTotalRow = True

I just want to let you know, that this is only some test code to find out how it works, more testing and error-checking has to come
I'will just tell you that I have to leave now and will be back tomorow, but I hope you have a kind of solution to the problem. I tested my self and got to the errormessage 2042 and might be I have to add sheetname
Thanks.

2 Comments

If this is intended as a clarification to your question, then please edit the question and add it there. Answers are not for comments/clarifications.
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

Scan up or down to find first row without values using WorksheetFunction.CountA(). Assume rng is a single row.

Function GetHeaderRow(ByRef rng As Range) As Boolean

    Dim i As Long, r As Long, tbl As ListObject
    
    ' check if table
    Set tbl = rng.ListObject
    If tbl Is Nothing Then
        r = rng.Row
       
        'scan up for blank row
        Do While WorksheetFunction.CountA(rng.Offset(-i)) > 0
            i = i + 1
            If i = r Then Exit Do
        Loop
        
        If i = r Or i = 0 Then
           'input rng is empty
           Set rng = Nothing
           Exit Function
        Else
           ' row below empty row
           Set rng = rng.Offset(1 - i)
        End If
    
    Else
        Set rng = tbl.HeaderRowRange
    End If
    GetHeaderRow = True

End Function

Function GetTotalsRow(ByRef rng As Range) As Boolean

    Dim i As Long, r As Long, tbl As ListObject
    
    ' check if table
    Set tbl = rng.ListObject
    If tbl Is Nothing Then
        r = rng.Row
       
        'scan down for blank row
        Do While WorksheetFunction.CountA(rng.Offset(i)) > 0
            i = i + 1
            ' limit i
            If r + i > Rows.Count Then
                i = 0
                Exit Do
            End If
        Loop
        
        If i = 0 Then
           ' input rng is empty
           Set rng = Nothing
           Exit Function
        Else
           ' row above empty row
           Set rng = rng.Offset(i - 1)
        End If
    
    Else
        Set rng = tbl.ListRows(tbl.ListRows.Count).Range
    End If
    GetTotalsRow = True

End Function

Comments

0

Thanks to CDP1802 contribution. I've followed and used his code as a template. I have some constrains. It's part of an small accountant system where both income and expenses are displayed on same sheet. Therefore I couldn't test against 1 or first Row, but I said if the header/total ain't shown up within 3 rows, the I will break. My test criteria if it's a header row, all columns has to have content. My test criteria for total row is that it different from a totally empty row. Some of the rows are not completely empty outside of the "Range" of the table, therefore I a little bit stubborn :-)) and use only first column to last column of the table and offset that with a certain amount of rows like this

Private Function CorrectRangeForHeaderRows(rRng As Range) As Range
  'rRng.Select
  Dim tmpRng As Range
  Set tmpRng = rRng.Range(Cells(1, 1), Cells(1, rRng.Columns.Count))
  'tmpRng.Select

  'Loop to a full Header row
  Dim lCor As Long: lCor = 1
  Do While WorksheetFunction.CountA(tmpRng.Offset(-lCor)) < rRng.Columns.Count
    lCor = lCor + 1
    If rRng.Row - lCor <= 1 Then
      Exit Do
    End If
  Loop
  If rRng.Row - lCor > 1 Then
    Set rRng = rRng.Offset(-lCor).Resize(rRng.Rows.Count + lCor)
  End If
  'rRng.Select
  CorrectRangeForHeaderRows = rRng
End Function
Private Function CorrectForTotalRow(rRng As Range) As Range
  'rRng.Select
  Dim tmpRng As Range
  Set tmpRng = rRng.Range(Cells(1, 1), Cells(1, rRng.Columns.Count))
  'tmpRng.Select

  Dim lCor As Long: lCor = rRng.Rows.Count
  Do While WorksheetFunction.CountA(tmpRng.Offset(lCor)) = 0
    lCor = lCor + 1
    If lCor > rRng.Rows.Count + 2 Then
      Exit Do
    End If
  Loop
  If lCor <= rRng.Rows.Count + 2 Then
    Set rRng = rRng.Resize(lCor + 1)
  End If
  'rRng.Select
   CorrectForTotalRow = rRng
End Function

Comments

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.