How can I make my copy and pasting work as intended - excel

Hello all I did a macro in VBA that should check column D for the first empty cell then paste on that row but on column C, and when adding new info in the table it should take the first empty cell again, but it is replacing data, I don't check column C for first row because I have an filled cell midway, and if data were to replace that cell it should add a new row and avoid that.
`Sub CopyPasteToAnotherSheet()
Dim sourceRange As Range
Dim targetRange As Range
Dim lastRow As Long
Dim firstEmptyRow As Long
Set sourceRange = Selection
Set targetRange = Sheets("PARKING").Range("D18")
lastRow = targetRange.End(xlDown).Row
firstEmptyRow = Sheets("PARKING").Range("D" & lastRow).End(xlUp).Row + 1
If lastRow = targetRange.Row Then
targetRange.EntireRow.Insert
End If
If Sheets("PARKING").Range("C" & firstEmptyRow).Value <> "" Then
firstEmptyRow = firstEmptyRow + 1
End If
Set targetRange = Sheets("PARKING").Range("C" & firstEmptyRow)
sourceRange.Copy
targetRange.PasteSpecial xlPasteValues
End Sub
`
I have tried to work with different search ranges but it keeps overwriting data.
also if it would keep numbering the newly added rows when adding new data it would be great I am clueless on how I should do that

Append Values
Sub AppendValues()
Const PROC_TITLE As String = "Append Values"
Const DST_NAME As String = "PARKING"
Const DST_FIRST_CELL As String = "C18"
If Selection Is Nothing Then Exit Sub ' no visible workbooks open
If Not TypeOf Selection Is Range Then Exit Sub ' not a range
Dim srg As Range: Set srg = Selection
Dim sws As Worksheet: Set sws = srg.Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
If Not sws.Parent Is wb Then Exit Sub ' not in this workbook
Dim dws As Worksheet: Set dws = wb.Sheets(DST_NAME)
If sws Is dws Then Exit Sub ' src. and dst. are the same worksheet
If dws.FilterMode Then dws.ShowAllData ' '.Find' will fail if 'dws' filtered
Dim dfCell As Range: Set dfCell = dws.Range(DST_FIRST_CELL)
Dim dlCell As Range
Set dlCell = dws.UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If Not dlCell Is Nothing Then
Set dfCell = dfCell.Offset(dlCell.Row - dfCell.Row + 1)
End If
Dim sarg As Range
For Each sarg In srg.Areas
dfCell.Resize(sarg.Rows.Count, sarg.Columns.Count).Value = sarg.Value
Set dfCell = dfCell.Offset(sarg.Rows.Count)
Next sarg
MsgBox "Values appended to worksheet """ & DST_NAME & """.", _
vbInformation, PROC_TITLE
End Sub

Related

Macro to fill data from sheet to another sheet

Hi I have created macro where it opens the sheet based on user input,
what I need is once the new sheet is opened I have some fields where user need to fill those data(Different subjects marks) and calculate the percentage using formula then I need to fill those data to another sheet named "Data" without overwriting previous data?.
Please suggest how to add data without overwriting in vba.
Sub open_sheet()
Dim sourcesheet As Worksheet
Dim ClassA As Worksheet
Dim ClassB As Worksheet
Dim ClassC As Worksheet
Set sourcesheet = Sheets("Main")
Set ClassA = Sheets("Class A")
Set ClassB = Sheets("Class B")
Set ClassC = Sheets("Class C")
If sourcesheet.Range("Class").Value = "Class A" Then
Worksheets("Class A").Activate
ElseIf sourcesheet.Range("Class").Value = "Class B" Then
Worksheets("Class B").Activate
Else:
Worksheets("Class C").Activate
End If
End Sub
Copy Cell Values to Another Worksheet
Option Explicit
Sub CopyData()
' Reference the workbook.
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the source worksheet.
Dim sws As Worksheet: Set sws = wb.Sheets("Main")
' Reference the source range (the values from these cells will be copied).
Dim srg As Range: Set srg = sws.Range("A3,B4,C5")
' Retrieve the destination worksheet name.
' Hopefully you have created a drop down to easily select the class.
Dim dName As String: dName = sws.Range("Class").Value
' Late at night (tired), a final check could become a life saver:
Dim Msg As Long
Msg = MsgBox("This will copy to """ & dName & """." & vbLf & vbLf _
& "Are you sure?", vbQuestion + vbYesNo)
If Msg = vbNo Then Exit Sub
' Reference the destination worksheet.
Dim dws As Worksheet: Set dws = wb.Sheets(dName)
If dws.FilterMode Then dws.ShowAllData ' 'Find' will fail if 'dws' filtered
' Reference the first (available) destination cell.
Dim dCell As Range ' First Destination Cell
With dws.UsedRange
Dim dlCell As Range ' Last Cell
Set dlCell = .Find("*", , xlFormulas, , xlByRows, xlPrevious)
If dlCell Is Nothing Then Exit Sub ' empty worksheet
Set dCell = dws.Cells(dlCell.Row + 1, "A") ' below last in column 'A'
End With
' Copy the values from the source to the destination cells.
Dim sCell As Range
For Each sCell In srg.Cells
dCell.Value = sCell.Value
Set dCell = dCell.Offset(, 1) ' next, adjacent to the right
Next sCell
MsgBox "Data copied.", vbInformation
End Sub
In general, here's a way to append info to a table. I would just put your average calculations in the table total row.
Option Explicit
Sub FillNewRow1()
Dim Class_A As Worksheet
Dim ClassName As String
Dim DataRange
Dim lRow As Long
ClassName = Worksheets("Master").Range("B2").Value
Set Class_A = ThisWorkbook.Worksheets(ClassName)
DataRange = Worksheets("Master").Range("B5:B8")
lRow = Class_A.Range("A" & Rows.Count).End(xlUp).Row + 1
Class_A.Range("A" & lRow).Resize(1, UBound(DataRange, 1)).Value = _
Application.Transpose(DataRange)
End Sub
But seeing as we have no idea what your source od destination data look like that's the best help I can give.
Suplimentary :
PivotCharts & Pivot Tables are awesome:

get position of activecell in a named table

so i have a table named "Table1" in "sheet1" which range is from A2:B4, if i select B3 that would be Sheet("sheet1").range("Table1").cells(2,2) how would you check thru vba that the activecell in table1 is in cells(2,2)
im doing this because i will be copying/reflecting the value to another named table in another sheet to the same cells(2,2) the table has the same no. of rows and columns, it is exactly the same table just located in another sheet and in a different range
You could do it like this:
Sub Tester()
Dim rngT1 As Range, rngT2 As Range, rng As Range, rng2 As Range, addr
Set rngT1 = ActiveSheet.Range("Table1")
Set rngT2 = ActiveSheet.Range("Table2") 'could be different sheet...
Set rng = Application.Intersect(Selection, rngT1) 'part of selection within Table1
If Not rng Is Nothing Then 'any selection in table?
'get the address of the selection *relative* to Table1
addr = rng.Offset(-rngT1.Row + 1, -rngT1.Column + 1).Address(False, False)
Debug.Print addr
Set rng2 = rngT2.Range(addr) 'same relative range in Table2
rng2.Select 'for example
End If
End Sub
Reference the Same Cell in Another Same Sized Table
Sub ReferenceSameCell()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sws As Worksheet: Set sws = wb.Sheets("Sheet1")
Dim slo As ListObject: Set slo = sws.ListObjects("Table1")
Dim srg As Range: Set srg = slo.Range
Dim sCell As Range: Set sCell = ActiveCell
If Not sCell.Worksheet Is sws Then
MsgBox "Select a cell in worksheet '" & sws.Name & "'.", vbExclamation
Exit Sub
End If
If Intersect(sCell, srg) Is Nothing Then
MsgBox "Select a cell in table '" & slo.Name & "'.", vbExclamation
Exit Sub
End If
Dim dws As Worksheet: Set dws = wb.Sheets("Sheet2")
Dim dlo As ListObject: Set dlo = dws.ListObjects("Table2")
Dim drg As Range: Set drg = dlo.Range
Dim r As Long: r = sCell.Row - srg.Row + 1
Dim c As Long: c = sCell.Column - srg.Column + 1
Dim dCell As Range: Set dCell = drg.Cells(r, c)
Debug.Print r, c, sCell.Address, dCell.Address
End Sub

Find from InputBox, copy row of found cell without using .Select

I have a spreadsheet with over 10000 rows. I need to search it using InputBox (UPC field, input is from a barcode scanner).
I need to copy the row of the found cell, and paste it to another sheet.
This process should loop until the user cancels the InputBox.
I have done this, but it gives me an error on the SelectCells.Select line, but not every time.
Sub Scan()
Do Until IsEmpty(ActiveCell)
Dim Barcode As Double
Barcode = InputBox("Scan Barcode")
Dim ws As Worksheet
Dim SelectCells As Range
Dim xcell As Object
Set ws = Worksheets("Sheet1")
For Each xcell In ws.UsedRange.Cells
If xcell.Value = Barcode Then
If SelectCells Is Nothing Then
Set SelectCells = Range(xcell.Address)
Else
Set SelectCells = Union(SelectCells, Range(xcell.Address))
End If
End If
Next
SelectCells.Select
Set SelectCells = Nothing
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Sheets("Sheet2").Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Loop
End Sub
Copy Rows
Option Explicit
Sub Scan()
Const sName As String = "Sheet1"
Const Header As String = "Barcode"
Const dName As String = "Sheet2"
Const dFirstCellAddress As String = "A2"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim surg As Range: Set surg = sws.UsedRange
Dim slCell As Range
Set slCell = surg.Cells(surg.Rows.Count, surg.Columns.Count)
Dim shCell As Range
Set shCell = surg.Find(Header, slCell, xlFormulas, xlWhole, xlByRows)
If shCell Is Nothing Then
MsgBox "The cell containing the header '" & Header _
& "' was not found.", vbCritical
Exit Sub
End If
Dim sfCol As Long: sfCol = surg.Column
Dim srg As Range
Set srg = sws.Range(sws.Cells(shCell.Row + 1, sfCol), slCell)
Dim scColIndex As Long: scColIndex = shCell.Column - sfCol + 1
Dim scrg As Range: Set scrg = srg.Columns(scColIndex)
Dim SelectedRows As Range
Dim Barcode As Variant
Dim srIndex As Variant
Do
Barcode = InputBox("Scan Barcode")
If Len(CStr(Barcode)) = 0 Then Exit Do
If IsNumeric(Barcode) Then
srIndex = Application.Match(CDbl(Barcode), scrg, 0)
If IsNumeric(srIndex) Then
If SelectedRows Is Nothing Then
Set SelectedRows = srg.Rows(srIndex)
Else
Set SelectedRows = Union(SelectedRows, srg.Rows(srIndex))
End If
End If
End If
Loop
If SelectedRows Is Nothing Then
MsgBox "No scan results.", vbExclamation
Exit Sub
End If
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfCell As Range: Set dfCell = dws.Range(dFirstCellAddress)
Dim durg As Range: Set durg = dws.UsedRange
Dim dlRow As Long: dlRow = durg.Row + durg.Rows.Count - 1
Dim dlCell As Range
If dlRow < dfCell.Row Then
Set dlCell = dfCell
Else
Set dlCell = dws.Cells(dlRow + 1, dfCell.Column)
End If
SelectedRows.Copy dlCell
MsgBox "Rows copied.", vbInformation
End Sub
You can try something like this:
Sub Scan()
Dim Barcode As String, rngData As Range, m, rngDest As Range
'Column with barcodes
With Worksheets("Sheet1")
Set rngData = .Range("D1", .Cells(Rows.Count, "D").End(xlUp))
End With
'First paste postion
Set rngDest = Worksheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Offset(1)
Do
Barcode = InputBox("Scan Barcode")
If Len(Barcode) = 0 Then Exit Do
'm = Application.Match(Barcode, rngData, 0) 'Barcodes formatted as text
m = Application.Match(CDbl(Barcode), rngData, 0) 'Barcodes formatted as numbers
If Not IsError(m) Then
rngData.Rows(m).EntireRow.Copy rngDest 'copy to Sheet2
Set rngDest = rngDest.Offset(1)
Else
'if no match then what?
Debug.Print "no match"
End If
Loop
End Sub
Depending on how your barcodes are stored (as text, or a numeric values) you may need to use CDbl(Barcode) inside the call to Match()

How to copy a range from sheet to other sheets?

I'm trying to create a macro that copies a certain range (CA1:CZ99) from "Sheet A" to lots of other sheets. The names of the other sheets are based on a value of column F in "Sheet B".
The code for copying the data is easy to find.
Worksheets("Sheet A").Range("CA1:CZ99").Copy Worksheets("Sheet X").Range("CA1")
But how do I loop this part over all the sheets from column F?
Copy a Range to Multiple Worksheets
Option Explicit
Sub CopyRange()
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Source
Dim sws As Worksheet: Set sws = wb.Worksheets("Sheet A")
Dim srg As Range: Set srg = sws.Range("CA1:CZ99")
' Lookup
Dim lws As Worksheet: Set lws = wb.Worksheets("Sheet B")
Dim lfRow As Long: lfRow = 2
Dim llRow As Long: llRow = lws.Cells(lws.Rows.Count, "F").End(xlUp).Row
If llRow < lfRow Then Exit Sub ' no data
Dim lrg As Range: Set lrg = lws.Cells(lfRow, "F").Resize(llRow - lfRow + 1)
' Copy to Destination
Dim dws As Worksheet
Dim lCell As Range
Dim lCount As Long
For Each lCell In lrg.Cells
On Error Resume Next ' check if the worksheet exists
Set dws = wb.Worksheets(CStr(lCell.Value))
On Error GoTo 0
If Not dws Is Nothing Then ' the worksheet exists
lCount = lCount + 1
srg.Copy dws.Range("CA1")
Set dws = Nothing
'Else ' the worksheet doesn't exist
End If
Next lCell
' Inform
MsgBox "Range copied to " & lCount & " worksheets.", _
vbInformation, "CopyRange"
End Sub
Specify exactly where to get the data from as a variable, and then loop over it. Example:
Sub loopCopy()
Dim shtRng As Range
Dim c As Variant
Set shtRng = Worksheets("Sheet B").Range("F1:F5")
For Each c In shtRng
Worksheets("Sheet A").Range("CA1:CZ99").Copy Worksheets(c.Value).Range("CA1")
Next c
End Sub
This is a very basic setup. If the value from the column doesn't match a sheet, or if "Sheet A" or "Sheet B" change names, it will crash.
You might want to have the list adjust in size dynamically by finding last row, etc.

VBA Selecting parts of multible columns

So I want to copy lets say Rows 5-15 from Columns B,E,G, from one worksheet to another.
So far I have tried it like this
Sheets("Table1").Select
Range("B5:B15,E5:E15,G5:G15").Select
Selection.Copy
Sheets("Table2").Select
Range("B4").Select
ActiveSheet.Paste
That's the concept.
I have much more Columns to copy and when doing it it doesn't work as I want like this
Sheets("Table1").Select
Range("CT5:CT15,CB5:CB15,CN5:CN15,DJ5:DJ15,DL5:DL15,E5:E15,AP5:AP15,CU5:CU15,AZ5:AZ15,AX5:AX15,CZ5:CZ15,CV5:CV15,AR5:AR15,AM5:AM15,Q5:Q15,CG5:CG15,AC5:AC15,R5:R15,CY5:CY15,G5:G15,Z5:Z15,C5:C15,DP5:DP15,Y5:Y15,X5:X15,CJ5:CJ15,DQ5:DQ15,CQ5:CQ15,AK5:AK15,AJ5:AJ15,BA5:BA15,BQ5:BQ15,CL5:CL15,BH5:BH15,DO5:DO15,AB5:AB15,CH5:CH15,CK5:CK15,P5:P15,CI5:CI15").Select
Selection.Copy
Sheets("Table2").Select
Range("B4").Select
ActiveSheet.Paste
Is there a way to streamline? To say I wand Row 5-15 from all these columns?
Thank you
You could use Intersect to get the range to copy.
Dim rngCopy As Range
Dim rngCols As Range
Dim rngRows As Range
With Sheets("Tabelle1")
Set rngCols = .Range("B:B, E:E, G:G")
Set rngRows = .Rows("5:15")
End With
Set rngCopy = Intersect(rngCols, rngRows)
rngCopy.Copy Sheets("Tabelle2").Range("A4")
Copy Non-Contiguous Columns Range
Adjust the values in the constants section.
Option Explicit
Sub copyMultiColumns()
' Source
Const sName As String = "Table1"
Const sRows As String = "5:15"
Const sColsList As String = "" _
& "C,E,G,P,Q,R,X,Y,Z," _
& "AB,AC,AJ,AK,AM,AP,AR,AX,AZ," _
& "BA,BH,BQ," _
& "CB,CG,CH,CI,CJ,CK,CL,CN,CQ,CT,CU,CV,CY,CZ," _
& "DJ,DL,DO,DP,DQ"
' Destination
Const dName As String = "Table2"
Const dFirst As String = "B4"
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Source
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim sCols() As String: sCols = Split(sColsList, ",")
Dim srg As Range
Dim n As Long
For n = 0 To UBound(sCols)
If srg Is Nothing Then
Set srg = sws.Columns(sCols(n))
Else
Set srg = Union(srg, sws.Columns(sCols(n)))
End If
Next n
Set srg = Intersect(srg, sws.Rows(sRows))
' Destination
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
srg.Copy dws.Range(dFirst)
End Sub

Resources