Distributing evenly the Cell value of column A to B C D - excel

I'm very new to Excel VBA so please be good to me :)
My problem is I want to copy values of Column A until the last cell with value and paste it to B C D respectively
Example
Column A has 3 Rows with values Tim,john,Mer respectively
I want to paste it to Columns B2 C2 D2 respectively too
Problem: Column A has a dynamic number of row so I want it to copy until the last notempty cell. but when column A is more than 3 (number of columns to paste) it will loop and paste it to B3 then C3 then D3 and so on until all non empty cell is distributed evenly to the 3 columns(B,C, and D)
Hope this problem is clear

Sub CopyData()
Dim x As Long, i As Long
Application.ScreenUpdating = False
For i = 1 To 100 Step 3
x = x + 1
Range("A" & i & ":A" & i + 2).Copy
Range("B" & x).PasteSpecial xlPasteValues, , , True
Next i
Application.ScreenUpdating = True
End Sub

Maybe make use of the TRANSPOSE function?
Sub TransposeToColumns()
Dim lLastRow As Long
With ThisWorkbook.Worksheets("Sheet1")
'Get the last row (same as going to end of sheet and pressing Ctrl+Up).
lLastRow = .Range("A" & Rows.Count).End(xlUp).Row
If lLastRow > 3 Then
'Cells(1,2) is row 1, column 2.
With .Range(.Cells(1, 2), .Cells(1, lLastRow + 1))
'R1C1 style of referencing - absolute reference to A1 is R1C1 (row 1 column 1).
.FormulaArray = "=TRANSPOSE(R1C1:R" & lLastRow & "C1)"
'Replace formula with values.
.Value = .Value
End With
End If
End With
End Sub
Just realised - this will error out if you try and do it with more than 16383 rows (i.e. the number of columns -1). But it will do all columns in 0.040469668631069 seconds. :)

Related

If cell A1 is greater than B1, cut and paste row to first empty row

If cell in column I1-I14 is greater than cell in column J1-J14, I want to cut the entire row and paste values to the first empty row. (From row 16 and down.)
If cell i is greater than cell j, cut row and paste values to first empty row (row 16 in this example)
This code just pastes in the first row:
Sub Knapp6_Klicka()
Dim i As Long
Dim j As Long
j = 1
For i = 3 To 500
If Cells(i, 9).Value > Cells(i, 10).Value Then
Cells(i, 12).EntireRow.Cut Sheets("Blad1").Range("A" & j)
j = j + 1
End If
Next i
End Sub
I tried to combine the paste with two different solutions.
One like this, where I recorded a macro and went to the last cell, then up to the first empty cell:
Range("A1048576").Select
Selection.End(xlUp).Select
ActiveCell.Offset(1, 0).Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
And one solution that I found on an Excel community:
Sub compareresult()
Dim row1 As Integer
Dim row2 As Integer
row2 = 1
For row1 = 8 To 500
If sheet1.Cells(row1, 11).value > sheet1.Cells(row1, 9).value Then
sheet1.Cells(row1, 1).EntireRow.Copy Sheets(11).Cells(row2, 1)
row2 = row2 + 1
End If
Next row1
End Sub
If cell in column I1-I14 is greater than cell in column J1-J14, i want to cut entire row and paste values to the first empty row. (From row 16 and down)
Here is a method which doesn't cut and paste in a loop. Since you are not deleting the row or "cutting and inserting" the row, here is a simple approach. The below code follows a basic logic
Logic
Loop and identify the range.
If found, then copy the range in 1 go.
Finally clear the range which was copied (if copied).
Code
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim rngToCopy As Range
Dim i As Long
'~~> Change this to relevant sheet
Set ws = Sheet1
With ws
'~~> Loop and identify the range
For i = 2 To 14
If .Range("I" & i).Value2 > .Range("J" & i).Value2 Then
If rngToCopy Is Nothing Then
Set rngToCopy = .Rows(i)
Else
Set rngToCopy = Union(rngToCopy, .Rows(i))
End If
End If
Next i
'~~> If found then copy and clear
If Not rngToCopy Is Nothing Then
rngToCopy.Copy .Rows(16)
rngToCopy.Clear
End If
End With
End Sub
EDIT:
To incorporate new edits
Works perfectly! Thanks! :) I failed to fully describe my problem.. What i also need is to paste it as special (only paste the value and not the formulas). Do you got any quick solution for that? – Johl 5 hours ago
Replace
rngToCopy.Copy .Rows(16)
to
rngToCopy.Copy
DoEvents
.Rows(16).PasteSpecial Paste:=xlPasteValues
Have a try with this.
It's based on the range you gave. Skipped over row 1 since you have headers in it.
Dim i As Long, lRow As Long, ws As Worksheet
Set ws = Sheets("Blad1") 'Your sheet name
lRow = ws.Range("I" & Rows.Count).End(xlUp).Row + 1 'Finding the last row
If lRow < 16 Then lRow = 16 'The starting row you want to cut to
For i = 2 To 14 'Your range of rows to check
If ws.Range("I" & i) > ws.Range("J" & i) Then
ws.Range("I" & i).EntireRow.Cut ws.Range("A" & lRow) 'Cutting the whole row so you use column A to cut to
lRow = lRow + 1 'Move down 1 row for where to cut to
End If
Next i
Edit:
Because you only want the values to copy accross we can't use Cut and PasteSpecial xlValues so instead we will duplicate the value of the entire row to the new location, then clear the row (filling in for the cutting part). If clear is too much we can just ClearContents to remove the values in the cells instead of the formatting if that happens. Make sure to always save before running VBA code for the first time.
Dim i As Long, lRow As Long, ws As Worksheet
Set ws = Sheets("Blad1") 'Your sheet name
lRow = ws.Range("I" & Rows.Count).End(xlUp).Row + 1 'Finding the last row
If lRow < 16 Then lRow = 16 'The starting row you want to cut to
For i = 2 To 14 'Your range of rows to check
If ws.Range("I" & i) > ws.Range("J" & i) Then
ws.Range("A" & lRow).EntireRow.Value = ws.Range("I" & i).EntireRow.Value 'Copying the values over
ws.Range("I" & i).EntireRow.Clear 'Clear the row
lRow = lRow + 1 'Move down 1 row for where to cut to
End If
Next i
Your code is doomed to failure because you do not take into consideration that you are cutting the found row. Think about what that means. Your row with the In,Out is row 15 and you wish to paste to row 16. If you cut row 5 (for example) then rows 15 and 16 will become rows 14 and 15. It also means that your next row (which you think will be row 6) will actually be what was row 7 before the cut.

How to shift a range down one row based upon adjacent cell value using VBA?

I'm attempting to move the adjacent cell range D:E down one row based upon the value in column B.
For example, if a row in column B contains the word "Deposit", then the macro should shift the adjacent cell range D:E down one row.
My issue is that the macro is inserting two rows instead of just one.
I've included some screenshots of my data.
Here is my code:
Sub InsertCellsDown()
Application.ScreenUpdating = False
Dim LastRow As Long
Dim cba As Range
LastRow = Cells.Find("Deposit", SearchOrder:=xlRows, SearchDirection:=xlPrevious).Row
For Each cba In Range("B2:B" & LastRow)
If cba <> cba.Offset(1, 0) Then
Range("D" & cba.Row & ":E" & cba.Row).Insert Shift:=xlDown
End If
Next cba
Application.ScreenUpdating = True
End Sub
Starting data:
Goal:
Problem:

Excel copy-paste range on specific sheet according to cell value

I have a workbook with a master sheet called "NIR" containing the following data: Column A contains product names(the same as the rest of the worksheets names);Column B contains quantity and Column C contains prices.
I want to create a VBA to search in my master sheet "NIR" in Column A and copy Columns B and C to specific sheets according to master sheet "NIR" ,cells in Column A.
Example:
Sheet "NIR"
A3="shoes"
A4="pants"
B3 = 3 (pairs)
C3 = 10 (price)
copy B3 and C3 to sheets "shoes" and "pants"according to Sheet"NIR" A3
Try:
Option Explicit
Sub Macro1()
Dim LastRowNIR As Long, i As Long, LastRowWs As Long
Dim arr As Variant
With ThisWorkbook.Worksheets("NIR")
'Find the last row of column A
LastRowNIR = .Cells(.Rows.Count, "A").End(xlUp).Row
'Import all data in an array starting from A1 to C last row
arr = .Range("A1:C" & LastRowNIR)
'Loop array
For i = LBound(arr) To UBound(arr)
With ThisWorkbook.Worksheets(arr(i, 1))
'Find the last row of column B
LastRowWs = .Cells(.Rows.Count, "B").End(xlUp).Row
'Write in the next available row the quantity
.Range("B" & LastRowWs + 1).Value = arr(i, 2)
'Write in the next available row the prices
.Range("C" & LastRowWs + 1).Value = arr(i, 3)
End With
Next i
End With
End Sub

How to delete all rows of a multiple entry even if just one row meets defined criteria

Below is the current (incomplete) code I'm using which works fine to delete any one given row, but what I really need to do is identify rows which meet certain criteria:
Cell Value in Column L > 90%
OR
Cell Value in Column M > 90%
Then if either of those is true I need to find the Cell Value in same row Column G and delete all rows which contain that same Value in Column G.
Sub sbDelete_Rows_Based_On_Multiple_Criteria()
Dim lRow As Long
Dim iCntr As Long
lRow = Cells(Rows.Count, "G").End(xlUp).Row
For iCntr = lRow To 2 Step -1
If Cells(iCntr, "L") > 0.90 OR Cells(iCntr, "M") > 0.90 Then
Cells(iCntr, "G").EntireRow.Delete
End If
Next iCntr
End Sub
--
What I hope to accomplish in my example would result in the only Serial # which is NOT deleted would be 1910910
thank you in advance for your assistance.
Sub ToDelete()
Dim last_row&
'// NOTE! The code assumes that range:
'// 1) starts in column A
'// 2) ends in column O
last_row = Cells(Rows.Count, "G").End(xlUp).Row
'// Helper column 1
With Range("P2:P" & last_row)
.Formula = "=IF(OR(M2>0.9,L2>0.9),1,0)"
.Value = .Value 'Overwrite formula
End With
'// Helper column 2
With Range("Q2:Q" & last_row)
.Formula = "=IF(SUMIF(G:G,G2,P:P)>0,1,0)"
.Value = .Value 'Overwrite formula
End With
Rows(1).CurrentRegion.AutoFilter Field:=17, Criteria1:=1
Rows("2:" & last_row).EntireRow.Delete
ActiveSheet.AutoFilterMode = False 'Remove filter
Columns("P:Q").Delete 'Remove helper columns
End Sub

Excel VBA: Maintaining number formatting with digits and letters

I am writing a code where basically I need to follow the sequence in logic. I am going through all the lines
Set rep = Sheets("Details")
For i = 2 To n
If Sheets("Work").Range("A:A").Find(Worksheets("Work_report").Range("E" & i).Value, lookat:=xlWhole) Is Nothing Then
Else:
o = rep.Range("A" & Rows.Count).End(xlUp).Row + 1
rep.Range("A" & o).Value = "FT_EXCEL"
rep.Range("B" & o).Value = Sheets("Start").Range("C5") & "AB" & o - 1
End If
Next i
So this the last line (there are more than 50 in original code) returns me a value of the cell C5 (20170331) & AB & the o minus 1 (because I have started at 2 (1st line header)). So this is giving 20170331AB1, but it should give 20170331AB01 (zero before the 0). This sequence works like a charm after 10, but before ten when I need to add a zero - I got stuck.
Any ideas? Thank you.
Try this:
rep.Range("B" & o).Value = Sheets("Start").Range("C5") & "AB" & Format(o - 1, "00")
you can do it in one shot with exploiting AutoFilter() method's operator xlFilterValues value
Sub main()
Dim rep As Worksheet
Dim criteriaArr As Variant
With Worksheets("Work_report") '<--| reference "Work_report" sheet
criteriaArr = Application.Transpose(.Range("E2", .Cells(.Rows.Count, "E").End(xlUp)).Value) '<--| store its column E cells content from row 2 down to last not empty one
End With
Set rep = Sheets("Details")
With Worksheets("Work") '<--| reference "Work" sheet
With .Range("A1", .Cells(.Rows.Count, "A").End(xlUp)) '<--| reference its column A cells from row 1 (header) down to last not empty one
.AutoFilter Field:=1, Criteria1:=criteriaArr, Operator:=xlFilterValues '<--| filter it with "Work_report" sheet column E content
If Application.WorksheetFunction.Subtotal(103, .Cells) > 1 Then '<--| if any filtered cells other then headers
With .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible) '<--| reference filtered cells skipping header
rep.Range("A" & Rows.Count).End(xlUp).Offset(1).Resize(.Rows.Count).Value = "FT_EXCEL" '<--| write 'rep' sheet column A corresponding cells content
With rep.Range("B" & Rows.Count).End(xlUp).Offset(1).Resize(.Rows.Count)
.Formula = "=CONCATENATE(Start!$C$5,""AB"",TEXT(ROW(),""00""))" '<--| '<--| write 'rep' sheet column B corresponding cells content
.Value = .Value
End With
End With
End If
End With
.AutoFilterMode = False
End With
End Sub

Resources