VBA Importing other spreadsheets into one - vba

Hello thanks for reading my question. I'm trying to import a lot of files into one workbook.
This portion of the scrip works once through the first workbook but crashes on the second workbook when it hits sheet three.
Do While Filename <> ""
Workbooks.Open Filename:=Path & Filename, ReadOnly:=True
Set tmpWb = ActiveWorkbook
For Each Sheet In tmpWb.Sheets
Range("A2").Select
If Range("A2").Value <> "" Then
sFileName = tmpWb.Name
sFileName = Replace(sFileName, ".xlsx", "")
Sheet.Name = sFileName
wbNew.Activate
Sheet.Copy After:=wbNew.Sheets(1)
Else
'do nothing
End If
tmpWb.Activate
On Error GoTo LastSheet
Worksheets(ActiveSheet.Index + 1).Select
LastSheet:
Next Sheet
Workbooks(Filename).Close
Filename = dir()
Loop
It's crashing at Worksheets(ActiveSheet.Index + 1).Select
with this error
Run-Time error 9 Subscript out of range

Done, took a bit of time to figure it out but this functions nicely now, there maybe another bug but it can be used to import files and sheets from the files into one workbook
Sub GetSheets()
Dim sFileName As String
Dim Path As String
Dim wbNew As Workbook
Dim tmpWb As Workbook
Dim tSheets As Long
Dim iSheets As Long
iSheets = 0
Set wbNew = gWrkBook() 'creat new workbook
Path = gGetFolder("Any default folder path")
If gSearch(Path, "\", "LastChar") > 0 Then
Path = Path + "\"
End If
Filename = dir(Path & "*.xlsx")
Do While Filename <> ""
Workbooks.Open Filename:=Path & Filename, ReadOnly:=True
Set tmpWb = ActiveWorkbook
tSheets = tmpWb.Worksheets.Count
If tSheets > 0 Then
iSheets = 1
tmpWb.Sheets(iSheets).Activate
For iSheets = 1 To tSheets
tmpWb.Sheets(iSheets).Activate
Range("A2").Select
If Range("A2").Value <> "" Then
sFileName = tmpWb.Name + "-" + CStr(iSheets)
sFileName = Replace(sFileName, ".xlsx", "")
tmpWb.Sheets(iSheets).Name = sFileName
wbNew.Activate
tmpWb.Sheets(iSheets).Copy After:=wbNew.Sheets(1)
Else
End If
tmpWb.Activate
Next
End If
Workbooks(Filename).Close savechanges:=False
Filename = dir()
Loop
End Sub
Public Function gGetFolder(strPath As String) As String
Dim fldr As FileDialog
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
gGetFolder = sItem
Set fldr = Nothing
End Function

Related

Do While Loop not triggering

I'm trying to use msoFileDialogFolderPicker to select a folder and then loop through the folder. I can't seem to get Do While Len(myFile) > 0 to trigger with FolderPicker if I specifyfilepath with C:\Test\ it works perfectly.
Option Explicit
Sub LoopThroughDirectory()
Dim myFile As String, filepath As String
Dim wbc As Long, ws As Worksheet, wb As Workbook
Dim diaFolder As FileDialog
Set diaFolder = Application.FileDialog(msoFileDialogFolderPicker)
diaFolder.AllowMultiSelect = False
If diaFolder.Show = -1 Then
myFile = diaFolder.SelectedItems(1)
End If
wbc = 0
filepath = diaFolder
Application.ScreenUpdating = False
'Only try to open xlsm workbooks
myFile = Dir(filepath & "*.xlsm*")
Do While Len(myFile) > 0
'Make sure myFile isn't ThisWorkbook
If Split(myFile & ".", ".")(0) <> Split(ThisWorkbook.Name & ".", ".")(0) Then
Set wb = Workbooks.Open(Filename:=filepath & myFile, ReadOnly:=True)
'Check if there is a Results worksheet
On Error Resume Next
Set ws = wb.Worksheets("Results")
On Error GoTo 0
If Not ws Is Nothing Then
'Transfer cells B2 & C2 from the results worksheet
With ws.Range("A2:B2")
ThisWorkbook.Worksheets("AMT").Range("B4").Offset(wbc, 0).Resize(.Rows.Count, .Columns.Count) = .Value
End With
End If
'Close wb most recently opened
wb.Close SaveChanges:=False
wbc = wbc + 1
If wbc > 1000 Then Exit Do
End If
Set ws = Nothing
myFile = Dir
Loop
ActiveWorkbook.Save
End Sub
The reason it does not work is because you assign myFile to the wrong variable:
Your code:
filepath = diaFolder
Correct code:
filepath = myFile
PLUS
myFile = Dir(filepath & "*.xlsm*")
should be
myFile = Dir(filepath & "\*.xlsm")

Need to push updates to closed workbook, having issues with source range

As the title says, I'm trying to push contents of a range of cells from a source workbook to the same range in a target (closed) workbook. I'm using the following code:
Option Explicit
Sub UpdateAdminBook()
Dim MyPath As String
Dim MyFile As String
Dim Wkb As Workbook
Dim Cnt As Long
Application.ScreenUpdating = False
MyPath = "C:FILEPATH\" 'change the path accordingly
If Right(MyPath, 1) <> "\" Then MyPath = MyPath & "\"
MyFile = Dir(MyPath & "Administration.xlsx")
Cnt = 0
Do While Len(MyFile) > 0
Cnt = Cnt + 1
Set Wkb = Workbooks.Open(MyPath & MyFile)
Wkb.Worksheets("Administration").Range("D18:D37").Value = ActiveWorkbook.Sheets("Administration").Range("D18:D37") 'change the new value accordingly
Wkb.Close savechanges:=True
MyFile = Dir
Loop
If Cnt > 0 Then
MsgBox "Completed...", vbExclamation
Else
MsgBox "No files were found!", vbExclamation
End If
Application.ScreenUpdating = True
End Sub
I'm having trouble starting at "ActiveWorkbook" and I keep getting "TRUE" or blanks. Any idea how I can fix this?
When you open a workbook, it becomes the active workbook, rather than the original workbook. Change to this
Dim wbSrc As Workbook
Set wbSrc = ActiveWorkbook
'...
Do ...
' ...
Set Wkb = Workbooks.Open(MyPath & MyFile)
Wkb.Worksheets("Administration").Range("D18:D37").Value = wbSrc.Sheets("Administration").Range("D18:D37") 'change the new value accordingly
you could assume your copying range as reference in a With - End With block
Sub UpdateAdminBook()
Dim MyPath As String
Dim MyFile As String
Dim Cnt As Long
Application.ScreenUpdating = False
MyPath = "C:FILEPATH\" 'change the path accordingly
If Right(MyPath, 1) <> "\" Then MyPath = MyPath & "\"
MyFile = Dir(MyPath & "Administration.xlsx")
With ActiveWorkbook.Sheets("Administration").Range("D18:D37")
Cnt = 0
Do While Len(MyFile) > 0
Cnt = Cnt + 1
Workbooks.Open(MyPath & MyFile).Worksheets("Administration").Range("D18:D37").Value = .Value 'change the new value accordingly
ActiveWorkbook.Close savechanges:=True
MyFile = Dir
Loop
End With
If Cnt > 0 Then
MsgBox "Completed...", vbExclamation
Else
MsgBox "No files were found!", vbExclamation
End If
Application.ScreenUpdating = True
End Sub

How to move Workbooks from one folder to another with conditions?

There is a ready script that counts number of rows in Workbooks from a selected folder. In case number of rows in any workbook is more than 1, this workbook is copied and saved into another folder.
Sub OpenFiles()
Dim MyFolder As String
Dim MyFile As String
Dim TargetWB As Workbook
MyFolder = GetFolder("C:\Users\user\Desktop")
MyFile = Dir(MyFolder & "*.*")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Do While MyFile <> ""
Set TargetWB = Workbooks.Open(Filename:=MyFolder & "\" & MyFile & "*.*")
With TargetWB
If CountUsedRows(TargetWB) > 1 Then
.SaveAs "C:\Users\user\Desktop\vba\" & MyFile
End If
.Close
End With
MyFile = Dir
Loop
'Workbooks.Close savechanges:=False
Shell "explorer.exe C:\Users\user\Desktop\vba", vbMaximizedFocus
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Function GetFolder(strPath As String) As String
Dim fldr As FileDialog
Dim sItem As String
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = strPath
If .Show <> -1 Then GoTo NextCode
sItem = .SelectedItems(1)
End With
NextCode:
GetFolder = sItem
Set fldr = Nothing
End Function
Function CountUsedRows(Wbk As Workbook) As Long
Dim WS As Worksheet
Set WS = Wbk.Sheets(1)
CountUsedRows = WS.Range("A" & Rows.Count).End(xlUp).Row
End Function
Is it possible to move a Worbook to another folder insted of coping it in case it contains more than 1 row.
And is it possible to use something like: Workbooks.Close savechanges:=False in order to close chosen Workbooks after rows counting? Thanks!
You can move a file easily using the MoveFile method of FileSystemObject object. To use this type with early binding add a reference to Microsoft Sripting Runtime in your VBA project.

Searching excel files for specific sheets to create a list

I have worked on this for a while. It's my first Excel VBA macro and I think I am almost there. I just can't seem to find a way to get the information I need from my function or I can't get my function to give me the right information.
I need a macro that will search through a selected folder and its sub-folders for excel workbooks that have specific sheet names contained with in then out put the paths to an excel spreadsheet. Currently my code will either only find the files in a single folder or it will list all the files indiscriminately. Now the code is a bit of a mess because i am unsure of which parts I need and which parts I don't.
Option Explicit
Public ObjFolder As Object
Public objFso As Object
Public objFldLoop As Object
Public lngCounter As Long
Public objFl As Object
Sub ImportSheet()
Dim i As Integer
Dim SourceFolder As String
Dim FileList As Variant
Dim GrabSheet As String
Dim FileType As String
Dim ActWorkBk As String
Dim ImpWorkBk As String
Dim NoImport As Boolean
Dim FileToWriteTo As Variant
Dim xRow As Long
Dim xDirect$, xFname$, InitialFoldr$
Dim MyDir As String, myList()
'Startup folder to begin filedialog search
InitialFoldr$ = "C:"
'Define filetype
FileType = "*.xlsx"
'Define sheetname to copy
GrabSheet = Application.InputBox(prompt:="Please enter name of sheet you wish to find.", Title:="Specify Sheet Name")
'open dialog for user to select a folder to search
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = Application.DefaultFilePath & "\"
.Title = "Please select a folder to list Files from"
.InitialFileName = InitialFoldr$
If .Show = True Then
MyDir = .SelectedItems(1)
End If
End With
On Error Resume Next
myList = SearchFiles(MyDir, "*.xlsx", 0, myList())
If Err = 0 Then
'If user selects folder count the items to search
xDirect$ = MyDir & "\"
xFname$ = Dir(xDirect$, 8)
'Creates list with filenames
FileList = ListFiles(xDirect$ & FileType)
'Imports data
Application.ScreenUpdating = False
ActWorkBk = ActiveWorkbook.Name
NoImport = False
'Clear contents of Active sheet and set active cell to A1
Sheets(1).UsedRange.ClearContents
Sheets(1).Select
Range("A1").Select
For i = 1 To UBound(FileList)
'Opens file
Workbooks.Open (xDirect$ & FileList(i))
ImpWorkBk = ActiveWorkbook.Name
'Checks to see if the specific sheet exists in the workbook
On Error Resume Next
ActiveWorkbook.Sheets(GrabSheet).Select
If Err > 0 Then
NoImport = True
GoTo nxt
End If
Err.Clear
On Error GoTo 0
xFname$ = Dir(xDirect$ & FileList(i))
Do While xFname$ <> ""
ThisWorkbook.Activate
ActiveCell.Offset(xRow) = xDirect$ & xFname$
xRow = xRow + 1
xFname$ = Dir
Loop
'Copies sheet
'ActiveWorkbook.Sheets(GrabSheet).Copy after:=Workbooks(ActWorkBk).Sheets(Workbooks(ActWorkBk).Sheets.Count)
'Renames the imported sheet
On Error Resume Next
ActiveSheet.Name = "Specs with " & GrabSheet
Err.Clear
On Error GoTo 0
nxt:
'Closes importfile
Workbooks(ImpWorkBk).Activate
Application.DisplayAlerts = False
ActiveWorkbook.Saved = True
ActiveWorkbook.Close SaveChanges:=False
Application.DisplayAlerts = True
'Workbooks(ActWorkBk).Activate
Next i
'Error if some sheets were not found
' If NoImport = True Then MsgBox "Some of the files did not contain the sheet " & GrabSheet
Application.ScreenUpdating = True
Else
MsgBox "No file found"
End If
On Error GoTo 0
' End If
'End With
'End Function
End Sub
'WITH SUBFOLDERS - Function that creates an array with all the files in the folder
Private Function SearchFiles(MyDir As String, myFileName As String, n As Long, myList()) As Variant
Dim fso As Object, myFolder As Object, myFile As Object
Set fso = CreateObject("Scripting.FileSystemObject")
For Each myFile In fso.getfolder(MyDir).Files
If (Not myFile.Name Like "~$*") * (myFile.Name <> ThisWorkbook.Name) _
* (myFile.Name Like myFileName) Then
n = n + 1
ReDim Preserve myList(1 To 2, 1 To n)
myList(1, n) = MyDir
myList(2, n) = myFile.Name
End If
Next
For Each myFolder In fso.getfolder(MyDir).subfolders
SearchFiles = SearchFiles(myFolder.Path, myFileName, n, myList)
Next
SearchFiles = IIf(n > 0, myList, "")
End Function
'WITHOUT SUBFOLDERS - Function that creates an array with all the files in the folder
Function ListFiles(Source As String) As Variant
Dim GetFileNames() As Variant
Dim i As Integer
Dim FileName As String
On Error GoTo ErrHndlr
i = 0
FileName = Dir(Source)
If FileName = "" Then GoTo ErrHndlr
'Loops until no more mathing files are found
Do While FileName <> ""
i = i + 1
ReDim Preserve GetFileNames(1 To i)
GetFileNames(i) = FileName
FileName = Dir()
Loop
ListFiles = GetFileNames
On Error GoTo 0
Exit Function
'If error
ErrHndlr:
ListFiles = False
On Error GoTo 0
End Function
This will work right now to give a list using the "ListFiles" Function.
But I can't seem to figure out how to get it to out put a list using the "SearchFiles" Function. Which, ultimately,is what I need it to do.
Please help i feel like I am so close!!!
Ok i figured it out. I was having trouble with the syntax to access my array of arrays. here is the code that ended up doing the trick.
Option Explicit
Public ObjFolder As Object
Public objFso As Object
Public objFldLoop As Object
Public lngCounter As Long
Public objFl As Object
Sub ImportSheet()
Dim i As Integer
Dim GrabSheet As String
Dim ActWorkBk As String
Dim ImpWorkBk As String
Dim NoImport As Boolean
Dim xRow As Long
Dim xFname As String
Dim InitialFoldr As String
Dim MyDir As String, myList()
'Startup folder to begin filedialog search
InitialFoldr = "C:\Users\george.EASYWAY\Desktop\TEST1\"
'Define sheetname to copy
GrabSheet = Application.InputBox(prompt:="Please enter name of sheet you wish to find.", Default:="snagit", Title:="Specify Sheet Name")
'open dialog for user to select a folder to search
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = Application.DefaultFilePath & "\"
.Title = "Please select a folder to list Files from"
.InitialFileName = InitialFoldr
If .Show = True Then
MyDir = .SelectedItems(1)
End If
End With
On Error Resume Next
myList = SearchFiles(MyDir, "*.xlsx", 0, myList())
If Err = 0 Then
'Imports data
Application.ScreenUpdating = False
ActWorkBk = ActiveWorkbook.Name
NoImport = False
'Clear contents of Active sheet and set active cell to A1
Sheets(1).UsedRange.ClearContents
Sheets(1).Select
Range("A1").Select
For i = 1 To UBound(myList, 2)
'Opens file
Workbooks.Open (myList(1, (i)) & "\" & (myList(2, (i))))
ImpWorkBk = ActiveWorkbook.Name
'Checks to see if the specific sheet exists in the workbook
On Error Resume Next
ActiveWorkbook.Sheets(GrabSheet).Select
If Err > 0 Then
NoImport = True
GoTo nxt
End If
Err.Clear
On Error GoTo 0
xFname = Dir(myList(1, (i)) & "\" & (myList(2, (i))))
Do While xFname <> ""
ThisWorkbook.Activate
ActiveCell.Offset(xRow) = (myList(1, (i)) & "\" & (myList(2, (i))))
xRow = xRow + 1
xFname = Dir
Loop
'Renames the imported sheet
On Error Resume Next
ActiveSheet.Name = "Specs with " & GrabSheet
Err.Clear
On Error GoTo 0
nxt:
'Closes importfile
Workbooks(ImpWorkBk).Activate
Application.DisplayAlerts = False
ActiveWorkbook.Saved = True
ActiveWorkbook.Close SaveChanges:=False
Application.DisplayAlerts = True
'Workbooks(ActWorkBk).Activate
Next i
'Error if some sheets were not found
' If NoImport = True Then MsgBox "Some of the files did not contain the sheet " & GrabSheet
Application.ScreenUpdating = True
Else
MsgBox "No file found"
End If
On Error GoTo 0
End Sub
'Function that creates an array with all the files in the folder with subfolders
Function SearchFiles(MyDir As String, myFileName As String, n As Long, myList()) As Variant
Dim fso As Object, myFolder As Object, myFile As Object
Set fso = CreateObject("Scripting.FileSystemObject")
For Each myFile In fso.getfolder(MyDir).Files
If (Not myFile.Name Like "~$*") * (myFile.Name <> ThisWorkbook.Name) _
* (myFile.Name Like myFileName) Then
n = n + 1
ReDim Preserve myList(1 To 2, 1 To n)
myList(1, n) = MyDir
myList(2, n) = myFile.Name
End If
Next
For Each myFolder In fso.getfolder(MyDir).subfolders
SearchFiles = SearchFiles(myFolder.Path, myFileName, n, myList)
Next
SearchFiles = IIf(n > 0, myList, "")
End Function

DIR loop with specific sheet names

I have 5 files in a folder. I need to split a sheet called Marrs Upload into a separate worksheet.
I've managed to get it to work for the first file but after that it comes up with the "Run Time error: 9 Subscript out of range" message.
Here is my current code:
Sub Hello()
StrFile = Application.ActiveWorkbook.Path + "\" 'Get path name
GetFullFile = ActiveWorkbook.Name 'File name
sFilename = Left(GetFullFile, (InStr(GetFullFile, ".") - 1)) 'Fine the . and
i = 1 'Part of the name counter
ExportFile = StrFile + "Import to Marrs\"
SaveAsFileName = "Marrs Upload " & Format(Date, "dd-mm-yyyy ") ' Saves the filename Marrs Upload (Date) followed by counter
Application.DisplayAlerts = False
strFilename = Dir(StrFile)
If Len(strFilename) = 0 Then Exit Sub ' exit if no files in folder
Do Until strFilename = ""
Sheets("Marrs Upload").Move ' Moves Marrs Upload tab
ActiveWorkbook.Close (False)
ActiveWorkbook.SaveAs (ExportFile & SaveAsFileName & i)
'ActiveWorkbook.Close (False)
'ActiveWorkbook.Close (False)
i = i + 1
strFilename = Dir()
Loop
End Sub
I've tried most things and cannot get any further.
Kind Regards,
Ashley
I've added to original code to only work if a certain sheet name exists.
Sub Hello()
StrFile = Application.ActiveWorkbook.Path + "\" 'Get path name
GetFullFile = ActiveWorkbook.Name 'File name
sFileName = Left(GetFullFile, (InStr(GetFullFile, ".") - 1)) 'Find the . and returns only file name minus extension
i = 1 'Counter
ExportFile = StrFile + "Import to Marrs\" 'Saves new worksheet in a specific folder
SaveAsFileName = "Marrs Upload " & Format(Date, "dd-mm-yyyy ") ' Saves the filename Marrs Upload (Date) followed by counter
Application.DisplayAlerts = False 'Don't display alerts "Overwrite, ect"
StrFileName = Dir(StrFile) 'No extension as can be a combination of .xlsm and .xls
Do While Len(StrFileName) > 0 'Loop when files are in DIR
If CheckSheet("Marrs Upload") Then 'if workseet contains a tab called "Marrs Upload" then continue.
Sheets("Marrs Upload").Move ' Moves Marrs Upload tab
ActiveWorkbook.SaveAs (ExportFile & SaveAsFileName & i) 'Save worksheet as Marrs Upload (Date) (Counter)
ActiveWorkbook.Close (False) 'Don't need to save original file (Audit Trail)
i = i + 1 'Increase counter by 1
End If
StrFileName = Dir() 'used when worksheet doesn't contain sheet called "Marrs Upload"
Loop
End Sub
Function CheckSheet(ByVal sSheetName As String) As Boolean
Dim oSheet As Worksheet
Dim bReturn As Boolean
For Each oSheet In ActiveWorkbook.Sheets
If oSheet.Name = sSheetName Then
bReturn = True
Exit For
End If
Next oSheet
CheckSheet = bReturn
End Function
Kind Regards,
Ashley
EDIT: Tested, and works for me.
Sub Hello()
Dim SourceFolder As String, DestFolder As String
Dim f As String, SaveAsFileName As String, sFileName As String
Dim i As Long, wb As Workbook
'*** if ActiveWorkbook has the macro, safer to use ThisWorkbook
SourceFolder = Application.ActiveWorkbook.Path + "\"
DestFolder = SourceFolder & "Import to Marrs\"
'*** what are you doing with this?
sFileName = Left(ActiveWorkbook.Name, _
(InStr(ActiveWorkbook.Name, ".") - 1))
' Saves the filename Marrs Upload (Date) followed by counter
SaveAsFileName = "Marrs Upload " & Format(Date, "dd-mm-yyyy ")
Application.DisplayAlerts = False
i = 1 'Part of the name counter
f = Dir(SourceFolder & "*.xls*") '*** use wildcard for XL files only
Do While Len(f) > 0
Debug.Print f
Set wb = Workbooks.Open(SourceFolder & f)
If CheckSheet(wb, "Marrs Upload") Then
wb.Sheets("Marrs Upload").Move ' Moves Marrs Upload tab
'*** the wb with the moved sheet is now active: save it
With ActiveWorkbook
.SaveAs (DestFolder & SaveAsFileName & i)
.Close True
End With
i = i + 1
End If
wb.Close False '***close the one we just opened. Not saving?
f = Dir() '*** next file
Loop
End Sub
Function CheckSheet(wb as WorkBook, ByVal sSheetName As String) As Boolean
Dim oSheet As Worksheet
Dim bReturn As Boolean
For Each oSheet In wb.WorkSheets
If oSheet.Name = sSheetName Then
bReturn = True
Exit For
End If
Next oSheet
CheckSheet = bReturn
End Function