Loop the code till the cell is empty in excel - excel

I stuck with this problem:
I have this code and it works but I struggle now.
I want the loop this whole code till in Table1 the cell D1 is empty.
Sub strule()
Dim myCellRange As Range
Worksheets("Table1").Select
Code = Range("D1")
Wert = Range("E10")
Worksheets("Table2").Select
Worksheets("Table2").Range("A1").Select
lMaxRows = Cells(Rows.Count, "A").End(xlUp).Row
Range("A" & lMaxRows).Select
ActiveCell.Offset(1, 0).Select
ActiveCell.Value = Code
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = Wert
Sheets("Table1").Select '
Rows("1:10").Select
Selection.Cut
Application.CutCopyMode = False
Selection.Delete Shift:=xlUp
End Sub

I've had a guess at what you want... could be completely wrong though.
First of all your original code with all the selecting & activating removed:
Sub strule()
Dim WrkSht1 As Worksheet
Set WrkSht1 = Worksheets("Table1")
'Worksheets("Table1").Select
Dim Code As String
Code = WrkSht1.Range("D1")
Dim Wert As String
Wert = WrkSht1.Range("E10")
Dim WrkSht2 As Worksheet
Set WrkSht2 = Worksheets("Table2")
'Worksheets("Table2").Select
'Worksheets("Table2").Range("A1").Select
Dim lMaxRows As Long
lMaxRows = WrkSht2.Cells(Rows.Count, "A").End(xlUp).Row
WrkSht2.Cells(lMaxRows + 1, 1) = Code 'Lastrow+1 in column A.
WrkSht2.Cells(lMaxRows + 1, 2) = Wert 'Lastrow+1 in column B.
'Range("A" & lMaxRows).Select
'ActiveCell.Offset(1, 0).Select
'ActiveCell.Value = Code
'ActiveCell.Offset(0, 1).Select
'ActiveCell.Value = Wert
WrkSht1.Rows("1:10").Delete shift:=xlUp
'Sheets("Table1").Select '
'Rows("1:10").Select
'Selection.Cut
'Application.CutCopyMode = False
'Selection.Delete Shift:=xlUp
End Sub
Now what I think you want:
Sub strule1()
Dim WrkSht1 As Worksheet
Set WrkSht1 = Worksheets("Table1")
Dim WrkSht2 As Worksheet
Set WrkSht2 = Worksheets("Table2")
Dim lLastRow1 As Long
lLastRow1 = WrkSht1.Cells(Rows.Count, "A").End(xlUp).Row
Dim x As Long
Dim lLastRow2 As Long
Dim Code As String
Dim Wert As String
For x = 1 To lLastRow1 Step 10
Code = WrkSht1.Cells(x, 4) 'Loop 1 grabs from row 1, loop 2 from row 11
Wert = WrkSht1.Cells(x + 9, 5) 'Loop 1 grabs from row 10, loop 2 from row 20
lLastRow2 = WrkSht2.Cells(Rows.Count, "A").End(xlUp).Row
WrkSht2.Cells(lLastRow2 + 1, 1) = Code 'Lastrow+1 in column A.
WrkSht2.Cells(lLastRow2 + 1, 2) = Wert 'Lastrow+1 in column B.
Next x
WrkSht1.Rows("1:" & x).Delete shift:=xlUp
End Sub

Related

How to run a loop through filtered list in excel

i am trying to run this loop/code through a filtered list in excel where the row numbers are not in sequence eg the first row that meets the filtered criteria could be row 3, followed by row 7 then row 34 for instance.
this is my current code which runs for every row in the stated range but it will not work through for filtered list. How would you modify the code such that this loop can run through a filtered list?
Sub specialloop()
Dim i As Integer
Dim j As Integer
Dim input_var As String
lastrow = Cells(Rows.Count, 1).End(xlUp).row
rowinput = InputBox("input row number to start from")
j = rowinput
For i = j To lastrow
Cells(i, 26).Select
input_var = InputBox("degree verify")
ActiveCell.Value = UCase(input_var)
ActiveCell.Offset(0, 8).Select
input_var = InputBox("med invoice date")
ActiveCell.Value = UCase(input_var)
ActiveCell.Offset(0, 1).Select
input_var = InputBox("med clear")
ActiveCell.Value = UCase(input_var)
ActiveCell.Offset(1, -9).Select
Next i
End Sub
The quick and dirty way would just be to add a condition in your loop for the RowHeight. If that is 0 then the row is filtered.
For i = j To lastRow
If ActiveSheet.Rows(i).RowHeight > 0 Then
Cells(i, 26).Select
input_var = InputBox("degree verify")
ActiveCell.Value = UCase(input_var)
ActiveCell.Offset(0, 8).Select
input_var = InputBox("med invoice date")
ActiveCell.Value = UCase(input_var)
ActiveCell.Offset(0, 1).Select
input_var = InputBox("med clear")
ActiveCell.Value = UCase(input_var)
ActiveCell.Offset(1, -9).Select
End If
Next i
You might want to look at how-to-avoid-using-select-in-excel-vba
How to iterate over visible data
For this purpose you can use Range.SpecialCells method:
Sub SpecialLoop()
' Loop over visible cells in Data range
' and fill in some data (see Shift... constants below)
Dim Data as Range
Dim Cell as Range
Dim FirstRow as Long, LastRow as Long
Dim input_var As String
Const ShiftDegree = 25
Const ShiftInvoice = ShiftDegree + 8
Const ShiftMedClear = ShiftInvoice + 1
With ActiveSheet
FirstRow = InputBox("input row number to start from")
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
Set Data = .Range(.Cells(FirstRow, 1), .Cells(LastRow, 1))
End With
For Each Cell in Data.SpecialCells(xlCellTypeVisible)
input_var = InputBox("degree verify")
Cell.Offset(0, ShiftDegree).Value = UCase(input_var)
input_var = InputBox("med invoice date")
Cell.Offset(0, ShiftInvoice).Value = UCase(input_var)
input_var = InputBox("med clear")
Cell.Offset(0, ShiftMedClear).Value = UCase(input_var)
Next Cell
End Sub
Notes
Row numbers should be Long, not Integer
Here I assume that meaningful filtered data are collected in the first column
Try if not Cells(i, 26).EntireRow.Hidden then ... as an alternative

Function.Match in a Loop

I am trying to match a value from a cell (grid_2.range "A1") and grid_2.range("B1") with a column P on a sheet named grid_2 ("Grid2") to copy all the row where there value is located. Therefore, I will need to check on my data and copy/paste the entire row to another sheet maned grid. But for some reason my code loops but only find the match and copy and paste once.
Sub new_copyPaste()
Dim targetSh As Worksheet
Dim i As Variant
Dim lastRow As Long
lastRow = grid.Cells(Rows.Count, "C").End(xlUp).Row + 1
For i = 3 To grid_2.Cells(Rows.Count, "P").End(xlUp).Row
Position = WorksheetFunction.Match(grid_2.Range("A1"), Worksheets("Grid2").Columns(16), 0)
If grid_2.Cells(i, 16).Value = grid_2.Range("A1") Then
Worksheets("Grid2").Rows(Position).Copy
grid.Range("A" & lastRow).PasteSpecial
End If
Next i
For i = 3 To grid_2.Cells(Rows.Count, "P").End(xlUp).Row
Position = WorksheetFunction.Match(grid_2.Range("B1"), Worksheets("Grid2").Columns(16), 0)
If grid_2.Cells(i, 16).Value = grid_2.Range("B1") Then
Worksheets("Grid2").Rows(Position).Copy
grid.Range("A" & lastRow).PasteSpecial
End If
Next i
End Sub
Maybe do you know what I am doing wrong?
I thought about using VLookup, but after researching, it seems that function match would be more appropriate.
I am open for suggestions :)
Match only returns the first match and is not needed here:
Sub new_copyPaste()
Dim lastRow As Long
Dim i As Long
For i = 3 To grid_2.Cells(Rows.Count, "P").End(xlUp).Row
If grid_2.Cells(i, 16).Value = grid_2.Range("A1") Then
Worksheets("Grid2").Rows(i).Copy
lastRow = grid.Cells(Rows.Count, "C").End(xlUp).Row + 1
grid.Range("A" & lastRow).PasteSpecial
End If
Next i
For i = 3 To grid_2.Cells(Rows.Count, "P").End(xlUp).Row
If grid_2.Cells(i, 16).Value = grid_2.Range("B1") Then
Worksheets("Grid2").Rows(i).Copy
lastRow = grid.Cells(Rows.Count, "C").End(xlUp).Row + 1
grid.Range("A" & lastRow).PasteSpecial
End If
Next i
End Sub

Search column headers and insert new column if header does not already exist using Excel VBA

I have a spreadsheet that is updated regularly. The user will update two columns on sheet(create) with container type (this is the header name) and the quantity, which will be transferred to sheet(Tracking). I am trying to figure out how to search sheet2(Tracking for existing headers (container types), if found then quantity will be updated within that column for the next available row. If header is not found, therefore a new column is added to the right with that new header name, as well as updating the quantity.
I did find some good example such as the below. However not sure how to apply it. Maybe there could be a way to loop it to search the headers.
Sub TrackR()
Dim cl As Range
For Each cl In Range("1:1")
If cl = sheets(“Create”).range(“J11:J36”) Then
cl.EntireColumn.Insert Shift:=xlToRight
End If
cl.Offset(0, 1) = "New Conatainer Name"
Next cl
Application.ScreenUpdating = False
Sheets("Tracking").Range("A" & Rows.Count).End(xlUp).Offset(1, 0) = Date
'Trailer No.
Sheets("Create").Range("L8").Copy
Sheets("Tracking").Range("B" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
'total container qty
Sheets("Create").Range("G43").Copy
Sheets("Tracking").Range("D" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
'Supplier
Sheets("Create").Range("K4").Copy
Sheets("Tracking").Range("C" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
'quantities
Sheets("Create").Range("L11").Copy
Sheets("Tracking").Range("E" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
Sheets("Create").Range("L12").Copy
Sheets("Tracking").Range("F" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
Sheets("Create").Range("L13").Copy
Sheets("Tracking").Range("G" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
Sheets("Create").Range("L14").Copy
Sheets("Tracking").Range("H" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
Sheets("Create").Range("L15").Copy
Sheets("Tracking").Range("I" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = False
End Sub
Not sure, try this ... ~
Sub TrackB()
Dim wsCreat As Worksheet: Set wsCreat = Sheets("Create")
Dim wsTracking As Worksheet: Set wsTracking = Sheets("Tracking")
Dim cl As Range, lastHCell As Range, header As Range, i As Integer, j As Integer,k as integer, str As Variant
With wsTracking
Set header = .[a1:xx1]: Set lastHCell = header.End(xlToRight)
iLstRow = .[a10000].End(xlUp).Offset(1, 0).Row
'Update default data [A:D]
.Range("A" & iLstRow) = Date
For Each str In Array("L8", "C4", "G43")
.Cells(iLstRow, i + 2) = wsCreat.Range(str): i = i + 1
Next
'add Column if not Match
For Each cl In wsCreat.[B11:B37, E11:E37]
Dim k: k = Application.Match(cl, header, 0)
If IsError(k) And cl <> vbNullString Then _
lastHCell.Offset(0, 1).EntireColumn.Insert Shift:=xlToRight, CopyOrigin:=True: _
Set lastHCell = lastHCell.Offset(0, 1): lastHCell.Value2 = cl
Next cl
'Update input Data
i = 5
Dim arr As Variant: arr = Array("B11:B37", "E11:E37")
Dim arrResult As Variant: arrResult = Array("C10" , "F10")
Dim cell As Range: k = 0
For k = 0 To UBound(arr)
j=1
For Each cell In wsCreat.Range(arr(k)).Cells
If cell.Value2 <> vbNullString Then
.Cells(iLstRow, Application.Match(cell, header, 0)) = wsCreat.Range(arrResult(k)).Offset(j, 0)
End If
j = j + 1
Next cell
Next
End With
End Sub
Untested but something like this should work:
Sub TrackR()
Dim wsTrack As Worksheet, wsCreate As Worksheet, cont, qty, h As Range
Dim c As Range, m, rw As Range, rngHeaders As Range, col As Long
Set wsCreate = ThisWorkbook.Worksheets("Create")
Set wsTrack = ThisWorkbook.Worksheets("Track")
'get the next empty row on the Tracking sheet
Set rw = wsTrack.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).EntireRow
'fill in the common cells in the row
rw.Cells(1).Value = Date
rw.Cells(2).Value = wsCreate.Range("L8").Value
rw.Cells(3).Value = wsCreate.Range("K4").Value
rw.Cells(4).Value = wsCreate.Range("G43").Value
'now loop over the containers and add each one
Set rngHeaders = wsTrack.Cells(1, "E").Resize(1, 5000) 'or whatever would cover your data
For Each c In wsCreate.Range("J11:J36").Cells
cont = c.Value
qty = c.Offset(0, 2).Value
If Len(cont) > 0 And Len(qty) > 0 Then
m = Application.Match(cont, rngHeaders, 0) 'any existing match ?
If IsError(m) Then
'no match - find the first empty cell and add the container
Set h = rngHeaders.Cells(rngHeaders.Cells.Count).End(xlToLeft).Offset(0, 1)
h.Value = cont
col = h.Column 'column number for the added header
Else
'matched: get the column number
col = rngHeaders.Cells(m).Column
End If
rw.Cells(col).Value = qty '<< add the quantity
End If
Next c
End Sub

VBA function not calling correctly

I have the following function which finds the last row in a worksheet and am trying to call it in my Sub Submit_data(). The sub doesn't seem to recognise it and so the message box returns 0. However, if I place the exact same code in a test sub with nothing else in it it works. Anyone have any idea why this would be? note: my submit data sub is longer so I have just included the the first portion where the error occurs.
Private Function lasrow() As Long
Worksheets("Data - Complete").Select
lasrow = Cells.Find(What:="*", _
After:=Range("A1"), _
LookAt:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
End Function
Sub Submit_data()
Dim lRow As Long
Dim lCol As Long
Dim colName As Long
Dim resetrange As Range
Dim indicator As String
Dim Dire(1 To 6, 1 To 2) As String
Dim i As Integer
Dim lasrow As Long, lasCol As Long
Dim lro As Long
Dire(1, 1) = "B2": Dire(1, 2) = "D2"
Dire(2, 1) = "B3": Dire(2, 2) = "D3"
Dire(3, 1) = "B4": Dire(3, 2) = "D4"
Dire(4, 1) = "G7": Dire(4, 2) = "I7"
Dire(5, 1) = "G11": Dire(5, 2) = "I11"
Dire(6, 1) = "G13": Dire(6, 2) = "I13"
Application.ScreenUpdating = False
If IsEmpty(Range("I15")) = False Then
lro = lasrow
Worksheets("User").Select
Range("I15").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Data - Complete").Select
Cells(lro + 1, 5).Select 'problem with selecting column
ActiveSheet.Paste
Worksheets("User").Select
Range("I15").Select
Selection.ClearContents
MsgBox ("lRow is " & lro)
End If
Just to sum things up:
To fix the problem you are having you need to remove the variable declaration that has the same name as your function.
To make it even simpler you can just remove the function and have your sub like this:
Sub Submit_data()
Dim lRow As Long
Dim lCol As Long
Dim colName As Long
Dim resetrange As Range
Dim indicator As String
Dim Dire(1 To 6, 1 To 2) As String
Dim i As Integer
Dim lasCol As Long
Dim lro As Long
Dire(1, 1) = "B2": Dire(1, 2) = "D2"
Dire(2, 1) = "B3": Dire(2, 2) = "D3"
Dire(3, 1) = "B4": Dire(3, 2) = "D4"
Dire(4, 1) = "G7": Dire(4, 2) = "I7"
Dire(5, 1) = "G11": Dire(5, 2) = "I11"
Dire(6, 1) = "G13": Dire(6, 2) = "I13"
Application.ScreenUpdating = False
If IsEmpty(Range("I15")) = False Then
'Change this so find the last row without the function
'The "1" is telling it to look in column "A"
'The ActiveSheet.Rows.Count is using the maximum number of possible rows as the row which is 1048576
'So it is starting in A1048576 and going up till it finds the first non-empty row and returning that row number
lro = ActiveSheet.Cells(ActiveSheet.Rows.count, 1).End(xlUp).row
Worksheets("User").Select
Range("I15").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Data - Complete").Select
Cells(lro + 1, 5).Select 'problem with selecting column
ActiveSheet.Paste
Worksheets("User").Select
Range("I15").Select
Selection.ClearContents
MsgBox ("lRow is " & lro)
End If
and you still don't need the lasrow variable with what is showing here.

Excel macro Do While loop not compiling

Its a simple code to go to a sheet pull a row, go back to the first one sheet and paste it, then repeat until the value in column A of the inventory changes (New employee) at which point it needs to make a new worksheet to start storing the new data. And repeat until its done.
Dim i As Integer
Dim j As Integer
Set i = 2
Set j = 1
Do While i < 6
Sheets("Inventory").Select
If Cells("i,1").Value = Cells("i-1,1").Value Then
Cells("i:i").Select
Selection.Copy
Sheets("Sheetj").Select
Cells("i,1").Select
Selection.Paste
i = i + 1
Else
Sheets.Add After:=Sheets(Sheets.Count)
j = j + 1
Sheets("Inventory").Select
Cells("i:i").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheetj").Select
Range("A3").Select
ActiveSheet.Paste
i = i + 1
End If
End Sub
Add this:
Loop
Before you end the sub. The i's also shouldn't have double quote if you're referencing what the number I should be. Should be like Cells(i , 1), or Cells(i , i), I'll leave you up to fix the rest.
Sorry, misread your original post. fixed.
I would do something like this to add create new sheets for each data group.
Updated: reduced my code now your "sheetj" part is clear
code
Sub Other()
Dim rng1 As Range
Dim rng2 As Range
Dim ws As Worksheet
Set rng1 = Sheets("Inventory").Range("I2:i6")
Set ws = Sheets.Add
For Each rng2 In rng1
If rng2 <> rng2.Offset(-1, 0) Then Set ws = Sheets.Add
rng2.EntireRow.Copy ws.Rows(rng2.Row)
Next
End Sub
Sub test()
Dim i As Integer
Dim j As Integer
i = 2 ' got rid of set
j = 1 ' got rid of set
Do While i < 6
Sheets("Inventory").Select
If Cells("i,1").Value = Cells("i-1,1").Value Then
Cells("i:i").Select
Selection.Copy
Sheets("Sheetj").Select
Cells("i,1").Select
Selection.Paste
i = i + 1
Else
Sheets.Add After:=Sheets(Sheets.Count)
j = j + 1
Sheets("Inventory").Select
Cells("i:i").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheets" & j).Select ' for completeness...
Range("A3").Select
ActiveSheet.Paste
i = i + 1
End If
Loop ' missing this
End Sub
Untested, but i think you use too many selects (tried with .activate ?)
Dim i As long 'long is faster for loops
Dim j As long
i = 2 'dont need set
j = 1
Do While i < 6
with Sheets("Inventory")
If .Cells(i,1).Value = .Cells(i-1,1).Value Then 'i removed the quotes in cells
.range("i:i").Copy Sheets("Sheetj").Cells(i,1)
i = i + 1
Else
Sheets.Add After:=Sheets(Sheets.Count)
j = j + 1
.Cells("i:i").copy Sheets("Sheetj").Range("A3")
i = i + 1
End If
end with
Application.CutCopyMode = False
loop 'you forgot a ending loop

Resources