I am fairly new to VBA and trying to do something that I feel is basic, but I keep getting stuck in the commands.
I have one worksheet "RA REQUEST FORM" that I am using as a form. Upon clicking a command button I would like certain cells (A22, D11, C18, C19) to be copied to the cells of the next empty row of an array on another worksheet "ACTIVE CREDITS", (COLUMNS A,B,E G) respectively. Can anyone help?
Perhaps something like:
Sub ButtonCode()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim DestRow As Long
Set ws1 = Sheets("RA REQUEST FORM")
Set ws2 = Sheets("ACTIVE CREDITS")
DestRow = ws2.Cells(Rows.Count, "A").End(xlUp).Row + 1
ws1.Range("A22").Copy ws2.Range("A" & DestRow)
ws1.Range("D11").Copy ws2.Range("B" & DestRow)
ws1.Range("C18").Copy ws2.Range("E" & DestRow)
ws1.Range("C19").Copy ws2.Range("G" & DestRow)
End Sub
Ugly but it works.
Sub Macro1()
'
' Macro1 Macro
'
'
Dim a22 As String
Dim d11 As String
Dim c18 As String
Dim c19 As String
Worksheets("RA REQUEST FORM").Activate
a22 = Range("A22").Value
d11 = Range("D11").Value
c18 = Range("C18").Value
c19 = Range("c19").Value
Worksheets("ACTIVE CREDITS").Activate
'select the first row with not value in column A skipping the first row e.g. - Offset(1)
Range("A" & Rows.Count).End(xlUp).Offset(1).Select
ActiveCell.Offset(0, 0).Value = a22
ActiveCell.Offset(0, 1).Value = d11
ActiveCell.Offset(0, 4).Value = c18
ActiveCell.Offset(0, 6).Value = c19
End Sub
Here is what I came up with after having issues with the text formatting messing up the look of the "active credits" worksheet. What do you think?
Sub SENDTOLOG_Click()
Application.ScreenUpdating = False
Dim copysheet As Worksheet
Dim pastesheet As Worksheet
Set copysheet = Worksheets("RA REQUEST FORM")
Set pastesheet = Worksheets("ACTIVE CREDITS")
'Copy data from the RA REQUEST FORM to the active credits worksheet
'copy date
copysheet.Range("A22").Copy
pastesheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
'copy company name
copysheet.Range("D11").Copy
pastesheet.Cells(Rows.Count, 1).End(xlUp).Offset(0, 1).PasteSpecial xlPasteValues
'copy credit amount
copysheet.Range("C19").Copy
pastesheet.Cells(Rows.Count, 1).End(xlUp).Offset(0, 4).PasteSpecial xlPasteValues
'copy invoice number
copysheet.Range("C18").Copy
pastesheet.Cells(Rows.Count, 1).End(xlUp).Offset(0, 6).PasteSpecial xlPasteValues
'insert basic status description into STATUS cell
pastesheet.Cells(Rows.Count, 1).End(xlUp).Offset(0, 3).Value = "WAITING FOR CREDIT CONFIRMATION"
'select payment method cell
pastsheet.Cells(Rows.Count, 1).End(xlUp).Offset(0, 2).Select
Application.CutCopyMode = False
Application.ScreenUpdating = True
Sheets("ACTIVE CREDITS").Activate
End Sub
Related
I have the following code it copies a certain range and paste inserts it in the next worksheet, but it copies formulas, I want it to insert the amount of rows copied and paste values only.
Sub create_payroll()
'copies values from 'Driver' Worksheet (till last row) and pastes values into Invoice Data A14
Dim LastRow As Long
Application.ScreenUpdating = False
LastRow = Worksheets("Driver").Cells(Rows.Count, "B").End(xlUp).Row
Sheets("Driver").Range("A3:H" & LastRow).Copy
Sheets("Invoice Data").Range("A14").Insert xlShiftDown
Or bypass the clipboard entirely:
Sheets("Invoice Data").Range("A14:H" & LastRow + 11).Value = Sheets("Driver").Range("A3:H" & LastRow).Value
To bypass the clipboard and insert rows use:
Sheets("Invoice Data").Rows("14:").Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Sheets("Invoice Data").Range("A14:H" & LastRow + 11).Value = Sheets("Driver").Range("A3:H" & LastRow).Value
Try using something like the following:
Sub create_payroll()
'copies values from 'Driver' Worksheet (till last row) and pastes values into Invoice Data A14
Dim LastRow As Long
Dim srcRng As Range
Application.ScreenUpdating = False
With Sheets("Driver")
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
Set srcRng = .Range("A3:H" & LastRow)
End With
With Sheets("Invoice Data")
.Range("A14").Resize(srcRng.Rows.Count - 1, srcRng.Columns.Count).Insert shift:=xlDown
.Range("A14").Resize(srcRng.Rows.Count, srcRng.Columns.Count).Value = srcRng.Value
End With
End Sub
I have a workbook with 3 sheets: first one is the raw data sheet, then 2 target sheets. I would need a macro that would look at cell C in raw data sheet and based on the 2 values (YES or NO), will copy and paste the range A:Y in sheets 2, respectively 3.
Example: if on C2 in raw data sheet i have YES, copy A2:Y2 and paste into sheet 2, same range A2:Y2. If instead i have the value NO, copy A2:Y2 and paste into sheet 3.
Then go to next row and copy-paste A3:Y3 to sheet 2 if YES or A3:Y3 to sheet 3 if NO.
I wrote something that only works for the 2nd row, but i don't know how to make it loop... so basically when it passes to the next rows, it still copies the values from A2:Y2 to the target sheet, instead of copying A3:Y3, A4:Y4 etc..
Pasting my poor code below:
Sub IdentifyInfraction()
Dim rngA As Range
Dim cell As Range
Set rngA = Range("C2", Range("C65536").End(xlUp))
For Each cell In rngA
Worksheets("raw_data").Select
If cell.Value = "YES" Then
Range("A2:Y2").Copy
Worksheets("Value_YES").Select
Range("A2").PasteSpecial Paste:=xlPasteValues
ElseIf cell.Value = "NO" Then
Range("A2:Y2").Copy
Worksheets("Value_NO").Select
Range("A2").PasteSpecial Paste:=xlPasteValues
End If
Next cell
End Sub
Please help!!! :-s
Easiest solution would just be to replace the number 2 in each of your ranges to a variable which you then increment at the end your statement, before you go to the next cell.
For example:
Dim i = 2
Set rngA = Range("C2", Range("C65536").End(xlUp))
For Each cell In rngA
Worksheets("raw_data").Select
If cell.Value = "YES" Then
Range("A" & i & ":Y" & i).Copy
Worksheets("Value_YES").Select
Range("A" & i).PasteSpecial Paste:=xlPasteValues
ElseIf cell.Value = "NO" Then
Range("A" & i & ":Y" & i).Copy
Worksheets("Value_NO").Select
Range("A" & i).PasteSpecial Paste:=xlPasteValues
End If
i = i + 1
Next cell
So, originally we set i = 2, this is to go in line with your starting row of 2 mentioned in your question. Then, Range("A" & i & ":Y" & i).Copy is the same as saying Range("A2:Y2").Copy or Range("A3:Y3").Copy, etc.
This will go through any copy each row, a new row each time, and paste it to the respective row in the various sheets.
I hope this works for what you are trying to do, if not let me know.
There are a few things I'd also recommend looking into. There's a much better way to copy and paste, without going back and forward through the sheets.
ThisWorkbook.Sheets("raw_data").Rows(i).Copy Destination:=Worksheets("Value_YES").Range("A" & i)
Something like this would take the whole row from raw_data and transfer it to Value_YES. You'd have to mess around with it and change the range from Rows(i), but that's just an example.
I'd also recommend that you look into How to avoid using Select in Excel VBA to better understand why it's frowned upon to use Select and Activate in Excel VBA.
My version:
Sub GetR_Done()
Dim rng As Range, c As Range, LstRw As Long
Dim ws As Worksheet, Nr As Long, Yr As Long
Dim Ys As Worksheet, Ns As Worksheet
Set ws = Sheets("raw_data")
Set Ys = Sheets("Value_YES")
Set Ns = Sheets("Value_NO")
With ws
LstRw = .Cells(.Rows.Count, "C").End(xlUp).Row
Set rng = .Range("C2:C" & LstRw)
For Each c In rng.Cells
If c = "YES" Then
With Ys
Yr = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
End With
.Range(.Cells(c.Row, "A"), .Cells(c.Row, "Y")).Copy Ys.Range("A" & Yr)
End If
If c = "NO" Then
With Ns
Nr = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
End With
.Range(.Cells(c.Row, "A"), .Cells(c.Row, "Y")).Copy Ns.Range("A" & Nr)
End If
Next c
End With
End Sub
If you really require to paste values, then use this one
Sub GetR_Done()
Dim rng As Range, c As Range, LstRw As Long
Dim ws As Worksheet, Nr As Long, Yr As Long
Dim Ys As Worksheet, Ns As Worksheet
Set ws = Sheets("raw_data")
Set Ys = Sheets("Value_YES")
Set Ns = Sheets("Value_NO")
Application.ScreenUpdating = False
With ws
LstRw = .Cells(.Rows.Count, "C").End(xlUp).Row
Set rng = .Range("C2:C" & LstRw)
For Each c In rng.Cells
If c = "YES" Then
With Ys
Yr = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
End With
.Range(.Cells(c.Row, "A"), .Cells(c.Row, "Y")).Copy
Ys.Range("A" & Yr).PasteSpecial xlPasteValues
End If
If c = "NO" Then
With Ns
Nr = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
End With
.Range(.Cells(c.Row, "A"), .Cells(c.Row, "Y")).Copy
Ns.Range("A" & Nr).PasteSpecial xlPasteValues
End If
Next c
End With
Application.CutCopyMode = False
End Sub
you could try this:
Sub IdentifyInfraction()
Dim cell As Range
With Worksheets("raw_data") 'reference "raw data" sheet
For Each cell In .Range("C2", .cells(.Rows.Count, "C").End(xlUp)) ' loop through referenced sheet column C cells from row 2 down to last not empty one
Worksheets("Value_" & cell.Value).Range(cell.Address).Resize(, 25).Value = cell.Resize(, 25).Value 'have proper target sheet A:Y current cell row values as "raw data" sheet ones
Next
End With
End Sub
Straight to the point:
I am trying to match A2 on sheet "PRD" to A2 on sheet "CRD", if this is a match I want to compare B2 on sheet PRD to B2 on sheet CRD and then A3 same thing on and on to the end of the range. If there is no match between cells in column A I am trying to copy the whole row to a third sheet, if there is a match between cells in A but there is not a match between cells in B I am trying to copy the row to a third sheet.
I am stuck, I think after hours of looking at the code and Googling, not being able to check column B... I seem to be able to check, copy and paste cells that do not match contents in column A fine.
I hope I am asking the right questions and am clear, thanks for any help!!
Dim r1 As Range
Dim r2 As Range
Dim r3 As Range
Dim r4 As Range
Dim cell As Range
Dim cell2 As Range
Dim lastrow As Long
'CRD date
With ThisWorkbook.Worksheets("CRD")
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set r1 = .Range("A2:A" & lastrow)
End With
'CRD quantity
With ThisWorkbook.Worksheets("CRD")
lastrow = .Cells(.Rows.Count, "B").End(xlUp).Row
Set r3 = .Range("B2:B" & lastrow)
End With
'PRD date
With ThisWorkbook.Worksheets("PRD")
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set r2 = .Range("A2:A" & lastrow)
End With
'PRD quantity
With ThisWorkbook.Worksheets("PRD")
lastrow = .Cells(.Rows.Count, "B").End(xlUp).Row
Set r4 = .Range("B2:B" & lastrow)
End With
'match PRD date to CRD date: output "Found" for record, or copy/paste onto report page
Range("A2").Select
For Each cell In r1
If IsError(Application.Match(cell, r2, 0)) Then
'select active cell's row and copy, pasting in report page
Rows(ActiveCell.Row).Select
Selection.Copy
Sheets("Sheet1").Select
Range("A1").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("CRD").Select
Application.CutCopyMode = False
'if no error check quantity(B) of same cell, if match continue, if no match copy
ElseIf IsError(Application.Match(r3, r4, 0)) Then
For Each cell2 In r3
Rows(ActiveCell.Row).Select
Selection.Copy
Sheets("Sheet1").Select
Range("A1").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("CRD").Select
ActiveCell.Offset(rowOffset:=0, columnOffset:=1).Activate
Application.CutCopyMode = False
Next
Else
End If
ActiveCell.Offset(rowOffset:=1, columnOffset:=0).Activate
Next
End Sub
Your code relies too much on Select, ActiveCell, Selection and Activate, you should avoid all these Selecting and use fully qualified objects instead.
See the code below, and explanations inside the code's comments.
Modified Code
Option Explicit
Sub Match2Columns()
Dim r1 As Range
Dim r2 As Range
Dim r3 As Range
Dim r4 As Range
Dim cell As Range
Dim cell2 As Range
Dim lastrow As Long
'CRD date
With ThisWorkbook.Worksheets("CRD")
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set r1 = .Range("A2:A" & lastrow)
End With
'CRD quantity
With ThisWorkbook.Worksheets("CRD")
lastrow = .Cells(.Rows.Count, "B").End(xlUp).Row
Set r3 = .Range("B2:B" & lastrow)
End With
'PRD date
With ThisWorkbook.Worksheets("PRD")
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set r2 = .Range("A2:A" & lastrow)
End With
'PRD quantity
With ThisWorkbook.Worksheets("PRD")
lastrow = .Cells(.Rows.Count, "B").End(xlUp).Row
Set r4 = .Range("B2:B" & lastrow)
End With
Dim PasteRow As Long ' row to paste at "sheet1"
'match PRD date to CRD date: output "Found" for record, or copy/paste onto report page
With ThisWorkbook.Worksheets("CRD") ' <-- make sure you are looping and copying from "CRD" sheet
For Each cell In r1
If IsError(Application.Match(cell, r2, 0)) Then
' select active cell's row and copy, pasting in report page
.Rows(cell.Row).Copy
' get last empty row and add 1 row where to paste
PasteRow = Sheets("Sheet1").Range("A1").End(xlDown).Row + 1
' paste action
Sheets("Sheet1").Range("A" & PasteRow).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
'if no error check quantity(B) of same cell, if match continue, if no match copy
ElseIf IsError(Application.Match(r3, r4, 0)) Then
For Each cell2 In r3
' select active cell's row and copy, pasting in report page
.Rows(cell2.Row).Copy
' get last empty row and add 1 row where to paste
PasteRow = Sheets("Sheet1").Range("A1").End(xlDown).Row + 1
' paste action
Sheets("Sheet1").Range("A" & PasteRow).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
Next cell2
Else
' you are doing nothing here, not sure why you need it ???
End If
Next cell
End With
End Sub
I have written the below code. I have 3 worksheets: Dashboard, Workings and Data. I have a data validation list on worksheet(Dashboard) which has a long list of companies.
I want to be able to select a company from the list, press a button and then match from a company list in the worksheet data which has plenty of other columns for corresponding data for that company. I want to be able to take certain data from the company chosen and paste it into the next available row in worksheet (Workings). The list in the worksheet (data) has multiple entries for the same company, hence why I have added a loop in here.
This code does no give an error but does not give any result.
Can someone please tell me where I'm going wrong
Many thanks.
Sub pull_data()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableCancelKey = xlDisabled
CompanyListLocation = Worksheets("Dashboard").Cells(2, 4).Value
'Company = Worksheets("Data").Cells(CompanyListLocation, 1).Value
For x = 2 To 1000000
If Worksheets("Data").Cells(x, 5).Value = CompanyListLocation Then
Worksheets("Data").Cells(x, 5).Copy
Worksheets("Workings").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Worksheets("Data").Cells(x, 14).Copy
Worksheets("Workings").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Worksheets("Data").Cells(x, 15).Copy
Worksheets("Workings").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
End If
Next x
End Sub
Are you trying to copy all the data from Data Sheet in column A of Workings Sheet?
You may try something like below. Tweak it if required.
Sub CopyData()
Dim wsCriteria As Worksheet, wsData As Worksheet, wsDest As Worksheet
Dim CompanyListLocation
Dim lr As Long, dlr As Long
Application.ScreenUpdating = False
Set wsCriteria = Sheets("Dashboard")
Set wsData = Sheets("Data")
Set wsDest = Sheets("Workings")
CompanyListLocation = wsCriteria.Range("D2").Value
lr = wsData.UsedRange.Rows.Count
dlr = wsDest.Cells(Rows.Count, 1).End(xlUp).Row + 1
wsData.AutoFilterMode = False
With wsData.Rows(1)
.AutoFilter field:=5, Criteria1:=CompanyListLocation
If wsData.Range("E1:E" & lr).SpecialCells(xlCellTypeVisible).Cells.Count > 1 Then
wsData.Range("E2:E" & lr).SpecialCells(xlCellTypeVisible).Copy wsDest.Range("A" & Rows.Count).End(3)(2)
wsData.Range("N2:N" & lr).SpecialCells(xlCellTypeVisible).Copy wsDest.Range("A" & Rows.Count).End(3)(2)
wsData.Range("O2:O" & lr).SpecialCells(xlCellTypeVisible).Copy wsDest.Range("A" & Rows.Count).End(3)(2)
End If
.AutoFilter
End With
Application.ScreenUpdating = True
End Sub
If you want to copy values only, change the copy paste code to this...
If wsData.Range("E1:E" & lr).SpecialCells(xlCellTypeVisible).Cells.Count > 1 Then
wsData.Range("E2:E" & lr).SpecialCells(xlCellTypeVisible).Copy
wsDest.Range("A" & Rows.Count).End(3)(2).PasteSpecial xlPasteValues
wsData.Range("N2:N" & lr).SpecialCells(xlCellTypeVisible).Copy
wsDest.Range("A" & Rows.Count).End(3)(2).PasteSpecial xlPasteValues
wsData.Range("O2:O" & lr).SpecialCells(xlCellTypeVisible).Copy
wsDest.Range("A" & Rows.Count).End(3)(2).PasteSpecial xlPasteValues
End If
I am writing a macro that creates variable worksheets based on a value on an existing worksheet. I managed that part fine, but now I need to add a VLOOKUP formula on another sheet that references the newly created sheets. There is no set pattern to the name of the new worksheets, so I having trouble referencing them. Here is the code I used to create the new worksheets:
Dim ws As Worksheet
Dim rngCriteria As Range
Dim sName As String
Dim I As Long
Dim LastRow As Long
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
With Sheets("Part Type REC")
If .AutoFilterMode = True Then .AutoFilterMode = False
.Range("D1:D" & LastRow).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=.Range("J1"), Unique:=True
Set rngCriteria = .Range("J1").CurrentRegion
For I = 2 To .Cells(Rows.Count, "J").End(xlUp).Row
sName = .Cells(I, "J")
Set ws = ThisWorkbook.Worksheets.Add
ws.Name = sName
.Range("D1:D" & LastRow).AutoFilter Field:=1, Criteria1:="=" & .Cells(I, "J").Value
.Range("A1:H" & LastRow).SpecialCells(xlCellTypeVisible).Copy Destination:=ws.Range("A1")
Next I
.AutoFilterMode = False
End With
Sheets("Part Type REC").Select
Columns("J:J").Select
Selection.ClearContents
Range("A1").Select
And here is the VLOOKUP that I need to reference the new worksheets:
Sheets("TP Parts").Select
Range("O2").Select
Application.CutCopyMode = False
ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[-1],'ws.name'!C[-14],1,FALSE)"
Range("O2").Select
Where am I going wrong with this?
Thanks in advance!
Try this (UNTESTED - Just typed it here)
Range("O2").FormulaR1C1 = "=VLOOKUP(RC[-1]," & ws.name & "!C[-14],1,FALSE)"