Select and Copy multiple ranges with VBA - excel

I want to copy multiple range to another workbook. I have the code below. How can I replace the number 1000 by iLastRow
iLastRow = Sh.Range("B" & Rows.Count).End(xlUp).Row
sh.Range("A3:AG1000, AL3:EJ1000").Select
Selection.Copy

Try the code below, explanation inside the code as comments:
Option Explicit
Sub CopyMultipleRanges()
Dim iLastRow As Long
Dim sh As Worksheet
Dim MultiRng As Range
Set sh = ThisWorkbook.Worksheets("Sheet1") ' <-- change to your sheet's name
With sh
iLastRow = .Cells(.Rows.Count, "B").End(xlUp).Row
' use the union to set a range combined from multiple ranges
Set MultiRng = Union(.Range("A3:A" & iLastRow), .Range("AL3:EJ" & iLastRow))
End With
' copy the range, there's no need to select it first
MultiRng.Copy
End Sub
Another question is how you want to paste the merged reanges that have a gap in the middle.

The Union method is a solution to this problem. but it also has its cons
The union range should be the same first row and last row.
On the other hand, you can just select the first cell to paste.
you can alway do like this. the main point here is the row number should be the same. here I synchronize both range with the same variable. in your case, change to last cell.
j=1
i = 4
Set MultiRng = Union(Range("A" & j & ":B" & i), Range("D" & j & ":E" & i))

Change Range params from this:
iLastRow = Sh.Range("B" & Rows.Count).End(xlUp).Row
sh.Range("A3:AG1000, AL3:EJ1000").Select
To:
iLastRow = Sh.Range("B" & Rows.Count).End(xlUp).Row
sh.Range("A3:AG" & iLastrow &", AL3:EJ" & iLastRow).Select
Since with multiple selection Copy will not work. You may need to call it twice in your case. (as per suggestion by #YowE3K)
sh.Range("A3:AG" & iLastrow).Select
Selection.Copy
sh.Range("AL3:EJ" & iLastrow).Select
Selection.Copy

Option Explicit
Sub import_APVP()
Dim master As Worksheet, sh As Worksheet
Dim wk As Workbook
Dim strFolderPath As String
Dim selectedFiles As Variant
Dim iFileNum As Integer, iLastRowReport As Integer, iNumberOfRowsToPaste As Integer
Dim strFileName As String
Dim iCurrentLastRow As Integer, iRowStartToPaste As Integer
Dim MultiRng As Range
Dim startTime As Double
getSpeed (True)
Set master = ActiveWorkbook.ActiveSheet
strFolderPath = ActiveWorkbook.Path
ChDrive strFolderPath
ChDir strFolderPath
Application.ScreenUpdating = False
'On Error GoTo NoFileSelected
selectedFiles = Application.GetOpenFilename( _
filefilter:="Excel Files (*.xls*),*.xlsx*", MultiSelect:=True)
For iFileNum = LBound(selectedFiles) To UBound(selectedFiles)
strFileName = selectedFiles(iFileNum)
Set wk = Workbooks.Open(strFileName)
For Each sh In wk.Sheets
If sh.Name Like "DATA*" Then
With sh
iLastRowReport = .Range("D" & .Rows.Count).End(xlUp).Row
iNumberOfRowsToPaste = iLastRowReport + 2 - 1
'.Range("A3:AG" & iLastRowReport & " , AL3:EJ & iLastRowReport").Select
' Selection.Copy
Set MultiRng = Union(.Range("A3:AG" & iLastRowReport), .Range("AL3:EJ" & iLastRowReport))
'you delete the 3 in range ("AL:EJ....) that make your code not work.
MultiRng.Copy
With master
iCurrentLastRow = .Range("B" & .Rows.Count).End(xlUp).Row
iRowStartToPaste = iCurrentLastRow + 1
'.Activate ' <-- not needed
.Range("A" & iRowStartToPaste).PasteSpecial xlPasteAll
'ActiveSheet.Paste <-- not needed
End With
End With
End If
Next sh
wk.Close
Next
getSpeed (False)
Application.ScreenUpdating = True
NoFileSelected:
End Sub

Related

How to Cut Incomplete Rows and Paste In Another Workbook with VBA?

I am cycling through all the Green Tabs in a workbook. When I come to a row of data where there is no value in Column G, I select that row, cut it, and open another workbook entitled "Unpaid AR." In that workbook, I find the first unused row, and Paste. Everything functions properly except for the Paste - nothing pastes, and I have tried several different techniques. Any ideas what could be going wrong?
Public Sub CutNPaste()
Dim ws As Worksheet
Dim ARRange As String
Dim ARFilePath As String
Dim ARcell As Range
Dim CopyRange As String
Dim i As Integer
Dim varRange As String
ARFilePath = "Unpaid AR.xlsx"
For Each ws In ThisWorkbook.Worksheets
ws.Activate
If ws.Tab.ColorIndex = 10 Then 'If Tab is Green, Then...
ReportRows = ActiveSheet.UsedRange.Rows.Count 'Get how many rows in the report
Let ARRange = "G" & "2" & ":" & "G" & ReportRows 'Range to Inspect for Blanks
i = 2
For Each ARcell In Range(ARRange)
Let CopyRange = "A" & i & ":" & "I" & i 'Set the copy range when blank is encountered
If ARcell.Value = "" Then
Range(CopyRange).Select
Selection.Cut
Workbooks.Open ARFilePath 'Open the Unpaid AR workbook
Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Select 'Find the first open row
ActiveSheet.Paste 'This is where NOTHING happens
Workbooks("Unpaid AR.xlsx").Close SaveChanges:=True 'Save and close destination wkbk
Application.CutCopyMode = False
End If
i = i + 1
Next ARcell
End If
Next ws
End Sub
i change a little bit...
Public Sub CutNPaste()
Dim ws As Worksheet
Dim ARRange As String
Dim ARFilePath As String
Dim ARcell As Range
Dim CopyRange As Range
Dim i As Integer
Dim varRange As String
Dim wkbTarget As Workbook
Dim ReportRows As Long
ARFilePath = ThisWorkbook.Path & "\Unpaid AR.xlsx"
Set wkbTarget = Workbooks.Open(ARFilePath) 'Open the Unpaid AR workbook
For Each ws In ThisWorkbook.Worksheets
If ws.Tab.ColorIndex = 10 Then
ReportRows = ws.UsedRange.Rows.Count
For i = ReportRows To 2 Step -1
Set CopyRange = ws.Range("A" & i & ":" & "I" & i)
If ws.Cells(i, 7).Value = "" Then
CopyRange.Cut Destination:=wkbTarget.Worksheets(1).Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
Application.CutCopyMode = False
End If
Next i
End If
Next ws
wkbTarget.Close SaveChanges:=True 'Save and close destination wkbk
End Sub
BR
Bernd

Convert Multiple Excel Sheet Ranges as PDF VBA

The below code is take the Status of Col"E" If it is = Include then its corresponding sheets ranges will will be converted to PDF.
I have tried at my end but its not working receiving an error invalid procedure call or argument on the line
rng.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=saveLocation
Your help will be appreciated to fix the problem.
Sub SelectSheets_Ranges()
Dim sh As Worksheet, lastR As Long, rng As Range, arr, arrSplit, i As Long, k As Long
Set sh = ActiveSheet
lastR = sh.Range("C" & sh.Rows.Count).End(xlUp).Row
ReDim arr(lastR - 1)
For i = 6 To lastR
If sh.Range("E" & i).Value = "Include" Then
arr(k) = sh.Range("C" & i).Value & "|" & sh.Range("D" & i).Value: k = k + 1
End If
Next i
ReDim Preserve arr(k - 1)
For i = 0 To UBound(arr)
arrSplit = Split(arr(i), "|")
Set rng = Worksheets(arrSplit(0)).Range(arrSplit(1))
'Create and assign variables
Dim saveLocation As String
saveLocation = "C:\Users\marks\OneDrive\Documents\myPDFFile.pdf"
'Save a range as PDF
rng.ExportAsFixedFormat Type:=xlTypePDF, _
Filename:=saveLocation
Next
End Sub
Please, try the next code. It saves in ThisWorkbook path, naming the pdf file as "myPDFFile_sheetName.pdf". Each created file will be open in the default pdf application. If it works OK, you can appropriately change the last parameter:
Sub SelectSheets_Ranges_ExpPdf()
Dim sh As Worksheet, lastR As Long, rng As Range, arr, arrSplit, i As Long, k As Long
Set sh = ActiveSheet
lastR = sh.Range("C" & sh.Rows.Count).End(xlUp).Row
ReDim arr(lastR - 1)
For i = 6 To lastR
If sh.Range("E" & i).Value = "Include" Then
arr(k) = sh.Range("C" & i).Value & "|" & sh.Range("D" & i).Value: k = k + 1
End If
Next i
If k > 0 Then
ReDim Preserve arr(k - 1)
Else
MsgBox "No appropriate range (containing ""Include"") could be found...:exit sub"
End If
Dim boolHide As Boolean, boolProt As Boolean
ActiveWorkbook.Unprotect "4321" 'in order to unprotect he workbook structure
For i = 0 To UBound(arr)
boolHide = False: boolProt = False
arrSplit = Split(arr(i), "|")
Set rng = Worksheets(arrSplit(0)).Range(arrSplit(1))
If ActiveWorkbook.Sheets(arrSplit(0)).ProtectContents Then _
ActiveWorkbook.Sheets(arrSplit(0)).Unprotect "4321": boolProt = True
Debug.Print arrSplit(0)
If ActiveWorkbook.Sheets(arrSplit(0)).Visible <> xlSheetVisible Then _
ActiveWorkbook.Sheets(arrSplit(0)).Visible = xlSheetVisible: boolHide = True
'Create and assign variables
Dim saveLocation As String
saveLocation = ThisWorkbook.Path & "\myPDFFile_" & arrSplit(0) & ".pdf"
'Save a range as PDF
rng.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
saveLocation, Quality:=xlQualityStandard, IgnorePrintAreas:=False, OpenAfterPublish:=True
If boolHide Then ActiveWorkbook.Sheets(arrSplit(0)).Visible = xlSheetHidden
If boolProt Then ActiveWorkbook.Sheets(arrSplit(0)).Protect "4321"
Next
ActiveWorkbook.Protect "4321"
End Sub
Try this:
Sub SelectSheets_Ranges()
Dim sh As Worksheet, i As Long
Dim saveLocation As String, FirstSheet As Boolean
saveLocation = "C:\Users\marks\OneDrive\Documents\myPDFFile.pdf"
Set sh = ActiveSheet
FirstSheet = True
For i = 6 To sh.Range("C" & sh.Rows.Count).End(xlUp).Row
If sh.Cells(i, "E") = "Include" Then
'FirstSheet determines whether the sheet is added to currently-selected
' sheets or not (if not then it replaces them)
ThisWorkbook.Sheets(sh.Cells(i, "C").Value).Select FirstSheet
FirstSheet = False
End If
Next i
If Not FirstSheet Then
'at least one sheet was included
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=saveLocation
End If
End Sub
I assume you want all the ranges from the different sheets in one pdf.
Option Explicit
Sub SelectSheets_Ranges()
Const FOLDER = "C:\Users\marks\OneDrive\Documents\"
Const FILENAME = "myPDFFile.pdf"
Dim wb As Workbook, wbPDF As Workbook
Dim sh As Worksheet, wsPDF As Worksheet
Dim lastR As Long, rng As Range, r As Long, n As Integer, m As Integer
Set sh = ActiveSheet
Set wb = ActiveWorkbook
lastR = sh.Range("C" & sh.Rows.Count).End(xlUp).Row
' create temp workbook to hold ranges
Set wbPDF = Workbooks.Add
m = wbPDF.Sheets.Count
n = m
With sh
For r = 6 To lastR
If .Cells(r, "E").Value = "Include" Then
Set rng = wb.Sheets(.Cells(r, "C").Value).Range(.Cells(r, "D").Value)
Set wsPDF = wbPDF.Sheets.Add(After:=wbPDF.Sheets(n))
rng.Copy wsPDF.Range("A1")
n = n + 1
End If
Next
End With
' delete initial sheets
Application.DisplayAlerts = False
For n = m To 1 Step -1
wbPDF.Sheets(n).Delete
Next
Application.DisplayAlerts = True
'end
wbPDF.ExportAsFixedFormat Type:=xlTypePDF, FILENAME:=FOLDER & FILENAME
'wbPDF.SaveAs FOLDER & "debug.xlsx"
wbPDF.Close False
MsgBox "PDF created " & FOLDER & FILENAME, vbInformation
End Sub

Loop Through Directory (need help adding a second range)

I am very new to the world of code and VBA - but I am having a lot of fun learning and exploring just how powerful these tools are.
I am working on pulling data from one worksheet and placing it in my "master roadmap" spreadsheet. Just a little background: In the master sheet, I have been inserting data in columns A-S; however, column 'A' is reserved on the worksheet I am pulling data from so this is why the range below is set as Range (B:T). I am scanning columns by B:T; pulling that data and inserting it in columns A:S of my master sheet. However, my boss wants to make a change reserve columns "U' through "AD" on her spreadsheet.
So I would like to have VBA scan through two ranges "B:T" and then "AE:BB" (skipping U:AD) and then plug that information in my "master sheet" into columns "A:AQ."
In short, I am hoping all I have to do is insert a 'second range' in the code below to complete this task. Any help would be greatly appreciated!
Sub LoopThroughDirectory()
Dim MyFile As String
Dim erow As Double
Dim lastrow As Double
Dim MasterWorkbook As Workbook
Dim TempWorkbook As Workbook
Dim DirPath As String
'Clear current data
Sheet1.Visible = xlSheetVisible
Sheet2.Visible = xlSheetHidden
Sheet3.Visible = xlSheetHidden
Sheet1.Activate
lastrow = ActiveWorkbook.ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
If lastrow > 1 Then
Range("A2:AQ" & lastrow).Select
Selection.Clear
End If
DirPath = "C:\Users\rspktcod\Documents\RoadMap Test\Roadmaps\"
MyFile = Dir(DirPath)
Set MasterWorkbook = ActiveWorkbook
Do While Len(MyFile) > 0
Set TempWorkbook = Workbooks.Open(DirPath & MyFile)
lastrow = ActiveWorkbook.ActiveSheet.Range("B" & Rows.Count).End(xlUp).Row
Range("B2:T" & lastrow).Copy
MasterWorkbook.Activate
erow = Sheet1.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Paste Destination:=Worksheets("Roadmap").Range(Cells(erow, 1), Cells(erow, 43))
TempWorkbook.Activate
Application.CutCopyMode = False
ActiveWorkbook.Close
MyFile = Dir
Loop
End Sub
The short answer is, yes, you can just add another range.
Here is the long answer (with a few improvments...):
Sub LoopThroughDirectory()
Dim DirPath As String, MyFile As String
Dim LastRow As Long, eRow As Long ' Rows should be Long
'Dim MasterWorkbook As Workbook
Dim TempWorkbook As Workbook
Dim DestSheet As Worksheet
'Clear current data
Sheet1.Visible = xlSheetVisible
Sheet2.Visible = xlSheetHidden
Sheet3.Visible = xlSheetHidden
' Added DestSheet to be more clear, since Sheet1 is specific to this file.
' It also make the code more portable, if you want to change it to a different sheet, in a different file.
Set DestSheet = Sheet1
' MasterWorkbook is a good idea, but not required here.
'Set MasterWorkbook = ThisWorkbook 'ActiveWorkbook
LastRow = DestSheet.Range("A" & Rows.Count).End(xlUp).Row
If LastRow > 1 Then Range("A2:AQ" & LastRow).Clear
DirPath = "C:\Users\rspktcod\Documents\RoadMap Test\Roadmaps\"
' Added "*.xls*" to limit it to just Excel Workbooks
' You don't want to process the current and previous folders, which come across as "." & ".."
MyFile = Dir(DirPath & "*.xls*")
Do While Len(MyFile) > 0
Set TempWorkbook = Workbooks.Open(DirPath & MyFile)
' Used [TempWorkbook.ActiveSheet].Rows.Count, instead of just Rows.Count to be more percise
With TempWorkbook.ActiveSheet ' <-- Not a fan of Activesheet here
LastRow = .Range("B" & .Rows.Count).End(xlUp).Row
If LastRow > 1 Then
' Excel 2003-/2007+ have different number of rows, so be specific about what sheet to get the Rows from
eRow = DestSheet.Cells(DestSheet.Rows.Count, 1).End(xlUp).Row + 1
.Range("B2:T" & LastRow).Copy Destination:=DestSheet.Cells(eRow, 1)
.Range("AE2:BB" & LastRow).Copy Destination:=DestSheet.Range("T" & eRow)
End If
TempWorkbook.Close False ' Added SaveSanges = False for good measure
MyFile = Dir
End With
Loop
End Sub

Creating multiple worksheets or workbooks from one source worksheet

I have a spreadsheet with over a thousand rows. The unique identifier is the vendor ID which is located in column B. The data covers from column A to column N. I want to parse this master spreadsheet and create new worksheets or better yet create a new file/workbook by each vendor ID. The spreadsheet does not contain headers. A vendor ID may just have one row or it can have 20 rows of data, 3 rows of data, etc. Lastly, I would like to convert the new file into .CSV format. When creating the new worksheets or files I would like the maintain all the formats from the source spreadsheet. The data contains, amounts, dates, and regular input of characters.
I found the below code on-line a few days ago and modified it for my needs. I was able to get it to work but I do not like how it brings over the .value and I lose the format of the dates and it creates formatting issues for the end result.
I would like to build a code flexible enough where I can modify it to create multiple worksheets within the workbook (with or without headers) or have it flexible enough where I can modify it to create workbooks based off of each vendor ID criteria (or unique criteria if it is used for other purposes). I'm trying to prevent for a user to have to create 168 files or worksheets manually based off of a consolidated worksheet.
Sub AllocatedataCSV()
Dim ws As Worksheet
Set ws = Sheets("CSV Master")
Dim LastRow As Long
LastRow = Range("B" & ws.Rows.Count).End(xlUp).Row
' stop processing if we don't have any data
If LastRow < 2 Then Exit Sub
Application.ScreenUpdating = False
CopyDataToSheets LastRow, ws
ws.Select
Application.ScreenUpdating = True
End Sub
Sub CopyDataToSheets(LastRow As Long, src As Worksheet)
Dim rng As Range
Dim cell As Range
Dim Series As String
Dim SeriesStart As Long
Dim SeriesLast As Long
Set rng = Range("B1:B" & LastRow)
SeriesStart = 2
Series = Range("B" & SeriesStart)
For Each cell In rng
If cell.Value <> Series Then
SeriesLast = cell.Row - 1
CopySeriesToNewSheet src, SeriesStart, SeriesLast, Series
Series = cell.Value
SeriesStart = cell.Row
End If
Next
' copy the last series
SeriesLast = LastRow
CopySeriesToNewSheet src, SeriesStart, SeriesLast, Series
End Sub
Sub CopySeriesToNewSheet(src As Worksheet, Start As Long, Last As Long, _
name As String)
Dim tgt As Worksheet
If (SheetExists(name)) Then
MsgBox "Sheet " & name & " already exists. " _
& "Please delete or move existing sheets before" _
& " copying data from the Master List.", vbCritical, _
"Time Series Parser"
End
End If
Worksheets.Add(After:=Worksheets(Worksheets.Count)).name = name
Set tgt = Sheets(name)
' copy data from src to tgt
tgt.Range("A1:N" & Last).Value = _
src.Range("A" & Start & ":N" & Last).Value
End Sub
Function SheetExists(name As String) As Boolean
Dim ws As Worksheet
SheetExists = True
On Error Resume Next
Set ws = Sheets(name)
If ws Is Nothing Then
SheetExists = False
End If
End Function
To copy data and formatting, change:
tgt.Range("A1:N" & Last).Value = _
src.Range("A" & Start & ":N" & Last).Value
to:
src.Range("A" & Start & ":N" & Last).Copy
tgt.Range("A1").PasteSpecial xlPasteAll
To put the copied data into a new workbook:
Sub CopySeriesToNewSheet(src As Worksheet, Start As Long, Last As Long, _
name As String)
Dim wb As Workbook : Set wb = Workbooks.Add
Dim tgt As Worksheet
Set tgt = wb.Sheets(1)
tgt.name = name
src.Range("A" & Start & ":N" & Last).Copy
tgt.Range("A1:N" & Last).PasteSpecial xlPasteAll
wb.SaveAs name
wb.Close
End Sub
UPDATE to answer question in comment
If a source series has only one row, the pasted result will be incorrect. This can be resolved by pasting onto a single cell, so
tgt.Range("A1:N" & Last).PasteSpecial xlPasteAll
becomes
tgt.Range("A1").PasteSpecial xlPasteAll
I've updated my code above to reflect this change.
This can also be resolved in the original code:
tgt.Range("A1:N" & (1+Last-Start)).Value = _
src.Range("A" & Start & ":N" & Last).Value

VBA Copy Rows To New Workbook

I am not sure why the range that i am selecting when a new work book is not being copied over. The workbook sheets are blank and i cant figure out why.
Sub NB()
Dim X
Dim copyRange
Dim lngCnt As Long
Dim strDT As String
Dim strNewBook As String
Dim objWS As Object
Dim WB As Workbook
Dim bNewBook As Boolean
Dim topRow As Integer
topRow = -1
Set objWS = CreateObject("WScript.Shell")
strDT = objWS.SpecialFolders("Desktop") & "\Book1"
If Len(Dir(strDT, vbDirectory)) = 0 Then
MsgBox "No such directory", vbCritical
Exit Sub
End If
X = Range([f1], Cells(Rows.Count, "f").End(xlUp)).Value2
For lngCnt = 1 To UBound(X, 1)
If Len(X(lngCnt, 1)) > 0 Then
If (topRow = -1) Then
topRow = lngCnt
Else
If Not bNewBook Then
'make a single sheet workbook for first value
Set WB = Workbooks.Add(1)
copyRange = Range(Cells(topRow, "f"), Cells(lngCnt, 12).End(xlUp)).Value2
'find a way to copy copyRange into WB
Range(Cells(topRow, "f"), Cells(lngCnt, 12).End(xlUp)).Select
Range(Cells(topRow, "f"), Cells(lngCnt, 12).End(xlUp)).Copy
Range("A1").PasteSpecial
WB.SaveAs strDT & "\" & X(topRow, 1) & ".xls"
strNewBook = WB.FullName
WB.Close
bNewBook = True
Else
Set WB = Workbooks.Add(1)
copyRange = Range(Cells(topRow, "f"), Cells(lngCnt, 12).End(xlUp)).Value2
'find a way to copy copyRange into WB
Range(Cells(topRow, "f"), Cells(lngCnt, 12).End(xlUp)).Select
Range(Cells(topRow, "f"), Cells(lngCnt, 12).End(xlUp)).Copy
Range("A1").PasteSpecial
WB.SaveAs strDT & "\" & X(topRow, 1) & ".xls"
WB.Close
End If
topRow = lngCnt
End If
End If
Next
Set WB = Workbooks.Add(1)
When you create the new workbook it becomes active, so referring to ranges occurs in this new book, copying empty cells.
You need a reference to the current workbook
Dim wbCurrent As Workbook
Set wbCurrent = ThisWorkbook 'or ActiveWorkbook
Get references to the corresponding Worksheet(s) as well, then begin every Range or Cells use with a reference to the correct worksheet object-variable.
Dim wbCurrent As Workbook
Dim wsNew As Worksheet
Dim wsCurrent As Worksheet
Set wbCurrent = ThisWorkbook
Set wsCurrent = wbCurrent.Worksheets("Whatever Name")
Set WB = Workbooks.Add(1)
Set wsNew = WB.Worksheets(1)
You can go a step further and create object-variables to refer to ranges (of the different worksheets) as well. It may seem like overkill, but you need to clearly distinguish which workbook (worksheet, etc.) you are using. It will make your code easier to follow in the longer term as well.
Range(Cells(topRow, "f"), Cells(lngCnt, 12).End(xlUp)).Select
Range(Cells(topRow, "f"), Cells(lngCnt, 12).End(xlUp)).Copy
Range("A1").PasteSpecial
Is selecting and copying empty data from the new workbook to the same empty workbook
I found that it's not just a question of setting the active worksheet. The range property of the "Copy" method doesn't work if the source sheet is no longer active. In order to get this to work I had to go to simply copying the values in code without using copy and replace.
I found the original code hard to follow, so I tweaked it a little. Here is what I ended up with. This should sub-divide the spreadsheet based on captions in F and copy the data in G - M to output columns A - G
Sub NB()
Dim strDT As String
Dim WB As Workbook
Dim Ranges(10) As Range
Dim Height(10) As Integer
Dim Names(10) As String
Dim row As Long
Dim maxRow As Long
Dim top As Long
Dim bottom As Long
Dim iData As Integer
Dim iBook As Long
Set objWS = CreateObject("WScript.Shell")
strDT = objWS.SpecialFolders("Desktop") & "\Book1"
If Len(Dir(strDT, vbDirectory)) = 0 Then
MsgBox "No such directory", vbCritical
Exit Sub
End If
iData = 0
maxRow = Range("G" & 65536).End(xlUp).row
If (maxRow < 2) Then
MsgBox ("No Data was in the G column")
Exit Sub
End If
' The first loop stores the source ranges
For row = 1 To maxRow
If (Not IsEmpty(Range("F" & row))) Then
If (iData > 0) Then
Set Ranges(iData) = Range("G" & top & ":" & "M" & bottom)
Height(iData) = bottom - top
End If
iData = iData + 1
top = row + 1
bottom = row + 1
Names(iData) = Range("F" & row).Value2
Else
bottom = row + 1
End If
Next
Set Ranges(iData) = Range("G" & top & ":" & "M" & bottom)
Height(iData) = bottom - top
' The second loop copies the values to the output ranges.
For iBook = 1 To iData
'make a single sheet workbook for first value
Set WB = Workbooks.Add(1)
Range("A1:G" & Height(iBook)).Value = Ranges(iBook).Value2
WB.SaveAs (strDT & "\" & Names(iBook) & ".xls")
WB.Close
Next
End Sub
Function IsEmpty(ByVal copyRange As Range)
IsEmpty = (Application.CountA(copyRange) = 0)
End Function

Resources