Find function skips next row - excel

I have stuck with quite odd bug(?) using Find function. For some reason, it can't find next row (n+1), although, it finds any other row in determined range.
Sub band()
Dim laik As String
Dim row1 As Integer
Dim DbSh As Worksheet
Set DbSh = ThisWorkbook.Sheets("Sheet1")
eil = 9 'row in sheet
On Error Resume Next
Do While DbSh.Cells(eil, 1).Value <> ""
laik = DbSh.Cells(eil, 3).Value
row1 = DbSh.Range("C" & eil + 1 & ":C1000").Find(laik, LookIn:=xlValues, LookAt:=xlWhole).row
If Err.Number <> 0 Then Err.Number = 0: GoTo next1
If DbSh.Cells(eil, 4).Value = DbSh.Cells(row1, 4).Value And DbSh.Cells(eil, 6).Value = DbSh.Cells(row1, 6).Value And DbSh.Cells(eil, 8).Value = DbSh.Cells(row1, 8).Value Then
DbSh.Cells(eil, 5).Value = DbSh.Cells(eil, 5).Value & ", " & DbSh.Cells(row1, 5).Value
DbSh.Range(row1 & ":" & row1).EntireRow.Delete
eil = eil - 1 'subtract, still looking for more same values
End If
next1:
eil = eil + 1
Loop
End Sub
Basically, it looks for same values of cells(eil,3) and if it meets some criteria in D, F and H columns, found row is added to "eil" row (E column) and then it is deleted. If same values in C column are next to each other (eil and eil + 1),
row1 = DbSh.Range("C" & eil + 1 & ":C1000").Find(laik, LookIn:=xlValues, LookAt:=xlWhole).row
finds the second available row (from eil+2, eil+3, etc.), skipping eil+1 row. If I remove +1 from Range("C" & eil + 1 & ":C1000"), leaving just Range("C" & eil & ":C1000"), it finds the same row.
For now, I have a workaround, but it could be cool to find out why "Find" skips the following row.

The eil = eil + 1 is always adding 1 to eil. DbSh.Range("C" & eil + 1 & ":C1000").Find is also adding 1. Put together, you are skipping over the 'next' row whenever you find something.
This should rectify the issue.
...
row1 = DbSh.Range("C" & eil & ":C1000").Find(laik, LookIn:=xlValues, LookAt:=xlWhole).row
...
fwiw, I wouold recommend skipping all that 'controlled error' and use a Find/FindNext pair.

Related

To Get only one raw of result for a particular Range

Following code is suggested by a helpful user, this works well to Calculate "From", "To", "MAX" etc values of a range. But this code gives results in every row of a range. I want to get the results in only first row of each row. Please help with this.
Sub trial()
Dim lastrow As Long
Dim destSht As Worksheet
Dim i As Long, j As Long
Set destSht = Worksheets("Final")
With Worksheets("Source")
lastrow = .Range("B" & .Rows.Count).End(xlUp).Row
For i = 2 To lastrow + 1 'loop whole range (column C)
If .Cells(i, "C") <> "" Then 'If column C is not empty then
For j = i To lastrow + 1 'Loop "group" range to find next empty cell. Start from current loop i to last row and add one row to get to next empty cell.
If .Cells(j, "C") = "" Then 'When next empty cell is found (i.e. end of small group range) then apply formulas
.Cells(i, "E").Value = .Cells(i, "B").Value 'From
.Cells(i, "F").Value = .Cells(j - 1, "B").Value 'To
.Cells(i, "G").Formula = "=MAX(C" & i & ":C" & j - 1 & ")" 'MAX
.Cells(i, "H").Formula = "=MIN(C" & i & ":C" & j - 1 & ")" 'MIN
.Cells(i, "I").Formula = "=AVERAGE(C" & i & ":C" & j - 1 & ")" 'AVG
Exit For
End If
Next j
End If
Next I
End With
End Sub
This Code gives following result
Desired Result
Try changing this line:
If .Cells(i, "C") <> "" Then 'If column C is not empty then
To this line:
If .Cells(i, "C") <> "" AND .Cells(i-1, "C") = "" Then 'If column C is not empty AND the column C above is empty then

Deleting Cells after Concatenation in VBA

I am trying to reformat a text file that has been imported into Excel.
I have done several minor reformatting points including adding rows, deleting page numbers, and combining headlines back into a single cell via the & function (the text file was delimited when importing).
After a concatenate, in which I took certain cells from columns A-Z and combined them in Column A, I tried to delete the now redundant information from Columns B-Z.
I tried selecting the cells and deleting, and also Range.Clear, but it does not delete the cells. I receive no errors.
This is what I have to take care of this step:
'Fix Duplicate Cells from Concatenate
For i = lastRow2 To 2 Step -1
If IsEmpty(Range(i, 1).Offset(-1, 0)) = True Then
ActiveSheet.Range(Cells(i, 2), Cells(i, 26)).Clear
End If
Next
Ultimately, I would like to check if column A contains no information one row above the row where I would like to delete information from columns B-Z.
Full code:
Sub Format()
'This will delete page numbers
Dim lRow As Long
Dim iCntr As Long
lRow = 350
For iCntr = lRow To 1 Step -1
If IsNumeric(Cells(iCntr, 1)) Then
Rows(iCntr).Delete
End If
Next
'Add Row above each row with Headings
Dim lRow2 As Long, iRow As Long
With Worksheets("Sheet1")
lRow2 = .Cells(.Rows.Count, "A").End(xlUp).Row ' last row in column A
'loop backwards (bottom to top = Step -1) through all rows
For iRow = lRow2 To 1 Step -1
'check if column A of current row (iRow) is "DIM"
If .Cells(iRow, "A").Value = "DIM" Then
.Rows(iRow).Resize(RowSize:=1).Insert xlShiftDown
'insert 1 row and move current (iRow) row down (xlShiftDown)
'means: insert 1 row ABOVE current row (iRow)
End If
Next iRow
End With
'Combine Headings back to single Cell
Dim lngLastRow As String
Dim lastRow As Long
Dim lastcolumn As Long
lastRow = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count
lastcolumn = ActiveSheet.UsedRange.Column - 1 + ActiveSheet.UsedRange.Columns.Count
For i = lastRow To 1 Step -1
If Cells(i, 1).Value = "DIM" Then
Cells(i, 1).Value = Cells(i, 1).Value & " " & Cells(i, 2).Value & " " & _
Cells(i, 3).Value & " " & Cells(i, 4).Value & " " & Cells(i, 5).Value & " " & _
Cells(i, 6).Value & " " & Cells(i, 7).Value & " " & Cells(i, 8).Value & " " & _
Cells(i, 9).Value & " " & Cells(i, 10).Value & " " & Cells(i, 11).Value & " " & _
Cells(i, 12).Value & " " & Cells(i, 13).Value & " " & Cells(i, 14).Value & " " & _
Cells(i, 15).Value & " " & Cells(i, 16).Value & " " & Cells(i, 17).Value & " " & _
Cells(i, 18).Value & " " & Cells(i, 19).Value & " " & Cells(i, 20).Value & " " & _
Cells(i, 21).Value & " " & Cells(i, 22).Value & " " & Cells(i, 23).Value & " " & _
Cells(i, 24).Value & " " & Cells(i, 25).Value & " " & Cells(i, 25).Value
End If
Next
'Fix Duplicate Cells from Concatenate
For i = lastRow2 To 2 Step -1
If IsEmpty(Range(i, 1).Offset(-1, 0)) = True Then
ActiveSheet.Range(Cells(i, 2), Cells(i, 26)).Clear
End If
Next
End Sub
The reason I have a condition set for the clearing of cells after concatenate is because I do not simply want to clear all cells in range B:Z, or even the specific rows in this range. I only want to clear this range in the instances where there is a blank line above it (headers to data). The reason being: I am trying to keep the spreadsheet as generic as possible in order to use it again if the specific layout of rows changes based on the input file.
First, the variable lastRow2 doesn't seem to be declared, and as you don't get any errors, you obviously don't use Option Explicit. Please do, because that will warn you about such errors.
Secondly, I don't see that you in any way initialize lastRow2, which explains why the loop is never run. Did you run the code in the debugger to verify values of variables and progress of the execution? That is the first thing to do when you see unexpected results.
Thirdly, I don't understand why you have the condition and why you use offset If IsEmpty(Range(i, 1).Offset(-1, 0)) = True. Just clear the cells explicitly
Try this instead:
lastColumn = 26
For i = lastRow To 1 Step -1
Range(Cells(i, 2), Cells(i, lastColumn)).Clear
Next
edit:
I noticed you have the last column as 25 (as well as the previous one) in the part where you concatenate the values from the cells. The correct last column is 26.
edit2:
Based on your edit of your question and assuming you have declared and initialized lastRow2 the corrected function would look like this:
For i = lastRow2 To 2 Step -1
If IsEmpty(Range(Cells(i, 1), Cells(i, 1)).Offset(-1, 0)) = True Then
ActiveSheet.Range(Cells(i, 2), Cells(i, 4)).Clear
End If
Next

Create a checkpoint in a foreach statement

I am writing a code that put an X in a cell depending on a offset cell value, for exemple if the offset cell has a value of 3, it will put an X in the cell and decrement the offset cell value, i want to save the location of that cell and start the next for each with it.
For Each Cell In plage
If (Cell.Offset(0, 1).Value <> 0) Then
If (Cell.Value <> "X") Then
Cell.Offset(0, 1).Value = Cell.Offset(0, 1).Value - 1
Cell.Value = "X"
Checkpoint = Cell.Address
Exit For
Else
Cell.Value = ""
GoTo NextStep
End If
Exit For
Else
Cell.Value = ""
End If
NextStep:
Next Cell
The problem i am having with the current code is it start the loop all over again while i want it to keep till the end of the lines, until all offset value are equal to 0.
Try the below (there are notes on the code). If you face difficulties let me know.
Option Explicit
Sub test()
'In this example we assume that the data you want to loop appear in Column A
Dim i As Long, Lastrow As Long
Dim Checkpoint As Variant
With ThisWorkbook.Worksheets("Sheet1") '<- Change sheet name if needed
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row '< -Fins the lastrow of the column you want to loop
For i = 2 To Lastrow ' < -Start looping from row 2 to Lastrow fo the column
If .Range("A" & i).Offset(0, 1).Value <> 0 Then '<- You are looping
If .Range("A" & i).Value <> "X" Then
.Range("A" & i).Offset(0, 1).Value = .Range("A" & i).Offset(0, 1).Value - 1
.Range("A" & i).Value = .Range("A" & i).Value & "X"
Checkpoint = .Range("A" & i).Address
Else
.Range("A" & i).Value = ""
End If
Else
.Range("A" & i).Value = ""
End If
Next i
End With
End Sub
Is plage a range?
If so, you could update it to start from the checkpoint and include all cells up to some lastCell for example.
Something like:
set plage=thisWorkbook.Worksheets("Your Worksheet").Range(checkpoint,lastCell)
That way the next For-Each should start from your checkpoint.
BTW if I understand correctly what you'e trying to do, I would suggest you replace cell.value="" with cell.clearContents

How to do multiple select with ActiveCell

I'm trying to make multiple selections from Sheet2. The value is from the same column but different rows (thinking if using ActiveCell.Offset(1,0) will be feasible).
My code takes the value from an ActiveCell select and runs a macro compares it to another sheet (Sheet10) with some information to copy and paste in a target sheet (Sheet5).
The following is the code that I have right now.
a = Sheet10.Cells(Rows.Count, 1).End(xlUp).Row
c = Sheet2.Cells(Rows.Count, 5).End(xlUp).Row
For Each cell In Range(ActiveCell, ActiveCell.Offset(1, 0))
For i = 2 To a 'from Row 1 to the last row of "DMP"
Debug.Print ("i = " & i)
If cell.Value = Sheet10.Cells(i, 1).Value Then 'if selected cell matches (i,1) of "Sheet10 (DMP)"
Debug.Print ("ActiveCell =" & ActiveCell.Value)
For k = 1 To 20 'from Column 1 to Column 20
Debug.Print ("k = " & k)
For r = 1 To c 'from Row 1 to the last row of "Sheet 2(LightOn SKU)"
Debug.Print ("r = " & r)
If Sheet10.Cells(i, k).Value = Sheet2.Cells(r, 4).Value Then 'if value of (i,k) of "Sheet10 (DMP)" = (r,4) of "Sheet2 (LightOn SKU)"
Sheet2.Range("A" & r & ":G" & r).Copy
Sheet5.Activate
b = Sheet5.Cells(Rows.Count, 1).End(xlUp).Row
Sheet5.Cells(b + 1, 1).Select
ActiveSheet.Paste
Range("A" & r & ":L" & r).Borders.Color = vbBlack
End If
Next
Next
End If
Next
Next
Right now, it's running on an endless loop.
Still Unclear
Sub ACCopy2()
Dim a As Long
Dim c As Long
Dim r As Long
Dim i As Long
Dim k As Integer
Dim b As Long
a = Sheet10.Cells(Rows.Count, 1).End(xlUp).Row
c = Sheet2.Cells(Rows.Count, 5).End(xlUp).Row
For r = 1 To c ' from Row 1 to the last row of "Sheet 2(LightOn SKU)"
Debug.Print ("r = " & r)
For i = 2 To a ' from Row 1 to the last row of "DMP"
Debug.Print ("i = " & i)
' if selected cell matches (i,1) of "Sheet10 (DMP)"
If Sheet2.Cells(r, 1).Value = Sheet10.Cells(i, 1).Value Then
Debug.Print ("Sheet2 =" & Sheet2.Cells(r, 1).Value)
For k = 1 To 20 ' from Column 1 to Column 20
Debug.Print ("k = " & k)
' if value of (i,k) of "Sheet10 (DMP)" = (r,4) of
' "Sheet2 (LightOn SKU)"
If Sheet10.Cells(i, k).Value = Sheet2.Cells(r, 4).Value Then
With Sheet5
b = Sheet5.Cells(Rows.Count, 1).End(xlUp).Row
Sheet2.Range("A" & r & ":G" & r).Copy .Cells(b + 1, 1)
.Range("A" & r & ":L" & r).Borders.Color = vbBlack
End With
End If
Next
End If
Next
Next
End Sub

Copy and Insert Row Based on Cell Time Value

My main problem is that I am trying to add a row directly beneath another row based on the time value of that row. Here's an example of what I'm trying to do:
column F ========> new column F
2 1
2
2 1
2
1 1
1 1
2 1
2
To better explain, if the value in the first column F is a 2, that represents a time value that is greater than 0:59:00 and another row is added beneath it. If it is a 1, then it represents a time value that is equal to or less than 0:59:00and no row gets added.
I have multiple coding attempts at fixing this, and this first one is by someone more well-versed in VBA than I and includes some of his comments:
Public Sub ExpandRecords()
Dim i As Long, _
j As Long, _
LR As Long
'set variable types
LR = Range("A" & Rows.Count).End(xlUp).Row
'setting variable LR as number of rows with data
Application.ScreenUpdating = False
Columns("F:F").NumberFormat = "hh:mm:ss"
'sets number format in column b to text
For i = LR To 1 Step -1
'Executes following code from last row with data to row 1 working backwards
'If CLng(Left(Range("F" & i).Value, Len(Range("F" & i).Value) - 6)) > 0 Then
If CLng(Hour(Range("F" & i))) > 0 Then
'If the hour value in column F is greater than 1, then...
With Range("F" & i)
'starting with column F, loop through these statements...
'.Offset(1, 0).Resize(CLng(Left(Range("F" & i).Value, Len(Range("F" & i).Value) - 6)) - 1, 1).EntireRow.Insert Shift:=xlDown
.Offset(1, 0).Resize(CLng(Hour(Range("F" & i))).Value, Len(Range("F" & i).Value) - 1, 1).EntireRow.Insert Shift:=xlDown
'return the value of column F's hour value, change the range to insert the number of rows below based on hour value
'.Resize(CLng(Left(Range("F" & i).Value, Len(Range("F" & i).Value) - 6)), 1).EntireRow.Value = Range("A" & i).EntireRow.Value
.Resize(Hour(Range("F" & i)), 1).EntireRow.Value = Range("A" & i).EntireRow.Value
'Get value of row to be copied
'For j = 0 To CLng(Left(Range("F" & i).Value, Len(Range("F" & i).Value) - 6))
For j = 0 To Hour(Range("F" & i))
Range("H" & i).Offset(j - 1, 0).Value = Application.Text(j, "0")
Next j
End With
Else
Range("H" & i).Value = Application.Text(1, "0")
End If
Next i
Application.ScreenUpdating = True
End Sub
Here is a similar question from a previous user
Any help would be greatly appreciated.
Use this instead:
Public Sub ExpandRecords()
Dim i As Long, s As String
Const COL = "F"
For i = 1 To Cells(Rows.Count, COL).End(xlUp).Row
If Cells(i, COL) = 2 Then s = s & "," & Cells(i, COL).Address
Next
If Len(s) Then
Range(Mid$(s, 2)).EntireRow.Insert
For i = 1 To Cells(Rows.Count, COL).End(xlUp).Row
If Cells(i, COL) = vbNullString Then Cells(i, COL) = 1
Next
End If
End Sub

Resources