VBA Paste below collapsed Group - excel

I have a macro that copies rows from a Sheet named "Template" and pastes them onto the Active Sheet in the next blank row.
However this macro only works when the grouped cells on the Active Sheet are expanded.
If the grouped cells are collapsed, then the macro replaces a previous collapsed group.
I have done some reading and discovered that using a different method to calculate the last row i.e. the MergeArea property would work with collapsed groups but just sure how to apply it.
How could I achieve this with the current code?
This is my code:
Sub Paste_New_Product_from_Template()
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Dim LRow As Long, i As Long
Dim StartNumber As Long
Dim varString As String
'~~> This is your input sheet
Set copySheet = ThisWorkbook.Worksheets("Template")
'~~> Variable
varString = copySheet.Cells(2, 2).Value2
'~~> Change this to the relevant sheet
Set pasteSheet = ThisWorkbook.ActiveSheet
'~~> Initialize the start number
StartNumber = 1
With pasteSheet
'~~> Find the last cell to write to
If Application.WorksheetFunction.CountA(.Cells) = 0 Then
LRow = 2
Else
LRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
'~~> Find the previous number
For i = LRow To 1 Step -1
If .Cells(i, 2).Value2 = varString Then
StartNumber = .Cells(i, 6).Value2 + 1
Exit For
End If
Next i
End If
copySheet.Range("2:" & copySheet.Cells(Rows.Count, 1).End(xlUp).Row).Copy
.Rows(LRow).PasteSpecial Paste:=xlPasteAll
'~~> Set the start number
.Cells(LRow, 6).Value = StartNumber
'~~> Format the number
.Cells(LRow, 6).Value = "'" & Format(StartNumber, "000")
End With
End Sub
Here is the code that uses the MergeArea procedure:
Private Function RowIsEmpty(WSh As Worksheet, Row As Long, StartColumnNumber As Integer, EndColumnNuber As Integer) As Boolean
Dim j As Integer
RowIsEmpty = True
For j = StartColumnNumber To EndColumnNuber
If (WSh.Cells(WSh.Cells(Row, j).MergeArea.Row, WSh.Cells(Row, j).MergeArea.Column) <> "") Then
RowIsEmpty = False
Exit For 'One of columns isn't empty
End If
Next j
End Function
Private Function CalcLastRowNumber(WSh As Worksheet, StartColumnNumber As Integer, EndColumnNuber As Integer) As Long
Dim i As Long
Dim j As Integer
Dim Result As Long
Dim Found As Boolean
Result = 1
For i = 1 To Rows.Count
If RowIsEmpty(WSh, i, StartColumnNumber, EndColumnNuber) And _
RowIsEmpty(WSh, i + 1, StartColumnNumber, EndColumnNuber) And _
RowIsEmpty(WSh, i + 2, StartColumnNumber, EndColumnNuber) Then
'Stop searching
Exit For 'All Columns are empty for current row and for next 2 rows
End If
Result = i
Next i
CalcLastRowNumber = Result
End Function
Sub New_Reviss_Order()

Related

Copy 3rd Cell from under Same Row Where Col B is not empty

I have been trying to create a function which checks that if Col"B" <> Empty then copy the third cell which is under the same row.
I have this Data:
Where from i want to copy the Col"D" highlighted cells and paste them into same row where Col"B" <> empty.
Here is the final result. Your help will be appreciated in this regards.
Option Explicit
Sub CopyPasting()
Dim ws As Worksheet
Dim r As Long
Dim LastRow As Long
Dim n As Long
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
LastRow = .Range("D" & .Rows.Count).End(xlUp).Row
For r = LastRow To 2 Step -2
If .Cells(r, "B") <> "" Then
.Rows(r + "D").Copy
.Rows(r + "D").PasteSpecial
n = n + 1
End If
Next
End With
End Sub
Please, try the next code:
Sub testRetOffset3()
Dim sh As Worksheet, lastR As Long, rngV As Range, rngFin As Range, c As Range
Set sh = ActiveSheet 'use here the sheet you need
lastR = sh.Range("B" & sh.rows.count).End(xlUp).row 'last sheet row
On Error Resume Next 'if not empty cells in column, it will not return the range and raise an error
Set rngV = sh.Range("B2:B" & lastR).SpecialCells(xlCellTypeConstants)
On Error GoTo 0
If rngV Is Nothing Then Exit Sub 'stop the code if run on a wrong sheet, without empty cells in column B:B
For Each c In rngV.cells 'iterate between the discontinuous range cells
If rngFin Is Nothing Then 'if the final range is not set (first time)
Set rngFin = c.Offset(3, 2) 'set the range = the Offset necessary cell
Else
Set rngFin = Union(rngFin, c.Offset(3, 2)) 'make a Union between existing range and the Offset necessary cell
End If
Next
If Not rngFin Is Nothing Then 'copy both ranges in consecutive columns
rngV.Copy sh.Range("F2")
rngFin.Copy sh.Range("G2")
End If
End Sub
It will return in columns F:G, starting from the second row. It is easy to modify the range where to return...
You can even clear the existing processed columns and return in B:C, or in another sheet.
Edited:
In order to solve the last request, please use the next code:
Sub testRetOffsetMoreRows()
Dim sh As Worksheet, lastR As Long, rngV As Range, rngFin As Range, A As Range
Set sh = ActiveSheet
lastR = sh.Range("B" & sh.rows.count).End(xlUp).row
On Error Resume Next
Set rngV = sh.Range("A2:D" & lastR).SpecialCells(xlCellTypeConstants)
On Error GoTo 0
If rngV Is Nothing Then Exit Sub
For Each A In rngV.Areas 'iterate between the range areas
If rngFin Is Nothing Then
Set rngFin = A.cells(1,2).Offset(3, 3) 'use the second cell of the area
Else
Set rngFin = Union(rngFin, A.cells(1,2).Offset(3, 3))
End If
Next
If Not rngFin Is Nothing Then
rngV.Copy sh.Range("H2")
rngFin.Copy sh.Range("L2")
End If
End Sub
But take care to have continuous ranges when have a value in column B:B. Otherwise, the code may fail... The areas property will return differently.
I wasn't sure where you wanted the output, this will put it into a sheet called "Sheet2". (You'll have to make that before running the code it won't create it for you.)
Dim i As Long
Dim j As Long
Dim lr As Long
Dim srcWS As Worksheet
Dim destWS As Worksheet
Set srcWS = ThisWorkbook.Sheets("Sheet1")
Set destWS = ThisWorkbook.Sheets("Sheet2")
With srcWS
lr = .Cells(.Rows.Count, 4).End(xlUp).Row
j = 2
For i = 2 To lr
If .Cells(i, 2).Value <> "" Then
destWS.Cells(j, 1).Value = .Cells(i, 2).Value
destWS.Cells(j, 2).Value = .Cells(i, 4).Offset(2, 0).Value
j = j + 1
End If
Next i
End With
If you need the colors copied over as well then use this:
.Cells(i, 4).Offset(2, 0).Copy
destWS.Cells(j, 2).PasteSpecial xlPasteAll
instead of:
destWS.Cells(j, 2).Value = .Cells(i, 4).Offset(2, 0).Value

Copy rows from one sheet into six sheets

I’ve a spreadsheet that will have a different number of rows each day.
I am trying to divide that number of rows by 6 then copy the info into six different sheets within the same workbook.
For example – say the original sheet has 3000 rows. 3000 rows divided by 6 (500), copied into six different sheets or maybe there are 2475 rows, now dividing it by 6 and trying to keep the number of record split between sheets approximately the same (keeping the sheet with the original 3000 or 2475 rows as is) within the same workbook.
I have code that is creating 6 additional sheets but the records are not being copied to these sheets.
Option Explicit
Public Sub CopyLines()
Dim firstRow As Long
Dim lastRow As Long
Dim i As Long
Dim index As Long
Dim strsheetName As String
Dim sourceSheet As Worksheet
Dim strWorkbookName As Workbook
Sheets.Add
Sheets.Add
Sheets.Add
Sheets.Add
Sheets.Add
Sheets.Add
Set sourceSheet = Workbooks(strWorkbookName).Worksheets(strsheetName)
firstRow = sourceSheet.UsedRange.Row
lastRow = sourceSheet.UsedRange.Rows.Count + firstRow - 1
index = 1
For i = firstRow To lastRow
sourceSheet.Rows(i).Copy
Select Case index Mod 6
Case 0:
strsheetName = "Sheet1"
Case 1:
strsheetName = "Sheet2"
Case 2:
strsheetName = "Sheet3"
Case 3:
strsheetName = "Sheet4"
Case 4:
strsheetName = "Sheet5"
Case 5:
strsheetName = "Sheet6"
End Select
Worksheets(strsheetName).Cells((index / 6) + 1, 1).Paste
index = index + 1
Next i
End Sub
FEW THINGS:
Do not create sheets in the begining. Create them in a loop if required. This way you will not end up with blank sheets if there are only say 3 rows of data. Create them in a loop.
Also the code below assumes that you do not have Sheet1-6 beforehand. Else you will get an error at newSht.Name = "Sheet" & i
Avoid the use of UsedRange to find the last row. You may want to see see Finding last used cell in Excel with VBA
CODE:
I have commneted the code. You should not have a problem understanding the code but if you do then simply post back. Is this what you are trying?
Option Explicit
'~~> Set max sheets required
Const NumberOfSheetsRequired As Long = 6
Public Sub CopyLines()
Dim wb As Workbook
Dim ws As Worksheet, newSht As Worksheet
Dim lastRow As Long
Dim StartRow As Long, EndRow As Long
Dim i As Long
Dim NumberOfRecordToCopy As Long
Dim strWorkbookName as String
'~~> Change the name as applicable
strWorkbookName = "TMG JULY 2020 RENTAL.xlsx"
Set wb = Workbooks(strWorkbookName)
Set ws = wb.Sheets("MainSheet")
With ws
If Not Application.WorksheetFunction.CountA(.Cells) = 0 Then
'~~> Find last row
lastRow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
'~~> Get the number of records to copy
NumberOfRecordToCopy = lastRow / NumberOfSheetsRequired
'~~> Set your start and end row
StartRow = 1
EndRow = StartRow + NumberOfRecordToCopy
'~~> Create relevant sheet
For i = 1 To NumberOfSheetsRequired
'~~> Add new sheet
Set newSht = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count))
newSht.Name = "Sheet" & i
'~~> Copy the relevant rows
ws.Range(StartRow & ":" & EndRow).Copy newSht.Rows(1)
'~~> Set new start and end row
StartRow = EndRow + 1
EndRow = StartRow + NumberOfRecordToCopy
'~~> If start row is greater than last row then exit loop.
'~~> No point creating blank sheets
If StartRow > lastRow Then Exit For
Next i
End If
End With
Application.CutCopyMode = False
End Sub
Your code creates 6 sheets before it does anything with the data, which might be wasteful.
Also, once these sheets are created, there are no guarantee that they will have the names Sheet1, Sheet2, etc. These names might have already been used. That is why you should always check if the destination sheet exists before attempting to create them.
Option Explicit
Public Sub CopyLines()
Dim firstRow As Long
Dim lastRow As Long
Dim i As Long
Dim index As Long
Dim strSheetName As String
Dim sourceSheet As Worksheet
Dim strWorkbookName As String
'assume the current workbook is the starting point
strWorkbookName = ActiveWorkbook.Name
'assume that the first sheet contains all the rows
strSheetName = ActiveWorkbook.Sheets(1).Name
Set sourceSheet = Workbooks(strWorkbookName).Worksheets(strSheetName)
firstRow = sourceSheet.UsedRange.Row
lastRow = sourceSheet.UsedRange.Rows.Count + firstRow - 1
index = 1
For i = firstRow To lastRow
sourceSheet.Rows(i).Copy
Select Case index Mod 6
Case 0:
strSheetName = "Sheet1"
Case 1:
strSheetName = "Sheet2"
Case 2:
strSheetName = "Sheet3"
Case 3:
strSheetName = "Sheet4"
Case 4:
strSheetName = "Sheet5"
Case 5:
strSheetName = "Sheet6"
End Select
'check if the destination sheet exists
If Not Evaluate("ISREF('" & strSheetName & "'!A1)") Then
'if it does not, then create it
Sheets.Add
'and rename it to the proper destination name
ActiveSheet.Name = strSheetName
End If
'now paste the copied cells using PasteSpecial
Worksheets(strSheetName).Cells(Int(index / 6) + 1, 1).PasteSpecial
'advance to the next row
index = index + 1
'prevent Excel from freezing up, by calling DoEvents to handle
'screen redraw, mouse events, keyboard, etc.
DoEvents
Next i
End Sub
Try the next code, please. It uses arrays and array slices and it should be very fast:
Sub testSplitRowsOnSixSheets()
Dim sh As Worksheet, lastRow As Long, lastCol As Long, arrRows As Variant, wb As Workbook
Dim arr As Variant, slice As Variant, SplCount As Long, shNew As Worksheet
Dim startSlice As Long, endSlice As Long, i As Long, Cols As String, k As Long
Const shtsNo As Long = 6 'sheets number to split the range
Set wb = ActiveWorkbook 'or Workbooks("My Workbook")
Set sh = wb.ActiveSheet 'or wb.Sheets("My Sheet")
lastRow = sh.Range("A" & rows.count).End(xlUp).row 'last row of the sheet to be processed
lastCol = sh.UsedRange.Columns.count 'last column of the sheet to be processed
arr = sh.Range(sh.Range("A2"), sh.cells(lastRow, lastCol)) 'put the range in an array
SplCount = WorksheetFunction.Ceiling_Math(UBound(arr) / shtsNo) 'calculate the number of rows for each sheet
Cols = "A:" & Split(cells(1, lastCol).Address, "$")(1) 'determine the letter of the last column
clearSheets wb 'delete previous sheets named as "Sheet_" & k
For i = 1 To UBound(arr) Step SplCount 'iterate through the array elements number
startSlice = i: endSlice = i + SplCount - 1 'set the rows number to be sliced
'create the slice aray:
arrRows = Application.Index(arr, Evaluate("row(" & startSlice & ":" & endSlice & ")"), _
Evaluate("COLUMN(" & Cols & ")"))
'insert a new sheet at the end of the workbook:
Set shNew = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.count))
shNew.Name = "Sheet_" & k: k = k + 1 'name the newly created sheet
If UBound(arr) - i < SplCount Then SplCount = UBound(arr) - i + 1 'set the number of rows having data
'for the last slice
shNew.Range("A2").Resize(SplCount, lastCol).value = arrRows 'drop the slice array at once
Next i
End Sub
Sub clearSheets(wb As Workbook)
Dim ws As Worksheet
For Each ws In wb.Worksheets
If left(ws.Name, 7) Like "Sheet_#" Then
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
Next
End Sub
Try this following code. It streams through data and adds sheets dynamically, renames them according to the row# , copies the headers from the first row and the data block needed.
Public Sub DistributeData()
Const n_sheets As Long = 6
Dim n_rows_all As Long, n_cols As Long, i As Long
Dim r_data As Range, r_src As Range, r_dst As Range
' First data cell is on row 2
Set r_data = Sheet1.Range("A2")
' Count rows and columns starting from A2
n_rows_all = Range(r_data, r_data.End(xlDown)).Rows.Count
n_cols = Range(r_data, r_data.End(xlToRight)).Columns.Count
Dim n_rows As Long, ws As Worksheet
Dim n_data As Long
n_data = n_rows_all
' Get last worksheet
Set ws = ActiveWorkbook.Worksheets(ActiveWorkbook.Worksheets().Count)
Do While n_data > 0
' Figure row count to copy
n_rows = WorksheetFunction.Min(WorksheetFunction.Ceiling_Math(n_rows_all / n_sheets), n_data)
' Add new worksheet after last one
Set ws = ActiveWorkbook.Worksheets.Add(, ws, , XlSheetType.xlWorksheet)
ws.Name = CStr(n_rows_all - n_data + 1) & "-" & CStr(n_rows_all - n_data + n_rows)
' Copy Headers
ws.Range("A1").Resize(1, n_cols).Value = _
Sheet1.Range("A1").Resize(1, n_cols).Value
' Skip rows from source sheet
Set r_src = r_data.Offset(n_rows_all - n_data, 0).Resize(n_rows, n_cols)
' Destination starts from row 2
Set r_dst = ws.Range("A2").Resize(n_rows, n_cols)
' This copies the entire block of data
' (no need for Copy/Paste which is slow and a memory hog)
r_dst.Value = r_src.Value
' Update remaining row count to be copied
n_data = n_data - n_rows
' Go to next sheet, or wrap around to first new sheet
Loop
End Sub
Do not use Copy/Paste as it is slow and buggy. It is always a good idea to directly write from cell to cell the values. You can do that for an entire table of cells (multiple rows and columns) with one statement like in the example below:
ws_dst.Range("A2").Resize(n_rows,n_cols).Value = _
ws_src.Range("G2").Resize(n_rows,n_cols).Value
Sub split()
On Error Resume Next
Application.DisplayAlerts = False
Dim aws As String
Dim ws As Worksheet
Dim wb As Workbook
Dim sname()
sname = Array("one", "two", "three", "four", "five", "six")
aws = ActiveSheet.Name
For Each ws In Worksheets
If ws.Name = "one" Then ws.Delete
If ws.Name = "two" Then ws.Delete
If ws.Name = "three" Then ws.Delete
If ws.Name = "four" Then ws.Delete
If ws.Name = "five" Then ws.Delete
If ws.Name = "six" Then ws.Delete
Next ws
lr = (Range("A" & Rows.Count).End(xlUp).Row) - 1
rec = Round((lr / 6), 0)
Set ws = ActiveSheet
f = 1
t = rec + 1
i = 1
While i <= 6
Sheets.Add.Name = sname(i - 1)
Sheets(aws).Select
If i = 6 Then
Range("A" & (f + 1), "A" & (lr + 1)).Select
Else
Range("A" & (f + 1), "A" & t).Select
End If
Selection.Copy
Sheets(sname(i - 1)).Select
Range("A2").Select
ActiveSheet.Paste
Cells(1, 1).Value = ws.Range("A1").Value
f = f + rec
t = t + rec
i = i + 1
Wend
End Sub

Remove Duplicates in a Column and enter Sum in another Column

I want to remove duplicates based on the text in Column I and sum the values in Column C, the data in the other columns doesn't matter.
I do not want a pivot table and I am aware they are the preferred option for this type of thing.
An example of what I'd like to achieve:
I found VBA code and tried to modify it. It doesn't delete all the lines.
Sub Sum_and_Dedupe()
With Worksheets("data")
'deal with the block of data radiating out from A1
With .Cells(1, 1).CurrentRegion
'step off the header and make one column wider
With .Resize(.Rows.Count - 1, .Columns.Count + 1).Offset(1, 0)
.Columns(.Columns.Count).Formula = "=sumifs(c:c, i:i, i2)"
.Columns(3) = .Columns(.Columns.Count).Value
.Columns(.Columns.Count).Delete
End With
'remove duplicates
.RemoveDuplicates Columns:=Array(9), Header:=xlYes
End With
.UsedRange
End With
End Sub
This should be an answer to your question.
However, code might require adaptation if the range in which you look becomes very long.
Option Explicit
Sub test()
Dim wb As Workbook
Dim ws As Worksheet
Dim LastRow As Long, LastCol As Long, a As Double, i As Long
Dim Rng As Range
Dim Cell As Variant, Estimate As Variant
Set wb = ThisWorkbook
Set ws = wb.Sheets(1)
LastRow = ws.Cells(ws.Rows.Count, "I").End(xlUp).Row
LastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
Set Rng = ws.Range(ws.Cells(2, 9), ws.Cells(LastRow, 9))
For Each Cell In Rng
i = 0
a = 0
For Each Estimate In Rng
If Estimate.Value = Cell.Value Then
i = i + 1 'Count nr of intances
a = a + ws.Cells(Estimate.Row, 3).Value 'sum booking value
If i > 1 Then
ws.Rows(Estimate.Row).Delete
i = 1
LastRow = LastRow - 1
End If
End If
Next Estimate
ws.Cells(Cell.Row, 3).Value = a 'Enter sum in booked this week
Next Cell
End Sub
You'll either need to change your current sheet name to data, or change the first two lines of this code to fit your needs. sh = the data sheet that you showed us. osh = an output sheet that this code will generate. Note also if column C or I move you can update the positions easily by changing colBooked and colEstimate. If you have more than a thousand unique estimate entries then make the array number larger than 999.
Sub summariseEstimates()
Dim sh As String: sh = "data"
Dim osh As String: osh = "summary"
Dim colBooked As Integer: colBooked = 3
Dim colEstimate As Integer: colEstimate = 9
Dim myArray(999) As String
Dim shCheck As Worksheet
Dim output As Worksheet
Dim lastRow As Long
Dim a As Integer: a = 0
Dim b As Integer
Dim r As Long 'row anchor
Dim i As Integer 'sheets
'Build summary array:
With Worksheets(sh)
lastRow = .Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
For r = 2 To lastRow
If r = 2 Then 'first entry
myArray(a) = .Cells(r, colEstimate) & "," & .Cells(r, colBooked)
Else
For b = 0 To a
If VBA.LCase(VBA.Replace(.Cells(r, colEstimate), " ", "")) = VBA.LCase(VBA.Replace(VBA.Split(myArray(b), ",")(0), " ", "")) Then 'match
myArray(b) = VBA.Split(myArray(b), ",")(0) & "," & VBA.Split(myArray(b), ",")(1) + .Cells(r, colBooked)
Exit For
End If
Next b
If b = a + 1 Then 'completed loop = no match, create new array item:
a = a + 1
myArray(a) = .Cells(r, colEstimate) & "," & .Cells(r, colBooked)
End If
End If
Next r
End With
'Create summary sheet:
On Error Resume Next
Set shCheck = Worksheets(osh)
If Err.Number <> 0 Then
On Error GoTo 0
Set output = Worksheets.Add(After:=Worksheets(sh))
output.Name = osh
Err.Clear
Else
On Error GoTo 0
If MsgBox("*" & osh & "* sheet already exists. Proceed to delete and recreate?", vbOKCancel, "Summary") = vbCancel Then
Exit Sub
Else
Application.DisplayAlerts = False
Worksheets(osh).Delete
Set output = Worksheets.Add(After:=Worksheets(sh))
output.Name = osh
End If
End If
'Output to summary sheet:
With Worksheets(osh)
.Cells(1, 1).Value = "ESTIMATE"
.Cells(1, 2).Value = "BOOKED THIS WEEK"
For b = 0 To a
.Cells(b + 2, 1).Value = VBA.Split(myArray(b), ",")(0)
.Cells(b + 2, 2).Value = VBA.Split(myArray(b), ",")(1)
Next b
.Columns("A:B").AutoFit
End With
End Sub

Format number to be able to search properly

I am trying to format some numbers where some have a leading zero so that I can then search them.
I am needing to format a set of numbers where all are 6 digits and some have a leading zero. I then have a separate code search those numbers for a specific one so the resulting format needs to be searchable. The first code below is the formatting I can't figure out and then the search code. If I simply do an "000000" for formatting I don't believe it works for my search anymore as those now become Special format. Help please?
Sub (First Code)
Dim lngLastRow As Long
lngLastRow = Cells(Rows.Count, "A").End(xlUp).Row
Range("O2:P" & lngLastRow).Select 'specify the range which suits your purpose
With Selection
Selection.NumberFormat = "General"
.Value = .Value
End With
Dim SUPLCD As Range
Set SUPLCD = Range("Q2:Q")
With Selection
Selection.NumberFormat = "#"
Selection.Value = Format(Selection, "000000")
End With
End Sub
Sub Worksheet()
Dim i As Long
Dim j As Long
Dim wsCurrent As Worksheet
Set wsCurrent = ActiveSheet
Dim wsData As Worksheet
Dim rngData As Range
Set wsData = ThisWorkbook.Worksheets("Tempinterior")
Dim wsTempinterior As Worksheet
' Note that .Add will activate the new sheet so we'll
' need to reactivate the worksheet that was previously active
Set wsTempinterior = Worksheets.Add
wsTempinterior.Name = "copy"
' Find the used range in columns A to K and copy over starting
' at cell A1 of wsGalreq
Set rngData = Intersect(wsData.UsedRange, wsData.Range("A:M"))
' Copy over the first row containing column headers
j = 1
rngData.Rows(1).Copy Destination:=wsTempinterior.Cells(j, 1)
For i = 2 To rngData.Rows.Count
' Check cell of column 10 of row i and copy if matched
If rngData.Cells(i, 10).Value = "026572" Or rngData.Cells(i, 10).Value = "435740" Or rngData.Cells(i, 10).Value = "622639" Then
' Copy over to wsDalreq from row j
j = j + 1
rngData.Rows(i).Copy Destination:=wsTempinterior.Cells(j, 1)
End If
Next
End Sub
With above code, the search doesn't pull the entries with those numbers I think because they are formatted as Special.
You don't have to format Col Q to add a 0, you can accomplish your task with out formatting by using Like in your If statement. Because you are not clear about where the values are, you are formatting Col Q but searching Col J, I used Col Q.
Dim wsData As Worksheet
Set wsData = ThisWorkbook.Worksheets("Sheet1") '("Tempinterior")
Dim rngData As Range
Set rngData = Intersect(wsData.UsedRange, wsData.Range("A:M"))
Sheets.Add(After:=Sheets(Sheets.Count)).Name = "copy"
j = 1
rngData.Rows(1).Copy Destination:=Sheets("copy").Cells(j, 1) 'copy headers for rngData
For i = 2 To rngData.Rows.Count
If wsData.Cells(i, 17).Value Like "26572" Or Sheet1.Cells(i, 17).Value = "435740" Or _
Sheet1.Cells(i, 17).Value = "622639" Then
j = j + 1
rngData.Rows(i).Copy Destination:=Sheets("Copy").Cells(j, 1)
End If
Next i
End Sub
First avoid .Select and you will need to loop the change:
Sub first()
Dim lngLastRow As Long
With Worksheets("Sheet1") 'Change to your sheet
lngLastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
With .Range("O2:P" & lngLastRow) 'specify the range which suits your purpose
.NumberFormat = "General"
.Value = .Value
End With
Dim SUPLCD As Range
Set SUPLCD = .Range("Q2:Q" & lngLastRow)
Dim rng As Range
For Each rng In SUPLCD
rng.NumberFormat = "#"
rng.Value = Format(rng.Value, "000000")
Next rng
End With
End Sub

Excel - Fill with blocks of dates

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

Resources