I need help creating separate text files from each row in an excel spread sheet called "worksheet". I want the text files to be named with content of Column A, with columns B-G being the content, preferably with a double hard return between each column in the text file, so each column will have a blank line in between them.
Is this possible? How would I go about it. thanks!
#nutsch's answer is perfectly fine and should work 99.9% of the time. In the rare occasion that FSO is not available, here's a version that doesn't have a dependency. As is, it does require that the source worksheet doesn't have any blank rows in the content section.
Sub SaveRowsAsCSV()
Dim wb As Excel.Workbook, wbNew As Excel.Workbook
Dim wsSource As Excel.Worksheet, wsTemp As Excel.Worksheet
Dim r As Long, c As Long
Set wsSource = ThisWorkbook.Worksheets("worksheet")
Application.DisplayAlerts = False 'will overwrite existing files without asking
r = 1
Do Until Len(Trim(wsSource.Cells(r, 1).Value)) = 0
ThisWorkbook.Worksheets.Add ThisWorkbook.Worksheets(1)
Set wsTemp = ThisWorkbook.Worksheets(1)
For c = 2 To 7
wsTemp.Cells((c - 1) * 2 - 1, 1).Value = wsSource.Cells(r, c).Value
Next c
wsTemp.Move
Set wbNew = ActiveWorkbook
Set wsTemp = wbNew.Worksheets(1)
'wbNew.SaveAs wsSource.Cells(r, 1).Value & ".csv", xlCSV 'old way
wbNew.SaveAs "textfile" & r & ".csv", xlCSV 'new way
'you can try other file formats listed at http://msdn.microsoft.com/en-us/library/office/aa194915(v=office.10).aspx
wbNew.Close
ThisWorkbook.Activate
r = r + 1
Loop
Application.DisplayAlerts = True
End Sub
The attached VBA macro will do it, saving the txt files in C:\Temp\
Sub WriteTotxt()
Const forReading = 1, forAppending = 3, fsoForWriting = 2
Dim fs, objTextStream, sText As String
Dim lLastRow As Long, lRowLoop As Long, lLastCol As Long, lColLoop As Long
lLastRow = Cells(Rows.Count, 1).End(xlUp).Row
For lRowLoop = 1 To lLastRow
Set fs = CreateObject("Scripting.FileSystemObject")
Set objTextStream = fs.opentextfile("c:\temp\" & Cells(lRowLoop, 1) & ".txt", fsoForWriting, True)
sText = ""
For lColLoop = 1 To 7
sText = sText & Cells(lRowLoop, lColLoop) & Chr(10) & Chr(10)
Next lColLoop
objTextStream.writeline (Left(sText, Len(sText) - 1))
objTextStream.Close
Set objTextStream = Nothing
Set fs = Nothing
Next lRowLoop
End Sub
For the benefit of others, I sorted the problem out. I replaced "Chr(10) & Chr(10)" with "Chr(13) & Chr(10)" and it worked perfectly.
I used the simple code below for saving my excel rows as a text file or many other format for quite a long time now and it has always worked for me.
Sub savemyrowsastext()
Dim x
For Each cell In Sheet1.Range("A1:A" & Sheet1.UsedRange.Rows.Count)
' you can change the sheet1 to your own choice
saveText = cell.Text
Open "C:\wamp\www\GeoPC_NG\sogistate\igala_land\" & saveText & ".php" For Output As #1
Print #1, cell.Offset(0, 1).Text
Close #1
For x = 1 To 3 ' Loop 3 times.
Beep ' Sound a tone.
Next x
Next cell
End Sub
Note:
1. Column A1 = file title
2. column B1 = file content
3. Until the last row containing text (ie empty rows)
in reverse order, if you want to make it like this;
1. Column A1 = file title
2. column A2 = file content
3. Until the last row containing text (ie empty rows), just change Print #1, cell.Offset(0, 1).Text to Print #1, cell.Offset(1, 0).Text
My folder location = C:\wamp\www\GeoPC_NG\kogistate\igala_land\
My file extension = .php, you can change the extension to your own choice (.txt, .htm & .csv etc)
I included bip sound at the end of each saving to know if my work is going on
Dim x
For x = 1 To 3 ' Loop 3 times.
Beep ' Sound a tone.
Related
I have an excel data file with 2 sheet named "Data" and "GL Data"
Both these sheets contain a column called "Leader" which has 4 different names - say D1, D2, D3 and D4
I have 4 other workbooks named - Data_D1, Data_D2, Data_D3 and Data_D4 each with 2 sheet named "Data" and "GL Data".
I need to put each Leader's data in their sheet. That is :
1- Apply a filter on Leader column in sheet "data" and select D1
2- copy the filtered rows to "data" sheet of workbook Data_D1
3- Apply a filter on Leader column in sheet "GL data" and select D1
4- copy the filtered rows to "GL data" sheet of workbook Data_D1
5- Repeat the above steps for D2, D3 and D4
I am wondering if there's a better way of doing this quickly. I searched online but couldn't find anything. Any help would be useful. Thank you.
EDIT: Wrote some VBA code (see answer below). Facing some problem with its working.
I wrote the following code but I can't seem to figure out why the second time the second loop runs, the filtered values are not copied. Do I need to reset the filter or something ? The first loop seems to be working.
Sub foo()
Dim yr As String
Dim lastPd As String
Dim thisPd As String
Dim x As Workbook
Dim y As Workbook
Dim vals As Variant
Dim lr As Long
Dim strNames(1 To 4) As String
Dim fileNames(1 To 4) As String
Dim path As String
Dim sourceFileName As String
Dim i As Integer
Dim j As Integer
yr = "2022"
sourceFileName = "sourcefilename.xlsx"
path = "path to the file"
'populate the arrays
strNames(1) = "D1"
strNames(2) = "D2"
strNames(3) = "D3"
strNames(4) = "D4"
fileNames(1) = "Data_D1.xlsx"
fileNames(2) = "Data_D2.xlsx"
fileNames(3) = "Data_D3.xlsx"
fileNames(4) = "Data_D4.xlsx"
For i = 1 To 4
Set x = Workbooks.Open(path & sourceFileName)
x.Activate
Sheets("DATA").Activate
lr = Cells(Rows.Count, 1).End(xlUp).Row
Set y = Workbooks.Open(path & fileNames(i))
x.Sheets("DATA").Range("A1:N" & lr).AutoFilter Field:=14, Criteria1:=strNames(i)
x.Sheets("DATA").Range("A1:L" & lr).SpecialCells(xlCellTypeVisible).Copy
y.Sheets("DATA").Cells(1, 1).PasteSpecial
Next i
For j = 1 To 4
Set x = Workbooks.Open(path & sourceFileName)
x.Activate
Sheets("GL Data").Activate
lr = Cells(Rows.Count, 1).End(xlUp).Row
Set y = Workbooks.Open(path & fileNames(j))
x.Sheets("GL Data").Range("A1:P" & lr).AutoFilter Field:=15, Criteria1:=strNames(j)
x.Sheets("GL Data").Range("A1:L" & lr).SpecialCells(xlCellTypeVisible).Copy
y.Sheets("GL Data").Cells(1, 1).PasteSpecial
Next j
End Sub
I have some remarks about your VBA code :
1- The sourcefilename.xlsx file must be opened one. So, the opening
of the file has to be outside the two Next loop (i and j).
2- The filter (Autofilter) must be disabled (turned to False) before each
change of criterion.
3- The copy/paste operation can be done in same
line, like this source.Copy destination
4- Try to add one row (first)
on DATA & GL Data sheets of sourcefilename.xlsx. Because, when you
filter the first line is considered as header, so it's not filtered.
5- In the header of the VBA module (the first line). you have to put
the syntax: Option Base 1 so that the first element has the index
= 1 (and not 0).
I made some changes to your code. It does run perfectly :)
Sub foo()
Dim yr As String
Dim lastPd As String
Dim thisPd As String
Dim x As Workbook
Dim y As Workbook
Dim vals As Variant
Dim lr As Long
Dim strNames(1 To 4) As String
Dim fileNames(1 To 4) As String
Dim path As String
Dim sourceFileName As String
Dim i As Integer
Dim j As Integer
yr = "2022"
sourceFileName = "sourcefilename.xlsx"
path = "path to the file"
'populate the arrays
strNames(1) = "D1"
strNames(2) = "D2"
strNames(3) = "D3"
strNames(4) = "D4"
fileNames(1) = "Data_D1.xlsx"
fileNames(2) = "Data_D2.xlsx"
fileNames(3) = "Data_D3.xlsx"
fileNames(4) = "Data_D4.xlsx"
'Open the Main workbook
Workbooks.Open Filename:=Path & sourceFileName
Set x = ActiveWorkbook
For i = 1 To 4
x.Sheets("DATA").Activate
x.Sheets("DATA").AutoFilterMode = False
lr = Cells(Rows.Count, 1).End(xlUp).Row
Set Y = Workbooks.Open(Path & fileNames(i))
x.Sheets("DATA").Range("A1:N" & lr).AutoFilter Field:=14, Criteria1:=strNames(i)
x.Sheets("DATA").Range("A2:L" & lr).SpecialCells(xlCellTypeVisible).Copy Y.Sheets("DATA").Cells(1, 1)
Range("A1").Select
Next i
x.Sheets("DATA").AutoFilterMode = False
For j = 1 To 4
x.Activate
x.Sheets("GL Data").Activate
x.Sheets("GL Data").AutoFilterMode = False
lr = Cells(Rows.Count, 1).End(xlUp).Row
Set Y = Workbooks(fileNames(j))
x.Sheets("GL Data").Range("A1:P" & lr).AutoFilter Field:=15, Criteria1:=strNames(j)
x.Sheets("GL Data").Range("A2:L" & lr).SpecialCells(xlCellTypeVisible).Copy Y.Sheets("GL Data").Cells(1, 1)
Range("A1").Select
Next j
x.Sheets("GL Data").AutoFilterMode = False
End Sub
I have the below code that is copy & pasting data from one sheet to another.
If you need further details:Offset the Copy Row as part of a Loop
The main problem I am having is retaining the leading zero on the sizes once split into individual rows.
COL_SIZE in "SS21 Master Sheet"= 06|612|1218|1824
Column "AH" in "Buysheet" is = 6
612
1218
1824
How can i set column AH as Text so that it retains the zero (06)? I have tried a couple of options but none of them are working at the moment.
Private Sub Workbook_Open()
Sheets("BUYSHEET").Cells.Clear
Const COL_SIZE As String = "AO" 'This is the column with all the sizes listed in the mini master
Dim wb1 As Workbook, wsSource As Worksheet
Set wb1 = Workbooks.Open("U:\Design\KIDS\SS21 Kids Miniscale (Master) .xlsm") ' This is the file path to your mini master.
Dim wb2 As Workbook, wsTarget As Worksheet
Set wb2 = ThisWorkbook
Dim iLastRow As Long, iTarget As Long, iRow As Long
Dim rngSource As Range, ar As Variant, i As Integer
Set wsSource = wb1.Sheets("SS21 Master Sheet") ' This is the name of your manster tab
Set wsTarget = wb2.Sheets("BUYSHEET") 'this ths the name of your buysheet tab
iLastRow = wsSource.Range("A" & Rows.Count).End(xlUp).Row
iTarget = wsTarget.Range("A" & Rows.Count).End(xlUp).Row
With wsSource
For iRow = 1 To iLastRow
Set rngSource = Intersect(.Rows(iRow).EntireRow, .Range("A:C, E:Y, Z:AF, AH:AI, AO:AO")) 'This columns you want to pull though to the buysheet tab (if one column must still be range eg, AO:AO)
If iRow = 1 Then
rngSource.Copy wsTarget.Range("A1")
iTarget = iTarget + 1
Else
ar = Split(.Range(COL_SIZE & iRow), "|")
For i = 0 To UBound(ar)
rngSource.Copy wsTarget.Cells(iTarget, 1)
wsTarget.Range("AH" & iTarget).Value = ar(i) 'AI is the column the sizes will populate in - We want this to replace the size list
iTarget = iTarget + 1
Next
End If
Next
MsgBox "Completed"
End With
Ok, I see what's going on now.
wsTarget.Range("AH" & iTarget).Value = ar(i)
If that's writing 06, then Excel will be treating that as a number and make it 6.
You could "format as text" like this, before you write the value:
With wsTarget.Range("AH" & iTarget)
.NumberFormat = "#"
.Value = ar(i)
End With
Or you could just prefix the value with an apostrophe / single-quote:
wsTarget.Range("AH" & iTarget).Value = "'" & ar(i)
Either will do what you want.
This is odd, because it doesn't always happen as described here.
This Macro allows me to select multiple (non-adjacent) rows in any Workbook or Worksheet, copy them to clipboard and delete the rows.
Sub CopytoClipboardandDelete()
Dim obj As New MSForms.DataObject
Dim X, str As String
Dim count As Integer
count = 0
For Each X In Selection
count = count + 1
If X <> "" Then
If count = 1 Then
str = str & X
Else
str = str & Chr(9) & X
End If
End If
If count = 16384 Then
str = str & Chr(13)
count = 0
End If
Next
obj.SetText str
obj.PutInClipboard
Selection.Delete Shift:=xlUp
End Sub
Now, often, when I get to the Active Workbook or Worksheet to paste the row values the row line breaks are lost and all the data goes into the first single row.
Since this occurs so often, I setup a Macro to easily deal with this.
The problem is that this ONLY works when I happen to paste from the clipboard into a blank Worksheet with all the row data now in Row 1.
If I manually insert 4 rows in the other Worksheet or Workbook at a random point, say into Row 20 to Row 24, since there's 4 rows of data in the clipboard; of course this Macro won't work.
Sub FixAllOnLine1OneRowAtATimeToFirstEmpty()
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = ActiveSheet
Set pasteSheet = ActiveSheet
copySheet.Range("Q1:AF1").Copy
pasteSheet.Cells(Rows.count, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
Columns("Q:AF").Select
Selection.Delete Shift:=xlToLeft
End Sub
This solution is also close, but again lacks the random flexibility.
Split single row into multiple rows based on cell value in excel
So potentially I'm looking for either solution or both if possible. I am oddly curious why certain times pasting from the clipboard using the Sub CopytoClipboardandDelete the rows preserve their line breaks.
I have a clue to when this occurs, but no idea why. When I use the Sub CopytoClipboardandDelete from the source file that was saved as a text file (.txt or .csv) I rarely lose the row line breaks. But when I use the Sub and paste to a new workbook or worksheet, then use the Sub again from this new dataset and paste it on to another new workbook or worksheet it loses the row line-breaks nearly every time.
UPDATE: When using the Tab delimiter setting, I replace all the preexisting Tabs with 4 spaces.
Copy multiple (non-adjacent) ranges to Clip Board as Comma, Tab Or HTML Delimited Table
Notes:
Areas outside the worksheets UsedRange are cropped from source ange
Each Area in the source range is is broken into rows. Range("C1:D1,F1") will result in 2 rows C1:D1 and F1. 8:8,4:4,6:6 will add 3 rows with the first row being row 8 followed by row 4 and finally row 6.
Sample Data
Option Explicit
Enum ClipTableEnum
eCSV
eHTML
eTab
End Enum
Sub PutRangeIntoClipBoard(rSource As Range, Optional clipEnum As ClipTableEnum = eTab, Optional DebugPrint As Boolean = False)
Dim a, arr
Dim x As Long, rwCount As Long
Dim r As Range, rngRow As Range
Dim s As String
With rSource.Worksheet
Set r = Intersect(rSource, .UsedRange)
If InStr(r.Address(False, False), ",") Then
arr = Split(r.Address(False, False), ",")
Else
ReDim arr(0)
arr(0) = r.Address(False, False)
End If
For Each a In arr
rwCount = .Range(a).Rows.count
For x = 1 To rwCount
Set rngRow = .Range(a).Rows(x)
s = s & get1dRangeToString(rngRow, clipEnum)
Next
Next
End With
If DebugPrint Then Debug.Print vbCrLf & s
PutInClipBoard s
End Sub
Function get1dRangeToString(rSource As Range, Optional clipEnum As ClipTableEnum = eTab) As String
Dim arr
Dim s As String
Dim x As Long
If rSource.Cells.count = 1 Then
ReDim arr(0)
arr(0) = rSource.Value
Else
arr = WorksheetFunction.Transpose(rSource)
arr = WorksheetFunction.Transpose(arr)
End If
Select Case clipEnum
Case ClipTableEnum.eCSV
s = """" & Join(arr, """,""") & """" & vbCrLf
Case ClipTableEnum.eHTML
s = "<TR><TD>" & Join(arr, "</TD><TD>") & "</TD></TR>" & vbCrLf
Case ClipTableEnum.eTab
For x = LBound(arr) To UBound(arr)
arr(x) = Replace(arr(x), vbTab, " ")
Next
s = Join(arr, vbTab)
s = s & vbCrLf
End Select
get1dRangeToString = s
End Function
Sub PutInClipBoard(s As String)
Dim clip As DataObject
Set clip = New DataObject
clip.SetText s
clip.PutInClipBoard
Set clip = Nothing
End Sub
Ok I got it to work, sort-of. Now I can highlight any row that has the multiple rows pasted in; e.g. Highlight Row 10 with Row A10-P10 + Row Q10-AF10 + Row AG10-AV10 etc...and it copies Column Q10-AF10, inserts into Column A11-P11 and deletes Columns("Q:AF").
What I need the Macro to do is loop this process until there's no data outside Column A-P.
Sub FixAllOnLine1OneRowAtATimeInsertToNextRow()
Application.ScreenUpdating = False
Dim copySheet As Worksheet
Dim pasteSheet As Worksheet
Set copySheet = ActiveSheet
Set pasteSheet = ActiveSheet
copySheet.Range("Q" & ActiveCell.Row & ":AF" & ActiveCell.Row).Copy
Range("Q" & ActiveCell.Row & ":AF" & ActiveCell.Row).Offset(1).Select
pasteSheet.Cells(ActiveCell.Row, 1).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
Application.CutCopyMode = False
Application.ScreenUpdating = True
Columns("Q:AF").Select
Selection.Delete Shift:=xlToLeft
End Sub
I have a text string that is using the ^ symbol as a delimiter.
I need to separate the text into new rows rather than new columns.
I need to create new rows to not overwrite the next line of data below it.
Is this possible without using a macro? I'm not against using one, I just wouldn't know where to start to write it.
Below is a pic of some sample data. The top part is how it's listed, and the bottom (in yellow) is how I would like it.
Using Excel 2010 on Windows 7 Pro.
Thanks to those that responded. A friend was able to help by providing the following code:
Sub Breakout()
Application.ScreenUpdating = False
LR = Cells(Rows.Count, 1).End(xlUp).Row
For r = LR To 2 Step -1
Set MyCell = Cells(r, 1)
Arry = Split(MyCell.Value, "^")
For c = 0 To UBound(Arry)
If c > 0 Then MyCell.Offset(c, 0).EntireRow.Insert
MyCell.Offset(c, 0) = Arry(c)
Next c
Next r
End Sub
Could try something like this:
Sub reArrange()
Dim inFirstRng As Range
Dim inRng As Range
Dim inCur As Variant
Dim outFirstRng As Range
Dim outCurRng As Range
Dim ws As Worksheet
'CHANGE ARGUMENT TO YOUR SHEET NAME
Set ws = Worksheets("Sheet2")
With ws
'CHANGE ARGUMENT TO WHATEVER THE FIRST CELL OR YOUR DATA INPUT IS IN COLUMN A
Set inFirstRng = .Range("A3")
Set inRng = .Range(inFirstRng, inFirstRng.End(xlDown))
'CHANGE ARGUMENT TO WHATEVER THE FIRST CELL OR YOUR DATA OUTPUT IS IN COLUMN A
Set outFirstRng = .Range("A9")
Set outCurRng = outFirstRng
End With
For Each cell In inRng.Cells
inCur = WorksheetFunction.Transpose(Split(cell.Value, "^"))
outCurRng.Resize(UBound(inCur), 1).Value = inCur
With ws
.Range("G" & outCurRng.Row & ":L" & outCurRng.Row).Value = _
.Range("G" & cell.Row & ":L" & cell.Row).Value
End With
Set outCurRng = outCurRng.Offset(UBound(inCur), 0)
Next cell
ws.Range("F" & outFirstRng.Row & ":F" & outCurRng.Row - 1).Value = 1
End Sub
I'm attempting to write a macro to take an excel file of several thousand rows and split the inital sheet's rows up into sheets of 250 rows per-sheet, not including the original header row, which should also be copied to each sheet. There are 13 columns total, and some of the fields are empty.
I can sort the document myself - that's not an issue - I just don't have the macro skill to figure this one out.
I've tried searching, and found a few examples, but none quite fit..such as this one..
create macro that will convert excel rows from single sheet to new sheets ..or this one.. Save data input from one sheet onto successive rows in another sheet
Any help?
This should provide the solution you are looking for as well. You actually added your answer as I was typing it, but maybe someone will find it useful.
This method only requires that you enter the number of rows to copy to each page, and assumes you are on the "main" page once you execute it.
Sub AddSheets()
Application.EnableEvents = False
Dim wsMasterSheet As Excel.Worksheet
Dim wb As Excel.Workbook
Dim sheetCount As Integer
Dim rowCount As Integer
Dim rowsPerSheet As Integer
Set wsMasterSheet = ActiveSheet
Set wb = ActiveWorkbook
rowsPerSheet = 5
rowCount = Application.CountA(Sheets(1).Range("A:A"))
sheetCount = Round(rowCount / rowsPerSheet, 0)
Dim i As Integer
For i = 1 To sheetCount - 1 Step 1
With wb
'Add new sheet
.Sheets.Add after:=.Sheets(.Sheets.Count)
wsMasterSheet.Range("A1:M1").EntireRow.Copy Destination:=Sheets(.Sheets.Count).Range("A1").End(xlUp)
wsMasterSheet.Range("A" & (rowsPerSheet + 2) & ":M" & (2 * rowsPerSheet + 1)).EntireRow.Cut Destination:=Sheets(.Sheets.Count).Range("A" & Rows.Count).End(xlUp).Offset(1)
wsMasterSheet.Range("A" & (rowsPerSheet + 2) & ":M" & (2 * rowsPerSheet + 1)).EntireRow.Delete
ActiveSheet.Name = "Rows " + CStr(((.Sheets.Count - 1) * rowsPerSheet + 1)) & " - " & CStr((.Sheets.Count * rowsPerSheet))
End With
Next
wsMasterSheet.Name = "Rows 1 - " & rowsPerSheet
Application.EnableEvents = True
End Sub
#pnuts's suggested solution by Jerry Beaucaire worked perfectly.
https://sites.google.com/a/madrocketscientist.com/jerrybeaucaires-excelassistant/parse-functions/rows
Option Explicit
Sub SplitDataNrows()
'Jerry Beaucaire, 2/28/2012
'Split a data sheet by a variable number or rows per sheet, optional titles
Dim N As Long, rw As Long, LR As Long, Titles As Boolean
If MsgBox("Split the activesheet into smaller sheets?", vbYesNo, _
"Confirm") = vbNo Then Exit Sub
N = Application.InputBox("How many rows per sheet?", "N-Rows", 50, Type:=1)
If N = 0 Then Exit Sub
If MsgBox("Include the title row1 on each new sheet?", vbYesNo, _
"Titles?") = vbYes Then Titles = True
Application.ScreenUpdating = False
With ActiveSheet
LR = .Range("A" & .Rows.Count).End(xlUp).Row
For rw = 1 + ---Titles To LR Step N
Sheets.Add
If Titles Then
.Rows(1).Copy Range("A1")
.Range("A" & rw).Resize(N).EntireRow.Copy Range("A2")
Else
.Range("A" & rw).Resize(N).EntireRow.Copy Range("A1")
End If
Columns.AutoFit
Next rw
.Activate
End With
Application.ScreenUpdating = True
End Sub
--
Option Explicit
Sub SplitWorkbooksByNrows()
'Jerry Beaucaire, 2/28/2012
'Split all data sheets in a folder by a variable number or rows per sheet, optional titles
'assumes only one worksheet of data per workbook
Dim N As Long, rw As Long, LR As Long, Cnt As Long, Cols As String, Titles As Boolean
Dim srcPATH As String, destPATH As String, fNAME As String, wbDATA As Workbook, titleRNG As Range
srcPATH = "C:\Path\To\Source\Files\" 'remember the final \ in this string
destPATH = "C:\Path\To\Save\NewFiles\" 'remember the final \ in this string
'determine how many rows per sheet to create
N = Application.InputBox("How many rows per sheet?", "N-Rows", 50, Type:=1)
If N = 0 Then Exit Sub 'exit if user clicks CANCEL
'Examples of usable ranges: A:A A:Z C:E F:F
Cols = Application.InputBox("Enter the Range of columns to copy", "Columns", "A:Z", Type:=2)
If Cols = "False" Then Exit Sub 'exit if user clicks CANCEL
'prompt to repeat row1 titles on each created sheet
If MsgBox("Include the title row1 on each new sheet?", vbYesNo, _
"Titles?") = vbYes Then Titles = True
Application.ScreenUpdating = False 'speed up macro execution
Application.DisplayAlerts = False 'turn off system alert messages, use default answers
fNAME = Dir(srcPATH & "*.xlsx") 'get first filename from srcPATH
Do While Len(fNAME) > 0 'exit loop when no more files found
Set wbDATA = Workbooks.Open(srcPATH & fNAME) 'open found file
With ActiveSheet
LR = Intersect(.Range(Cols), .UsedRange).Rows.Count 'how many rows of data?
If Titles Then Set titleRNG = Intersect(.Range(Cols), .Rows(1)) 'set title range, opt.
For rw = 1 + ---Titles To LR Step N 'loop in groups of N rows
Cnt = Cnt + 1 'increment the sheet creation counter
Sheets.Add 'create the new sheet
If Titles Then titleRNG.Copy Range("A1") 'optionally add the titles
'copy N rows of data to new sheet
Intersect(.Range("A" & rw).Resize(N).EntireRow, .Range(Cols)).Copy Range("A1").Offset(Titles)
ActiveSheet.Columns.AutoFit 'cleanup
ActiveSheet.Move 'move created sheet to new workbook
'save with incremented filename in the destPATH
ActiveWorkbook.SaveAs destPATH & "Datafile_" & Format(Cnt, "00000") & ".xlsx", xlNormal
ActiveWorkbook.Close False 'close the created workbook
Next rw 'repeat with next set of rows
End With
wbDATA.Close False 'close source data workbook
fNAME = Dir 'get next filename from the srcPATH
Loop 'repeat for each found file
Application.ScreenUpdating = True 'return to normal speed
MsgBox "A total of " & Cnt & " data files were created." 'report
End Sub