Is it possible to store a PageSetup object that will be used to set the printing options of a worksheet? I tried with this code but I'm getting an error that says: Object variable or With block variable not set. This is how I'm doing it since I need to setup the settings first from a form and loop through some sheets using the printing settings stored in this object.
Dim curPageSetup As PageSetup
curPageSetup.paperSize = xlPaperA3
If all that you want to do is change the PaperSize for all of the sheets in your book, you can do it like this
Sub SetPaperSize()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.PageSetup.PaperSize = xlPaperA3
Next ws
End Sub
Not necessary to store PageSetup to change its attributes
Related
I'm trying to loop through all the worksheets in an Excel file using Access VBA.
The subroutine needs to select the first row and set the RowHeight in each worksheet.
I'm using a string variable to call the subroutine and passing the worksheet name to it. It works the first time but the next time I get
"Select method of Range Class Failed"
I tried moving the variable declarations around, changing where I open Excel (it opens twice if I put it in the subroutine) and doing it as function instead of a subroutine.
'My object and worksheet variables are declared at the top of the object:
Dim objExcel As Object
Dim wks As Worksheet
Dim wkb As Workbook
'I'm opening Excel and setting the workbook object in a subroutine:
Set objExcel = CreateObject("Excel.Application") 'Excel is invoked 01
Set wkb = objExcel.Workbooks.Open(strOutputPathAndFileName)
objExcel.Application.Visible = True
'Then calling the subroutine to set the row height and wrap text property
FirstRowHeightAndWrap ("ChangeTracking")
FirstRowHeightAndWrap ("FivePCalcsThisPPE")
'Here's the function
Function FirstRowHeightAndWrap(strSheetName As String)
Set wks = wkb.Sheets(strSheetName)
With wks
.Rows(1).Select
.Rows(1).RowHeight = 28
.Rows(1).WrapText = True
End With
End Function
It's something about setting the wks variable in a different place than the objExcel and wkb variables, clearly, 'cuz it works if I do it all in one place.
Why does it not work?
It's something about setting the wks variable in a different place than the objExcel and wkb variables, clearly, 'cuz it works if I do it all in one place.
The main reason why your function call does not work is because you are trying to use a variable that is outside it's scope. The variables that you declare and set inside a sub/function are local to that sub/function.
In your case, the wkb variable can only be referenced within the sub where it was declared and set. Once you call the FirstRowHeightAndWrap, you will get an Object required error because access does not know what the variable wkb is.
You can see this process by using the View > Locals Window and executing your code line by line, and you will notice that your existing local variables show up as Empty once it reaches a new sub/function call.
How can you fix it?
1. A fix would be to pass the wkb object as a reference in
your function. In other words you would need to adjust the lines as
follow :
In your sub ...
FirstRowHeightAndWrap wkb, "ChangeTracking"
FirstRowHeightAndWrap wkb, "FivePCalcsThisPPE"
You will need to also change the function header and function to:
If you want to loop for all worksheets ...
Function FirstRowHeightAndWrap(ByRef wkb As Object)
For Each wks In wkb.Worksheets
wks.Rows(1).RowHeight = 28
wks.Rows(1).WrapText = True
Next
End Function
If you want to keep your original function with the specific sheetname parameter ...
Function FirstRowHeightAndWrap(ByRef wkb As Object, strSheetName As String)
Set wks = wkb.Sheets(strSheetName)
With wks
.Rows(1).RowHeight = 28
.Rows(1).WrapText = True
End With
End Function
2. The easier solution, especially in cases where you are using simple functions, is to dump everything in the same sub so you don't have to pass a reference with each function call.
Also as mentioned in the comments, you do not need the .Select line in your function. I would also recommend using late binding for your variables in order to prevent any possible issues with references if you have other users using your application.
Good luck! :)
All you need is to loop the worksheets like this:
Public Function SetRowHeight()
Dim objExcel As Object
Dim wkb As Workbook
Dim wks As Worksheet
Set objExcel = CreateObject("Excel.Application")
Set wkb = objExcel.Workbooks.Open("c:\test\test.xlsx")
For Each wks In wkb.Worksheets
wks.Rows(1).RowHeight = 28
wks.Rows(1).WrapText = True
Next
wkb.Close True
Set wkb = Nothing
objExcel.Quit
Set objExcel = Nothing
End Function
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 know this might come off as a trivial question, but I can't seem to declare a workbook or a worksheet as a variable in VBA. I have the following code, but I can't figure out what I am doing wrong, it should be straight forward. Normally I don't have any problems declaring variables such as Dim i As Integer etc.
sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
Set ws = Sheet("name")
wb.ws.Select
End Sub
When I run the above code, I receive a type missmatch error.
Use Sheets rather than Sheet and activate them sequentially:
Sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
Set ws = Sheets("Sheet1")
wb.Activate
ws.Select
End Sub
If the worksheet you want to retrieve exists at compile-time in ThisWorkbook (i.e. the workbook that contains the VBA code you're looking at), then the simplest and most consistently reliable way to refer to that Worksheet object is to use its code name:
Debug.Print Sheet1.Range("A1").Value
You can set the code name to anything you need (as long as it's a valid VBA identifier), independently of its "tab name" (which the user can modify at any time), by changing the (Name) property in the Properties toolwindow (F4):
The Name property refers to the "tab name" that the user can change on a whim; the (Name) property refers to the code name of the worksheet, and the user can't change it without accessing the Visual Basic Editor.
VBA uses this code name to automatically declare a global-scope Worksheet object variable that your code gets to use anywhere to refer to that sheet, for free.
In other words, if the sheet exists in ThisWorkbook at compile-time, there's never a need to declare a variable for it - the variable is already there!
If the worksheet is created at run-time (inside ThisWorkbook or not), then you need to declare & assign a Worksheet variable for it.
Use the Worksheets property of a Workbook object to retrieve it:
Dim wb As Workbook
Set wb = Application.Workbooks.Open(path)
Dim ws As Worksheet
Set ws = wb.Worksheets(nameOrIndex)
Important notes...
Both the name and index of a worksheet can easily be modified by the user (accidentally or not), unless workbook structure is protected. If workbook isn't protected, you simply cannot assume that the name or index alone will give you the specific worksheet you're after - it's always a good idea to validate the format of the sheet (e.g. verify that cell A1 contains some specific text, or that there's a table with a specific name, that contains some specific column headings).
Using the Sheets collection contains Worksheet objects, but can also contain Chart instances, and a half-dozen more legacy sheet types that are not worksheets. Assigning a Worksheet reference from whatever Sheets(nameOrIndex) returns, risks throwing a type mismatch run-time error for that reason.
Not qualifying the Worksheets collection is an implicit ActiveWorkbook reference - meaning the Worksheets collection is pulling from whatever workbook is active at the moment the instruction is executing. Such implicit references make the code frail and bug-prone, especially if the user can navigate and interact with the Excel UI while code is running.
Unless you mean to activate a specific sheet, you never need to call ws.Activate in order to do 99% of what you want to do with a worksheet. Just use your ws variable instead.
Third solution:
I would set ws to a sheet of workbook wb as the use of Sheet("name") always refers to the active workbook, which might change as your code develops.
sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ActiveWorkbook
'be aware as this might produce an error, if Shet "name" does not exist
Set ws = wb.Sheets("name")
' if wb is other than the active workbook
wb.activate
ws.Select
End Sub
Just coming across the same problem.
What you need to do is to declare ws as Object
Also it should be:
Set ws = wb.Sheets("Sheet1")
And should not be:
Set ws = Sheet("Sheet1")
The code below are working to me.
sub kl()
Dim wb As Workbook
Dim ws As Object
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")
MsgBox ws.Name
End Sub
Try changing the name of the variable as sometimes it clashes with other modules/subs
Dim Workbk As Workbook
Dim Worksh As Worksheet
But also, try
Set ws = wb.Sheets("name")
I can't remember if it works with Sheet
to your surprise, you do need to declare variable for workbook and worksheet in excel 2007 or later version. Just add single line expression.
Sub kl()
Set ws = ThisWorkbook.Sheets("name")
ws.select
End Sub
Remove everything else and enjoy.
But why to select a sheet? selection of sheets is now old fashioned for calculation and manipulation.
Just add formula like this
Sub kl()
Set ws = ThisWorkbook.Sheets("name")
ws.range("cell reference").formula = "your formula"
'OR in case you are using copy paste formula, just use 'insert or formula method instead of ActiveSheet.paste e.g.:
ws.range("your cell").formula
'or
ws.colums("your col: one col e.g. "A:A").insert
'if you need to clear the previous value, just add the following above insert line
ws.columns("your column").delete
End Sub
I had the same issue. I used Worksheet instead of Worksheets and it was resolved. Not sure what the difference is between them.
Dim ws as Object
Set ws = Worksheets("name")
when declaring the worksheet as worksheet instead of an ojbect I had issues working with OptionButtons (Active X) in this worksheet (I guess the same will be with any Active-X element. When declared as object everything works fine.
Lots of answers above! here is my take:
Sub kl()
Dim wb As Workbook
Dim ws As Worksheet
Set ws = Sheets("name")
Set wb = ThisWorkbook
With ws
.Select
End With
End Sub
your first (perhaps accidental) mistake as we have all mentioned is "Sheet"... should be "Sheets"
The with block is useful because if you set wb to anything other than the current workbook, it will ececute properly
I'm attempting to copy the contents of a text box from one workbook to another. I have no problem copying cell values from the first workbook to the 2nd, but I get an object required error when I attempt to copy the text box. This macro is being run from the workbook containing the data I want copied. Using Excel 2007 Code:
Sub UploadData()
Dim xlo As New Excel.Application
Dim xlw As New Excel.Workbook
Set xlw = xlo.Workbooks.Open("c:\myworkbook.xlsx")
xlo.Worksheets(1).Cells(2, 1) = Range("d4").Value 'Copy cell content (this works fine)
xlo.Worksheets(1).Cells(2, 2) = TextBox1.Text 'This gives me the object required error
xlw.Save
xlw.Close
Set xlo = Nothing
Set xlw = Nothing
End Sub
Thanks for any help.
The problem with your macro is that once you have opened your destination Workbook (xlw in your code sample), it is set as the ActiveWorkbook object and you get an error because TextBox1 doesn't exist in that specific Workbook. To resolve this issue, you could define a reference object to your actual Workbook before opening the other one.
Sub UploadData()
Dim xlo As New Excel.Application
Dim xlw As New Excel.Workbook
Dim myWb as Excel.Workbook
Set myWb = ActiveWorkbook
Set xlw = xlo.Workbooks.Open("c:\myworkbook.xlsx")
xlo.Worksheets(1).Cells(2, 1) = myWb.ActiveSheet.Range("d4").Value
xlo.Worksheets(1).Cells(2, 2) = myWb.ActiveSheet.TextBox1.Text
xlw.Save
xlw.Close
Set xlo = Nothing
Set xlw = Nothing
End Sub
If you prefer, you could also use myWb.Activate to put back your main Workbook as active. It will also work if you do it with a Worksheet object. Using one or another mostly depends on what you want to do (if there are multiple sheets, etc.).
I think the reason that this is happening could be because TextBox1 is scoping to the VBA module and its associated sheet, while Range is scoping to the "Active Sheet".
EDIT
It looks like you may be able to use the GetObject function to pull the textbox from the workbook.
The issue is with this line
xlo.Worksheets(1).Cells(2, 2) = TextBox1.Text
You have the textbox defined at some other location which you are not using here. Excel is unable to find the textbox object in the current sheet while this textbox was defined in xlw.
Hence replace this with
xlo.Worksheets(1).Cells(2, 2) = worksheets("xlw").TextBox1.Text
I have a piece of script that’s in module1 that checks if an option button is clicked.
The option button is placed in Sheet1, name “Info”, so I thought the script below would work
Sub checkClicked()
dim Page as worksheet
set Page as worksheets(“Info”)
Debug.print Page.optClicked
End sub
But when I did it like this it says method or data member not found. It would only work if I replace it with
…
Debug.print Sheet1.optClicked
…
Can anyone give me an insight why this happens?
Think of Sheet1 as a "subclass" of "worksheet" - when you add controls to the sheet you're adding new members. A generic worksheet object doesn't have a member which represents your option button, whereas Sheet1 does.
Sub Test()
Dim sht As Worksheet
Dim sht1 As Sheet1
Set sht = ThisWorkbook.Sheets("Sheet1")
Set sht1 = Sheet1
Debug.Print sht.optClicked 'error
Debug.Print sht1.optClicked 'OK
End Sub
Set Page = ActiveWorkbook.Worksheets("Info") should work. I think worksheets is no real property in VBA...
Also, your debug print code looks weird, use debug.print("bla")..
Do you have Option explicit activated?
Try Set Page = Worksheets("Info") and do NOT use these curly “” quotes - just in case (for Excel formulas this DOES matter).
The argument within Worksheets is the name of the worksheet you are interested in, i.e. "Sheet1".
Other approach: the ActiveX controls on sheet are accessible from two collections: Shapes and OLEObjects. You could use the OLEObjects collection to get access to your checkbox.
Sub checkClicked()
Dim Page As Worksheet
Set Page = Worksheets("Info")
' 1/ ActiveX check box in Shapes collection
Dim myShape As Shape
Set myShape = Page.Shapes("optClicked")
' --------------------------------------
' 2/ ActiveX check box in OLEObjects collection
Dim myOLEObject As OLEObject
Set myOLEObject = Page.OLEObjects("optClicked")
' Use Object property to get access to your check box
Dim myCheckBox As Variant
Set myCheckBox = myOLEObject.Object
If (TypeOf myCheckBox Is MSForms.CheckBox) Then
Debug.Print myCheckBox.value
End If
End Sub