Do While Loop not triggering - vba

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")

Related

Trying to copy static cell value from workbook A and paste into dynamic location in workbook B

I'm trying to:
Copy cell "B2:C2" from every workbook in a folder from the "Results" worksheet.
Paste the value into Cell A1:A2 Sheet1 in workbook "x"in the same folder.
I think I know how to open and do something to every workbook within a folder.
Option Explicit
Sub LoopThroughDirectory()
Dim MyFile As String
Dim WorkbookCounter As Long
WorkbookCounter = 1
Dim Filepath As String
Dim wb As Workbook
Dim RowCounter As Long
RowCounter = 1
Filepath = "C:\Test\"
Application.ScreenUpdating = False
MyFile = Dir(Filepath)
'Opens workbooks located C:\Test\ in order
Do While Len(MyFile) > 0
Set wb = Workbooks.Open(Filepath & MyFile)
Application.DisplayAlerts = False
'Copy cells B2 & C2 from the results worksheet
ThisWorkbook.Worksheets("x").Range(Cells(RowCounter, 1), Cells(RowCounter, 2)).Value = _
wb.Worksheets("Results").Range("B2:C2").Value
'Close wb most recently opened
wb.Close SaveChanges:=False
Application.CutCopyMode = False
WorkbookCounter = WorkbookCounter + 1
If WorkbookCounter > 1000 Then
Exit Sub
End If
MyFile = Dir
RowCounter = RowCounter + 1
Loop
ActiveWorkbook.Save
Application.ScreenUpdating = True
End Sub
Update: With help in the comments below the above code now correctly loops through the correct folder and updates cell A1:A2.
Instead of overwriting cell A1:A2 I'd like to paste the copied text one line down.
i.e. Workbook 1 = A1:A2, Workbook 2 = B1:B2, etc
I don't see any check to make sure you are not trying to open ThisWorkbook and there is no check to see if there is a Results worksheet in the source workbook; in fact there is no check to ensure that you are trying to open a workbook at all, you could be trying to open a JPG.
Further error control could be added to ensure that you are not trying to open another workbook that is already open. I suspect that after all the testing, you might have a few.
Option Explicit
Sub LoopThroughDirectory()
Dim myFile As String, filepath As String
Dim wbc As Long, ws As Worksheet, wb As Workbook
wbc = 0
filepath = "C:\Test\"
'Application.ScreenUpdating = False
'only try to open workbooks
myFile = Dir(filepath & "*.xls*")
'Opens workbooks located C:\Test\ in order
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)
'Application.DisplayAlerts = False
'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("B2:C2")
ThisWorkbook.Worksheets("x").Range("A1").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
'Application.ScreenUpdating = True
End Sub

Loop through workbook and sheets in each workbook vba

I want to loop through all Workbooks in a folder and then loop through all worksheets of each workbook. I have the code below but currently the problem is with the line For Each ws in StrFile.Sheets:
Sub LoopThroughFiles()
Dim StrFile As String
StrFile = Dir("C:\Users\A9900899\Desktop\bob\VBAProject\Raw\")
Do While Len(StrFile) > 0
Debug.Print StrFile
For Each ws In StrFile.Sheets
Debug.Print ws.Name
Next ws
StrFile = Dir
Loop
End Sub
What is my mistake here?
In order to loop through all Workbook.Sheets you need to Set wb to the current StrFile, and then loop through wb.Sheets.
Using Application.ScreenUpdating = False and Application.DisplayAlerts = False will minimize all screen flickering and Excel alerts.
Code
Option Explicit
Sub LoopThroughFiles()
Dim StrFile As Variant
Dim fPath As String
Dim wb As Workbook
Dim ws As Worksheet
fPath = "C:\Users\A9900899\Desktop\bob\VBAProject\Raw\"
StrFile = Dir(fPath)
Application.ScreenUpdating = False
Application.DisplayAlerts = False
While StrFile <> ""
Debug.Print StrFile
If StrFile Like "*xls*" Then ' check that current file is Excel type
Set wb = Workbooks.Open(fPath & StrFile)
For Each ws In wb.Sheets
Debug.Print ws.Name
Next ws
wb.Close False ' close workbook and don't save changes
End If
StrFile = Dir
Wend
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

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

VBA Importing other spreadsheets into one

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

Excel VBA: select one row down in a loop

I have a source folder that contains many xls files. I want to create a master file - collect all information into one database from all files in the given source.
The following code creates 2 columns in master file and enters 2 values from the given source file (one file):
Sub getData()
Dim XL As Excel.Application
Dim WBK As Excel.Workbook
Dim scrFile As String
Dim myPath As String
myPath = ThisWorkbook.path & "\db\" 'The source folder
scrFile = myPath & "1.xlsx" 'Select first file
' Sheet name in the master file is "Sh"
ThisWorkbook.Sheets("Sh").Range("A1").Value = "Column 1"
ThisWorkbook.Sheets("Sh").Range("B1").Value = "Column 2"
Set XL = CreateObject("Excel.Application")
Set WBK = XL.Workbooks.Open(scrFile)
ThisWorkbook.Sheets("Sh").Range("A2").Value = WBK.ActiveSheet.Range("A10").Value
ThisWorkbook.Sheets("Sh").Range("B2").Value = WBK.ActiveSheet.Range("C5").Value
WBK.Close False
Set XL = Nothing
Application.ScreenUpdating = True
End Sub
Now I want to loop through all files and save the values from cells "A10" and "C5" from each file in one database, so the loop should select the next row to save new values.
I have an idea how to loop through all files, but don't know how to switch to the next row:
scrFile = Dir(myPath & "*.xlsx")
Do While scrFile <> ""
Set XL = CreateObject("Excel.Application")
Set WBK = XL.Workbooks.Open(scrFile)
' Here should be the code to save the values of A10 and C5 of the given file
'in the loop in next available row of the master file.
WBK.Close False
Set XL = Nothing
scrFile = Dir
Loop
Any help will be highly appreciated! :)
For simplicity, just use a counter:
scrFile = Dir(myPath & "*.xlsx")
n = 1 ' skip the first row with headers
Do While scrFile <> ""
n = n + 1
Set XL = CreateObject("Excel.Application")
Set WBK = XL.Workbooks.Open(scrFile)
' save the values of A10 and C5 of the given file in the next row
ThisWorkbook.Sheets("Sh").Range("A" & n).Value = WBK.ActiveSheet.Range("A10").Value
ThisWorkbook.Sheets("Sh").Range("B" & n).Value = WBK.ActiveSheet.Range("C5").Value
WBK.Close False
Set XL = Nothing
scrFile = Dir
Loop
msgbox n & " files imported."
BTW, you don't need to start a second Excel instance (CreateObject("Excel.Application")) just to open a second workbook. This will slow down your code a lot. Just open, read and close it. Address your master workbook not by ThisWorkbook but assign a varible to it:
Dim masterWB As Excel.Workbook
set masterWB = ThisWorkbook
...
masterWB.Sheets("Sh").Range("A" & n).Value = WBK.ActiveSheet.Range("A10").Value
You need to recalculate last row in the loop wtih End() function.
Like this for range .Range("A" & .Rows.Count).End(xlUp).Offset(1, 0)
Or to have an integer .Range("A" & .Rows.Count).End(xlUp).Offset(1, 0).Row
Give this a try :
Sub getData()
Application.ScreenUpdating = False
Dim XL As Excel.Application, _
WBK As Excel.Workbook, _
MS As Worksheet, _
scrFile As String, _
myPath As String
'Sheet name in the master file is "Sh"
Set MS = ThisWorkbook.Sheets("Sh")
'The source folder
myPath = ThisWorkbook.Path & "\db\"
MS.Range("A1").Value = "Column 1"
MS.Range("B1").Value = "Column 2"
Set XL = CreateObject("Excel.Application")
scrFile = Dir(myPath & "*.xlsx")
Do While scrFile <> ""
Set WBK = XL.Workbooks.Open(scrFile)
' Here should be the code to save the values of A10 and C5 of the given file
'in the loop in next available row of the master file.
With MS
.Range("A" & .Rows.Count).End(xlUp).Offset(1, 0).Value = WBK.ActiveSheet.Range("A10").Value
.Range("B" & .Rows.Count).End(xlUp).Offset(1, 0).Value = WBK.ActiveSheet.Range("C5").Value
End With
WBK.Close False
scrFile = Dir
Loop
XL.Quit
Set XL = Nothing
Set MS = Nothing
Set WBK = Nothing
Application.ScreenUpdating = True
End Sub
I actually have a code here that will loop through each file and deposit the code into your main file. You are also able to choose the directory of the target folder.
Sub GatherData()
Dim sFolder As String
Application.ScreenUpdating = True
With Application.FileDialog(msoFileDialogFolderPicker)
.InitialFileName = Application.DefaultFilePath & "\"
.Title = "Please select a folder..."
.Show
If .SelectedItems.Count > 0 Then
sFolder = .SelectedItems(1) & "\"
Else
Exit Sub
End If
End With
Call Consolidate(sFolder, ThisWorkbook)
End Sub
Private Sub Consolidate(sFolder As String, wbMaster As Workbook)
Dim wbTarget As Workbook
Dim objFso As Object
Dim objFiles As Object
Dim objSubFolder As Object
Dim objSubFolders As Object
Dim objFile As Object
Dim ary(3) As Variant
Dim lRow As Long
'Set Error Handling
On Error GoTo EarlyExit
'Create objects to enumerate files and folders
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFiles = objFso.GetFolder(strFolder).Files
Set objSubFolders = objFso.GetFolder(strFolder).subFolders
'Loop through each file in the folder
For Each objFile In objFiles
If InStr(1, objFile.Path, ".xls") > 0 Then
Set wbTarget = Workbooks.Open(objFile.Path)
With wbTarget.Worksheets(1)
ary(0) = .Range("B8") 'here you can change the cells you need the data from
ary(1) = .Range("B12")
ary(2) = .Range("B14")
End With
With wbMaster.Worksheets(1)
lRow = .Range("E" & .Rows.Count).End(xlUp).Offset(1, 0).Row 'here you can change the row the data is deposited in
.Range("E" & lRow & ":G" & lRow) = ary
End With
wbTarget.Close savechanges:=False
End If
Next objFile
'Request count of files in subfolders
For Each objSubFolder In objSubFolders
Consolidate objSubFolder.Path, wbMaster
Next objSubFolder
EarlyExit:
'Clean up
On Error Resume Next
Set objFile = Nothing
Set objFiles = Nothing
Set objFso = Nothing
On Error GoTo 0
End Sub