I'm using the following code:
Dim sourceBook As Workbook
Dim targetBook As Workbook
'## Open both workbooks first:
Set targetBook = Application.ActiveWorkbook
Set sourceBook = Application.Workbooks.Open("...\Documents\Log.xlsm")
'
With sourceBook.Sheets("Sheet1").UsedRange
'Now, paste to y worksheet:
targetBook.Sheets("Sheet1").Range("A1").Resize( _
.Rows.Count, .Columns.Count) = .Value
End With
'Close
sourceBook.Close
But when i run it my source book opens and nothing happens after. Not sure what i'm missing. Both workbooks have the same extension xlsm. Ive tried to change the source to xlsx also but Same result
Edit: Ive replaced the with statement with the following:
targetBook.Sheets("Sheet1").Range("A1").Value = sourceBook.Sheets("Sheet1").Range("A1")
to at least see if i can copy 1 value but when the sourcebook is opened it stops there.
I have recreated your example, and think it is do with the way you are opening the document. In your open method you have three dots Open("...\documents")
It raised an error for me, so can you check that is what you meant? It worked if I used ..\ rather than ...\
I need to use VBScript to change all of the sheets in an excel workbook to Page Layout View instead of the default view. However, I cannot figure out how to do that in VBS. With VBA, the code I've been using (with a while loop to go over each sheet) is
With ActiveWindow
.View = xlPageLayoutView
End With
which serves my purposes fine. But I need to do this in VBS. I think it has something to do with the Application object, though I'm not sure. Any help would be appreciated.
Edit: here's a sample of the code I've written with declarations and things. It's basically iterating over a number of sheets in a workbook and setting them all (or trying to) to Page Layout view. Missing from this segment is the sub where I populate the workbook with new sheets matching the entries from Names().
Dim destFile, objWorkbook
Set destFile = CreateObject("Excel.Application")
Set objWorkbook = destFile.Workbooks.Add()
objWorkBook.SaveAs(strPath)
Sub OverNames()
For i = 1 to 9
SetPagelayout(i)
Next
End Sub
Sub SetPageLayout(hNum)
Dim houseSheet, sheetName
'retrieves sheet name from array Names()
sheetName = Names(hNum, 0)
Set houseSheet = destFile.Worksheets(sheetName)
houseSheet.Window.View = xlPageLayoutView
End Sub
VBA already has excel and the workbook loaded. With VBS, you need to create an excel object and open your workbook with it. Also, VBA has static variables defined for excel settings, which you will have to define yourself in VBS.
Dim objExcel
Dim excelPath
Dim xlPageLayoutView=3 ' https://msdn.microsoft.com/en-us/library/office/ff838200.aspx
excelPath = "C:\scripts\servers.xlsx"
objExcel.DisplayAlerts = 0
Set objExcel = CreateObject("Excel.Application")
In order to change the state of a window, you have to access the window object. In excel there are Workbooks, which contain collections of Worksheets and Windows. The application also contains a collection of all windows in all worksheets. In the workbook window collection, the active window is always accessed through index 1.
Set currentWorkBook = objExcel.ActiveWorkbook
Set currentWorkSheet = currentWorkBook.Worksheets("Sheet Name Here")
currentWorkSheet.Activate
Set currentWindow = currentWorkBook.Windows(1)
currentWindow.View = xlPageLayoutView
I'm conducting my very first VBA macro and I'm having some difficulties with this seemingly easy code to read data from a closed workbook into my currently opened one.
Sub KAuto()
Dim path As String
path = "C:\files\Utfall.xlsx"
Dim currentWb As Workbook
Set currentWb = ThisWorkbook
Dim openWb As Workbook
Set openWb = Workbooks.Open(path)
Dim openWs As Worksheet
Set openWs = openWb.Sheets("March")
currentWb.Sheets("Indata").Range("A1").Value = openWs.Range("A3").Value
End Sub
The problem I'm having is that I get a code 9, subscript out of range. But I've checked that A1 and A3 is existent for the current workbook and the imported one respectively.
What I have tried to do is to omit the ".Value" in all combinations, as that was what the original author did.
Googling this problem I've encountered that people misused functions which I do not use, for instance windows(), or omitted "" for referencing the worksheets, or simply misspelled things. I don't Think I have any of these, and so I need further help.
How can I correct my subscript out of range? Is there a better way to achieve this copying of cells? In the future I want to import 10 files, will this then be obsolete? (I recall someone posting something in the lines of openWb = [file1,file2,file3] and looping through them, but I cannot find it; does anyone have a link?
EDIT: I've copied the path to the file from its properties, so it ought to be correct.
EDIT2:
currentWb.Sheets("Indata").Range("A1").Value = openWs.Range("A3").Value
snippet gives the error
EDIT3: VB editor print screen:
Try using ActiveWorkbook instead of ThisWorkbook.
Set currentWb = ActiveWorkbook
ThisWorkbook refers to the workbook in which the code resides. ActiveWorkbook refers to the workbook that is currently active i.e. "on top" in the Excel application. It looks like your case, the code resides in a different workbook; so what you want is ActiveWorkbook.
And you can ommit the .value from last line.
currentWb.Sheets("Indata").Range("A1") = openWs.Range("A3")
Your code worked fine for me, that`s why I cannot be sure if it will help. There can be an issue, when opening the openWs. The error line can be evaluated before the openWs is actually open. Then maybe add a line :
Application.Wait (Now + TimeValue("00:00:03")) 'this is 3 seconds from now
after the Set openWb = Workbooks.Open(path).
I have a directory with list of Workbooks, I want to loop through them withouth opening them and update a Cell in a certain Sheet
I have tried to use
Dim wb As Workbook
Set wb = Workbooks("Z:\dir\bla.xls") 'THIS WILL COME TRHOUGH WHEN I LOOP
Set ws2 = wb.Sheets("TestSheet") 'SHEET NAME
Set CurCell_2 = ws2.Range("A1")
CurCell_2.Value = 5
The Problem comes it only works when I have the Workbook already open. I can use:
Workbooks.Open
But then It opens up in the background and takes to long to run through them all.
Can anyone help please
You cannot do that without opening the workbooks. However, I have found in my case that using Application.EnableEvents and setting it to false sped up greatly the process because we have macros on workbook open event.
I want to search through existing Excel files with a macro, but I don't want to display those files when they're opened by the code. Is there a way to have them open "in the background", so to speak?
Not sure if you can open them invisibly in the current excel instance
You can open a new instance of excel though, hide it and then open the workbooks
Dim app as New Excel.Application
app.Visible = False 'Visible is False by default, so this isn't necessary
Dim book As Excel.Workbook
Set book = app.Workbooks.Add(fileName)
'
' Do what you have to do
'
book.Close SaveChanges:=False
app.Quit
Set app = Nothing
As others have posted, make sure you clean up after you are finished with any opened workbooks
If that suits your needs, I would simply use
Application.ScreenUpdating = False
with the added benefit of accelerating your code, instead of slowing it down by using a second instance of Excel.
To open a workbook as hidden in the existing instance of Excel, use following:
Application.ScreenUpdating = False
Workbooks.Open Filename:=FilePath, UpdateLinks:=True, ReadOnly:=True
ActiveWindow.Visible = False
ThisWorkbook.Activate
Application.ScreenUpdating = True
Using ADO (AnonJr already explained) and utilizing SQL is possibly the best option for fetching data from a closed workbook without opening that in conventional way. Please watch this VIDEO.
OTHERWISE, possibly GetObject(<filename with path>) is the most CONCISE way. Worksheets remain invisible, however will appear in project explorer window in VBE just like any other workbook opened in conventional ways.
Dim wb As Workbook
Set wb = GetObject("C:\MyData.xlsx") 'Worksheets will remain invisible, no new window appears in the screen
' your codes here
wb.Close SaveChanges:=False
If you want to read a particular sheet, need not even define a Workbook variable
Dim sh As Worksheet
Set sh = GetObject("C:\MyData.xlsx").Worksheets("MySheet")
' your codes here
sh.Parent.Close SaveChanges:=False 'Closes the associated workbook
A much simpler approach that doesn't involve manipulating active windows:
Dim wb As Workbook
Set wb = Workbooks.Open("workbook.xlsx")
wb.Windows(1).Visible = False
From what I can tell the Windows index on the workbook should always be 1. If anyone knows of any race conditions that would make this untrue please let me know.
Even though you've got your answer, for those that find this question, it is also possible to open an Excel spreadsheet as a JET data store. Borrowing the connection string from a project I've used it on, it will look kinda like this:
strExcelConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & objFile.Path & ";Extended Properties=""Excel 8.0;HDR=Yes"""
strSQL = "SELECT * FROM [RegistrationList$] ORDER BY DateToRegister DESC"
Note that "RegistrationList" is the name of the tab in the workbook. There are a few tutorials floating around on the web with the particulars of what you can and can't do accessing a sheet this way.
Just thought I'd add. :)
The problem with both iDevlop's and Ashok's answers is that the fundamental problem is an Excel design flaw (apparently) in which the Open method fails to respect the Application.ScreenUpdating setting of False. Consequently, setting it to False is of no benefit to this problem.
If Patrick McDonald's solution is too burdensome due to the overhead of starting a second instance of Excel, then the best solution I've found is to minimize the time that the opened workbook is visible by re-activating the original window as quickly as possible:
Dim TempWkBk As Workbook
Dim CurrentWin As Window
Set CurrentWin = ActiveWindow
Set TempWkBk = Workbooks.Open(SomeFilePath)
CurrentWin.Activate 'Allows only a VERY brief flash of the opened workbook
TempWkBk.Windows(1).Visible = False 'Only necessary if you also need to prevent
'the user from manually accessing the opened
'workbook before it is closed.
'Operate on the new workbook, which is not visible to the user, then close it...
Open the workbook as hidden and then set it as "saved" so that users are not prompted when they close out.
Dim w As Workbooks
Private Sub Workbook_Open()
Application.ScreenUpdating = False
Set w = Workbooks
w.Open Filename:="\\server\PriceList.xlsx", UpdateLinks:=False, ReadOnly:=True 'this is the data file were going to be opening
ActiveWindow.Visible = False
ThisWorkbook.Activate
Application.ScreenUpdating = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
w.Item(2).Saved = True 'this will suppress the safe prompt for the data file only
End Sub
This is somewhat derivative of the answer posted by Ashok.
By doing it this way though you will not get prompted to save changes back to the Excel file your reading from. This is great if the Excel file your reading from is intended as a data source for validation. For example if the workbook contains product names and price data it can be hidden and you can show an Excel file that represents an invoice with drop downs for product that validates from that price list.
You can then store the price list on a shared location on a network somewhere and make it read-only.
Open them from a new instance of Excel.
Sub Test()
Dim xl As Excel.Application
Set xl = CreateObject("Excel.Application")
Dim w As Workbook
Set w = xl.Workbooks.Add()
MsgBox "Not visible yet..."
xl.Visible = True
w.Close False
Set xl = Nothing
End Sub
You need to remember to clean up after you're done.
In excel, hide the workbooks, and save them as hidden. When your app loads them they will not be shown.
Edit: upon re-reading, it became clear that these workbooks are not part of your application. Such a solution would be inappropriate for user workbooks.