Code to pick a folder path to save multiple spreadsheets in a workbook? - vba

I have a workbook with multiple spreadsheets and am looking to save them as individual csv files (retaining the file name from their respective spreadsheets) in a folder of my choosing.
The following code seems to let me choose a path, but errors out with the following message:
Error code 9
Subscript out of range on this line
For Each ws In Sheets(Array("01 - Currencies", "...., "14 - User Defined
Fields"))
What am I missing?
Sub SaveOnlyCSVsThatAreNeeded()
Dim ws As Worksheet, newWb As Workbook
Dim pathh As Variant
Dim FolderName As String
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
If .Show = -1 Then
FolderName = .SelectedItems(1)
End If
End With
pathh = FolderName
Application.ScreenUpdating = False
For Each ws In Sheets(Array("01 - Currencies", "...., "14 - User Defined
Fields"))
ws.Copy
Set newWb = ActiveWorkbook
With newWb
.SaveAs pathh.path & "\" & ws.Name, xlCSV
.Close (False)
End With
Next ws
Application.ScreenUpdating = True
End Sub

Beyond the question of each worksheet's parent workbook, there was a problem with pathh.Path. FolderName is already the full path of the folder selected; you do not need to find its .Path. This would produce:
Runtime error 424: Object required.
Sub SaveOnlyCSVsThatAreNeeded()
Dim ws As Worksheet, wb As Workbook
Dim pathh As Variant
Set wb = ActiveWorkbook
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
If .Show = -1 Then 'a folder was picked
pathh = .SelectedItems(1)
End If
End With
If pathh = False Then Exit Sub 'no folder picked; pathh is false
Application.ScreenUpdating = False
For Each ws In wb.Sheets(Array("Sheet1", "Sheet2", "Sheet4"))
ws.Copy
With ActiveWorkbook
'Application.DisplayAlerts = False 'to avoid overwrite warnings
' pathh is a string (variant) of the path of the folder; does not need pathh.Path
.SaveAs pathh & "\" & ws.Name, xlCSV
.Close SaveChanges:=False
End With
Next ws
Application.ScreenUpdating = True
End Sub
Don't forget to double-check the worksheets names in the array for typos.

Maybe...
For Each ws In ActiveWorkbook.Worksheets
Or
For Each ws In Sheets(Array("01 - Currencies", "14 - User Defined Fields"))

Related

Loop through the files in a folder

I have built some code to loop through multiple files in a folder and then try to consolidate in one sheet.
I am mostly able to accomplish that, but it is failing whenever my source file has only one line item to copy.
It is failing at code Range(Selection, Selection.End(xlDown)).Select. I used this to copy entire rows from A7 row. It works when I have more than one line item. But the code fails when I have only one line item.
And also need to help to change the target sheet: I need to paste it into a new workbook.
Below is my code:
Option explicit
Const FOLDER_PATH = "C:\Users\1\Desktop\New folder (4)\" 'REMEMBER END BACKSLASH
Sub ImportWorksheets()
'=============================================
'Process all Excel files in specified folder
'=============================================
Dim sFile As String 'file to process
Dim wsTarget As Worksheet
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim rowTarget As Long 'output row
rowTarget = 7
'check the folder exists
If Not FileFolderExists(FOLDER_PATH) Then
MsgBox "Specified folder does not exist, exiting!"
Exit Sub
End If
'reset application settings in event of error
On Error GoTo errHandler
Application.ScreenUpdating = False
'set up the target worksheet
Set wsTarget = Sheets("Sheet1")
'loop through the Excel files in the folder
sFile = Dir(FOLDER_PATH & "*.xls*")
Do Until sFile = ""
'open the source file and set the source worksheet - ASSUMED WORKSHEET(1)
Set wbSource = Workbooks.Open(FOLDER_PATH & sFile)
Set wsSource = wbSource.Worksheets(1) 'EDIT IF NECESSARY
'import the data
With wsTarget
Range("A7:BI7").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Windows("Loop through files.xlsm").Activate
Range("A2").Select
Selection.End(xlDown).Select
ActiveCell.Offset(1, 0).Select
ActiveSheet.PasteSpecial
End With
'close the source workbook, increment the output row and get the next file
Application.DisplayAlerts = False
wbSource.Close SaveChanges:=False
Application.DisplayAlerts = True
rowTarget = rowTarget + 1
sFile = Dir()
Loop
errHandler:
On Error Resume Next
Application.ScreenUpdating = True
'tidy up
Set wsSource = Nothing
Set wbSource = Nothing
Set wsTarget = Nothing
End Sub
Private Function FileFolderExists(strPath As String) As Boolean
If Not Dir(strPath, vbDirectory) = vbNullString Then FileFolderExists = True
End Function
Try this. If all your workbooks start at A7, and there are no empty columns or rows, .CurrentRegion is much better than trying to figure out first, last row and column
Option Explicit
Const FOLDER_PATH = "C:\Users\1\Desktop\New folder (4)\" 'REMEMBER END BACKSLASH
Sub ImportWorksheets()
'=============================================
'Process all Excel files in specified folder
'=============================================
Dim sFile As String 'file to process
Dim wsTarget As Worksheet
Dim wbSource As Workbook
Dim wsSource As Worksheet
Dim rowTarget As Long 'output row
rowTarget = 7
'check the folder exists
If Not FileFolderExists(FOLDER_PATH) Then
MsgBox "Specified folder does not exist, exiting!"
Exit Sub
End If
'reset application settings in event of error
On Error GoTo errHandler
Application.ScreenUpdating = True
'set up the target worksheet
Set wsTarget = Sheets("Sheet1")
'loop through the Excel files in the folder
sFile = Dir(FOLDER_PATH & "*.xls*")
Do Until sFile = ""
'open the source file and set the source worksheet - ASSUMED WORKSHEET(1)
Set wbSource = Workbooks.Open(FOLDER_PATH & sFile)
Set wsSource = wbSource.Worksheets(1) 'EDIT IF NECESSARY
'import the data
With wsTarget
Range("A7").CurrentRegion.Copy
Windows("Loop through files.xlsm").Activate
Range("A1048576").Select
Selection.End(xlUp).Select
ActiveCell.Offset(1, 0).Select
ActiveSheet.PasteSpecial
End With
'close the source workbook, increment the output row and get the next file
Application.DisplayAlerts = False
wbSource.Close SaveChanges:=False
Application.DisplayAlerts = True
rowTarget = rowTarget + 1
sFile = Dir()
Loop
errHandler:
On Error Resume Next
Application.ScreenUpdating = True
'tidy up
Set wsSource = Nothing
Set wbSource = Nothing
Set wsTarget = Nothing
End Sub
Private Function FileFolderExists(strPath As String) As Boolean
If Not Dir(strPath, vbDirectory) = vbNullString Then FileFolderExists = True
End Function

Merging multiple worksheets with Images into one workbook - Image error

I just started using VBA and I've been using a code to merge multiple worksheets into a single workbook, it works fine except for worksheets containing images. In these cases the image won't show in the new workbook created. It appears the box where the image should be with an error message. I use MS Office 2010.
Here follows the code I've been using:
Sub MergePlans()
Dim CurFile As String, DirLoc As String
Dim DestWB As Workbook
Dim ws As Object
DirLoc = ThisWorkbook.Path & "\Merge\"
CurFile = Dir(DirLoc & "*.xlsx")
Application.ScreenUpdating = False
Application.EnableEvents = False
Set DestWB = Workbooks.Add(xlWorksheet)
Do While CurFile <> vbNullString
Dim OrigWB As Workbook
Set OrigWB = Workbooks.Open(Filename:=DirLoc & CurFile, ReadOnly:=True)
For Each ws In OrigWB.Sheets
ws.Select
ws.Copy After:=DestWB.Sheets(DestWB.Sheets.Count)
Next
OrigWB.Close Savechanges:=False
CurFile = Dir
Loop
Application.DisplayAlerts = False
DestWB.Sheets(1).Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Application.EnableEvents = True
Set DestWB = Nothing
End Sub
Any idea of what is going on? I'd appreciate any help!
Tks!
just found a workaround that helped!
I just added "Application.ScreenUpdating = True" before closing the source workbook, it takes longer to merge all worsheets, but at least the images are displayed correctly!
Here follows the new code:
Sub MergePlans()
Dim CurFile As String, DirLoc As String
Dim DestWB As Workbook
Dim ws As Object
DirLoc = ThisWorkbook.Path & "\Merge\"
CurFile = Dir(DirLoc & "*.xlsx")
Application.ScreenUpdating = False
Application.EnableEvents = False
Set DestWB = Workbooks.Add(xlWorksheet)
Do While CurFile <> vbNullString
Dim OrigWB As Workbook
Set OrigWB = Workbooks.Open(Filename:=DirLoc & CurFile, ReadOnly:=True)
For Each ws In OrigWB.Sheets
ws.Select
ws.Copy After:=DestWB.Sheets(DestWB.Sheets.Count)
Next
**Application.ScreenUpdating = True**
OrigWB.Close Savechanges:=False
CurFile = Dir
Loop
Application.DisplayAlerts = False
DestWB.Sheets(1).Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Application.EnableEvents = True
Set DestWB = Nothing
End Sub
Found this workaround here - Option 1!
Tks Dan!

Using for each to loop through a series of workbooks

I am a VBA newbie trying to figure out how to loop through a series of workbooks and their sheets in an effort to find a specific sheet but are having some trouble with my object variables.
Below is the code I have "written" (glued together might be a more apt description). I have tried various corrections but only seem to be moving the problem from one place to another. Any help will be appreciated!
Sub NestedForEach()
'Create an object variable to represent each worksheet
Dim WS As Worksheet
Dim WB As Workbook
Set WB = ActiveWorkbook
Set WS = Workbook.Sheets
'create a boolen variable to hold the status of whether we found worksheet "D"
Dim IsFound As Boolean
'initialise the IsFound boolean variable
IsFound = False
For Each WB In Application.Workbooks
For Each WS In WB.Worksheets
If WS.Name = "d" Then
IsFound = True
Exit For
End If
Next WS
Next WB
If IsFound Then
MsgBox "sheet D has been found in " & ActiveWorkbook.Name
Else
MsgBox "we could not locate sheet D in any of the open workbooks"
End If
End Sub
Only few changes were necessary in order to make your code work:
Option Explicit
Sub NestedForEach()
'Create a Worksheet variable to represent one worksheet
Dim WS As Worksheet
Dim WB As Workbook
'create a boolen variable to hold the status of whether we found worksheet "D"
Dim IsFound As Boolean
'initialise the IsFound boolean variable
IsFound = False
For Each WB In Application.Workbooks
For Each WS In WB.Worksheets
If WS.Name = "d" Then
IsFound = True
MsgBox "sheet D has been found in " & WB.Name
Exit Sub
End If
Next WS
Next WB
MsgBox "we could not locate sheet D in any of the open workbooks" & _
Chr(10) & "which are open in this instance of Excel" & _
Chr(10) & "(in case multiple Excels are running)"
End Sub
Let me know if you have any question regarding the changes.
Just 1 week ago I wrote a script to go to a specified folder (the user chooses) and list all Excel files and sheet names in that folder.
Public Sub LoopAllExcelFilesInFolder()
Dim WB As Workbook
Dim myPath As String
Dim myFile As String
Dim myExtension As String
Dim FldrPicker As FileDialog
Dim sht As Worksheet
Dim LastRow As Long
Application.DisplayAlerts = False
Sheets("ListFilesInFolder").Select
Set sht = ThisWorkbook.Worksheets("ListFilesInFolder")
sht.Activate
Rows("2:2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
Range("A1").Select
Set FldrPicker = Application.FileDialog(msoFileDialogFolderPicker)
With FldrPicker
.Title = "Select A Target Folder"
.AllowMultiSelect = False
If .Show <> -1 Then GoTo NextCode
myPath = .SelectedItems(1) & "\"
End With
'In Case of Cancel
NextCode:
myPath = myPath
If myPath = "" Then GoTo ResetSettings
'Target File Extension (must include wildcard "*")
myExtension = "*.xl*"
'Target Path with Ending Extention
myFile = Dir(myPath & myExtension)
Do While myFile <> ""
Set WB = Workbooks.Open(Filename:=myPath & myFile)
With Application
.AskToUpdateLinks = False
End With
For Each Sheet In Workbooks(myFile).Worksheets
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row + 1
Workbooks("Questionaire-Mock-Up.xlsb").Worksheets("ListFilesInFolder").Cells(LastRow, 1).Value = myPath & myFile
Workbooks("Questionaire-Mock-Up.xlsb").Worksheets("ListFilesInFolder").Cells(LastRow, 2).Value = myFile
Workbooks("Questionaire-Mock-Up.xlsb").Worksheets("ListFilesInFolder").Cells(LastRow, 3).Value = Sheet.Name
File = InStr(myFile, ".xl") - 1
LeftName = Left(myFile, File)
Workbooks("Questionaire-Mock-Up.xlsb").Worksheets("ListFilesInFolder").Cells(LastRow, 4).Value = LeftName
LastRow = LastRow + 1
Next Sheet
Workbooks(myFile).Close SaveChanges:=False
myFile = Dir
Loop
ResetSettings:
Application.DisplayAlerts = True
End Sub

Copy Active sheet of all workbooks in a folder to a new workbook

Hi I have the following code to copy all worksheets of all workbooks in a given folder to a single workbook. I need to modify this code to copy only the active sheet on all workbooks (now it copies all the sheets). Can you help me with this?
Option Explicit
Sub CombineFiles()
Dim Path As String
Dim FileName As String
Dim Wkb As Workbook
Dim WS As Worksheet
Application.EnableEvents = False
Application.ScreenUpdating = False
Path = "C:\" 'Change as needed
FileName = Dir(Path & "\*.xlsx", vbNormal)
Do Until FileName = ""
Set Wkb = Workbooks.Open(FileName:=Path & "\" & FileName)
For Each WS In Wkb.Worksheets
WS.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
Next WS
Wkb.Close False
FileName = Dir()
Loop
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
This way you can do what you want:
Option Explicit
Sub CombineFiles()
Dim Path As String
Dim FileName As String
Dim Wkb As Workbook
Dim WS As Worksheet
Application.EnableEvents = False
Application.ScreenUpdating = False
Path = "C:\" 'Change as needed
FileName = Dir(Path & "\*.xlsx", vbNormal)
Do Until FileName = ""
Set Wkb = Workbooks.Open(FileName:=Path & "\" & FileName)
ActiveSheet.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
'For Each WS In Wkb.Worksheets
' WS.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
'Next WS
Wkb.Close False
FileName = Dir()
Loop
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Note:
When you open the workbook, you go over all the sheets with the FOR LOOP, but you only need to copy the ActiveSheet then (as you said) you only need to copy to the new Wrokbook

Cycle a vba function through all workbooks in a folder

I want to cycle through all workbooks in a folder, extract worksheets named "Sheet Name", and save them as .csv files with the name of the file from which they originated. What's quick way to do this?
Example of vba function in question:
Sub Sheet_SaveAs()
Dim wb As Workbook
Sheets("Sheet Name").Copy
Set wb = ActiveWorkbook
With wb
.SaveAs ThisWorkbook.Path & "\" & ThisWorkbook.name, FileFormat:=xlCSV
'.Close False
End With
End Sub
Many thanks for looking
EDIT: Not a duplicate because I am working on extracting sheets from multiple workbooks, and not multiple worksheets from a single workbook.
EDIT2: thank you, everyone.
Something like this.
Change this path to suit your folder
strFolder = "c:\temp"
code
Sub LoopThroughFiles()
Dim Wb As Workbook
Dim ws As Worksheet
Dim strFolder As String
Dim strFile As String
strFolder = "c:\temp"
strFile = Dir(strFolder & "\*.xls*")
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
Do While Len(strFile) > 0
Set Wb = Workbooks.Open(strFolder & "\" & strFile)
Set ws = Nothing
On Error Resume Next
Set ws = Wb.Sheets("Sheet Name")
On Error GoTo 0
If Not ws Is Nothing Then ws.SaveAs Left$(Wb.FullName, InStrRev(Wb.FullName, ".")) & "csv", FileFormat:=xlCSV
Wb.Close False
strFile = Dir
Loop
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub