My macro is to append the values from three sheets in a weekly report workbook to the values in equivalent sheets in an accumulating workbook.
However, I cannot define the ranges in the ThisWorkbook.Sheets correctly - Only the cell A2 values from the wb.Sheets are appended.
Could someone please help me define the range correctly? Many thanks!
Sub Import_SheetData_ThisWorkbook()
Dim lRow As Long, lRow1 As Long, lRow2 As Long, lRow3 As Long
Dim Path As String, WeeklyCollation As String
Dim wkNum As Integer
Dim wb As Workbook
wkNum = Application.InputBox("Enter week number")
Path = "C:\xyz\"
WeeklyCollation = Path & "Activities 2021 w" & wkNum & ".xlsx"
lRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row + 1
Set wb = Workbooks.Open(WeeklyCollation)
lRow1 = wb.Sheets("Customer visits").Cells(Rows.Count, 1).End(xlUp).Row
lRow2 = wb.Sheets("Orders").Cells(Rows.Count, 1).End(xlUp).Row
lRow3 = wb.Sheets("Visits").Cells(Rows.Count, 1).End(xlUp).Row
'Replace with copy and paste
'Can't define range in ThisWorkbook
ThisWorkbook.Sheets("Customer visits").Range("A" & lRow + 1).Value = wb.Sheets("Customer visits").Range("A2:H" & lRow1).Value
ThisWorkbook.Sheets("Orders").Range("A" & lRow + 1).Value = wb.Sheets("Orders").Range("A2:I" & lRow2).Value
ThisWorkbook.Sheets("Visits").Range("A" & lRow + 1).Value = wb.Sheets("Visits").Range("A2:F" & lRow3).Value
wb.Close SaveChanges:=False
MsgBox ("Data added")
End Sub
Backup Data
Adjust the values in the constants section.
Option Explicit
Sub ImportSheetData()
' Constants
' Source
Const sPath As String = "C:\xyz\"
Const swsNamesList As String = "Customer visits,Orders,Visits"
Const slrCol As String = "A"
Const sfRow As Long = 2
' Destination
Const dwsNamesList As String = "Customer visits,Orders,Visits"
Const dlrCol As String = "A"
' Both
Const Cols As String = "A:H"
' Create the references to the workbooks.
Dim wkNum As Variant: wkNum = Application.InputBox( _
"Enter week number", "Import Sheet Data", , , , , , 1)
If wkNum = False Then
MsgBox "You canceled.", vbExclamation
Exit Sub
End If
Dim sWeeklyCollation As String
sWeeklyCollation = sPath & "Activities 2021 w" & wkNum & ".xlsx"
Dim swb As Workbook
On Error Resume Next
Set swb = Workbooks.Open(sWeeklyCollation)
On Error GoTo 0
If swb Is Nothing Then
MsgBox "Could not find the file '" & sWeeklyCollation & "'.", vbCritical
Exit Sub
End If
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
' Copy the data.
Dim swsNames() As String: swsNames = Split(swsNamesList, ",")
Dim dwsNames() As String: dwsNames = Split(dwsNamesList, ",")
Dim sws As Worksheet
Dim srg As Range
Dim slRow As Long
Dim dws As Worksheet
Dim drg As Range
Dim dCell As Range
Dim n As Long
Dim rCount As Long
Dim wsCount As Long ' Counts the number of worksheets processed
For n = 0 To UBound(swsNames)
On Error Resume Next
Set sws = swb.Worksheets(swsNames(n))
On Error GoTo 0
If Not sws Is Nothing Then ' source worksheet exists
On Error Resume Next
Set dws = dwb.Worksheets(dwsNames(n))
On Error GoTo 0
If Not dws Is Nothing Then ' destination worksheet exists
slRow = sws.Cells(sws.Rows.Count, slrCol).End(xlUp).Row
rCount = slRow - sfRow + 1
If rCount > 0 Then ' found data in source worksheet
Set srg = sws.Columns(Cols).Resize(rCount).Offset(sfRow - 1)
Set dCell = dws.Cells(dws.Rows.Count, dlrCol) _
.End(xlUp).Offset(1)
Set drg = dCell.Resize(rCount).EntireRow.Columns(Cols)
drg.Value = srg.Value
wsCount = wsCount + 1
' Else ' no data in source worksheet
End If
'Else ' destination worksheet doesn't exist
End If
'Else ' source worksheet doesn't exist
End If
Next n
' Finishing Touches
swb.Close SaveChanges:=False
'dwb.Save
' Or:
'dwb.Close SaveChanges:=True
MsgBox "Data from " & wsCount & " worksheets added.", vbInformation
End Sub
Related
I have multiple workbooks in a Folder around 8 and there are Similar columns in some of these workbooks.
For Example:
There are 6 Workbooks out of 8 have similar column which Header name is "SouthRecord" i want to search that header in 1st row of each workbook if finds then copy that entire column from multiple workbooks availble in Folder and Paste appended result into an open workbook where from code is being run.
Code is copeing tha data but getting error on this line LastRow = sht.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row Object variable and with block variable not set.
If 4 workbooks has Same Header then these 4 column will be pasted into open workbook as single column.
I would appreciate your help.
Sub MultipleSimilarColinto_1()
Dim xFd As FileDialog
Dim xFdItem As String
Dim xFileName As String
Dim wbk As Workbook
Dim sht As Worksheet
Dim twb As Workbook
Dim LastRow As Long
Dim ws As Worksheet
Dim desWS As Worksheet
Dim colArr As Variant
Dim order As Long
Dim i As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
ActiveWindow.View = xlNormalView
Set xFd = Application.FileDialog(msoFileDialogFolderPicker)
Set twb = ActiveWorkbook
Set desWS = twb.Sheets("Sheet1")
If xFd.Show Then
xFdItem = xFd.SelectedItems(1) & Application.PathSeparator
Else
Beep
Exit Sub
End If
xFileName = Dir(xFdItem & "*.xlsx")
Do While xFileName <> ""
Set wbk = Workbooks.Open(xFdItem & xFileName)
colArr = Array("MD")
For Each ws In wbk.Sheets
If ws.Name <> "Sheet1" Then
LastRow = ws.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
For i = LBound(colArr) To UBound(colArr)
order = ws.Rows(1).Find("MD", LookIn:=xlValues, lookat:=xlWhole).Column
ws.Range(ws.Cells(2, order), ws.Cells(LastRow, order)).Copy desWS.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
Next i
End If
Next ws
wbk.Close SaveChanges:=True
xFileName = Dir
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
Import Columns From Workbooks
Option Explicit
Sub ImportColumns()
' Source
Const sFilePattern As String = "*.xlsx"
Const sExceptionsList As String = "Sheet1" ' comma-separated, no spaces
Const sHeader As String = "SouthRecord"
Const sHeaderRow As Long = 1
' Destination
Const dColumn As String = "A"
' Source
Dim sfd As FileDialog
Set sfd = Application.FileDialog(msoFileDialogFolderPicker)
'sfd.InitialFileName = "C:\Test\"
Dim sFolderPath As String
If sfd.Show Then
sFolderPath = sfd.SelectedItems(1) & Application.PathSeparator
Else
'MsgBox "You canceled.", vbExclamation
Beep
Exit Sub
End If
Dim sFileName As String: sFileName = Dir(sFolderPath & sFilePattern)
If Len(sFileName) = 0 Then
'MsgBox "No files found.", vbExclamation
Beep
Exit Sub
End If
Dim sExceptions() As String: sExceptions = Split(sExceptionsList, ",")
' Destination
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = dwb.ActiveSheet ' improve!
Dim dfCell As Range
Set dfCell = dws.Cells(dws.Rows.Count, dColumn).End(xlUp).Offset(1)
' Loop.
Application.ScreenUpdating = False
Dim swb As Workbook
Dim sws As Worksheet
Dim srg As Range
Dim shrg As Range
Dim sData() As Variant
Dim sfCell As Range
Dim slCell As Range
Dim srCount As Long
Dim wsCount As Long
Do While Len(sFileName) > 0
Set swb = Workbooks.Open(sFolderPath & sFileName)
For Each sws In swb.Worksheets
If IsError(Application.Match(sws.Name, sExceptions, 0)) Then
Set shrg = sws.Rows(sHeaderRow)
Set sfCell = shrg.Find(sHeader, shrg.Cells(shrg.Cells.Count), _
xlFormulas, xlWhole)
If Not sfCell Is Nothing Then
Set sfCell = sfCell.Offset(1)
Set slCell = sfCell _
.Resize(sws.Rows.Count - sHeaderRow) _
.Find("*", , xlFormulas, , , xlPrevious)
If Not slCell Is Nothing Then
srCount = slCell.Row - sHeaderRow
Set srg = sfCell.Resize(srCount)
End If
End If
If srCount > 0 Then
If srCount = 1 Then
ReDim sData(1 To 1, 1 To 1): sData(1, 1) = srg.Value
Else
sData = srg.Value
End If
dfCell.Resize(srCount).Value = sData
Set dfCell = dfCell.Offset(srCount)
wsCount = wsCount + 1
srCount = 0
End If
End If
Next sws
swb.Close SaveChanges:=False
sFileName = Dir
Loop
' Save the destination workbook.
'dwb.Save
Application.ScreenUpdating = True
MsgBox wsCount & " '" & sHeader & "' columns copied.", vbInformation
End Sub
My code below browses through the folder and effectively picks out the required files but the copy paste codes that I have tried did not work for me. Cant use traditional copy paste as column order is not same. Column names are same though.
Sub ImportExcelfiles()
Dim strPath As String
Dim strFile As String
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim wsTarget As Worksheet
Dim bookName As Worksheet
Dim rowCountSource As Long
Dim colCountSource As Long
Dim rowOutputTarget As Long
Dim colOutputTarget As Long
'Variables for Sheet - Workbook Name
Dim nameCount As Long
Dim fileName As String
Application.DisplayAlerts = False
Application.ScreenUpdating = False
'====================================
'SET THE PATH AND FILE TO THE FOLDER
'====================================
strPath = ThisWorkbook.Worksheets("Control").Range("C4")
fileName = ThisWorkbook.Worksheets("Control").Range("C5")
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
'set the target worksheet
Set wsTarget = ThisWorkbook.Worksheets("Master Data")
Set bookName = ThisWorkbook.Worksheets("Workbook Name")
'set the initial output row and column count for master data and workbook name
rowOutputTarget = 2
nameCount = 2
'get the first file
strFile = Dir(strPath & "*.xlsx*")
'loop throught the excel files in the folder
Do While strFile <> ""
If InStr(strFile, fileName) > 0 Then
'open the workbook
Set wbSource = Workbooks.Open(strPath & strFile)
Set wsSource = wbSource.Worksheets("Details")
'get the row and column counts
With wsSource
'row count based on column 1 = A
rowCountSource = .Cells(.Rows.Count, 1).End(xlUp).Row
'column count based on row 1
colCountSource = .Cells(1, .Columns.Count).End(xlToLeft).Column
End With
-------------------------------Need help here to copy paste-------------------------------------
'copy and paste from A2
wsSource.Range("A3", "AD" & rowCountSource).Copy
wsTarget.Range("A" & rowOutputTarget).PasteSpecial
Paste:=xlPasteValues
bookName.Range("A" & nameCount).Value = wbSource.Name
nameCount = nameCount + 1
rowOutputTarget = rowOutputTarget + rowCountSource - 2
'close the opened workbook
wbSource.Close SaveChanges:=False
End If
'get the next file
strFile = Dir()
Loop
End Sub
Since the order of the columns is different you have to copy them one at a time.
Sub ImportExcelfiles()
Const ROW_COLNAME = 3
'Variables for Sheet - Workbook Name
Dim wbSource As Workbook
Dim wsTarget As Worksheet, wsName As Worksheet
Dim rowOutputTarget As Long, nameCount As Long
Dim strPath As String, strFile As String, fileName As String
With ThisWorkbook
'set the file and path to folder
strPath = .Sheets("Control").Range("C4")
fileName = .Sheets("Control").Range("C5")
If Right(strPath, 1) <> "\" Then strPath = strPath & "\"
'set the target and name worksheets
Set wsTarget = .Sheets("Master Data")
Set wsName = .Sheets("Workbook Name")
End With
' fill dictionary column name to column number from row 1
Dim dict As Object, k As String, rng As Range
Dim lastcol As Long, lastrow As Long, i As Long, n As Long
Set dict = CreateObject("Scripting.Dictionary")
With wsTarget
lastcol = .Cells(1, .Columns.Count).End(xlToLeft).Column
For i = 1 To lastcol
k = UCase(Trim(.Cells(1, i)))
dict.Add k, i
Next
End With
'set the initial output row and column count for master data and workbook nam
rowOutputTarget = 2
nameCount = 2
'get the first file
strFile = Dir(strPath & "*.xlsx*")
'loop through the excel files in the folder
Dim ar, arH, ky, bHasData
Application.ScreenUpdating = False
Do While strFile <> ""
If InStr(strFile, fileName) > 0 Then
'open the workbook
Set wbSource = Workbooks.Open(strPath & strFile, False, False)
wsName.Range("A" & nameCount).Value = wbSource.Name
nameCount = nameCount + 1
' copy values to arrays
With wbSource.Sheets("Details")
lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
arH = .Range("A1:AD1").Offset(ROW_COLNAME - 1).Value2 ' col names
ar = .Range("A" & ROW_COLNAME & ":AD" & lastrow).Value2
End With
'close the opened workbook
wbSource.Close SaveChanges:=False
' copy each columns
If lastrow > ROW_COLNAME Then
bHasData = False
For n = 1 To UBound(ar, 2)
k = UCase(Trim(arH(1, n)))
' determine target column using dictonary
' as lookup with approx match
i = 0
For Each ky In dict
If InStr(1, k, ky) > 0 Then
i = dict(ky)
Exit For
End If
Next
' valid match
If i > 0 Then
bHasData = True
Set rng = wsTarget.Cells(rowOutputTarget, i).Resize(UBound(ar))
' copy column n of array to column i of target sheet
rng.Value2 = Application.Index(ar, 0, n)
ElseIf Len(k) > 0 Then
Debug.Print "Column '" & k & "' not found " & strFile
End If
Next
If bHasData Then
rowOutputTarget = rowOutputTarget + UBound(ar) + 2
End If
End If
'get the next file
strFile = Dir()
End If
Loop
Application.ScreenUpdating = True
MsgBox nameCount - 2 & " books", vbInformation
End Sub
Import Data From Files in Folder
Option Explicit
Sub ImportExcelfiles()
' Source
Const sName As String = "Details"
Const siFileExtensionPattern As String = ".xlsx" ' maybe ".xls?" ?
Const sfCol As String = "A"
Const slCol As String = "AD"
Const sfRow As Long = 3
' Destination
Const dName As String = "Master Data"
Const dfCellAddress As String = "A2"
' Destination Lookup
Const dlName As String = "Control"
Const dlsFolderPathAddress As String = "C4"
Const dlsFileNamePatternAddress As String = "C5"
' Destination Name
Const dnName As String = "Workbook Name"
Const dnfCellAddress As String = "A2"
Dim dwb As Workbook: Set dwb = ThisWorkbook
' Destination Lookup Worksheet
' (contains the folder path and the partial file name)
Dim dlws As Worksheet: Set dlws = dwb.Worksheets(dlName)
Dim sFolderPath As String: sFolderPath = dlws.Range(dlsFolderPathAddress)
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
Dim sFileNamePattern As String ' contains i.e. leading and trailing '*'
sFileNamePattern = "*" & dlws.Range(dlsFileNamePatternAddress) & "*"
Dim sFileExtensionPattern As String
sFileExtensionPattern = siFileExtensionPattern
If Left(sFileExtensionPattern, 1) <> "." Then _
sFileExtensionPattern = "." & sFileExtensionPattern
Dim sFileName As String
sFileName = Dir(sFolderPath & sFileNamePattern & sFileExtensionPattern)
If Len(sFileName) = 0 Then
MsgBox "No files found.", vbCritical ' improve!
Exit Sub
End If
' Destination Worksheet (source data will by copied to)
Dim dws As Worksheet: Set dws = dwb.Worksheets(dName)
' Source and Destination Columns Count
Dim cCount As Long
cCount = dws.Columns(slCol).Column - dws.Columns(sfCol).Column + 1
' Destination First Row Range
Dim dfrrg As Range: Set dfrrg = dws.Range(dfCellAddress).Resize(, cCount)
' Destination Name Worksheet (source workbook names will be written to)
Dim dnws As Worksheet: Set dnws = dwb.Worksheets(dnName)
' Destination Name Cell
Dim dnCell As Range: Set dnCell = dnws.Range(dnfCellAddress)
Application.ScreenUpdating = False
' Source
Dim swb As Workbook
Dim sws As Worksheet
Dim srg As Range
Dim slRow As Long
' Destination
Dim drg As Range
' Both
Dim rCount As Long
Do While Len(sFileName) > 0
Set swb = Workbooks.Open(sFolderPath & sFileName)
' Attempt to reference the source worksheet.
On Error Resume Next
Set sws = swb.Worksheets("Details")
On Error GoTo 0
If Not sws Is Nothing Then ' worksheet exists
slRow = sws.Cells(sws.Rows.Count, sfCol).End(xlUp).Row
If slRow >= sfRow Then ' found data in column
rCount = slRow - sfRow + 1
Set srg = sws.Cells(sfRow, sfCol).Resize(rCount, cCount)
Set drg = dfrrg.Resize(rCount)
drg.Value = srg.Value
dnCell.Value = swb.Name
' Reset
Set dfrrg = dfrrg.Offset(rCount)
Set dnCell = dnCell.Offset(1)
'Else ' found no data in column; do nothing
End If
Set sws = Nothing
'Else ' worksheet doesn't exist; do nothing
End If
swb.Close SaveChanges:=False
sFileName = Dir
Loop
Application.ScreenUpdating = True
MsgBox "Data imported.", vbInformation
End Sub
How do I copy cells from a workbook based on a cell-value.
In the excel file that needs to be filled, column B contains a part of a filename in which the data can be found.
B2 contains 312123-145
B3 contains 312123-195
etc,
normally around 18rows, but the loop/step can go until a empty cell if found
The workbook the data contains is the cell-value.xlsm
There is a sheet with name Yield in the 312123-145.xlsm
From that sheet I would like to copy A2:N2, and paste that data at the main excel sheet, in columns E:R in the corrosponding row.
I don't know how to start on to look-up a cell value and find the file with the correct data and then how do I step to the next row.
This the code I started with, I hardcoded first all cellvalues to keep it simple.
Sub ImportWorksheet()
' This macro will import a file into this workbook
Sheets("Sheet1").Select
PathName = "C:\Documents\test\"
Filename = "312123-195"
TabName = "Yield"
ControlFile = ActiveWorkbook.Name
Workbooks.Open Filename:=PathName & Filename
ActiveSheet.Name = TabName
Sheets(TabName).Copy After:=Workbooks(ControlFile).Sheets(1)
Windows(Filename).Activate
ActiveWorkbook.Close SaveChanges:=False
Windows(ControlFile).Activate
End Sub
Import Data From Closed Workbooks
Option Explicit
Sub ImportData()
Dim sFolderPath As String: sFolderPath = "C:\Documents\test\"
Dim sFileExtension As String: sFileExtension = ".xlsm" ' ".xls*"
Const sName As String = "Yield"
Const srgAddress As String = "A2:N2"
Const sFileDelimiter As String = "-"
Const dName As String = "Sheet1"
Const dlCol As String = "B" ' Lookup
Const dvCol As String = "E" ' Value
Const dfRow As Long = 2
If Right(sFolderPath, 1) <> "\" Then sFolderPath = sFolderPath & "\"
If Left(sFileExtension, 1) <> "." Then sFileExtension = "." & sFileExtension
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = dwb.Worksheets(dName)
Dim dlRow As Long: dlRow = dws.Cells(dws.Rows.Count, dlCol).End(xlUp).Row
If dlRow < dfRow Then Exit Sub ' no data
Dim dlrg As Range
Set dlrg = dws.Range(dws.Cells(dfRow, dlCol), dws.Cells(dlRow, dlCol))
Dim dcCount As Long: dcCount = dws.Range(srgAddress).Columns.Count
Dim dvrg As Range: Set dvrg = dws.Cells(dfRow, dvCol).Resize(, dcCount)
Dim swb As Workbook
Dim sws As Worksheet
Dim sFilePattern As String
Dim sFileName As String
Dim dlCell As Range
Dim swsCount As Long
Application.ScreenUpdating = False
For Each dlCell In dlrg.Cells
sFilePattern = sFolderPath & Left(CStr(dlCell.Value), _
InStr(1, CStr(dlCell.Value), sFileDelimiter, vbTextCompare) - 1) _
& sFileExtension
sFileName = Dir(sFilePattern)
If Len(sFileName) > 0 Then ' file (workbook) exists
Set swb = Workbooks.Open(sFolderPath & sFileName)
On Error Resume Next
Set sws = swb.Worksheets(sName)
On Error GoTo 0
If Not sws Is Nothing Then ' worksheet exists
dvrg.Value = sws.Range(srgAddress).Value
swsCount = swsCount + 1
End If
swb.Close SaveChanges:=False
End If
Set dvrg = dvrg.Offset(1)
Next dlCell
Application.ScreenUpdating = True
Select Case swsCount
Case 0
MsgBox "No data imported", vbCritical
Case 1
MsgBox "Data imported from one worksheet.", vbInformation
Case Else
MsgBox "Data imported from " & swsCount & " worksheets.", vbInformation
End Select
End Sub
How can a list of sheet names be generated in excel, while skipping the unwanted sheets?
I would like to list “Expenses”, “Revenue”, and “Advisors” (Green tabs). While skipping “Template”, “Reference Data 1”, and “Reference Data 2” (Black tabs).
I receive an error while using the code below.
All help and guidance is appreciated.
Sub List_Sheets()
'
' List_Sheets Macro
'
Dim ws As Worksheet
Dim x As Integer
x = 1 'Starting Row
For Each ws In Worksheets
If InStr(ws.Name, "Template") Then 'Skip "Template" also skip "Referance data 1" and "Referance data 2"
GoTo NextIteration
Sheets("Summary").Cells(x, 1) = ws.Name 'Starting collunm 1 also know as A
x = x + 1
NextIteration:
Next ws
End Sub
This part:
If InStr(ws.Name, "Template") Then 'Skip "Template" also skip "Referance data 1" and "Referance data 2"
GoTo NextIteration
Sheets("Summary").Cells(x, 1) = ws.Name 'Starting collunm 1 also know as A
x = x + 1
NextIteration:
should become:
If InStr(ws.Name, "Template") > 0 or _
InStr(ws.Name, "Reference") > 0 Then GoTo NextIteration
Sheets("Summary").Cells(x, 1) = ws.Name 'Starting collunm 1 also know as A
x = x + 1
NextIteration:
List Certain Worksheets
Option Explicit
Sub ListSheetsSkip()
' The worksheets in the list will be SKIPPED.
Const dSkipSheetsList As String _
= "Template,Reference Data 1,Reference Data 2"
Const dfCol As String = "A"
Const dfRow As Long = 1
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = wb.Worksheets("Summary")
Dim dRow As Long: dRow = dfRow
Dim dSkipSheets() As String: dSkipSheets = Split(dSkipSheetsList, ",")
Dim sws As Worksheet
For Each sws In wb.Worksheets
If IsError(Application.Match(sws.Name, dSkipSheets, 0)) Then
dws.Cells(dRow, dfCol).Value = sws.Name
dRow = dRow + 1
End If
Next sws
MsgBox "Worksheets found: " & dRow - dfRow, vbInformation
End Sub
Sub ListSheetsPick()
' The worksheets in the list will be PICKED.
Const dPickSheetsList As String = "Summary,Expenses,Revenue,Advisors"
Const dfCol As String = "A"
Const dfRow As Long = 1
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = wb.Worksheets("Summary")
Dim dRow As Long: dRow = dfRow
Dim dPickSheets() As String: dPickSheets = Split(dPickSheetsList, ",")
Dim sws As Worksheet
For Each sws In wb.Worksheets
If IsNumeric(Application.Match(sws.Name, dPickSheets, 0)) Then
dws.Cells(dRow, dfCol).Value = sws.Name
dRow = dRow + 1
End If
Next sws
MsgBox "Worksheets found: " & dRow - dfRow, vbInformation
End Sub
Sub ListSheetsTabColor()
' The worksheets with a black tab color will be SKIPPED.
Const dfCol As String = "A"
Const dfRow As Long = 1
Const NotTabColor As String = "0" ' "0"-Black, "255"-Red, "False"-NoColor
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = wb.Worksheets("Summary")
Dim dRow As Long: dRow = dfRow
Dim sws As Worksheet
For Each sws In wb.Worksheets
If CStr(sws.Tab.Color) <> NotTabColor Then
dws.Cells(dRow, dfCol).Value = sws.Name
dRow = dRow + 1
End If
Next sws
MsgBox "Worksheets found: " & dRow - dfRow, vbInformation
End Sub
I am trying to split a file with 120 records into files of at-most 50 records each. So expectation is it should genarate 2 files with 50 records and 1 file wit 20 but what I am getting is 3 files of 51 records with 1 empty file in the end for first 2 and 31 empty lines in 3rd file.
Sub SplitAndSaveFile()
Dim myRow As Long, myBook As Workbook, splitCount As Integer, thisWBName As String, splitCountStr As String, spaceRange As Range
lastRow = ThisWorkbook.Sheets("Data").Cells(rows.Count, 1).End(xlUp).Row
splitCount = 1
splitCountStr = CStr(splitCount)
thisWBName = Replace(ThisWorkbook.Name, ".xlsm", "") + "_Part"
For myRow = 4 To lastRow Step 50
Set myBook = Workbooks.Add
ThisWorkbook.Sheets("Data").rows(myRow & ":" & myRow + 49).EntireRow.Copy myBook.Sheets("Sheet1").Range("A1")
myBook.SaveAs (ThisWorkbook.Path + "\" + thisWBName + splitCountStr + ".txt"), FileFormat:=xlText
myBook.Close
splitCount = splitCount + 1
splitCountStr = CStr(splitCount)
Next myRow
MsgBox ("File(s) generated.")
End Sub
Export Data by Number of Rows
A Partial Quick Fix
Your code seemed to work fine on my testing data, so the only thing I could think of, considering your description of the issue, was that in column A there are formulas evaluating to an empty string at the bottom, which you don't want to include. To fix this, you could use the Find method:
Dim LastRow As Long: LastRow = ThisWorkbook.Worksheets("Data") _
.Columns("A").Find("*", , xlValues, , , xlPrevious)
Unfortunately, you also didn't consider the case when there will be fewer than 50 records to be copied to the last workbook. See how it is handled in the 'In-Depth' solution.
In Depth
This will export the records in a worksheet to new workbooks, saved as text, containing maximally 50 rows.
Option Explicit
Sub SplitAndSaveFile()
Const ProcName As String = "SplitAndSaveFile"
Dim dwbCount As Long ' Generated Workbooks Count
On Error GoTo ClearError
' Source
Const swsName As String = "Data"
Const sCol As String = "A"
Const sfRow As Long = 4
' Destination
Const dfCellAddress As String = "A1" ' needs to be 'A' since entire rows.
Const dMaxRows As Long = 50
Const dNameSuffix As String = "_Part"
' In the loop, this will be replaced by a number ('dwbCount').
Const dIdPlaceHolder As String = "?" ' the '?' is illegal for file names
' The following two lines are dependent on each other.
Const dFileExtension As String = ".txt"
Dim dFileFormat As XlFileFormat: dFileFormat = xlText
' Create a reference to the source first cell ('sfCell').
Dim swb As Workbook: Set swb = ThisWorkbook
Dim sws As Worksheet: Set sws = swb.Worksheets(swsName)
Dim sfCell As Range: Set sfCell = sws.Cells(sfRow, sCol)
' Calculate the number of records (rows) ('drCount').
' This will find the last non-blank cell i.e. cells containing
' formulas evaluating to an empty string are ignored.
' Make sure that the worksheet is not filtered and there are no hidden
' cells.
Dim slCell As Range
Set slCell = sfCell.Resize(sws.Rows.Count - sfRow + 1) _
.Find("*", , xlValues, , , xlPrevious)
If slCell Is Nothing Then Exit Sub ' no data
Dim slRow As Long: slRow = slCell.Row
' This is the preferred way, but besides a few pros, it behaves like 'End'
' i.e. it will find the last non-empty cell. A cell is not empty
' if it contains a formula evaluating to an empty string ('""'):
' it is blank.
'Dim slCell As Range
'Set slCell = sfCell.Resize(sws.Rows.Count - sfRow + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
'If slCell Is Nothing Then Exit Sub ' no data
'Dim slRow As Long: slRow = slCell.Row
' The classic last row using 'End' will find the last non-empty cell.
'Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, sCol).End(xlUp).Row
Dim drCount As Long: drCount = slRow - sfRow + 1
If drCount < 1 Then Exit Sub ' no data (highly unlikely but...)
' Determine the generic file path (dwbGenericFilePath)
Dim swbBaseName As String: swbBaseName = swb.Name
Dim DotPosition As String: DotPosition = InStrRev(swb.Name, ".")
If DotPosition > 0 Then swbBaseName = Left(swbBaseName, DotPosition - 1)
Dim dwbExtension As String: dwbExtension = dFileExtension
If Left(dwbExtension, 1) <> "." Then dwbExtension = "." & dwbExtension
Dim dwbGenericFilePath As String
dwbGenericFilePath = swb.Path & Application.PathSeparator & swbBaseName _
& dNameSuffix & dIdPlaceHolder & dwbExtension
Application.ScreenUpdating = False
' Additional variables used in the loop.
Dim srg As Range
Dim dwb As Workbook
Dim dws As Worksheet
Dim dfCell As Range
Dim dFilePath As String
Do Until drCount = 0
' Create a reference to the current source range.
If drCount > dMaxRows Then ' all workbooks but the last
Set srg = sfCell.Resize(dMaxRows).EntireRow
Set sfCell = sfCell.Offset(dMaxRows)
drCount = drCount - dMaxRows
Else ' the last workbook
Set srg = sfCell.Resize(drCount).EntireRow
drCount = 0
End If
' Copy the current source range to the current destination range.
dwbCount = dwbCount + 1 ' count the number of generated workbooks
Set dwb = Workbooks.Add(xlWBATWorksheet) ' one worksheet only
Set dws = dwb.Worksheets(1)
Set dfCell = dws.Range(dfCellAddress)
srg.Copy dfCell
' Save and close the current destination workbook.
dFilePath = Replace(dwbGenericFilePath, dIdPlaceHolder, CStr(dwbCount))
Application.DisplayAlerts = False ' overwrite without confirmation
dwb.SaveAs dFilePath, dFileFormat
Application.DisplayAlerts = True
dwb.Close SaveChanges:=False
Loop
ProcExit:
Application.ScreenUpdating = True
Select Case dwbCount
Case 0
MsgBox "No files generated.", vbCritical, ProcName
Case 1
MsgBox "One file generated.", vbInformation, ProcName
Case Else
MsgBox dwbCount & " files generated.", vbInformation, ProcName
End Select
Exit Sub
ClearError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
Resume ProcExit
End Sub