I’ve got a workbook with 90000 lines and three worksheets (Sheet1, Sheet2, Sheet3)
Sheet 1 has the main data (90000 lines)
Sheet 2 has some data
Sheet 3 has some data
What I want is to split the data in sheet 1 into 5000 lines, copy sheet 2 and sheet 3 as it is and then save it as “filename-1”. I want to do this for all lines. I also need the headers in all split files. I want to save this in xml format.
If anyone can help will be great!
I have currently come until here, which splits sheet1 only and does not copy the headers and sheet2 and 3. And does not save it as xml. [ for sample purposes I’ve left this to save after every 5 rows]
Sub Macro1()
Dim rLastCell As Range
Dim rCells As Range
Dim strName As String
Dim lLoop As Long, lCopy As Long
Dim wbNew As Workbook
With ThisWorkbook.Sheets(1)
Set rLastCell = .Cells.Find(What:="*", After:=[A1], SearchDirection:=xlPrevious)
For lLoop = 1 To rLastCell.Row Step 5
lCopy = lCopy + 1
Set wbNew = Workbooks.Add
.Range(.Cells(lLoop, 1), .Cells(lLoop + 5, .Columns.Count)).EntireRow.Copy _
Destination:=wbNew.Sheets(1).Range("A1")
wbNew.Close SaveChanges:=True, Filename:="Chunk" & lCopy & "Rows" & lLoop & "-" & lLoop + 5
Next lLoop
End With
End Sub
Below is the code that does the trick!! May be helpful to someone.
Sub Macro1()
Dim inputFile As String, inputWb As Workbook
Dim lastRow As Long, row As Long, n As Long
Dim newCSV As Workbook
With ActiveWorkbook.Worksheets(1)
lastRow = .Cells(Rows.Count, "A").End(xlDown).row
Set newCSV = Workbooks.Add
n = 0
For row = 2 To lastRow Step 5
n = n + 1
.Rows(1).EntireRow.Copy newCSV.Worksheets(1).Range("A1")
.Rows(row & ":" & row + 5 - 1).EntireRow.Copy newCSV.Worksheets(1).Range("A2")
'Save in same folder as input workbook with .xlsx replaced by (n).csv
newCSV.SaveAs Filename:=n & ".CSV", FileFormat:=xlCSV, CreateBackup:=False
Next
End With
newCSV.Close saveChanges:=False
End Sub
Related
I have a workbook with multiple sheets, in each sheet I need to copy the same row contents to my master list. I have a code to get one cell value (which is N7) in each sheet to my master,
The problem is, in some sheets, the cell value to be get into master will be one cell , In other sheets, it will be two or more cells like (N7 TO N11)
How should I get this in to my master?
My current code is,
Dim DataFile As String
Workbooks.Open Filename:=Range("T3").Value
DataFile = ActiveWorkbook.Name
ThisWorkbook.Activate
Range("C4").Select
For i = 1 To Workbooks(DataFile).Worksheets.Count
ActiveCell.Value = Workbooks(DataFile).Worksheets(i).Range("N7").Value
ActiveCell.Offset(1, 0).Select
Next i
Please help me on this.
The following should work nicely, provided that you change the MasterFileSheetNameHere to your sheet name
Option Explicit
Sub CopyFromEachSheet()
Dim CurrentWorkSheet As Worksheet
Dim DataFile As Workbook
Dim DataFileLastRow As Long
Dim MasterFileSheet As Worksheet
Dim MasterFileLastRow As Long
Dim RangeToCopy As Range
Dim DataFileRowCount As Long
'Assuming that this scipt will be in your master file
'Replace with youor sheet name
Set MasterFileSheet = ThisWorkbook.Sheets("MasterFileSheetNameHere")
Set DataFile = Workbooks.Open(Filename:=MasterFileSheet.Range("T3").Value)
For Each CurrentWorkSheet In DataFile.Sheets
With MasterFileSheet
MasterFileLastRow = .Cells(.Rows.Count, "C").End(xlUp).Row
End With
With CurrentWorkSheet
DataFileLastRow = .Cells(.Rows.Count, "N").End(xlUp).Row
End With
Set RangeToCopy = CurrentWorkSheet.Range("N7:N" & DataFileLastRow)
'To insert rows before pasting into new rows
If RangeToCopy.Rows.Count > 1 Then
'-1 to counter the +2 below so that the additional rows are added below the first row in MasterFile
For DataFileRowCount = 1 To RangeToCopy.Rows.Count - 1
MasterFileSheet.Range("C" & MasterFileLastRow + 2).EntireRow.Insert xlDown
Next DataFileRowCount
End If
'Use this code to paste the values from DataFile to MasterFile
RangeToCopy.Copy MasterFileSheet.Range("C" & MasterFileLastRow + 1 & _
":C" & MasterFileLastRow + 1 + RangeToCopy.Rows.Count)
'Use this code if you want to transpose
'+1 here allows you to insert to the next unused line
'MasterFileSheet.Range("C" & MasterFileLastRow + 1).PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=True
Next CurrentWorkSheet
End Sub
HI Divya The below code may be helpful to u
Sub Selectvalue()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
Lastrow = Workbooks("Mastersheet").Sheets("sheet1").Range("C" & Rows.Count).End(xlUp).Row
Workbooks("Mastersheet").Sheets("sheet1").Range("C" & Lastrow).Offset(1, 0) = ws.Range("N7:N" & Cells(Rows.Count, "N").End(xlUp).Row)
Next ws
End Sub
The macro copies and pastes the values of a row X amount of times based on a cell value in M2. It pastes the exact numbers over and over. Is there a way to change it so that numbers will ascend as they are copied down?
E.g. if A2 contains "hello 3", after running the macro A3 will contain "hello 4", A4 will contain "hello 5".
Sub Sample()
Dim wsI As Worksheet, wsO As Worksheet
Dim lRow_I As Long, lRow_O As Long, i As Long, j As Long
'~~> Set your input and output sheets
Set wsI = ThisWorkbook.Sheets("Sheet1")
Set wsO = ThisWorkbook.Sheets("Sheet1")
'~~> Output row
lRow_O = wsO.Range("A" & wsO.Rows.Count).End(xlUp).Row + 1
With wsI
'~~> Get last row of input sheet
lRow_I = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Loop through the rows
For i = 2 To lRow_I
'~~> This will loop the number of time required
'~~> i.e the number present in cell M
For j = 1 To Val(Trim(.Range("M" & i).Value))
'~~> This copies
.Rows(i).Copy wsO.Rows(lRow_O)
'~~> Get the next output row
lRow_O = wsO.Range("A" & wsO.Rows.Count).End(xlUp).Row + 1
Next j
Next i
End With
End Sub
Example of how input screen and output screen should look:
Example of how output screen should look:
Actually no need for j loop if you use resize method.
Sub Sample()
Dim wsI As Worksheet, wsO As Worksheet, lCounter As Long
Dim lRow_I As Long, lRow_O As Long, i As Long
Set wsI = ThisWorkbook.Sheets("Sheet1")
Set wsO = ThisWorkbook.Sheets("Sheet2")
With wsI
lCounter = Val(Trim(.Range("M" & i).Value))
lRow_I = .Range("A" & .Rows.Count).End(xlUp).Row
For i = 2 To lRow_I
lRow_O = wsO.Range("A" & wsO.Rows.Count).End(xlUp).Row + 1
.Rows(i).Copy wsO.Rows(lRow_O).Resize(lCounter)
Next i
End With
I upgrade my solution to have the "counter" incremented
Sub Sample()
Dim wsI As Worksheet, wsO As Worksheet
Dim lRow_I As Long, lRow_O As Long, i As Long, nRowsToPaste As Long
Dim rngToCopy As Range, rngToPaste As Range
'~~> Set your input and output sheets
Set wsI = ThisWorkbook.Sheets("SheetI")
Set wsO = ThisWorkbook.Sheets("SheetO") '<=== I made it different that wsI
'~~> Output row
lRow_O = wsO.Range("A" & wsO.Rows.Count).End(xlUp).row + 1
With wsI
'~~> Get last row of input sheet
lRow_I = .Range("A" & .Rows.Count).End(xlUp).row
'~~> Loop through the rows
For i = 2 To lRow_I
nRowsToPaste = val(Trim(.Range("M" & i).Value)) '<== set number of rows to be pasted
Set rngToCopy = .Range(.Cells(i, 1), .Cells(i, wsI.Columns.Count).End(xlToLeft)) '<== set range to be copied
Set rngToPaste = wsO.Rows(lRow_O).Resize(1, rngToCopy.Columns.Count) '<== set 1st row of the range to be pasted
rngToCopy.Copy rngToPaste '<== copy&paste the 1st row in wsO sheet '<== copy and paste the 1st row
Call Prefix(rngToPaste) '<== differentiate each single cell of pasted range by means of adding a different prefix. this will subsequently have autofill method work on cells with originally the same value as well
With rngToPaste
.AutoFill .Resize(nRowsToPaste + 1) ' <== fill all rows exploiting AutoFill method, which will work on every column being their 1st row different from each other
.Resize(nRowsToPaste + 1).Replace What:="%%*%%", Replacement:="", LookAt:=xlPart '<== remove prefix
End With
lRow_O = lRow_O + nRowsToPaste + 1 '<== GET the next output row
Next i
End With
End Sub
Sub Prefix(rng As Range)
Dim j As Long
With rng
For j = 1 To .Columns.Count
.Cells(1, j).Value = "%%" & j & "%%" & .Cells(1, j).Value
Next j
End With
End Sub
where it eliminates the need of the inner j-loop and simply upgrades the lRow_O
I am writing a macro in Excel. Part of the code finds the cell that has "Attached Packaging" in it and then deletes the contents of a group of cells surrounding that cell.
Here is the code that currently achieves this:
Cells.Find("Attached Packaging").Activate
ActiveCell.Resize(2, 4).Select
Selection.Clear
ActiveCell.Offset(1, -1).Select
Selection.Clear
My problem now is that I, unexpectedly, have multiple cells with "Attached Packaging" in them which now also have to be deleted.
So, to summarize: I need to modify this code so It finds all "Attached Packaging" cells in a spreadsheet and deletes the group around them.
Sub clear()
Dim ws As Worksheet
Dim search As String
Dim f As Variant
Dim fRow As Long
Dim fCol As Long
search = "Attached Packaging"
Set ws = ThisWorkbook.Worksheets("Sheet4") 'change sheet as needed
With ws.Range("A1:AA1000") 'change range as needed
Set f = .Find(search, LookIn:=xlValues)
If Not f Is Nothing Then
Do
fRow = f.Row
fCol = f.Column
ws.Range(Cells(fRow, fCol), Cells(fRow + 1, fCol + 3)).clear
ws.Cells(fRow + 1, fCol - 1).clear
Set f = .FindNext(f)
Loop While Not f Is Nothing
End If
End With
End Sub
Sub clearCells()
Dim ws As Worksheet
Dim lastrow As Long, currow As Long
Dim critvalue As String
Set ws = Sheets("Sheet1")
' Change A to a row with data in it
lastrow = ws.Range("A" & Rows.Count).End(xlUp).Offset(1).Row - 1
'Change 2 to the first row to check
For currow = 2 To lastrow
critvalue = "Attached Packaging"
' Change A to the row you are looking in
If ws.Range("A" & currow).Value = critvalue Then
' Use the currow to select the row and then create an offset
ws.Range("A" & currow).offset("B" & currow - 1).clear
ws.Range("A" & currow).offset("B" & currow + 1).clear
End If
Next currow
End Sub
Make the changes needed where I commented. It should work.
I don't even know where to start so I don't have any example code. I am thinking that I need a nested loop but that is what throws me off. I look forward to learning from everyone.
Here is what I'd like to do:
Begin with the worksheet named "John" and loop through each worksheet to the right.
On each worksheet, if a cell in column L is not blank, copy cell F and cell L for that row.
Append all of the copied cells to the worksheet "Notes". Paste the data from F on each sheet to column A and paste the corresponding data from L in column B. Add the copied data from each worksheet to the end of the data in "Notes".
I really appreciate any help, thanks!!
UPDATE
Based on Alter's great help and suggestions, this is what I have and it works perfectly. Thanks Alter!
Sub test()
Dim ws As Worksheet
Dim notes_ws As Worksheet
Dim row
Dim lastrow
Dim notes_nextrow
'find the worksheet called notes
For Each ws In Worksheets
If ws.Name = "Notes" Then
Set notes_ws = ws
End If
Next ws
'get the nextrow to print to
notes_nextrow = notes_ws.Range("A" & Rows.Count).End(xlUp).row + 1
'loop through other worksheets
For Each ws In Worksheets
'ignore the notes worksheet
If ws.Name <> "Notes" And ws.Index > Sheets("John").Index Then
'find lastrow
lastrow = ws.Range("L" & Rows.Count).End(xlUp).row
For row = 1 To lastrow
'if the cell is not empty
If IsEmpty(ws.Range("L" & row)) = False Then
notes_ws.Range("A" & notes_nextrow).Value = ws.Range("F" & row).Value
notes_ws.Range("B" & notes_nextrow).Value = ws.Range("L" & row).Value
notes_nextrow = notes_nextrow + 1
End If
Next row
End If
Next ws
End Sub
Nested loop indeed, you can use the code below as a basis for what you want to do
Public Sub test()
Dim ws As Worksheet
Dim notes_ws As Worksheet
Dim row
Dim lastrow
Dim notes_nextrow
'find the worksheet called notes
For Each ws In Worksheets
If ws.name = "Notes" Then
Set notes_ws = ws
End If
Next ws
'get the nextrow to print to
notes_nextrow = notes_ws.Range("A" & Rows.Count).End(xlUp).row + 1
'loop through other worksheets
For Each ws In Worksheets
'ignore the notes worksheet
If ws.name <> "Notes" Then
'find lastrow
lastrow = ws.Range("L" & Rows.Count).End(xlUp).row
For row = 1 To lastrow
'if the cell is not empty
If IsEmpty(ws.Range("L" & row)) = False Then
notes_ws.Range("A" & notes_nextrow).Value = ws.Range("L" & row).Value
notes_nextrow = notes_nextrow + 1
End If
Next row
End If
Next ws
End Sub
I am writing a macro that copies a value from one excel worksheet, and pastes it into another. As seen below, I have a code that correctly copies and pastes my value into the correct worksheet, but I want it to paste into the next empty cell in row 3, instead of just cell "C3". All help is appreciated.
Private Sub CommandButton1_Click()
Dim wsMaster As Worksheet, wbDATA As Workbook
Dim NextRow As Long, LastRow As Long
Dim vMax As Variant
Set wsMaster = ThisWorkbook.Sheets("Contract Metrics")
NextRow = wsMaster.Range("A" & Rows.Count).End(xlUp).Row + 1
Set wbDATA = Workbooks.Open("C:\Documents and Settings\Michael Palkovitz\My Documents\Test\Contracts Metrics.xlsx")
With wbDATA.Sheets("Contract Task Summary(1)")
LastRow = .Range("C" & .Rows.Count).End(xlUp).Row
If LastRow > 1 Then
.Range("C" & LastRow).Copy
wsMaster.Range("C" & 3).PasteSpecial xlPasteValues
wsMaster.Range("C" & 3).PasteSpecial xlPasteFormats
End If
End With
wbDATA.Close False
End Sub
This is the code you are looking for:
Private Sub CommandButton1_Click()
Dim wsMaster As Worksheet, wbDATA As Workbook
Dim NextRow As Long, LastRow As Long
Dim vMax As Variant
Dim columnToPaste As Integer
Dim lastColumnToPaste As Integer
Dim lastColumn as Integer
Set wsMaster = ThisWorkbook.Sheets("Contract Metrics")
NextRow = wsMaster.Range("A" & Rows.Count).End(xlUp).Row + 1
Set wbDATA = Workbooks.Open("C:\Documents and Settings\Michael Palkovitz\My Documents\Test\Contracts Metrics.xlsx")
With wbDATA.Sheets("Contract Task Summary(1)")
LastRow = .Range("C" & .Rows.Count).End(xlUp).Row
If LastRow > 1 Then
.Range("C" & LastRow).Copy
lastColumn = 3
lastColumnToPaste = lastColumn + 20
columnToPaste = lastColumn - 1
Do
columnToPaste = columnToPaste + 1
If IsEmpty(wsMaster.Cells(lastRow, columnToPaste)) Then
wsMaster.Cells(lastRow, columnToPaste).PasteSpecial xlPasteValues
wsMaster.Cells(lastRow, columnToPaste).PasteSpecial xlPasteFormats
Exit Do
End If
Loop While (columnToPaste < lastColumnToPaste)
End If
End With
wbDATA.Close False
End Sub
This is just a basic approach to how the problem should be solved. You should update some values dynamically (e.g., maximum row to check, given by the variable lastRowToPaste).
Note that writing/pasting between two different workbooks is very inefficient. In case of having to repeat this process for a long enough time, I would: open the input spreadsheet and store all the values in a temporary location (depending upon the size, in an array or in a temporary file), close it; open the destination spreadsheet and write the data from this location (without relying on copy/paste). This is a much faster approach to the problem.