I've been working on this for longer than I'd like to admit. I'm comparing two Worksheets (A & B). I'm looping through A-Column("B") and for each value in that column I'm checking it against B-Column("C"). If there's a match, I want to delete the entire row.
I've done it a number of different ways and I just can't get it to work. This is the original:
Option Explicit
Sub Purge()
Dim wipWS As Worksheet
Dim invWS As Worksheet
Dim C As Range
Dim SourceLastRow As Long
Dim DestLastRow As Long
Dim LRow As Long
Dim D As Range
Set wipWS = Worksheets("Work in Process")
Set invWS = Worksheets("Inventory Allocation")
With wipWS
' find last row in Work in Process Column B
SourceLastRow = .Cells(.Rows.count, "E").End(xlUp).Row
' find last row in Inventory Allocation Column C
DestLastRow = invWS.Cells(invWS.Rows.count, "B").End(xlUp).Row
' define the searched range in "Inventory Allocation" sheet
Set C = invWS.Range("B1:B" & DestLastRow)
Set D = wipWS.Range("E1:E" & SourceLastRow)
' allways loop backwards when deleting rows or columns
' choose 1 of the 2 For loops below, according to where you want to delete
' the matching records
' --- according to PO request delete the row in Column B Sheet A
' and the row in Column C in "Inventory Allocation" worksheet
' I am looping until row 3 looking at the PO original code
For LRow = SourceLastRow To 1 Step -1
' found a match between Column B and Column C
If Not IsError(Application.Match(.Cells(LRow, "E"), C, 0)) Then
.Cells(LRow, 2).EntireRow.Delete Shift:=xlUp
invWS.Cells(Application.Match(.Cells(LRow, "E"), C, 0), 2).EntireRow.Delete Shift:=xlUp
End If
Next LRow
End With
End Sub
It works, except it leaves 1 row left (that should be deleted). I think I know why it's happening, except I have no idea of how to do it. I've tried a For loop and it works, except I have to set a range (eg., "A1:A200") and I want it to only loop through based on the number of rows.
Any help would be greatly appreciated!
Instead of running 2 loops, you can run 1 For loop in yout Worksheets("Work in Process"), scanning Column B, and then just use the Match function to search for that value in the entire C range - which is Set to Worksheets("Inventory Allocation") at Column C (untill last row that has data).
Note: when deleting rows, allways use a backward loop (For loop counting backwards).
Code
Option Explicit
Sub Purge()
Dim wipWS As Worksheet
Dim invWS As Worksheet
Dim C As Range
Dim SourceLastRow As Long
Dim DestLastRow As Long
Dim LRow As Long
Set wipWS = Worksheets("Work in Process")
Set invWS = Worksheets("Inventory Allocation")
With wipWS
' find last row in Sheet A Column B
SourceLastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
' find last row in Sheet B Column C
DestLastRow = invWS.Cells(invWS.Rows.Count, "C").End(xlUp).Row
' define the searched range in "Inventory Allocation" sheet
Set C = invWS.Range("C1:C" & DestLastRow)
' allways loop backwards when deleting rows or columns
' choose 1 of the 2 For loops below, according to where you want to delete
' the matching records
' --- according to PO request delete the row in Column B Sheet A
' and the row in Column C in "Inventory Allocation" worksheet
' I am looping until row 3 looking at the PO original code
For LRow = SourceLastRow To 3 Step -1
' found a match between Column B and Column C
If Not IsError(Application.Match(.Cells(LRow, "B"), C, 0)) Then
.Cells(LRow, 2).EntireRow.Delete Shift:=xlUp
invWS.Cells(Application.Match(.Cells(LRow, "B"), C, 0), 3).EntireRow.Delete Shift:=xlUp
End If
Next LRow
End With
End Sub
You are comparing two Worksheets (A & B). You want to loop through A-Column("B") and for each value in that column, check against B-Column("C").
So you can have a counter (ie. bRow) to keep track of which row you are looking at in worksheet B
Dim cell as Range
Dim bRow as Integer
bRow = 1
With Worksheets("A")
For Each cell in Range(.Range("B1"), .Range("B1").End(xlDown))
If (cell.Value = Worksheets("B").Range("C" & bRow).Value0 Then
cell.EntireRow.Delete Shift:=xlUp
Worksheets("B").Range("C" & bRow).EntireRow.Delete Shift:=xlUp
Else
bRow = bRow + 1
End If
Next cell
End WIth
So I finally figured this out. It's not pretty and I'm sure there is a more elegant way of doing this, but here it is.
Option Explicit
Public Sub purWIP()
Dim wipWS As Worksheet
Dim invWS As Worksheet
Dim P As Range
Dim i As Integer, x As Integer
Set wipWS = Worksheets("Work in Process")
Set invWS = Worksheets("Inventory Allocation")
' Start by checking conditions of a certain row
For x = wipWS.UsedRange.Rows.count To 1 Step -1
With wipWS
' For each cell in wipWS I'm going to check whether a certain condition exists
For Each P In wipWS.Range(.Cells(6, 5), .Cells(wipWS.Rows.count, 5).End(xlUp))
'If it does, then I'm going to check the Inventory Allocation Worksheet to see if there's a match
If (IsDate(P.Offset(0, 7))) Then
invWS.Activate
' I do a for loop here and add 1 to i (this was the part that fixed it)
For i = invWS.UsedRange.Rows.count + 1 To 3 Step -1
If invWS.Cells(i, "B") = P.Offset(0, 0) Then
invWS.Rows(i).EntireRow.Delete Shift:=xlUp
End If
Next
P.EntireRow.Delete Shift:=xlUp
End If
Next
End With
Next
wipWS.Activate
End Sub
Related
I have a excel which has multiple rows and columns and range of column values differ for each row.
Need a macro which will delete all cells in a row except first and last in each row and paste the last value next to first value.
Tried the below script:
Sub test()
Dim sh As Worksheet
Dim IDS As range
Dim ID As range
Set sh = ThisWorkbook.Sheets("Sheet1")
Set IDS = ActiveSheet.range("A2", range("A1").End(xlDown))
For Each ID In IDS
Dim b As Integer
Dim k As Integer
k = sh.range("ID", sh.range("ID").End(xlToRight)).Columns.Count
b = k - 1
range(ID.Offset(0, 0), ID.Offset(0, "b")).Select
Selection.ClearContents
Next ID
End Sub
This is a little different approach but should help.
Also, it is generally not best to declare variables in a loop as you do with b & k just fyi
Sub test()
Dim sh As Worksheet
Dim row As Integer
Dim lastCol As Integer
Set sh = ThisWorkbook.Sheets("Sheet1")
For row = 2 To sh.Cells(Sheets(1).Rows.Count, "A").End(xlUp).row
lastCol = sh.Cells(row, Columns.Count).End(xlToLeft).Column
sh.Range("B" & row).Value = sh.Cells(row, lastCol).Value
sh.Range(sh.Cells(row, 3), sh.Cells(row, lastCol)).ClearContents
Next
End Sub
Best of luck
I'd go as follows:
Sub test()
Dim cell As Range
With ThisWorkbook.Sheets("Sheet1") ' reference relevant sheet
For Each cell In .Range("A2", .Cells(.Rows.Count, "A").End(xlUp)) ' loop through referenced sheet column A cells from row 2 down to last not empty one
With .Range(cell, .Cells(cell.Row, .Columns.Count).End(xlToLeft)) ' reference referenced sheet range spanning from current cell to last not empty one in the same row
If .Count > 2 Then ' if referenced range has more then 2 cells
cell.Offset(, 1).Value = .Cells(1, .Count).Value ' store last cell value next to the current one
.Offset(, 2).Resize(, .Columns.Count - 1).ClearContents 'clear all cells right of current one
End If
End With
Next
End With
End Sub
You can use Range.Delete Method (Excel)
range(ID.Offset(0, 0), ID.Offset(0, b)).Delete Shift:=xlToLeft
I'm not sure where I'm going wrong. I'm trying to compare values within a column ("B") to a cell referenced to ("A1"). If the values in Column "B" equal "A1" I want it to count up. When it gets to the end of Column "B" I'm trying to get it to loop back and compare values in column "B" with "A2", etc. For example:
So Far I've written two different codes one with a nested do while loop and a nested do while if loop but i cant get them to loop through the whole column
Sub CountDb()
Dim i As Long
Dim iRow As Long
Dim initial As Long
i = 1
iRow = 1
initial = 1
Do While Cells(iRow, "A").Value <> "" 'initial loop, whilst there are values in cell "A" continue the loop
Do While Cells(i, "B").Value = Cells(iRow, "A").Value 'nested while loop, comparing the first B1 and cell A1.
If True Then Cells(i, "C") = initial 'if they A1 and B1 are equal, print 1 in column C
initial = initial + 1 'and move on comparing A1 with B2
If False Then
i = i + 1 'if not satisfied, move on to cell B2 etc.
Loop
iRow = iRow + 1 'when you get to the end of column B, start again and compare values with A2 and B
Loop
End Sub
Sub CountDb()
Dim i As Long
Dim iRow As Long
Dim initial As Long
'same comments as above, just different methodology
i = 1
iRow = 1
initial = 1
Do While Cells(iRow, "A").Value <> ""
If Cells(i, "B").Value = Cells(iRow, "A").Value Then
Cells(i, "C") = initial
Else
initial = initial + 1
i = i + 1
End If
iRow = iRow + 1
Loop
End Sub
Any help would be appreciated. Thanks!
*EDIT - fixed up column references
**EDIT - applied comments to code
Try this instead:
Option Explicit
Sub test()
Dim sht As Worksheet
Dim lastrow As Long, i as integer, j as integer, initial as integer
Set sht = Workbooks("Book1").Worksheets("Sheet1") 'Don't forget to change this
lastrow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
For i = 1 To lastrow
initial = 1
lastrow = sht.Cells(sht.Rows.Count, "B").End(xlUp).Row
For j = 1 To lastrow
If Workbooks("Book1").Worksheets("Sheet1").Range("A" & i).Value = Workbooks("Book1").Worksheets("Sheet1").Range("B" & j).Value Then
Workbooks("Book1").Worksheets("Sheet1").Range("C" & j).Value = initial
initial = initial + 1
End If
Next j
Next i
End Sub
I prefer using For loops as opposed to Whiles, just because I can see the ranges being looped through more easily. Here we use nested For loops, the first to loop through column A, the second to loop through column B. If our value in column A equals our value in column B, we place the initial number in column C using our variable from the nested loop.
Notice how to make this work, we re-initialize our lastrow variable to make the ranges for our loops.
It is useful to use countif.
Sub test()
Dim rngOrg As Range, rngDB As Range
Dim Wf As WorksheetFunction
Dim vR() As Variant
Dim i As Long, n As Long
Set Wf = WorksheetFunction
Set rngOrg = Range("a1", Range("a" & Rows.Count).End(xlUp))
Set rngDB = Range("b1", Range("b" & Rows.Count).End(xlUp))
n = rngDB.Rows.Count
ReDim vR(1 To n, 1 To 1)
For Each Rng In rngDB
i = i + 1
If Wf.CountIf(rngOrg, Rng) Then
vR(i, 1) = Wf.CountIf(Range("b1", Rng), Rng)
End If
Next Rng
Range("c1").Resize(n) = vR
End Sub
Here is another method, this time using Find. This is probably quicker than the looping method since it leverages the in-built find function to skip to the next match.
I've commented the code below for clarity, but basically we loop through values in column A (using a For loop because they're less prone to disguised infinite looping than While) and look for them in column B.
Note: This looks a bit longer, but that's mainly because (a) I've added lots of comments and (b) I've used a With statement to ensure the ranges are fully qualified.
Sub countdb()
Dim c As Range, fnd As Range, listrng As Range, cnt As Long, addr As String
' Use with so that our ranges are fully qualified
With ThisWorkbook.Sheets("Sheet1")
' Define the range to look up in (column B in this case)
Set listrng = .Range("B1", .Range("B1").End(xlDown))
' Loop over values in the index range (column
For Each c In .Range("A1", .Range("A1").End(xlDown))
cnt = 0
' Try and find the c value
Set fnd = listrng.Find(what:=c.Value, lookat:=xlWhole, LookIn:=xlValues, after:=listrng.Cells(listrng.Cells.Count))
If Not fnd Is Nothing Then
' Store the address of the first find so we can stop when we find it again!
addr = fnd.Address
' Loop over all other matches in the range. By using a "Do ... Loop While"
' style loop, we ensure that the loop is run at least once!
Do
' Increase count and assign value to next column
cnt = cnt + 1
fnd.Offset(0, 1).Value = cnt
' Find next match after current
Set fnd = listrng.Find(what:=c.Value, lookat:=xlWhole, LookIn:=xlValues, after:=fnd)
Loop While fnd.Address <> addr
End If
Next c
End With
End Sub
The trick is in making the declarations transparent. After that the programming is very easy.
Sub CountMatches()
Dim Rng As Range ' "count" range (= column "B")
Dim Itm As String ' item from the "items' column (= "A")
Dim Rla As Long, Rlb As Long ' last row in columns A and B
Dim Ra As Long, Rb As Long ' row counters
Dim Counter As Long ' count matches
With ActiveSheet
' look for the last used rows
Rla = .Cells(.Rows.Count, "A").End(xlUp).Row
Rlb = .Cells(.Rows.Count, "B").End(xlUp).Row
' start looking for matches from row 2
Set Rng = .Range(.Cells(2, "B"), .Cells(Rlb, "B"))
' start looping in row 2
For Ra = 2 To Rla
Itm = .Cells(Ra, "A").Value
If Len(Trim(Itm)) Then ' skip if blank
' start comparing from row 2
For Rb = 2 To Rlb
' compare not case sensitive
If StrComp(.Cells(Rb, "B").Value, Itm, vbTextCompare) = 0 Then
Counter = Counter + 1
End If
Next Rb
.Cells(Ra, "C").Value = Counter
Counter = 0
End If
Next Ra
End With
End Sub
Now the question is whether the transparency that workred for me appears transparent to you. I hope it does. :-)
This should be significantly faster.
Sub CountMatches_2()
Dim Rng As Range ' "count" range (= column "B")
Dim Itm As String ' item from the "items' column (= "A")
Dim Rla As Long, Rlb As Long ' last row in columns A and B
Dim Ra As Long, Rb As Long ' row counters
With ActiveSheet
' look for the last used rows
Rla = .Cells(.Rows.Count, "A").End(xlUp).Row
Rlb = .Cells(.Rows.Count, "B").End(xlUp).Row
' start looking for matches from row 2
Set Rng = .Range(.Cells(2, "B"), .Cells(Rlb, "B"))
' start looping in row 2
For Ra = 2 To Rla
Itm = .Cells(Ra, "A").Value
If Len(Trim(Itm)) Then ' skip if blank
.Cells(Ra, "C").Value = Application.CountIf(Rng, Itm)
End If
Next Ra
End With
End Sub
This code presumes that each item in column A is unique. If it is not duplicates will be created which, however, it would be easy to eliminate either before or after they are created.
I have a worksheet, that I need to move the row, if the value on the last column is equal to false.
I don't know how to move to sheet 2 and make go through entire sheet.
Thank for the help.
Sub DeleteMatches2()
Dim a As Range, b As Range
Dim c As String
'The column that has the value is V2
With Sheets("Controle Estoque Fixo")
Set a = .Range(.Cells(2, "V"), .Cells(Rows.Count, "V").End(xlUp))
End With
For Each b In a
If b.Value = "False" Then
Sheets("Sheet1").Select
'know I am lost
End If
Next
End Sub
There are many ways to do this, the simplest is to keep a row counter, which tracks how many rows you've used on on the other sheet. Increment this counter by one each time. Lets assume you have column headers on sheet1, so the first available row is row 2:
Sub DeleteMatches2()
Dim a As Range, b As Range
Dim c As String
Dim rowCounter As Long
rowCounter = 2 ' start at row 2
'The column that has the value is V2
With Sheets("Controle Estoque Fixo")
Set a = .Range(.Cells(2, "V"), .Cells(Rows.Count, "V").End(xlUp))
End With
For Each b In a
If b.Value = "False" Then
'Sheets("Sheet1").Select ' you don't need to select an object to access it, so remove this
'here's the bit you need
Sheets("Controle Estoque Fixo").Rows(b.row).Cut Sheets("Sheet1").Rows(rowCounter) ' this cuts and pastes all in one line
' you use the row counter to specify the destination
rowCounter = rowCounter + 1 ' the next time you'll paste on the next row
End If
Next
End Sub
As people have commented there are many many many ways to do this so have a good look on Stack Overflow, something else might appeal to you.
I've been working on a Macro that i need to copy, concatenate what has been selected through the counter. e.g. is below
excel snapshot example
so what i want to do is set a count in column c from 1 to "infinite" because each worksheet varies to go up to 10 or hundreds and when the counter hits a value of 1 again to stop concatenate column D what is in the range from 1 to "the last digit it stopped before hitting 1 again" and paste it on a different sheet. I know little to nothing on VBA but I understand the copy and paste to different sheet part. I'm just stuck on the counter and the concatenate part. Here is the code i have so far(i edited it to resemble the example for better reference)
'select counter/concatenate
Sheets(1).Select
Columns("C").EntireColumn
Do
Columns("C").Count
For i = 1 To 9999
Loop While (i <= 1)
If i = 1 Then
select.columns("D")
after the count is where i am stuck. this count is what I've come up with looking at different variations of counters.
I suggest you Forget about column and use just one cell for easier understanding. A cell is a reference that allows you to refer to any other cells on the sheet by using Offsets. You may use two Loops, the outer one crawling the columns, the inner one working downward until it finds 1
Dim i As Long ' note that in VBA integer Overflows at 65535 rows
Dim s As String
Set aCell = Worksheet("Sheet1").Range("D1")
While aCell.Column < 255
i = 0
s = ""
While Not aCell.Offset(i, 0).Value = 1
s = s & aCell.Offset(1, 0).Value
Wend
' paste s somewhere by using range.value = s
Set aCell = aCell.Offset(0, 1)
Wend
By specifying the workbook and worksheet before the range, you may refer to the proper cell without being dependent on the active worksheet or range.
Hope this works for you.
You can try this (not tested):
Dim s As String, firstAddr as String
Dim f as range, iniCell As Range
With Worksheet("MySheet") '<--| change "MySheet" to your actual sheet name
With .Range("C1", .Cells(.Rows.Count, 3).End(xlUp))
Set f = .Find(What:=1, LookAt:=xlWhole, LookIn:=xlValues, After:=.Cells(.Rows.Count, 1))
If Not f Is Nothing Then
firstAddr = f.Address
Set iniCell = f
Set f = FindNext(f)
Do While f.Address <> firstAddr
s = s & Join(Range(iniCell, f.Offset(-1)).Offset(, 1), "")
' here code to paste s somewhere
Set iniCell = f
Set f = FindNext(f)
Loop
End If
End With
End With
Here's one I actually tested, using some random data in columns C and D.
You'll have to modify a little to get exactly where you want the data to go, but should get you in the right direction.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim i As Long
Dim s As String
Dim lastRow As Long
Dim c As Integer
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws2 = ThisWorkbook.Sheets("Sheet2")
lastRow = ws1.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
'This will get an accurate last row
c = 1
For i = 1 To lastRow
s = s & ws1.Cells(i, 4).Value 'Build the string
If ws1.Cells(i + 1, 3).Value = 1 Or ws1.Cells(i + 1, 3).Value = "" Then
ws2.Cells(c, 1).Value = s
s = ""
c = c + 1
'If the next cell to check is 1 or blank, then copy the values to the next cell in order on sheet2
End If
Next
End Sub
Walking through it, lastRow is set using the last row in the sheet with a value in it. Then, c is set to one, although you could set this to the last available row in ws2 using the same process. After that it just steps through the rows from 1 To LastRow building strings and transferring the value to ws2 when it's about to hit a 1.
This is my first time to code in VBA.
I have several worksheets in a file and they are in order by dates.
So what I am trying to do is to collect data sets in a worksheet if they have the same period of time.
date1 value1
date2 value2
date3 value3
Since they are in order I just compare the first date values and if they are different it moves on to the next worksheet. If they are the same then copy the value and do the same process until it reaches the last worksheet.
However it copies one worksheet fine but after that Excel freezes.
I would be appreciated if you find any errors or give me other suggestions to do it.
Following is my code:
Sub matchingStock()
Dim sh1 As Worksheet, sh2 As Worksheet
' create short references to sheets
' inside the Sheets() use either the tab number or name
Set sh1 = Sheets("combined")
Dim col As Long
'since first column is for Tbill it stock price should place from the third column
col = 3
Dim k As Long
'go through all the stock worksheets
For k = Sheets("WLT").Index To Sheets("ARNA").Index
Set sh2 = Sheets(k)
' Create iterators
Dim i As Long, j As Long
' Create last rows values for the columns you will be comparing
Dim lr1 As Long, lr2 As Long
' create a reference variable to the next available row
Dim nxtRow As Long
' Create ranges to easily reference data
Dim rng1 As Range, rng2 As Range
' Assign values to variables
lr1 = sh1.Range("A" & Rows.Count).End(xlUp).Row
lr2 = sh2.Range("A" & Rows.Count).End(xlUp).Row
If sh1.Range("A3").Value = sh2.Range("A3").Value Then
Application.ScreenUpdating = False
' Loop through column A on sheet1
For i = 2 To lr1
Set rng1 = sh1.Range("A" & i)
' Loop through column A on sheet1
For j = 2 To lr2
Set rng2 = sh2.Range("A" & j)
' compare the words in column a on sheet1 with the words in column on sheet2
'Dim date1 As Date
'Dim date2 As Date
'date1 = TimeValue(sh1.Range("A3"))
'date2 = TimeValue(sh2.Range("A3"))
sh1.Cells(1, col).Value = sh2.Range("A1").Value
' find next empty row
nxtRow = sh1.Cells(Rows.Count, col).End(xlUp).Row + 1
' copy the word in column A on sheet2 to the next available row in sheet1
' copy the value ( offset(0,1) Column B ) to the next available row in sheet1
sh1.Cells(nxtRow, col).Value = rng2.Offset(0, 6).Value
'when the date is different skip to the next worksheet
Set rng2 = Nothing
Next j
Set rng1 = Nothing
Next i
'sh3.Rows("1:1").Delete
Else
GoTo Skip
End If
Skip:
col = col + 1
Next k
End Sub
I cannot identify a specific error so this is a list of suggestions that may help you identify the error and may help improve your code.
Suggestion 1
Do you think the Else block of If-Then-Else-End-If is compulsory?
If sh1.Range("A3").Value = sh2.Range("A3").Value Then
:
Else
GoTo Skip
End If
Skip:
is the same as:
If sh1.Range("A3").Value = sh2.Range("A3").Value Then
:
End If
Suggestion 2
I do not like:
For k = Sheets("WLT").Index To Sheets("ARNA").Index
The value of property Index for a worksheet may not what you think it is. This may not give you the set or sequence of worksheets you expect. Do you want every worksheet except "Combined"? The following should be more reliable:
For k = 1 To Worksheets.Count
If Worksheets(k).Name <> sh1.Name Then
:
End If
Next
Suggestion 3
You use:
.Range("A" & Rows.Count)
.Range("A3")
.Cells(1, col).Value
.Cells(Rows.Count, col)
rng2.Offset(0, 6)
All these methods of identifying a cell or a range have their purposes. However, I find it confusing to use more than one at a time. I find .Cells(row, column) and .Range(.Cells(row1, column1), .Cells(row2, column2)) to be the most versatile and use them unless there is a powerful reason to use one of the other methods.
Suggestion 4
I cannot decypher what this code is attempting to achieve.
You say: "I have several worksheets in a file and they are in order by dates. So what I am trying to do is to collect data sets in a worksheet if they have the same period of time."
If you have set Worksheet("combined").Range("A3").Value to a particular date and you want to collect data from all those sheets with the same value in cell A3 then the outer For-Loop and the If give this effect. But if so, if does not matter how the worksheets are ordered. Also you start checking cell values from row 2 which suggests row 3 is a regular data row.
The outer loop is for each worksheet, the next loop is for each row in "combined" and the inner loop is for each row in the worksheet selected by the outer loop. The middle loop does not appear to do anything but set rng1 which is not used.
Perhaps you can add an explanation of what you are trying to achieve.
Suggestion 5
Are you trying to add an entire column of values from the source worksheets to "Combined". The macro below:
Identifies the next free row in column A of "Combined"
Identifies the last used row in column A of "Sheet2"
Assumes the first interesting row of "Sheet2" is 2.
Adds the entire used range of column A of "Sheet2" (complete with formatting) to the end of "Combined"'s column A in a single statement.
This may demonstrate a better way of achieving the effect you seek.
Sub Test()
Dim RngSrc As Range
Dim RngDest As Range
Dim RowCombNext As Long
Dim RowSrcFirst As Long
Dim RowSrcLast As Long
With Worksheets("Combined")
RowCombNext = .Cells(Rows.Count, "A").End(xlUp).Row + 1
Set RngDest = .Cells(RowCombNext, "A")
End With
With Worksheets("Sheet2")
RowSrcFirst = 2
RowSrcLast = .Cells(Rows.Count, "A").End(xlUp).Row
Set RngSrc = .Range(.Cells(RowSrcFirst, "A"), .Cells(RowSrcLast, "A"))
End With
RngSrc.Copy Destination:=RngDest
End Sub