New to VBA
I am trying to copy rows containing a month from a table and paste them into cells. However, they paste upward instead of downward. Any help is appreciated.
Sub tblcopypast()
Dim Month As String
Dim tbl As ListObject
Dim i As Integer
Dim lastrow As Integer
Set tbl = ActiveSheet.ListObjects("Table1")
Month = ActiveSheet.Range("E1").Value
lastrow = tbl.ListRows.Count
For i = 1 To lastrow
If tbl.DataBodyRange(i, 2) = Month Then
tbl.ListRows(i).Range.Copy
ActiveSheet.Range("rng").End(xlUp).Offset(1, 0).PasteSpecial xlPasteValuesAndNumberFormats
End If
Next
End Sub
Your ActiveSheet.Range("rng").End(xlUp).Offset(1, 0).PasteSpecial is quite tricky. Especially in a loop. Try below code:
Option Explicit
Sub tblcopypast()
Dim Month As String
Dim tbl As ListObject
Dim iCt As Integer
Dim jCt As Integer
Dim lastrow As Integer
Dim targetRange As Range
Dim actRange As Range
Set tbl = ActiveSheet.ListObjects("Table1")
Month = ActiveSheet.Range("E1").Value
lastrow = tbl.ListRows.Count
jCt = 0
Set actRange = ActiveCell
Set targetRange = ActiveSheet.Range("rng").End(xlUp).Offset(1, 0)
For iCt = 1 To lastrow
If tbl.DataBodyRange(iCt, 2) = Month Then
tbl.ListRows(iCt).Range.Copy
targetRange.Offset(jCt, 0).PasteSpecial xlPasteValues
jCt = jCt + 1
End If
Next
actRange.Select
End Sub
Sub DefineSamples()
'sample data I used to review your code!
Dim cell As Range
Range("M1") = "F1"
Range("N1") = "F2"
Range("O1") = "F3"
Range("P1") = "F4"
For Each cell In Range("M2:P12")
cell.Value = Int(Rnd() * 100)
Next cell
Range("E1").Value = "Jan"
Range("N3").Value = "Jan"
Range("N5").Value = "Jan"
Range("N7").Value = "Jan"
Range("N9").Value = "Jan"
Range("N10").Value = "Jan"
Range("N11").Value = "Jan"
On Error Resume Next
ActiveSheet.ListObjects.Add(xlSrcRange, Range("$M$1:$P$12"), , xlYes).Name = "Table1"
On Error GoTo 0
Range("Table1").HorizontalAlignment = xlCenter
End Sub
Related
I have a "Data" worksheet that holds data. It has 20 columns A-U and in the G column is the date that is meant for dd/mm/yyyy. I have a separate worksheet called "NoEntry" and here is where I would like the dates to be entered by the user (Start-date L15 and End-date in L16) and once a button clicked all the data between and including the start and end date will go into another worksheet called "DateData".
The code I have below does not work at all and I don't know why. The error message I get is: Run-time error 1004:
Private Sub CommandButton2_Click()
Application.ScreenUpdating = False
Dim wsData As Worksheet, wsDate As Worksheet, wsNoEntry As Worksheet
Dim dSDate As Date, dEDate As Date
Dim lRowStart As Long, lRowEnd As Long
Dim aData() As Variant
Dim i As Long
'set the worksheet objects
Set wsData = ThisWorkbook.Sheets("Data")
Set wsDate = ThisWorkbook.Sheets("DateData")
Set wsNoEntry = ThisWorkbook.Sheets("NoEntry")
'required variables
dSDate = wsNoEntry.Range("L15").Value
dEDate = wsNoEntry.Range("L16").Value
'set the array - you can make this dynamic!
aData = wsData.Range("A1:U1000").Value
'for loop to find start
For i = 1 To 1000
If aData(i, 7) = dSDate Then
lRowStart = i
Debug.Print "Start row = " & lRowStart
Exit For
End If
Next i
'now loop backwards to find end date
For i = 1000 To 1 Step -1
If aData(i, 7) = dEDate Then
lRowEnd = i
Exit For
End If
Next i
'now we have start and end dates
'going to use copy/ paste for simplicity
wsData.Range("A" & lRowStart, "U" & lRowEnd).Copy
'paste in date sheet
wsDate.Range("A1").PasteSpecial Paste:=xlPasteValues
'clear clipboard
Application.CutCopyMode = False
Application.ScreenUpdating = True
End Sub
Any help would be much appreciated,
Thanks :)
Try this one:
Private Sub CommandButton2_Click()
Dim wsData As Worksheet, wsDate As Worksheet, wsNoEntry As Worksheet
Dim dSDate As Date, dEDate As Date
Dim lRowStart As Long, lRowEnd As Long
Dim aData() As Variant
Dim i As Long
Application.ScreenUpdating = False
Set wsData = ThisWorkbook.Sheets("Data")
Set wsDate = ThisWorkbook.Sheets("DateData")
Set wsNoEntry = ThisWorkbook.Sheets("NoEntry")
dSDate = wsNoEntry.Range("L15").Value
dEDate = wsNoEntry.Range("L16").Value
j = 1
For i = 1 To 1000
If wsData.Cells(i, 7).Value >= dSDate and wsData.Cells(i, 7).Value <= dEDate Then
Range("A" & i & ":U" & i).Copy Destination:=wsDate.Range("A" & j)
j = j + 1
End If
Next i
Application.ScreenUpdating = True
End Sub
Hope it helps
I am looking to fill a spreadsheet with data repeating data, so 25 appointments for today, 25 appointments for tomorrow with the same name and so on for as far as possible.
Is the a simple way of filling the table where the date increases in blocks of 25?
Example of what i am trying to do
Try using this you might be able to achieve what you want ,any problems shout out
'to change the date to the next day
Public Function ExtraDay(strDate As String)
Dim tDay As Date
tDay = Format(DateAdd("d", 1, strDate), "dd/mm/yy")
ExtraDay = tDay
End Function
'gets the last used row
Function getThelastUsedRowAddress() As Integer
'Get Last Row in Worksheet UsedRange
Dim LastRow As Range, ws As Worksheet
Set ws = ActiveSheet
MsgBox ws.UsedRange.Rows(ws.UsedRange.Rows.Count).Row
getThelastUsedRowAddress = ws.UsedRange.Rows(ws.UsedRange.Rows.Count).Row
End Function
'button command on the sheet
Private Sub CommandButton1_Click()
Dim n, t As Integer
Dim ns As String
n = getThelastUsedRowAddress()
t = n + n
ns = CStr(t)
Call getThelastUsedRow(CStr(n))
Call TheLoopRange(CStr(n) + 1, ns)
End Sub
'get the last used and paste after
Sub getThelastUsedRow(address As String)
'Get Last Row in Worksheet UsedRange
Dim LastRow As Range, ws As Worksheet
Dim numcopied As Integer
Dim numonpaper As Integer
Set ws = ActiveSheet
numcopied = ws.UsedRange.Rows(ws.UsedRange.Rows.Count).Row
numonpaper = numcopied + 1
ws.UsedRange.Copy 'Destination:=Wst.Cells(1, 1)
'paste
Sheets("Sheet1").Range("A" & numonpaper).PasteSpecial xlPasteValues
End Sub
'loop the pasted range and change date to the next day from date
Sub TheLoopRange(rangestart As String, rangeend As String)
'rangestart,rangeend
Dim rCell As Range
Dim rRng As Range
Set rRng = Sheet1.Range("E" & rangestart & ":E" & rangeend)
For Each rCell In rRng.Cells
'MsgBox rCell.Value
rCell.Value = ExtraDay(rCell.Value)
Next rCell
End Sub
Lets as assume that:
We use Sheet1
Company column is column D
Date column is column I
Pease try:
Option Explicit
Sub Test()
Dim Lastrow As Long, i As Long
With ThisWorkbook.Worksheets("Sheet1")
Lastrow = .Cells(.Rows.Count, "D").End(xlUp).Row
For i = 2 To Lastrow
If i = 2 Then
.Cells(i, 9).Value = Date + 1
ElseIf i <> 2 And .Cells(i, 4).Value = 1 Then
.Cells(i, 9).Value = .Cells(i, 9).Offset(-1, 0).Value + 1
Else: .Cells(i, 9).Value = .Cells(i, 9).Offset(-1, 0).Value
End If
Next i
End With
End Sub
I may have up to 8 unique values in column D. I am looking for a code that will copy & paste each row with unique value to a new sheet.
So I may have up to 8 new sheets.
Could you help me to build the code that will do that?
This is what I have so far:
Option Explicit
Sub AddInstructorSheets()
Dim LastRow As Long, r As Long, iName As String
Dim wb As Workbook, ws As Worksheet, ts As Worksheet, nws As Worksheet
Dim i As Integer
Dim m As Integer
'set objects
Set wb = ActiveWorkbook
Set ws = ActiveSheet
Set ts = Sheets("Master")
'set last row of instructor names
LastRow = ws.Cells(ws.Rows.Count, "K").End(xlUp).Row
'add instructor sheets
On Error GoTo err
Application.ScreenUpdating = False
For r = 17 To LastRow 'assumes there is a header
iName = ws.Cells(r, 4).Value
With wb 'add new sheet
ts.Copy After:=.Sheets(.Sheets.Count) 'add template
Set nws = .Sheets(.Sheets.Count)
nws.Name = iName
Worksheets(iName).Rows("17:22").Delete
Worksheets("Master").Activate
Range(Cells(r, 2), Cells(r, 16)).Select
Selection.Copy
m = Worksheets(iName).Range("A15").End(xlDown).Row
Worksheets(iName).Cells(m + 1, 1).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End With
Next r
err:
ws.Activate
Application.ScreenUpdating = True
End Sub
The thing is that this macro is creating new sheets, which is not necessary. I only want to make following.
If you find a unique value in column D (which will have exact name as other sheet), find this sheet and paste whole row in there.
Sub CopyFromColumnD()
Dim key As Variant
Dim obj As Object
Dim i As Integer, lng As Long, j As Long
Dim sht As Worksheet, mainsht As Worksheet
Set obj = CreateObject("System.Collections.ArrayList")
Set mainsht = ActiveSheet
With mainsht
lng = .Range("D" & .Rows.Count).End(xlUp).Row
With .Range("D1", .Range("D" & lng))
For Each key In .Value
If Not obj.Contains(key) Then obj.Add key
Next
End With
End With
For i = 0 To obj.Count - 1
Set sht = Sheets.Add(After:=Sheets(Sheets.Count))
sht.Name = obj(i)
For j = 1 To lng
If mainsht.Cells(j, 4).Value = obj(i) Then
mainsht.Rows(j).EntireRow.Copy Destination:=Range("A1")
Exit For
End If
Next
Next
End Sub
Ok, I did the workaround. I have created a list of unique values in a separate sheet.
Sub copypaste()
Dim i As Integer
Dim j As Integer
LastRow = Worksheets("Master").Range("D17").End(xlDown).Row
For i = 17 To LastRow
For j = 2 To 10
Workstream = Worksheets("Database").Cells(j, 5).Value
Worksheets("Master").Activate
If Cells(i, 4) = Worksheets("Database").Cells(j, 5).Value Then
Range(Cells(i, 2), Cells(i, 16)).Select
Selection.Copy
Worksheets(Workstream).Cells(1, 1).PasteSpecial Paste:=xlPasteValues
Else
End If
Next j
Next i
End Sub
Thank you everyone for help and your time!
I am trying to clear the contents of worksheet one after the following macro. I have tried using Sheets("Sheet1").UsedRange.ClearContents, but it seems to clear both sheets. I have a feeling it has to do with the Do...Until loop I have, despite putting the clear line right after Loop. This is the first macro I have written and am still learning hence all the comments.
Sub LookUpTable()
'Declare Variables'
Dim rngB As Range
Dim Rng As Range
Dim sh As Worksheet
Dim iCountComma
Dim VarArr As Variant
Dim i As Long
'Separate Cell C2 into Column C by Comma'
Set sh = Sheets("Sheet1")
Set rngB = sh.Range("C2")
For Each Rng In rngB
If InStr(Rng, ",") > 0 Then
iCountComma = Len(Rng) - Len(Replace(Rng, ",", ""))
VarArr = Split(Rng, ",")
For i = 0 To iCountComma
Rng.Offset(i) = Trim(VarArr(i))
Next
End If
Next
'I Don't really know what these do'
Application.CutCopyMode = True
Application.ScreenUpdating = True
'Declare Variables'
Dim BedPre As String
Dim BedSuf As String
Dim HISPre As String
Dim HISSuf As String
Dim ID As String
Dim Bed As String
Dim HIS As String
Dim NextRow As Long
'Assign cell values to variables'
BedPre = Range("A2").Value
BedSuf = Range("B2").Value
HISPre = Range("D2").Value
HISSuf = Range("E2").Value
ID = Range("F2").Value
'Select Cell C2'
Sheets("Sheet1").Select
Range("C2").Select
'Loop until empty value in Column C'
Do Until ActiveCell.Value = ""
'Find last empty cell in sheet 2'
NextRow = Sheets("Sheet2").Cells(Sheets("Sheet2").Rows.Count, "A").End(xlUp).Offset(1, 0).Row
'Concantenate cells and append Sheet 2'
Bed = BedPre & ActiveCell & BedSuf
HIS = HISPre & ActiveCell & HISSuf
Sheets("Sheet2").Cells(NextRow, 1) = Bed
Sheets("Sheet2").Cells(NextRow, 2) = HIS
Sheets("Sheet2").Cells(NextRow, 3) = ID
ActiveCell.Offset(1, 0).Select
Loop
Sheets("Sheet1").UsedRange.ClearContents
End Sub
I dont see data clear both sheets.
you can use this code
Sub LookUpTable()
'Declare Variables'
Dim Rng As Range
Dim VarArr As Variant
Dim i As Long
Dim BedPre As String
Dim BedSuf As String
Dim HISPre As String
Dim HISSuf As String
Dim ID As String
Dim Bed As String
Dim HIS As String
Dim NextRow As Long
'Assign cell values to variables'
With Sheets("Sheet1")
BedPre = Range("A2").Value
BedSuf = Range("B2").Value
HISPre = Range("D2").Value
HISSuf = Range("E2").Value
ID = Range("F2").Value
Set Rng = .Range("C2")
End With
NextRow = Sheets("Sheet2").Cells(Sheets("Sheet2").Rows.Count, "A").End(xlUp).Offset(1, 0).Row
If InStr(Rng, ",") > 0 Then
VarArr = Split(Rng, ",")
For i = 0 To UBound(VarArr)
Bed = BedPre & Trim(VarArr(i)) & BedSuf
HIS = HISPre & Trim(VarArr(i)) & HISSuf
NextRow = NextRow + 1
Sheets("Sheet2").Cells(NextRow, 1) = Bed
Sheets("Sheet2").Cells(NextRow, 2) = HIS
Sheets("Sheet2").Cells(NextRow, 3) = ID
Next
End If
Sheets("Sheet1").Range("A2:F2").ClearContents
End Sub
What I want to do is, if there is a "1" in column A* then I want the macro to copy the rows, from column B*:L* to a new worksheet, then print the worksheet when it is has gone through the complete range.
If there is no "1" in column A then I just want it to continue to the next row to check. Would love some help?
Sub PrintFlaggedRows()
Const STARTSEARCHROW As Long = 1
Const STARTPRINTROW As Long = 2
Const ENDSEARCHROW As Long = 250
Const STARTCOLUMN As Integer = 1 ' Column A
Const ENDCOLUMN As Integer = 1 ' Column A
Dim oldAlerts As Boolean
Dim oldUpdates As Boolean
Dim destSheet As Worksheet
Dim srcSheet As Worksheet
Dim destRange As Range
Dim i As Long
oldUpdates = Application.ScreenUpdating
Application.ScreenUpdating = False
oldAlerts = Application.DisplayAlerts
Application.DisplayAlerts = False
Set srcSheet = Sheets("Estimating & Building Quote")
Set destSheet = Worksheets.Add
Set destRange = destSheet.Cells(STARTPRINTROW, 1)
For i = STARTSEARCHROW To ENDSEARCHROW
If (srcSheet.Cells(i, 1) = 1) _
Or (srcSheet.Cells(i, 1) = "1") Then
srcSheet.Range(Cells(i, STARTCOLUMN), Cells(i, ENDCOLUMN)).Copy
dstRange.PasteSpecial xlPasteValues
dstRange.PasteSpecial xlPasteFormats
Set dstRange = dstRange.Offset(0, 1)
End If
Next i
destSheet.Columns.AutoFit
destSheet.PrintOut
destSheet.Delete
Application.DisplayAlerts = oldAlerts
Application.ScreenUpdating = oldUpdates
End Sub
srcSheet.Range(Cells(i, STARTCOLUMN), Cells(i, ENDCOLUMN)).Copy
Here the unqualified Cells() refers always to the ActiveSheet, which may not be what you want.
Try:
With srcSheet
.Range(.Cells(i, STARTCOLUMN), .Cells(i, ENDCOLUMN)).Copy
End With