Just doing something at work, and trying to reference a file on a network directory on VBA.
Sub CostPriceMain()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
NewFile = Application.GetOpenFilename(FileFilter:="Microsoft Excel Files
(*.xlsx; *.xls), (*.xlsx; *.xls), All Files, *.*", FilterIndex:=1)
If NewFile = False Then Exit Sub
If NewFile <> False Then
Set wkbk = Workbooks.Open(NewFile)
End If
Dim Sh As Worksheet
For Each Sh In wkbk.Worksheets
If Sh.Visible = True Then
Sh.Activate
Sh.Cells.Copy
Workbooks("S:\Stafford\WK24 WH.xls").Sheets("Name").Range("A1").PasteSpecial Paste:=xlValues
End If
Next Sh
Application.CutCopyMode = False
ActiveWorkbook.Close True
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Done = MsgBox("Task Complete", vbOKOnly)
End Sub
I'm trying to open it so that that I can paste data from wkbk into it. However I keep getting a 'Microsoft Office Excel cannot access the file' runtime error 1004.
Is this an issue because the file is not stored locally? As I'm scratching my head at this.
Try this:
Sub CostPriceMain()
Dim SourceWkb As Workbook
Dim TargetWkb As Workbook
Dim SourceWksht As Worksheet
Application.ScreenUpdating = False
Application.DisplayAlerts = False
NewFile = Application.GetOpenFilename(FileFilter:="Microsoft Excel Files (*.xlsx; *.xls), (*.xlsx; *.xls), All Files, *.*", FilterIndex:=1)
If NewFile = False Then Exit Sub
If NewFile <> False Then
Set SourceWkb = Workbooks.Open(NewFile)
End If
Set TargetWkb = Workbooks.Open("S:\Stafford\WK24.xls") ' warning - XLS file could cause problems - see note
For Each SourceWksht In SourceWkb.Worksheets
If SourceWksht.Visible Then
SourceWksht.Copy After:=TargetWkb.Sheets(TargetWkb.Sheets.Count)
End If
Next SourceWksht
TargetWkb.Close True
SourceWkb.Close False
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Done = MsgBox("Task Complete", vbOKOnly)
End Sub
I notice your "wk24" is an XLSfile, yet you invite the user to choose XLSor XLSX files to import from. You can't import an XLSX file into an XLS file using this method. I'd suggest changing your target file to WK24.XLSX
You open your workbook within the loop which means it will try and open it for every sheet - and throw an error when it's already open.
Open the workbook before you start looping and then just reference it. This code will copy each visible sheet from the workbook containing the code to WK24.xls (note, no activating of sheets required):
Sub Test()
Dim wrkBk As Workbook
Dim wrkSht As Worksheet
Set wrkBk = Workbooks.Open("S:\Stafford\WK24.xls")
For Each wrkSht In ThisWorkbook.Worksheets
If wrkSht.Visible Then
'Copy sheet.
wrkSht.Copy After:=wrkBk.Sheets(wrkBk.Sheets.Count)
End If
Next wrkSht
End Sub
Edit:
I've made a few changes to your posted code.
I removed If NewFile = False Then Exit Sub - If NewFile isn't false it will run the code, otherwise it jumps straight to the end. It provides a single exit point for your procedure.
I updated ActiveWorkbook.Close True to your referenced workbooks. ActiveWorkbook may not always be the correct book - always best to avoid Active or Select... if you find yourself using either (or Activate or Selected or anything similar) then you're probably making more work for yourself.
Your MsgBox isn't going to act on any response, it's just informing you so no need to set it to a variable.
If you're still finding it says the workbook isn't accessible then triple check the file location, file name, whether it's already open.
Which file is causing the problem? NewFile or WK24?
Also - are you copying the whole sheet, cells from the sheet, copy & pastespecial - you keep changing your code.
Sub CostPriceMain()
Dim NewFile As Variant
Dim wkbk As Workbook
Dim wrkBk As Workbook
Dim wrkSht As Worksheet
NewFile = Application.GetOpenFilename(FileFilter:="Microsoft Excel Files (*.xlsx; *.xls), (*.xlsx; *.xls), All Files, *.*", FilterIndex:=1)
If NewFile <> False Then
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set wkbk = Workbooks.Open(NewFile)
Set wrkBk = Workbooks.Open("S:\Stafford\WK24.xls")
For Each wrkSht In wkbk.Worksheets
If wrkSht.Visible Then
'Copy all cells with formula, etc.
'wrkSht.Cells.Copy Destination:=wrkBk.Worksheets("Sheet1").Range("A1")
'Copy and pastespecial all cells.
'wrkSht.Cells.Copy
'wrkBk.Worksheets("Sheet1").Range("A1").PasteSpecial xlPasteValues
'Copy whole sheet to WK2 (Sheets includes ChartSheets)
wrkSht.Copy After:=wrkBk.Sheets(wrkBk.Sheets.Count)
End If
Next wrkSht
wrkBk.Close True 'Closes WK24.
wkbk.Close False 'Closes your chosen file without saving.
Application.ScreenUpdating = True
Application.DisplayAlerts = True
MsgBox "Task Complete", vbOKOnly
End If
End Sub
Related
Here is my code of adding a sheet in multiple workbooks. I want to know how to skip or replace the exiting data in those multiple workbooks.
Sub AddingChklist()
ActiveWorkbook.Save
Dim path As String
Dim file As String
Dim Chklist As Workbook
path = "C:\Users\Documents\Macro Project\"
file = Dir(path)
Application.ScreenUpdating = False
Do While Not file = ""
Workbooks.Open (path & file)
Set Chklist = ActiveWorkbook
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Name = "Recon Checklist"
ThisWorkbook.Sheets("Recon Checklist").Range("A1:C25").Copy Destination:=Chklist.Sheets("Recon Checklist").Range("A1")
Range("A1:C25").EntireColumn.AutoFit
Range("A1:C25").EntireRow.AutoFit
Chklist.Save
Chklist.Close
file = Dir
Loop
Application.ScreenUpdating = True
MsgBox "Checklist has been added to all the files"
End Sub
Copied from discussion below:-
My question was if the recon checklist sheet was already in one of the workbooks while running this macro. How we need to skip or replace the existing sheet.
Please try this code. In order to do away with the heavy flicker connected with opening many files in succession this procedure creates an invisible instance of Excel dedicated to this task. While this works very smoothly, it unfortunately raises the problem of not being able to copy formatting from one instance of Excel to another. Therefore my code only copies values. However, you have full access to each new sheet. For now only AutoFit is applied but you could do a lot of more formatting at that point if you feel the need.
Sub AddingChklist()
' 242
Const WsName As String = "Recon Checklist" ' Ws actual name
Dim Xl As New Excel.Application ' dedicated instance of Excel
Dim ChkList As Variant ' Checklist
Dim Path As String
Dim File As String
Dim Sp() As String ' split of File
Dim Wb As Workbook ' loop object
Dim Ws As Worksheet ' loop object: CheckList
Xl.Visible = True ' hide the newly opened workbooks
Path = "C:\Users\Documents\Macro Project\"
ChkList = ThisWorkbook.Sheets(WsName).Range("A1:C25").Value
File = Dir(Path)
Do While Not File = ""
Sp = Split(File, ".") ' process only Excel workbooks
If InStr(1, Sp(UBound(Sp)), "xls", vbTextCompare) = 1 Then
Set Wb = Xl.Workbooks.Open(Path & File)
Application.StatusBar = "Processing " & Wb.Name
On Error Resume Next
Set Ws = Wb.Worksheets(WsName)
If Err.Number = 9 Then
On Error GoTo 0
Set Ws = Wb.Sheets.Add(Before:=Wb.Sheets(1))
Ws.Name = WsName
End If
With Ws
.Cells.ClearContents
.Cells(1, 1).Resize(UBound(ChkList), UBound(ChkList, 2)).Value = ChkList
.Columns.AutoFit
.Rows.AutoFit
End With
Wb.Close SaveChanges:=True
End If
File = Dir
Loop
Xl.Quit ' close the dedicated instance of Excel
' MsgBox "Checklist has been added to all the files"
Application.StatusBar = "Checklist has been added to all the files"
End Sub
Observe that the code first looks for an existing tab by the same name. If such a sheet doesn't exist it will be created. Any existing sheet will be wiped clean. Finally, the contents of your template will be pasted to the new/clean sheet.
Note that I added a test to the code to ensure that only Excel workbooks will be processed.
I want to transfer data from the master workbook to another workbook
If the transfer to destination.xlsx is successful
but if transfer to destination.xlsm is unsuccessful
this is my code
Private Sub CommandButton1_Click()
Dim strPath2 As String
Dim wbk As Workbook
strPath2 = "C:\destination.xlsm"
On Error Resume Next
Set wbk = Workbooks.Open(strPath2)
Application.ScreenUpdating = False
Application.DisplayAlerts = False
ThisWorkbook.Worksheets("Master").Range("A1:A30").Copy
wbk.Worksheets("destination").[E15].PasteSpecial Paste:=xlPasteValues
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
You entire code work properly, except this part,
ThisWorkbook.Worksheets("Master").Range("A1:A30").Copy
wbk.Worksheets("destination").[E15].PasteSpecial Paste:=xlPasteValues
By using copy method, you can input destination subsequent without the need for paste special:
Sheet1.Range("A1:A5").Copy wbk.Worksheets("Sheet1").Range("A1")
Eventually it perform same step as your need with less code.
I am trying to create a macro that deletes the active sheet without displaying the prompt. Which is what the code below does...This works great until the last sheet. I get the prompt no matter what. I do not want to delete the last sheet and at the same time, I don't want the error '1004' message to come up. Is there a way to change the code above to not delete my last sheet and not display the error message at the same time?
Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True
If the idea is to delete the ActiveSheet and only it, this is something that will work, until there is only 1 sheet in the workbook:
Sub DeleteActiveSheet()
If ThisWorkbook.Worksheets.Count = 1 Then
Exit Sub
Else
Application.DisplayAlerts = False
ThisWorkbook.ActiveSheet.Delete
Application.DisplayAlerts = True
End If
End Sub
If the idea is to delete all worksheets, but the last, then follow this sequence:
assign a worksheet variable wksToStay from the type Worksheet and set it to the last worksheet in the workbook;
loop through all the Worksheets in the Workbook.Worksheets collection, starting from the last one;
always perform a check, whether the worksheet to be deleted wksToDelete has the same name as the wksToStay;
delete, if the name is not the same;
it will delete all the worksheets, including the hidden and the very hidden ones;
Sub DeleteAllButLast()
Dim wksToStay As Worksheet
Dim wksToDelete As Worksheet
Dim i As Long
Set wksToStay = ThisWorkbook.Worksheets(Worksheets.Count)
For i = Worksheets.Count To 1 Step -1
Set wksToDelete = ThisWorkbook.Worksheets(i)
If wksToDelete.Name <> wksToStay.Name Then
Application.DisplayAlerts = False
wksToDelete.Delete
Application.DisplayAlerts = True
End If
Next
End Sub
Test the next code, please:
Sub deleteExceptTheLastSh()
If ActiveWorkbook.Sheets.count > 1 Then
Application.DisplayAlerts = False
ActiveSheet.Delete
Application.DisplayAlerts = True
Else
MsgBox "This is the last sheet and it cannot be deleted!"
End If
End Sub
This happens because you cannot delete the last worksheet in a workbook. Is the macro you have executed with a button? If you do not like the 1004 message, one possible solution may be to create a custom error message:
Sub deleteActiveSheet()
Application.DisplayAlerts = False
On Error GoTo Error
ActiveSheet.Delete
Application.DisplayAlerts = True
Exit Sub
Error:
MsgBox "you cannot delete the last worksheet in the workbook!"
End Sub
If I understand correctly, you don't want to delete the last worksheet, and you want to avoid the error message.
You could try this:
Sub deleteallbutlast()
Application.DisplayAlerts = False
If Worksheets.Count > 1 Then
ActiveSheet.Delete
Else
End
End If
Application.DisplayAlerts = True
End Sub
I have a query in my sheet. I need to export the query range into a new .xlsx workbook to a variable folder (SaveAs).
How can I SaveAs a specific range?
I tried the Application.FileDialog(msoFileDialogSaveAs), which does save the entire workbook, but I just want to save a specific range of the workbook.
Sub SaveAsDialog()
On Error Resume Next
With Application.FileDialog(msoFileDialogSaveAs)
If .Show = 0 Then
Exit Sub
End If
Application.DisplayAlerts = False
.Execute
Application.DisplayAlerts = True
End With
End Sub
You are looking for something like this:
Copy and paste the data in a new Workbook and Save it
Sub SaveAsDialog()
Dim od As Workbook, nod As Workbook
Set od = ThisWorkbook
'Copy data that you want to save
od.Worksheets("Sheet1").Range("A1:B10").Copy
' Add a new workbook
Set nod = Workbooks.Add
nod.Worksheets(1).Range("A1").PasteSpecial xlPasteValues
'Save the new workbook
nod.SaveAs od.Path & "\New_Book.xlsx"
nod.Close True
End Sub
Good day
I am trying to run a very simple code, where I open a workbook, copy column "a:a", open another workbook and paste it there. The issue i am facing is that the data is being copied from the second workbook into the second workbook, nothing is being copied from the first.
Code below for more clarity
Sub Copytocurrent()
strSecondFile = "Z:\AR\AR PROGRESS\2014\MENACA REPORTS\0MENACA Working File\AR Working File\UAE\RECEIVABLE.xls"
strThirdFile = "Z:\AR\AR PROGRESS\2014\MENACA REPORTS\0MENACA Working File\AR Working File\UAE\Working File - UAE.xlsx"
Set wbk2 = Workbooks.Open(strSecondFile)
Set wbk3 = Workbooks.Open(strThirdFile)
'-------------------------------------------------------'
'Copy column A in Receivable to Column XB in Working File'
'-------------------------------------------------------'
Application.CutCopyMode = False
wbk2.Sheets("receivable").Activate
With wbk2.Sheets("receivable")
Range("a:a").Copy
End With
wbk3.Sheets("Sheet1").Activate
With wbk3.Sheets("sheet1")
Range("XB1").PasteSpecial
End With
'-------------------------------------------------------'
'Copy column B in Receivable to Column XA in Working File'
'-------------------------------------------------------'
Application.CutCopyMode = False
wbk2.Sheets("receivable").Activate
With wbk2.Sheets("receivable")
Range("b:b").Copy
End With
wbk3.Sheets("Sheet1").Activate
With wbk3.Sheets("sheet1")
Range("XA1").PasteSpecial
End With
wbk2.Close True
wbk3.Close True
End Sub
Try this, activate Workbook objects accordingly like you would do in a real copypaste flow. I run this method in a third xlsm workbook.
Public Sub testCopy()
Dim wb1 As Workbook
Dim wb2 As Workbook
Set wb1 = Workbooks.Open("C:\projects\excel\book1.xlsx")
Set wb2 = Workbooks.Open("C:\projects\excel\book2.xlsx")
Application.CutCopyMode = False
wb1.Activate
With wb1.Sheets("Sheet1")
Range("A:A").Copy
End With
wb2.Activate
With wb2.Sheets("Sheet1")
Range("E1").PasteSpecial
End With
Application.CutCopyMode = False
wb1.Activate
With wb1.Sheets("Sheet1")
Range("B:B").Copy
End With
wb2.Activate
With wb2.Sheets("Sheet1")
Range("F1").PasteSpecial
End With
wb1.Close True
wb2.Close True
End Sub
edit: ok I was late you discovered the same fix by yourself a second before my post.
As you already identified, you're issue was that you're using the activeworkbook for the copying, but forget to use .Activate. Better than using ActiveWorkbook, try accessing the ranges directly. This makes the code more robust - and less bloated:
Sub CopyToCurrent()
Dim wbkSource As Workbook, wbkTarget As Workbook 'Alays Dim your variables to prevent errors from typos!
Dim wsSource As Worksheet, wsTarget As Worksheet
Application.ScreenUpdating = False 'Prevent screen flickering
Set wbkSource = Workbooks.Open("Z:\AR\AR PROGRESS\2014\MENACA REPORTS\0MENACA Working File\AR Working File\UAE\RECEIVABLE.xls")
Set wbkTarget = Workbooks.Open("Z:\AR\AR PROGRESS\2014\MENACA REPORTS\0MENACA Working File\AR Working File\UAE\Working File - UAE.xlsx")
Set wsSource = wbkSource.Sheets("receivable")
Set wsTarget = wbkTarget.Sheets("Sheet1")
wsSource.Range("A:A").Copy
wsTarget.Range("XB1").PasteSpecial
wsSource.Range("B:B").Copy
wsTarget.Range("XA1").PasteSpecial
wbkSource.Close False 'No need to save any changes
wbkTarget.Close True
Application.ScreenUpdating = True
End Sub
Note that I also added some small improvements (Dimming, prevent screenflickering)