Find if workbook for individual user exists, if workbook does not exist, create a new workbook with template - vba

I have a data file that I am trying to make for each person in my work group. The data file needs to be identical to a master file as each persons data will be collected into said master file as well as an individual data file.
So far, I have the following code where I try to identify whether a user already has a workbook. I want the created workbook to have the same first four sheets as the master workbook.
The folder specified only contains the "DataFile Master" Workbook so I wouldn't expect the macro to take longer than ~5 seconds. However, when I try to run the macro, the workbook becomes non responsive.
The program does not induce an error report or indicate something to debug.
Does anyone have any ideas?
Sub StoreToPersonal()
Application.ScreenUpdating = False
ckIndWkbk = False
folderpath = "\\netappa\Path\MACRO UPDATE WORKBOOKS" 'change to suit
If Right(folderpath, 1) <> "\" Then folderpath = folderpath + "\"
filename = Dir(folderpath & "*.xlsm")
'Look through path length and find if user has an individual Workbook with a Boolean Statement
Do While filename <> ""
If InStr(filename, Environ("Username")) Then
ckIndWkbk = True
Else
End If
Loop
If ckIndWkbk = False Then
Set wb = Workbooks.Open("\\netappa\Path\MACRO UPDATE WORKBOOKS\DataFile Master.xlsm")
ws = wb.Sheets.Count
For Each ws In wb
If ws.Index > 4 Then
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
Next ws
wb.SaveAs ("\\netappa\Path\MACRO UPDATE WORKBOOKS\\DataFile For " & Environ("Username"))
End If
Application.ScreenUpdating = True
End Sub

The first Dir call sets the parameters and return the first file in the directory. You need to use the Dir in your Do Loop to return subsequent files.
Note: I added Exit Do to after the condition is met.
MSDN Dir Function
Sub StoreToPersonal()
Application.ScreenUpdating = False
ckIndWkbk = False
folderpath = "\\netappa\Path\MACRO UPDATE WORKBOOKS" 'change to suit
If Right(folderpath, 1) <> "\" Then folderpath = folderpath + "\"
Filename = Dir(folderpath & "*.xlsm")
'Look through path length and find if user has an individual Workbook with a Boolean Statement
Do While Filename <> ""
If InStr(Filename, Environ("Username")) Then
ckIndWkbk = True
Exit Do
End If
Filename = Dir
Loop
If ckIndWkbk = False Then
Set wb = Workbooks.Open("\\netappa\Path\MACRO UPDATE WORKBOOKS\DataFile Master.xlsm")
ws = wb.Sheets.Count
For Each ws In wb
If ws.Index > 4 Then
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
Next ws
wb.SaveAs ("\\netappa\Path\MACRO UPDATE WORKBOOKS\\DataFile For " & Environ("Username"))
End If
Application.ScreenUpdating = True
End Sub

Related

Copy range from sheet, and loop through files in a directory and do the following, Add rows to specific sheet, and paste values into sheet

I need to copy data from one sheet on my desktop, and paste it to every xlsx file in a specified folder. The problem I am encountering is an endless loop of copy paste / adding rows.
paste_value is the value to be pasted in the specified range in the specified sheet " Exhibit 1d"
Below is the code
Sub loopFile()
Dim Filename, Pathname As String
Dim wb As Workbook
Dim paste_value As String
paste_value = Workbooks("copy_file.xlsx").Worksheets("EXHIBIT 1D").Range("B59:C64").Copy
Pathname = "C:\Users\GP8535\Desktop\loop_folder\"
Filename = Dir(Pathname & "\*.xls*")
Do While Filename <> ""
Application.DisplayAlerts = False
Application.ScreenUpdating = False
paste_value = Workbooks("copy_file.xlsx").Worksheets("EXHIBIT 1D").Range("B59:C64").Copy
Set wb = Workbooks.Open(Pathname & Filename)
wb.Worksheets("EXHIBIT 1D").Rows("57:63").EntireRow.Insert
wb.Worksheets("EXHIBIT 1D").Range("B59:C63").PasteSpecial
wb.Close SaveChanges:=True
Loop
End Sub
Try this. A few issues
your syntax for defining paste_value was wrong; I think better to define the range (using Set) and do this outside the loop as it doesn't change
key thing to loop through your files is the last line in the loop; your code would have opened the same workbook each time
don't forget to turn alerts and updating back on at the end
Sub loopFile()
Dim Filename, Pathname As String
Dim wb As Workbook
Dim paste_value As Range
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Pathname = "C:\Users\GP8535\Desktop\loop_folder\"
Filename = Dir(Pathname & "\*.xls*")
Set paste_value = Workbooks("copy_file.xlsx").Worksheets("EXHIBIT 1D").Range("B59:C64")
Do While Filename <> ""
Set wb = Workbooks.Open(Pathname & Filename)
wb.Worksheets("EXHIBIT 1D").Rows("57:63").EntireRow.Insert
paste_value.Copy wb.Worksheets("EXHIBIT 1D").Range("B59:C63")
wb.Close SaveChanges:=True
Filename = Dir
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

Merge multiple Excel files into a new Excel file

I know the question has been asked so many times already, and I have tried to use Google to search the interest but failed to find the correct code. ( Trust me, I am not a taker).
Anyway, the idea is to run a script to merge all Excel files (CAD,GBP,JPY,USD) into a new Excel file (tab shows name "CAD","GBP", "JPY","USD") in the current folder. I have written the following script to merge Excel files, but it does not even work.
Sub CombineWorkbooks()
Dim Path As String
Dim FileName As String
Dim Wkb As Workbook
Dim WS As Worksheet
Application.EnableEvents = False
Application.ScreenUpdating = False
Path = "X:\PATH\TO\EXCEL\FILES"
FileName = Dir(Path & "\*.xls", 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
You only have one small mistake.
Change:
Wkb.Close False
To:
Wkb.Close SaveChanges:=False
Here's my full, tested and working solution:
Sub CombineWorkbooks()
Dim Path As String
Dim FileName As String
Dim Wkb As Workbook
Dim WS As Worksheet
Application.EnableEvents = False
Application.ScreenUpdating = False
Path = "X:\PATH\TO\EXCEL\FILES"
FileName = Dir(Path & "\*.xls", 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 SaveChanges:=False
FileName = Dir()
Loop
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
If this doesn't work for you, please give more detail about the results and/or errors. A list of the file names in the folder would also be helpful.
If this does work for you, please remember to mark this as your answer, so others will know you have your solution. Thanks!

Pick folder routine going to Error handler - Excel VBA

Below is code that allows the user to choose a folder and opens files within the folder. It essentially does this:
On open, look for filepath saved in worksheet in workbook based on username. If doesn't exist, then prompt user to find folder, then save filepath in worksheet
From step 1, if filepath is found based on user, use that filepath
Error handler: From step 1, if filepath is found based on user, but that filepath is not in use anymore(i.e. user moved the folder to a different filepath), then have user find the folder again, then update existing record
What i'm experiencing is this:
When there's no entries in the sheet, then it will prompt user to
find the folder, but then proceed to the errorhandler and ask the
user to find the folder again
When there are entries in the sheet and the file path is working, the errorhandler is still opened and asks the user to find the
folder again
If I take out the errorhandler, everything is smooth. It's just that I want to cover the possibility of the user moving the folder , so I want the workbook to prompt the user to find where they moved the folder, and update the existing record in the workbook to the new path
What am I doing wrong here?
Private Sub Workbook_Open()
Dim wkb1 As Workbook
Dim sht1 As Worksheet
Dim wkb2 As Workbook
Dim sht2 As Worksheet
Dim vafiles As Variant
Dim filepath As String
Dim filepath2 As String
Dim filepath3 As String
Dim rw As Long
Dim ws As Worksheet
Dim lastrow As Long
Dim icounter As Long
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlManual
Set ws = Worksheets("Paths")
rw = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row + 1
Set wkb1 = ThisWorkbook
Set sht1 = wkb1.Sheets("Extract")
'======================================================
'Determine if Path was already saved before. If not, prompt user to choose folder
'======================================================
sal = Application.VLookup(Environ("username"), ws.Range("a:b"), 2, 0)
If IsError(sal) Then
MsgBox ("Please choose where your main folder is located. This will be stored so you won't need to look for it again.")
filepath = PICK_A_FOLDER()
ws.Cells(rw, 2) = PICK_A_FOLDER()
ws.Cells(rw, 1) = Environ("username")
Set wkb2 = Workbooks.Open(filepath & "\ Export.xlsx")
Set sht2 = wkb2.Sheets("Sheet1")
sht2.Cells.Copy Destination:=sht1.Range("a1")
Application.CutCopyMode = False
wkb2.Close True
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
Worksheets("Instructions").Activate
Application.Calculation = xlAutomatic
Else
'======================================================
'If filepath exists, use that one
'======================================================
filepath2 = sal
Set wkb2 = Workbooks.Open(filepath2 & "Export.xlsx")
Set sht2 = wkb2.Sheets("Sheet1")
sht2.Cells.Copy Destination:=sht1.Range("a1")
Application.CutCopyMode = False
wkb2.Close True
End If
'======================================================
'If user has moved their folder, we can find it again and update their record
'======================================================
On Error GoTo Errorhandler
Errorhandler:
MsgBox ("Looks like you've moved your Folder. Please find it so your record will be updated")
filepath3 = PICK_A_FOLDER()
lastrow = ws.Cells(Rows.Count, 1).End(xlUp).Row
For icounter = 2 To lastrow
If Cells(icounter, 1) = Environ("username") Then
Cells(icounter, 2) = PICK_A_FOLDER()
End If
Next icounter
Set wkb2 = Workbooks.Open(filepath3 & "")
Set sht2 = wkb2.Sheets("Sheet1")
sht2.Cells.Copy Destination:=sht1.Range("a1")
Application.CutCopyMode = False
wkb2.Close True
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
Worksheets("Instructions").Activate
Application.Calculation = xlAutomatic
End Sub
Actually solved this by taking out the errorhandler and inserting another if statement that captures an invalid directory:
if dir(sal & "Export.xlsx") = "" then
write error handler code
When a SubRoutine performs more that one task you should consider extracting the individual tasks into separate SubRoutines.
In this way:
You can debug each task independently of the other tasks
The logic is simplified into smaller units
The code is easier to read
You can reduce clutter by placing these SubRoutines into separate modules
Possible code reuse
Another unapparent benefit is that by simplifying the function of a SubRoutine it is much easier to remember the routines pattern and reuse the pattern when a similar situation arises.
Note: I often use If Len(...) then which is analogous to If Len(...) > 0 then. I do this to reduce clutter.
Standard Module
Function getSharedFolder() As String
Dim f As Range
With Worksheets("Paths")
Set f = .Range("A1", .Range("A" & .Rows.Count).End(xlUp)).Find(What:=Environ("username"), After:=.Range("A1"), LookAt:=xlWhole)
If Not f Is Nothing Then
'Dir([PathName], vbDirectory) returns empty if the [PathName] isn't a folder
If Len(Dir(f.Offset(0, 1).Value, vbDirectory)) Then
If Right(f.Offset(0, 1), 1) = "\" Then
getSharedFolder = f.Offset(0, 1)
Else
getSharedFolder = f.Offset(0, 1) & "\"
End If
End If
End If
End With
End Function
Function setSharedFolder() As Boolean
Dim f As Range
Dim PathName As String
PathName = PickSharedFolder
If Len(PathName) Then
setSharedFolder = True
With Worksheets("Paths")
Set f = .Range("A1", .Range("A" & .Rows.Count).End(xlUp)).Find(What:=Environ("username"), After:=.Range("A1"), LookAt:=xlWhole)
If f Is Nothing Then Set f = .Range("A1", .Range("A" & .Rows.Count).End(xlUp)).Offset(1)
f.Value = Environ("username")
f.Offset(0, 1) = PathName
End With
End If
End Function
Function PickSharedFolder() As String
Application.FileDialog(msoFileDialogFolderPicker).ButtonName = "Select Folder"
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Title = "Select Main Folder Location"
If .Show = -1 And .SelectedItems.Count = 1 Then
PickSharedFolder = .SelectedItems(1)
Else: Exit Function
End If
End With
End Function
Sub ToggleEvents(EnableEvents As Boolean, Optional DisplayAlerts = True)
With Application
.DisplayAlerts = DisplayAlerts
.EnableEvents = EnableEvents
.ScreenUpdating = EnableEvents
.Calculation = IIf(EnableEvents, xlCalculationAutomatic, xlCalculationManual)
End With
End Sub
Sub UpdateWorkBook(FilePath As String)
Dim WSSource As Worksheet
With Workbooks.Open(FilePath)
Set WSSource = .Sheets("Sheet1")
If WSSource Is Nothing Then
MsgBox "Sheet1 not found in " & FILENAME, vbCritical, "Update Cancelled"
Else
WSSource.Copy Destination:=ThisWorkbook.Sheets("Extract").Range("A1")
End If
.Close True
End With
End Sub
Workbook Module
Private Sub Workbook_Open()
Const FILENAME As String = "Export.xlsx"
Const PROMPT As String = "Press [Yes] to continue or [No] to cancel"
Dim FilePath As String, Title As String, SharedFolder As String
ToggleEvents False, False
Do
SharedFolder = getSharedFolder()
If Len(SharedFolder) = 0 Then
Title = "Folder not found"
Else
FilePath = SharedFolder & FILENAME
If Len(Dir(FilePath)) = 0 Then Title = "File not found"
End If
If Len(SharedFolder) = 0 Then
If MsgBox(PROMPT:=PROMPT, Buttons:=vbYesNo, Title:=Title) = vbYes Then
setSharedFolder
Else
Exit Sub
End If
End If
Loop Until Len(Dir(FilePath))
UpdateWorkBook FilePath
ToggleEvents True, True
End Sub

Merge Many excel files to one new file with different sheet

I am trying to merge many excel files (workbooks) from a folder.
My problem is that I want to move different sheets to the new excel file.
At the moment my code can only move one sheet at the time from these different files.
Example:
I have 3 excel files named
1.xlsx
2.xlsx
3.xlsx
all 3 files have 3 sheets in it and I want to take sheet1 from 1.xlsx and sheet1 and sheet2 from 2.xlsx and finally sheet3 from 3.xlsx and put in a new excel file.
My code at the moment can only takes one sheet (and same sheet number) from each file and put in the new file.
My code so fare:
Sub MergeMultiSheets()
Dim wbDst As Workbook
Dim wbSrc As Workbook
Dim wsSrc As Worksheet
Dim Path As String
Dim Filename As String
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
path = "C:\Users\*ChangeThis*\Desktop\merge"
Set wbDst = Workbooks.Add(xlWBATWorksheet)
Filename = Dir(path & "\*.xlsx", vbNormal)
If Len(Filename) = 0 Then Exit Sub
Do Until Filename = ""
Set wbSrc = Workbooks.Open(Filename:=path & "\" & Filename)
sheet = 1
Set wsSrc = wbSrc.Worksheets(sheet)
wsSrc.Copy After:=wbDst.Worksheets(wbDst.Worksheets.Count)
wbSrc.Close False
Filename = Dir()
Loop
wbDst.Worksheets(1).Delete
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Many thank in advance
You need to loop through all the Sheets in the current Workbook found in your folder.
Try the code below:
Sub MergeMultiSheets()
Dim wbDst As Workbook
Dim wbSrc As Workbook
Dim wsSrc As Worksheet
Dim Path As String
Dim Filename As String
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
Path = "C:\Users\*ChangeThis*\Desktop\merge"
Set wbDst = Workbooks.Add(xlWBATWorksheet)
Filename = Dir(Path & "\*.xlsx", vbNormal)
If Len(Filename) = 0 Then Exit Sub
Do Until Filename = ""
Set wbSrc = Workbooks.Open(Filename:=Path & "\" & Filename)
Sheet = 1
' ****** you need to loop on all sheets per Excel workbook found in Folder ******
For Each wsSrc In wbSrc.Sheets
wsSrc.Copy After:=wbDst.Worksheets(wbDst.Worksheets.Count)
Next wsSrc
wbSrc.Close False
Filename = Dir()
Loop
wbDst.Worksheets(1).Delete
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub

Compile a list/ summary of a specific cell from multiple workbooks with VBA?

I have multiple workbooks in the same layout. In the cell "I8" I have calculated a specific value that I want to compile from all workbooks.
Here is an example of my code:
Sub Code()
Dim file As String
Dim wbResults As Workbook
Dim myPath As String
Application.ScreenUpdating = False
Application.DisplayAlerts = False
myPath = "C:\Test\"
file = Dir$(myPath & "*.xls*")
While (Len(file) > 0)
Set wbResults = Workbooks.Open(Filename:=myPath & file, UpdateLinks:=0)
With wbResults.Worksheets(Split(file, ".")(0))
With .Range("I8")
.Formula = "=10^(D28+(I7*I2))"
End With
End With
wbResults.Close SaveChanges:=True
file = Dir
Wend
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
I would like to add to this code and compile a list in another excel workbook where column A puts the name of the file of a workbook and column B puts the value of "I8" in that respective workbook.
Here is my answer:
Sub Code()
Dim file As String
Dim wbResults As Workbook
Dim myPath As String
myPath = "C:\Test\"
'---------------- Create a new workbook then save it ----------------
Dim WBSummary As Workbook
Set WBSummary = Excel.Application.Workbooks.Add
WBSummary.SaveAs myPath & "WBSummary.xls"
'--------------------------------------------------------------------
Application.ScreenUpdating = False
Application.DisplayAlerts = False
file = Dir$(myPath & "*.xls*")
Dim i As Long 'To update row number in WBSummary
While (Len(file) > 0)
i = i + 1
If file <> "WBSummary.xls" Then
Set wbResults = Workbooks.Open(Filename:=myPath & file, UpdateLinks:=0)
With wbResults.Worksheets(Split(file, ".")(0))
With .Range("I8")
.Formula = "=10^(D28+(I7*I2))"
.Calculate 'To update value in "I8"
WBSummary.Worksheets(1).Cells(i, 1).Value = file
WBSummary.Worksheets(1).Cells(i, 2).Value = .Value
End With
End With
wbResults.Close SaveChanges:=True
End If
file = Dir
Wend
WBSummary.Close True 'Close and Save WBSummary
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub