vba for loop for 4 different column - excel

Dim I As Long
For I = 2 To lastrow
If Not IsEmpty(Cells(I, "f")) And IsEmpty(Cells(I, "j")) Then
Cells(I, "j").Value = "unregister"
End If
Next I
Dim I2 As Long
For I2 = 2 To lastrow
If IsEmpty(Cells(I2, "f")) Then
Cells(I2, "i").Value = Cells(I2 - 1, "i").Value
End If
Next I2
can you make this code more simple i want to copy above row for 3 different column if column f is empty

You can do something like this, using a single loop and Offset(-1, 0) to get the cell above:
Dim i As Long, ws As Worksheet
Set ws = ActiveSheet
For i = 2 To ws.Cells(ws.Rows.Count, "F").End(xlUp).Row
With ws.Rows(i)
If Not IsEmpty(.Columns("F")) Then
If IsEmpty(.Columns("J")) Then .Columns("J").Value = "unregister"
Else
.Columns("I").Value = .Columns("I").Offset(-1, 0).Value
.Columns("L").Value = .Columns("L").Offset(-1, 0).Value
'etc
End If
End With
Next I2

Related

Calculate the average of cells in empty cells in a column

The VBA code below calculates the Sum of cells above empty cells in a column in Excel. The number of rows preceding each empty cell in the column is in not the same. I want to adjust the code to calculate the average instead. A counter can be added and then divide the sum (which is already calculated) by the counter.
The original problem and the code (written by Bernard Liengme) are presented on the link below:
https://answers.microsoft.com/en-us/msoffice/forum/all/automatically-calculate-the-sum-of-data-separated/a691afcf-683e-463f-bad7-9fa3a81cf48c
Thanks.
Sub tryme()
lastRow = Cells(Rows.Count, "A").End(xlUp).Row
For k = 1 To lastRow
If Cells(k, "A") <> "" Then
Subtotal = Subtotal + Cells(k, "B")
Else
Cells(k, "B") = Subtotal
Subtotal = 0
End If
Next k
Cells(lastRow + 1, "B") = Subtotal
End Sub
Add Subaverages
A Quick Fix
Option Explicit
Sub AddSubAVG()
Dim ws As Worksheet: Set ws = ActiveSheet ' improve
Dim LastRow As Long: LastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Dim k As Long
Dim tCount As Long
Dim tSum As Double
For k = 1 To LastRow
If ws.Cells(k, "A").Value <> "" Then
tSum = tSum + ws.Cells(k, "B").Value
tCount = tCount + 1
Else
If tCount > 0 Then
ws.Cells(k, "B").Value = tSum / tCount
tSum = 0
tCount = 0
End If
End If
Next k
If tCount > 0 Then ws.Cells(LastRow + 1, "B").Value = tSum / tCount
End Sub

If cell value same with upper cell value

I tried to make macro for my daily job, but i cannot use IF as formula due to so many item in my excel file, so solution is to convert formula to VBA code.
I need help to convert if formula to VBA code in excel as below:
=IF(J2<>J1,AD2-X2,AE1-X2).
Here is an answer to your question. However, it is limited to only work with OP information. Also, if the calculations are taking too long then, you should try setting your calculation to Manual (Formulas->Calculation Options->Manual).
Option Explicit
Public Sub RunIF()
Dim vntOut As Variant
Dim rngSame As Range
With ActiveSheet
Set rngSave = .Range("X2")
If (LCase(Trim(.Range("J2").Value)) <> LCase(Trim(.Range("J1").Value))) Then
vntOut = .Range("AD2").Value - rngSave.Value
Else
vntOut = .Range("AE1").Value - rngSave.Value
End If
.Range("AE2").value = vntOut
Set rngSave = Nothing
End With
End Sub
And here is your code converted to use Column J:
Private Sub CommandButton12_Click()
Dim x As Long
Dim LastRow As Long
Dim i as long
With Sheets("Shipping Schedule")
LastRow = .Cells(.Rows.Count, "J").End(xlUp).Row
For i = 2 to LastRow
set r = .Range("J" & I)
'For Each r In .Range("J2:J" & LastRow)
If LCase(Trim(r.Value)) <> LCase(Trim(r.Offset(-1, 0).Value)) Then
'ae2 = "AD2" - "x2"
r.Offset(0, 21).Value = r.Offset(0, 20).Value - r.Offset(0, 14).Value
Else
'ae2 = "AE1" - "x2"
r.Offset(0, 21).Value = r.Offset(-1, 21).Value - r.Offset(0, 14).Value
End If
set r = nothing
Next i
End With
End Sub
However, you should increment with I instead of for each as the cells are dependent on the previous row and excel may not loop through the range like you would prefer.
Excel Formula to VBA: Fill Column
Sub FillColumn()
Const cCol As Variant = "J" ' Last-Row-Column Letter/Number
Const cCol1 As Variant = "AD"
Const cCol2 As Variant = "X"
Const cCol3 As Variant = "AE"
Const cFirstR As Long = 1 ' First Row
Dim rng As Range ' Last Used Cell in Last-Row-Column
Dim i As Long ' Row Counter
Set rng = Columns(cCol).Find("*", , xlFormulas, , xlByColumns, xlPrevious)
If rng Is Nothing Then Exit Sub
For i = cFirstR To rng.Row - 1
If Cells(i + 1, cCol) <> Cells(i, cCol) Then
Cells(i + 1, cCol3) = Cells(i + 1, cCol1) - Cells(i + 1, cCol2)
Else
Cells(i + 1, cCol3) = Cells(i, cCol3) - Cells(i + 1, cCol2)
End If
Next
End Sub
Private Sub CommandButton12_Click()
Dim x As Long
Dim LastRow As Long
Sheets("Shipping Schedule").Select
With Sheets("Shipping Schedule")
LastRow = .Cells(.Rows.Count, "N").End(xlUp).Row
For Each r In .Range("N2:N" & LastRow)
If r.Value <> "" Then
r.Offset(0, 19).Value = ………………………………….
End if
Next r
End With
End Sub

Increment months in next available column, but multiple rows

I have VBA code which increments dates in the active cell to the next available column.
Dim lngLastCol As Long, lngRow As Long
lngRow = ActiveCell.Row
lngLastCol = Cells(lngRow, Columns.Count).End(xlToLeft).Column
If IsDate(Cells(lngRow, lngLastCol)) Then
With Cells(lngRow, lngLastCol + 1)
.Value = DateAdd("M", 1, CDate(Cells(lngRow, lngLastCol)))
.NumberFormat = Cells(lngRow, lngLastCol).NumberFormat
End With
End If
Instead of incrementing the month (and year) on the active row I am currently clicked on, I want to update the months in certain fixed rows i.e. Row 3, 17 and 42 (all in the same column).
Another approach, loop one column to the last row (in this case 250). In the second If formula you set which rows to add new columns to. So if this statement is true Cells(i, 2).Row = 3 (current row we loop is 3) then add a new column.
Therefore we replace the active row with a loop:
lngRow = ActiveCell.Row -> lngRow = Cells(i, 2).Row
The For i loop will from row 3 to row 250.
Sub ColumnsAdd()
Dim lngLastCol As Long, lngRow As Long, i As Long
For i = 3 To 250 'Loop from row 3 to 250
If Cells(i, 2).Row = 3 Or Cells(i, 2).Row = 17 Or Cells(i, 2).Row = 42 Then 'If any of the rows is 3, 17 or 42 then go and add new column
lngRow = Cells(i, 2).Row
lngLastCol = Cells(lngRow, Columns.Count).End(xlToLeft).Column
If IsDate(Cells(lngRow, lngLastCol)) Then
With Cells(lngRow, lngLastCol + 1)
.Value = DateAdd("M", 1, CDate(Cells(lngRow, lngLastCol)))
.NumberFormat = Cells(lngRow, lngLastCol).NumberFormat
End With
End If
End If
Next i
End Sub
I dont understand exactly what to you want but you can use the below code and if you want more adjustment let me know.
Option Explicit
Sub test()
Dim lngLastCol As Long, lngRow As Long
lngRow = ActiveCell.Row
lngLastCol = Cells(lngRow, Columns.Count).End(xlToLeft).Column
If IsDate(Cells(lngRow, lngLastCol)) Then
With Union(Cells(3, lngLastCol + 1), Cells(17, lngLastCol + 1), Cells(42, lngLastCol + 1))
.Value = DateAdd("M", 1, CDate(Cells(lngRow, lngLastCol)))
.NumberFormat = Cells(lngRow, lngLastCol).NumberFormat
End With
End If
End Sub

Copy cell and adjacent cell and insert as new row: Excel VBA

I'm trying to copy a cell and the adjacent cell in a row and insert it as a new row with all the data to the right of this cell also copied over. My data looks like this after mining.
and im trying to get my data to look like this:
the image above is just one record but essentially its moving all the people and their corresponding position in the original row to a new row. In each row there are about 5 employees and their positions.
thanks
EDIT Attempted code for just 2 cols. 1 position. the idea was to create the empty rows and just copy the rest of the data with auto fill, then work from there
Sub TransposeInsertRows()
Dim rng As Range
Dim i As Long, j As Long, k As Long
Dim x As Long, y As Long
Set rng = Application.InputBox _
(Prompt:="Range Selection...", _
Title:="Enter the name col and pos col", Type:=8)
Application.ScreenUpdating = False
x = rng(1, 1).Column + 2
y = rng(1, rng.Columns.Count).Column
For i = rng(rng.Rows.Count, 1).Row To rng(1, 1).Row Step -1
If Cells(i, x) <> "" And Cells(i, x + 1) <> "" Then
k = Cells(i, x - 2).End(xlToRight).Column
If k > y Then k = y
For j = k To x + 1 Step -1
Cells(i + 1, 1).EntireRow.Insert
With Cells(i + 1, x - 2)
.Value = .Offset(-1, 0)
.Offset(0, 1) = .Offset(-1, 1)
.Offset(0, 2) = Cells(i, j)
End With
Cells(i, j).ClearContents
Next j
End If
Next i
Application.ScreenUpdating = True
End Sub
If there are always 5 people in each row then this should do it:
Sub foo()
LastRow = Sheet1.Cells(Sheet1.Rows.Count, "A").End(xlUp).Row
For i = 1 To LastRow 'loop through rows
For x = 1 To 10 Step 2 'loop through columns
LastRow2 = Sheet2.Cells(Sheet2.Rows.Count, "A").End(xlUp).Row + 1 'find the next free row on Sheet2
Sheet2.Cells(LastRow2, 1).Value = Sheet1.Cells(i, x).Value 'add Person Name to Sheet2
Sheet2.Cells(LastRow2, 2).Value = Sheet1.Cells(i, x + 1).Value 'add position to Sheet2
Sheet1.Range("K" & i & ":U" & i).Copy Destination:=Sheet2.Cells(LastRow2, 3) 'copy range from K to U to Sheet2
Next x
Next i
End Sub

Copy data with in sheets

enter image description hereThere are 2 sheets, Sheet1 and Sheet2.
Sheet1 contain 10 columns and 5 rows with data including blank.
The requirement is to copy the data from Sheet 1 and to put in another sheet Sheet 2, wherein only populate the cell which is not blank.
I get the run time error 1004 - Application or object defined error.
The code snippet is:-
Set wsht1 = ThisWorkbook.Worksheets("Sheet1")
Set wsht2 = Sheets("Sheet2")
finalrow = wsht1.Cells(wsht1.Rows.Count, 1).End(xlUp).Row
For i = 1 To finalrow
If wsht1.Cells(i, 1).Value <> " " Then
Range(Cells(i, 2), Cells(i, 2)).Copy
Worksheets("Sheet2").Select
wsht2.Range(Cells(1, i)).PasteSpecial Paste:=xlPasteFormats
End If
Next i
Can u help me in sorting this out?
You cannot define a range like that:
wsht2.Range(Cells(1, i))
you might use:
wsht2.Cells(1, i).PasteSpecial Paste:=xlPasteFormats
BTW: with this code you won't find empty cells:
If wsht1.Cells(i, 1).Value <> " " Then
you should use:
If wsht1.Cells(i, 1).Value <> "" Then
(the difference is a missing space between the quotes)
if you want to copy the values only and to make it with a loop I'd do the following:
Sub copying()
Set wsht1 = ThisWorkbook.Worksheets("Sheet1")
Set wsht2 = Sheets("Sheet2")
finalrow = wsht1.Cells(wsht1.Rows.Count, 1).End(xlUp).Row
For i = 1 To finalrow
If wsht1.Cells(i, 1).Value <> "" Then
For j = 1 To 5
wsht2.Cells(i, j).Value = wsht1.Cells(i, j).Value
Next j
End If
Next i
End Sub
If you only have 5 cells with data in Sheet 1 and only want those 5 rows copying to Sheet 2 use the following, similar to Shai's answer above with an extra counter for the rows in Sheet 2.
Sub copying()
Set wsht1 = ThisWorkbook.Worksheets("Sheet1")
Set wsht2 = Sheets("Sheet2")
finalrow = wsht1.Cells(wsht1.Rows.Count, 1).End(xlUp).Row
k = 1
For i = 1 To finalrow
If wsht1.Cells(i, 1).Value <> "" Then
For j = 1 To 5
wsht2.Cells(k, j).Value = wsht1.Cells(i, j).Value
Next j
k = k + 1
End If
Next i
End Sub
EDIT
As per your comment if you want to dynamically change j replace For j = 1 To 5 with
For j = 1 To wsht1.Cells(i, Columns.Count).End(xlToLeft).Column
The code below will copy only values in Column A (non-empty cells) from Sheet 1 to Sheet2:
Dim j As Long
Set wsht1 = ThisWorkbook.Worksheets("Sheet1")
Set wsht2 = Sheets("Sheet2")
finalrow = wsht1.Cells(wsht1.Rows.Count, 1).End(xlUp).Row
j = 1
For i = 1 To finalrow
With wsht1
' if you compare to empty string, you need to remove the space inside the quotes
If .Cells(i, 1).Value <> "" And .Cells(i, 1).Value <> " " Then
.Cells(i, 1).Copy ' since you are copying a single cell, there's no need to use a Range
wsht2.Range("A" & j).PasteSpecial Paste:=xlPasteValues, Paste:=xlPasteFormats
j = j + 1
End If
End With
Next i

Resources