Excel VBA - open a workbook and pasting data - excel

I found this excellent code however I need to adapt it for my purposes.
Firstly I need to open a data workbook that is on our network. The problem I have is that it is likely at times to be open by another user and will offer the option of "read only". How can I get it to accept the read-only option so that I can commence extracting the data.
Secondly it copies using the "=" . How can I change it to copy just the values?
First macro:
Sub test()
'to open another workbook
Application.ScreenUpdating = False
Workbooks.Open Filename:=ThisWorkbook.Path & "\Schedule.xls"
ThisWorkbook.Activate
Application.ScreenUpdating = True
End Sub
2nd Macro:
Dim Sh As Worksheet
Dim Newsh As Worksheet
Dim myCell As Range
Dim ColNum As Integer
Dim RwNum As Long
Dim Basebook As Workbook
With Application
.Calculation = xlCalculationManual
.ScreenUpdating = False
End With
'Delete the sheet "Summary-Sheet" if it exist
Application.DisplayAlerts = False
On Error Resume Next
ThisWorkbook.Worksheets("Summary-Sheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a worksheet with the name "Summary-Sheet"
Set Basebook = ThisWorkbook
Set Newsh = Basebook.Worksheets.Add
Newsh.Name = "Summary-Sheet"
'The links to the first sheet will start in row 2
RwNum = 1
For Each Sh In Basebook.Worksheets
If Sh.Name <> Newsh.Name And Sh.Visible Then
ColNum = 1
RwNum = RwNum + 1
'Copy the sheet name in the A column
Newsh.Cells(RwNum, 1).Value = Sh.Name
For Each myCell In Sh.Range("A1,D5:E5,Z10") '<--Change the range
ColNum = ColNum + 1
Newsh.Cells(RwNum, ColNum).Formula = _
"='" & Sh.Name & "'!" & myCell.Address(False, False)
Next myCell
End If
Next Sh
Newsh.UsedRange.Columns.AutoFit
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
End Sub

You could always open the workbook as read-only if you are only extracting data.
Instead of using .formula use .value

Related

SCript does not generate a new workbook for each filtered value

This script loops through each value within a filtered column with the aim of filtering one by one, copy the data, create a new workbook, paste it and save it.
It it now creating a signle new workbook with all the worksheets, instead of one workbook per worksheet.
Can someone point out how can I mend the code to create one workbook per value filtered?
On the other hand, the workbook is also keeping the original sheet1. I am also looking on how to remove it, but thought it would be importat to let you know.
Sub test()
Application.DisplayAlerts = False
Application.EnableEvents = False
Application.ScreenUpdating = False
' -------------------
Dim x As Range
Dim rng As Range
Dim rng1 As Range
Dim last As Long
Dim sht As String
Dim newBook As Excel.Workbook
Dim Workbk As Excel.Workbook
Dim ws As Worksheet
'Specify sheet name in which the data is stored
sht = "Report"
'Workbook where VBA code resides
Set Workbk = ThisWorkbook
'New Workbook
Set newBook = Workbooks.Add(xlWBATWorksheet)
Workbk.Activate
Set ws = Workbk.Worksheets(sht)
'change filter column in the following code
last = ws.Cells(Rows.Count, "BR").End(xlUp).Row
With ws
Set rng = .Range("A1:BR" & last)
End With
ws.Range("G1:G" & last).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("BT1"), Unique:=True
For Each x In ws.Range([BT2], Cells(Rows.Count, "BT").End(xlUp))
With rng
.AutoFilter
.AutoFilter Field:=7, Criteria1:=x.Value
.SpecialCells(xlCellTypeVisible).Copy
newBook.Sheets.Add(After:=newBook.Sheets(newBook.Sheets.Count)).Name = x.Value
newBook.Activate
ActiveSheet.Paste
End With
Next x
' Turn off filter
ws.AutoFilterMode = False
With Application
.CutCopyMode = False
.ScreenUpdating = True
End With
' -------------------
Application.DisplayAlerts = True
Application.EnableEvents = True
Application.ScreenUpdating = True
MsgBox "Check."
End Sub ```
Put the Workbooks.Add line inside the loop.
Option Explicit
Sub test()
Dim wb As Workbook, wbNew As Workbook
Dim ws As Worksheet, wsNew As Worksheet
Dim rng As Range, cel As Range
Dim iLastRow As Long, iLastRowBT As Long
Dim folder As String
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
'Workbook where VBA code resides
Set wb = ThisWorkbook
Set ws = wb.Sheets("Report")
folder = wb.Path & "\"
With ws
'change filter column in the following code
iLastRow = .Cells(Rows.Count, "BR").End(xlUp).Row
.Range("BT:BT").Clear
.Range("G1:G" & iLastRow).AdvancedFilter Action:=xlFilterCopy, _
CopyToRange:=Range("BT1"), Unique:=True
Set rng = .Range("A1:BR" & iLastRow)
iLastRowBT = .Cells(Rows.Count, "BT").End(xlUp).Row
End With
' create workbooks
For Each cel In ws.Range("BT2:BT" & iLastRowBT)
' Open New Workbook
Set wbNew = Workbooks.Add(xlWBATWorksheet)
Set wsNew = wbNew.Sheets(1)
wsNew.Name = cel.Value
' filter and copy data
With rng
.AutoFilter
.AutoFilter Field:=7, Criteria1:=cel.Value
.SpecialCells(xlCellTypeVisible).Copy
End With
' paste and save
wsNew.Paste
wbNew.SaveAs folder & cel.Value & ".xlsx"
wbNew.Close SaveChanges:=False
Next
' Turn off filter
ws.AutoFilterMode = False
With Application
.CutCopyMode = False
.ScreenUpdating = True
.DisplayAlerts = True
.EnableEvents = True
End With
MsgBox iLastRowBT - 1 & " Workbooks created in " & folder, vbInformation
End Sub

Get error message "expected end of line" when using PasteSpecial

I am copying a range from all open workbooks with the goal of pasting the copied cells into a consolidated sheet in the master (active) workbook. I need to paste the values only but get an "end of line" error message with this code
Spent pretty much all day googling my problem to no avail
Sub Consolidate()
Dim oBook As Workbook, ws As Worksheet, wb As Workbook, bk As Workbook
Dim copyFrom As Range
'Disable Screen Updating - stop screen flickering
' And Disable Events to avoid inturupted dialogs / popups
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the Consolidate_Data WorkSheet if it exists
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Sheets("Consolidate_Data").Delete
Application.DisplayAlerts = True
'Add a new WorkSheet and name as 'Consolidate_Data'
With ActiveWorkbook
Set DstSht = .Sheets.Add(After:=.Sheets(.Sheets.Count))
DstSht.Name = "Consolidate_Data"
End With
'Loop through each WorkBook in the folder and copy the data to the 'Consolidate_Data' WorkSheet in the ActiveWorkBook
Set wb = ActiveWorkbook
For Each oBook In Application.Workbooks
If Not oBook.Name = wb.Name Then
'Find the last row on the 'Consolidate_Data' sheet
DstRow = fn_LastRow(DstSht) + 1
'Determine Input data range
Set copyFrom = oBook.Worksheets(1).Range("A6:C8")
'Copy data to the 'consolidated_data' WorkSheet
copyFrom.Copy _
DstSht.Range("A" & DstRow).PasteSpecial xlPasteValues
End If
Next
IfError:
'Enable Screen Updating and Events
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
'Find the last Row of specified Sheet
Function fn_LastRow(ByVal Sht As Worksheet)
Dim lastRow As Long
lastRow = Sht.Cells.SpecialCells(xlLastCell).Row
lRow = Sht.Cells.SpecialCells(xlLastCell).Row
Do While Application.CountA(Sht.Rows(lRow)) = 0 And lRow <> 1
lRow = lRow - 1
Loop
fn_LastRow = lRow
End Function
Consolidate()
Dim oBook As Workbook, ws As Worksheet, wb As Workbook, bk As Workbook
Dim copyFrom As Range
'Disable Screen Updating - stop screen flickering
' And Disable Events to avoid inturupted dialogs / popups
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the Consolidate_Data WorkSheet if it exists
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Sheets("Consolidate_Data").Delete
Application.DisplayAlerts = True
'Add a new WorkSheet and name as 'Consolidate_Data'
With ActiveWorkbook
Set DstSht = .Sheets.Add(After:=.Sheets(.Sheets.Count))
DstSht.Name = "Consolidate_Data"
End With
'Loop through each WorkBook in the folder and copy the data to the 'Consolidate_Data' WorkSheet in the ActiveWorkBook
Set wb = ActiveWorkbook
For Each oBook In Application.Workbooks
If Not oBook.Name = wb.Name Then
'Find the last row on the 'Consolidate_Data' sheet
DstRow = fn_LastRow(DstSht) + 1
'Determine Input data range
Set copyFrom = oBook.Worksheets(1).Range("A6:C8")
'Copy data to the 'consolidated_data' WorkSheet
copyFrom.Copy _
DstSht.Range("A" & DstRow).PasteSpecial xlPasteValues
End If
Next
IfError:
'Enable Screen Updating and Events
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
'Find the last Row of specified Sheet
Function fn_LastRow(ByVal Sht As Worksheet)
Dim lastRow As Long
lastRow = Sht.Cells.SpecialCells(xlLastCell).Row
lRow = Sht.Cells.SpecialCells(xlLastCell).Row
Do While Application.CountA(Sht.Rows(lRow)) = 0 And lRow <> 1
lRow = lRow - 1
Loop
fn_LastRow = lRow
End Function
Get an error message at the PasteSpecial line. Everything works fine without the paste special but, as the copied range includes formulas, I do not get the values which is what I need.
.Copy and .PasteSpecial have to be done in 2 different lines but you concatenated the lines with _
copyFrom.Copy _
DstSht.Range("A" & DstRow).PasteSpecial xlPasteValues
Change it to:
copyFrom.Copy 'no line concatenation here !
DstSht.Range("A" & DstRow).PasteSpecial xlPasteValues
For more information see the documentation:
Range.Copy method
Range.PasteSpecial method / Worksheet.PasteSpecial method

VBA script to export sheets as CSV files to a specific location after deleting rows that are blank or "blank" but contain formula

I am working on a VBA script to allow manipulation and export of a number of worksheets as csv files from an Excel workbook. I'd like to be able to export a list of specified sheets as csv files to a save location that is able to be selected, in addition any cell in a specific column that is blank but may contain a formula needs to be have the entire row deleted. The below script is what I currently have and it seems to work to a point but there are three main issues:
The line below will remove lines if the cell in column A is really blank i.e contains no formula, but does not work if formula is present: Columns("A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
The cycling through the sheets is untidy but functional, is there a way to use a list of named sheets to make the script more concise?
Ideally the save location would also be selectable from a choose file directory dialog box. Any suggestions on how to achieve this?
Many thanks in advance.
Sub createCSVfiles()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
'Declare and set variables
Dim wb1 As Workbook, ws1 As Worksheet
Dim wbname As String, i As Integer
Set wb1 = ThisWorkbook
'Cycle through sheets
For i = 1 To Worksheets.Count
wbname = Worksheets(i).Name
'Create Sheet1.csv
If InStr(1, (Worksheets(i).Name), "Sheet1", vbTextCompare) > 0 Then
Worksheets(i).Copy
Columns("A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
ActiveWorkbook.SaveAs Filename:="C:\Users\forename.surname\Desktop\export\" & ActiveSheet.Name & ".csv", _
FileFormat:=xlCSV, CreateBackup:=False
ActiveWorkbook.Close
wb1.Activate
End If
'Create Sheet2.csv
If InStr(1, (Worksheets(i).Name), "Sheet2", vbTextCompare) > 0 Then
Worksheets(i).Copy
ActiveWorkbook.SaveAs Filename:="C:\Users\forename.surname\Desktop\export\" & ActiveSheet.Name & ".csv", _
FileFormat:=xlCSV, CreateBackup:=False
ActiveWorkbook.Close
wb.Activate
End If
Next i
'Clean
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
I think something like this is what you're looking for:
Sub createCSVfiles()
'Declare and set variables
Dim wb As Workbook
Dim ws As Worksheet
Dim wsTemp As Worksheet
Dim aSheets() As Variant
Dim vSheet As Variant
Dim sFilePath As String
Dim sNewFileName As String
Dim oShell As Object
Dim i As Long
'Select folder to save CSV files to
Set oShell = CreateObject("Shell.Application")
On Error Resume Next
sFilePath = oShell.BrowseForFolder(0, "Select folder to save csv files", 0).Self.Path & Application.PathSeparator
On Error GoTo 0
If Len(sFilePath) = 0 Then Exit Sub 'Pressed cancel
'Define sheet names here
aSheets = Array("Sheet1", "Sheet2")
With Application
.Calculation = xlCalculationManual
.EnableEvents = False
.ScreenUpdating = False
.DisplayAlerts = False
End With
Set wb = ThisWorkbook
'Cycle through sheets
For Each vSheet In aSheets
'Test if sheet exists
Set ws = Nothing
On Error Resume Next
Set ws = wb.Sheets(vSheet)
On Error GoTo 0
If Not ws Is Nothing Then
'Sheet exists
ws.Copy
Set wsTemp = ActiveSheet
'Remove rows with blanks in column A
With wsTemp.Range("A1", wsTemp.Cells(wsTemp.Rows.Count, "A").End(xlUp))
.AutoFilter 1, "=", xlFilterValues
.Offset(1).EntireRow.Delete
.AutoFilter
End With
'Save and close
wsTemp.Parent.SaveAs sFilePath & wsTemp.Name & ".csv", xlCSV
wsTemp.Parent.Close False
End If
Next vSheet
'Clean
With Application
.Calculation = xlCalculationAutomatic
.EnableEvents = True
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub

Row count and insert function

I'm using the following code to copy from an excel file starting with "Backorder Details":
Sub INSERT()
Dim Wb1 As Workbook, wb2 As Workbook, wB As Workbook
Dim rngToCopy As Range
Dim countEND As Long
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Sheets("RAW_DATA").Select
Worksheets("RAW_DATA").Range("A3:CA45000").ClearContents
If ActiveSheet.AutoFilterMode Then ActiveSheet.AutoFilter.ShowAllData
For Each wB In Application.Workbooks
If Left(wB.Name, 17) = "Backorders Detail" Then
Set Wb1 = wB
Exit For
End If
Next
If Not Wb1 Is Nothing Then
Set wb2 = ThisWorkbook
With Wb1.Sheets(2)
Set rngToCopy = .Range("A3:BX3", .Cells(.Rows.Count, "A").End(xlUp))
End With
wb2.Sheets("RAW_DATA").Range("A3:BX3").Resize(rngToCopy.Rows.Count).Value = rngToCopy.Value
End If
With wb2.Sheets("RAW_DATA")
countEND = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("BY3:BY" & countEND).Formula = "=IFERROR(IF(AND(VLOOKUP(VALUE(AS3);BG_DATA!A:A;1;FALSE)=(VLOOKUP(VALUE(AS3);BG_DATA!A:A;1;FALSE));(AF3>0));"""";""x"");""x"")" 'Check
.Range("BZ3:BZ" & countEND).Formula = "=VLOOKUP(VALUE(AS3);BG_DATA!A:I;9;FALSE)" 'Vendor'
.Range("CA3:CA" & countEND).Formula = "=VLOOKUP(VALUE(AS3);BG_DATA!A:J;10;FALSE)" 'Planner
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
MsgBox "DONE!"
End Sub
I copied this function from another excel file I've made. It worked pretty good. But for some reason the following part is giving me an error now:
With wb2.Sheets("RAW_DATA")
countEND = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("BY3:BY" & countEND).Formula = "=IFERROR(IF(AND(VLOOKUP(VALUE(AS3);BG_DATA!A:A;1;FALSE)=(VLOOKUP(VALUE(AS3);BG_DATA!A:A;1;FALSE));(AF3>0));"""";""x"");""x"")" 'Check
.Range("BZ3:BZ" & countEND).Formula = "=VLOOKUP(VALUE(AS3);BG_DATA!A:I;9;FALSE)" 'Vendor'
.Range("CA3:CA" & countEND).Formula = "=VLOOKUP(VALUE(AS3);BG_DATA!A:J;10;FALSE)" 'Planner
End With
Run-time error 1004 - Application-defined or object defined error.
I googled this but didn't find a solution. Excel file was an XLSX and is an XLSM now. Can someone please tell what the problem is?
You are using semicolon ; as a delimiter in your formula, but the delimiter depends on the localization of your workbook. Use comma , instead:
With wb2.Sheets("RAW_DATA")
countEND = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("BY3:BY" & countEND).Formula = "=IFERROR(IF(AND(VLOOKUP(VALUE(AS3),BG_DATA!A:A,1,FALSE)=(VLOOKUP(VALUE(AS3),BG_DATA!A:A,1,FALSE)),(AF3>0)),"""",""x""),""x"")" 'Check
.Range("BZ3:BZ" & countEND).Formula = "=VLOOKUP(VALUE(AS3),BG_DATA!A:I,9,FALSE)" 'Vendor'
.Range("CA3:CA" & countEND).Formula = "=VLOOKUP(VALUE(AS3),BG_DATA!A:J,10,FALSE)" 'Planner
End With
Alternatively you could use .FormulaLocal instead of .Formula, but it will work only in the workbooks where localization defines semicolon as the delimiter.

Avoiding spaghetti code when copying from one wb to another

Is there an alternative to using ActiveWorkbook and ActiveSheet in VBA when working with multiple workbooks (copying from workbooks in a list to a master sheet) ? It is turning out to be more confusing than anything to know which workbook is open when working with multiple functions which need to use different workbooks. Is it a matter of code organization ?
For the moment I think I can manage by storing the activeworkbook's name at the beginning of every function and restoring it, but it seems like a lot of work and probably a lot of processing time for not much results.
Ideas ?
You might be interested in this page http://www.techrepublic.com/blog/10things/10-ways-to-reference-excel-workbooks-and-sheets-using-vba/967
Specifically look at 4: Explicitly reference a workbook
Or 10: Refer to a sheet’s code name property
Typically when you work through a list you will use a workbook variable to open, manipulate and then close each book
My code below is an example of work through and collate a directory of workbooks (similar to your list example). From Collating worksheets from one or more workbooks into a summary file
Public Sub ConsolidateSheets()
Dim Wb1 As Workbook
Dim Wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim rngArea As Range
Dim lrowSpace As Long
Dim lSht As Long
Dim lngCalc As Long
Dim lngRow As Long
Dim lngCol As Long
Dim X()
Dim bProcessFolder As Boolean
Dim bNewSheet As Boolean
Dim StrPrefix
Dim strFileName As String
Dim strFolderName As String
'variant declaration needed for the Shell object to use a default directory
Dim strDefaultFolder As Variant
bProcessFolder = (MsgBox("Process a single folder (Yes)," & vbNewLine & "or single file (No)", vbYesNo, "Application Scope: Folder or single File") = vbYes)
bNewSheet = (MsgBox("Extract all data to a single sheet (Yes)," & vbNewLine & "or a target file sheet for each source sheet (No)", vbYesNo, "Output Format: Single sheet or sheet by sheet collection") = vbYes)
If Not bProcessFolder Then
If Not bNewSheet Then
MsgBox "There isn't much point creating a exact replica of your source file :)"
Exit Sub
End If
End If
'set default directory here if needed
strDefaultFolder = "C:\temp"
'If the user is collating all the sheets to a single target sheet then the row spacing
'to distinguish between different sheets can be set here
lrowSpace = 1
If bProcessFolder Then
strFolderName = BrowseForFolder(strDefaultFolder)
'Look for xls, xlsx, xlsm files
strFileName = Dir(strFolderName & "\*.xls*")
Else
strFileName = Application _
.GetOpenFilename("Select file to process (*.xls*), *.xls*")
End If
Set Wb1 = Workbooks.Add(1)
Set ws1 = Wb1.Sheets(1)
If Not bNewSheet Then ws1.Range("A1:B1") = Array("workbook name", "worksheet count")
'Turn off screenupdating, events, alerts and set calculation to manual
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
lngCalc = .Calculation
.Calculation = xlCalculationManual
End With
'set path outside the loop
StrPrefix = strFolderName & IIf(bProcessFolder, "\", vbNullString)
Do While Len(strFileName) > 0
'Provide progress status to user
Application.StatusBar = Left("Processing " & strFolderName & "\" & strFileName, 255)
'Open each workbook in the folder of interest
Set Wb2 = Workbooks.Open(StrPrefix & strFileName)
If Not bNewSheet Then
'add summary details to first sheet
ws1.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) = Wb2.Name
ws1.Cells(Rows.Count, "A").End(xlUp).Offset(0, 1) = Wb2.Sheets.Count
End If
For Each ws2 In Wb2.Sheets
If bNewSheet Then
'All data to a single sheet
'Skip importing target sheet data if the source sheet is blank
Set rng2 = ws2.Cells.Find("*", ws2.[a1], xlValues, , xlByRows, xlPrevious)
If Not rng2 Is Nothing Then
Set rng1 = ws1.Cells.Find("*", ws1.[a1], xlValues, , xlByRows, xlPrevious)
'Find the first blank row on the target sheet
If Not rng1 Is Nothing Then
Set rng3 = ws2.Range(ws2.UsedRange.Cells(1), ws2.Cells(rng2.Row, "A"))
'Ensure that the row area in the target sheet won't be exceeded
If rng3.Rows.Count + rng1.Row < Rows.Count Then
'Copy the data from the used range of each source sheet to the first blank row
'of the target sheet, using the starting column address from the source sheet being copied
ws2.UsedRange.Copy ws1.Cells(rng1.Row + 1 + lrowSpace, ws2.UsedRange.Cells(1).Column)
Else
MsgBox "Summary sheet size exceeded. Process stopped on " & vbNewLine & _
"sheet: " & ws2.Name & vbNewLine & "of" & vbNewLine & "workbook: " & Wb2.Name
Wb2.Close False
Exit Do
End If
'colour the first of any spacer rows
If lrowSpace <> 0 Then ws1.Rows(rng1.Row + 1).Interior.Color = vbGreen
Else
'target sheet is empty so copy to first row
ws2.UsedRange.Copy ws1.Cells(1, ws2.UsedRange.Cells(1).Column)
End If
End If
Else
'new target sheet for each source sheet
ws2.Copy after:=Wb1.Sheets(Wb1.Sheets.Count)
'Remove any links in our target sheet
With Wb1.Sheets(Wb1.Sheets.Count).Cells
.Copy
.PasteSpecial xlPasteValues
End With
On Error Resume Next
Wb1.Sheets(Wb1.Sheets.Count).Name = ws2.Name
'sheet name already exists in target workbook
If Err.Number <> 0 Then
'Add a number to the sheet name till a unique name is derived
Do
lSht = lSht + 1
Set ws3 = Wb1.Sheets(ws2.Name & " " & lSht)
Loop While Not ws3 Is Nothing
lSht = 0
End If
On Error GoTo 0
End If
Next ws2
'Close the opened workbook
Wb2.Close False
'Check whether to force a DO loop exit if processing a single file
If bProcessFolder = False Then Exit Do
strFileName = Dir
Loop
'Remove any links if the user has used a target sheet
If bNewSheet Then
With ws1.UsedRange
.Copy
.Cells(1).PasteSpecial xlPasteValues
.Cells(1).Activate
End With
Else
'Format the summary sheet if the user has created separate target sheets
ws1.Activate
ws1.Range("A1:B1").Font.Bold = True
ws1.Columns.AutoFit
End If
With Application
.CutCopyMode = False
.DisplayAlerts = True
.EnableEvents = True
.ScreenUpdating = True
.Calculation = lngCalc
.StatusBar = vbNullString
End With
End Sub
Function BrowseForFolder(Optional OpenAt As Variant) As Variant
'From Ken Puls as used in his vbaexpress.com article
'http://www.vbaexpress.com/kb/getarticle.php?kb_id=284
Dim ShellApp As Object
'Create a file browser window at the default folder
Set ShellApp = CreateObject("Shell.Application"). _
BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
'Set the folder to that selected. (On error in case cancelled)
On Error Resume Next
BrowseForFolder = ShellApp.self.Path
On Error GoTo 0
'Destroy the Shell Application
Set ShellApp = Nothing
'Check for invalid or non-entries and send to the Invalid error
'handler if found
'Valid selections can begin L: (where L is a letter) or
'\\ (as in \\servername\sharename. All others are invalid
Select Case Mid(BrowseForFolder, 2, 1)
Case Is = ":"
If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
Case Is = "\"
If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
Case Else
GoTo Invalid
End Select
Exit Function
Invalid:
'If it was determined that the selection was invalid, set to False
BrowseForFolder = False
End Function

Resources