VBA: Initialize Combo Box in worksheet - vba

I have an error during initialization and I do not get why this is not working:
Private Sub Workbook_Open()
Dim ws As Worksheet
Set ws = Worksheets(1)
ws.ComboC15.AddItem "Technology"
end sub
It is very weird, the code should be correct. I have checked the combo name and it is "ComboC15".
In fact, this is the sub:
Private Sub ComboC15_Change()
Ps: I also checked the sheet and it is the first sheet where I have the Combo

The Worksheet object in VBA doesn't have a property or method called ComboC15, as this is entirely your own invention. However, the individual worksheet object in your workbook, i.e. the sheet itself as a physical sheet and not as a VBA sheet, knows all about ComboC15 since it's been dropped on it by you. Therefore, you need to access the worksheet object (notice the little w) and not the Worksheet object (notice the big W). If it's confusing to read, imagine how confusing it is for me to try to explain this...
To get access to the worksheet Object, you can do any of the following:
' Assuming "Sheet1" is the code name of the object. You can find this code name
' in the VBA editor. In the "Project Explorer" window, look under Microsoft
' Excel Objects. Your sheets are listed there in the form (for a blank, new
' workbook) "Sheet1 (Sheet1)". The bit *outside* the brackets is the code name.
Sheet1.ComboC15.AddItem "Technology"
' You can even call it directly from the "Worksheet" object by using the sheet
' index.
Worksheets(1).ComboC15.AddItem "Technology"
However, if you want to create a variable with it so you don't have to copy/paste the same thing over and over, declare it as an Object and not as a Worksheet. So do this:
Private Sub Workbook_Open()
Dim ws As Object ' Declare ws as "Object"!
Set ws = Worksheets(1)
ws.ComboC15.AddItem "Technology"
End Sub
The following SO Q&A explains a bit more about the different kind of sheet names:
Excel tab sheet names vs. Visual Basic sheet names
and I hope this article might give you a better insight on how to reference different kinds of objects in VBA.

Related

Variable name of a worksheet

I want to name a worksheet in excel as the value inside cell "C6" in the tab named "Control". I am new to VBA and what I tried was typing this on a module.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'
' Macro2 Macro
'
'
Dim month As String
month = Sheet2.Range("C5")
Sheets("Month").Name = month
End Sub
Moreover, I do not know whether the name will be updated automatically. I do not want to have to run a macro to change the worksheet name...
Thanks!
It sounds like you want to be able to always refer to the same worksheet, regardless of the worksheet's name changing (as shown on the worksheet's tab) .
This is where the worksheets' CODENAME Property comes in handy.
Let's say you have an object variable declare for your worksheet like Dim ws As Worksheet. You can refer to a worksheet three basic ways.
...by Name :
Set object variable:
Set ws = Sheets("Sheet1")
The worksheet name is the only worksheet identifier that can be changed to whatever you want, which (as you're probably aware) is done like:
ws.Name = "NewSheetname"
...or alternatively, like:
Sheets("Sheet1").Name = "NewSheetName"
...by Index Number :
The index number identifies the position of the worksheet's "tab", compared to the others (and cannot be changed without changing the order of the worksheets)
Set object variable:
Set ws = Sheets(1)
...then you could (still) change the worksheets name like:
ws.Name = "NewSheetname"
...or you could change the name by referring to the worksheet index number like:
Sheets(1).Name = "NewSheetName"
NOTE: If the worksheet is moved (or another worksheet is inserted before it), the Index number will change! Therefore, it's usually not the preferred method of referring to a worksheet.
...by CodeName :
The CodeName is how Excel refers to the worksheets internally. It is the original name that Excel gave the worksheet, and it does not change since it is a read-only property.
Set object variable:
Set ws = Sheet1
...then you could (still) change the worksheets name like:
ws.Name = "NewSheetname"
...or you could change the name by referring to the worksheet codename like:
Sheet1.Name = "NewSheetName"
You can check a worksheets' CodeName property like:
MsgBox Sheets("YourSheetName").CodeName
...or, if ws is already referencing the worksheet:
MsgBox ws.CodeName
So, in your case, you could change the name of your worksheet as often as you like, with:
Sheet2.Name = "NewNameHere"
...just keep referring to it as Sheet2.
One more example to clarify the difference:
Create a new workbook. (It will automatically have worksheet named Sheet1.)
Change the worksheet name to "Sheet1999", either manually (by double-clicking the name on it's tab) or programmatically (with Sheet1.Name="Sheet1999")
Now, if you want to find out how many rows on that sheet have been used, you use use either:
MsgBox Sheets("Sheet1999").UsedRange.Rows.Count
...or:
MsgBox Sheet1.UsedRange.Rows.Count
A note about Sheets versus Worksheets:
When referring to a worksheet Sheets and Worksheets can usually be used interchangeably, so for example these two lines do the same thing:
Worksheets("mySheet").Calculate
Sheets("mySheet").Calculate
The difference is that:
the Worksheets object searches the Worksheets Collection for a matching Name, Index, or CodeName.
the Sheets object searches the Worksheets Collection **and the Charts Collection** for a matching Name, Index, or CodeName.
Therefore, the only time it would be a problem is if you have a chart and a worksheet with the same name.
So, don't ever name a chart the same as a worksheet, and then you won't have to worry about it, and can go on saving 4 keystrokes any time you refer to a Sheet... :)
More Information:
MSDN : Worksheet Object
MSDN : Worksheet Properties
MSDN : Worksheet Methods
MSDN : Sheets Object

Open a closed workbook to a specific sheet based of a cell value

I've spent to much time trying to figure this out and would appreciate some help.
I would like to open a closed workbook based off a cell value (eg A1) containing a file path and have it open up to the sheet matching another cell (eg A2).
for example A1 = C:\User\TEST.xls
and A2= Sheet3
I would like a button that opens C:\User[TEST.xls]Sheet3
Here's what I've got so far:
Sub OpenSesame()
Dim ClosedBook As Workbook
Set ClosedBook = Workbooks.Open(Filename:=Application.Range("ClosedBookFile").Value)
'ClosedBookFile is a named cell
ClosedBook.Sheets(*DYNAMIC CELL VALUE*).Activate
Range("A1").Select
End Sub
What can I put instead of dynamic cell value to open to a specific sheet or am I barking up the wrong tree?
Thanks for your help
Probably it is a good idea to refer the Name of the worksheet as a variable and refer it later. Something like this:
Option Explicit
Sub OpenSesame()
Dim ClosedBook As Workbook
Dim nameOfWorksheet As String
Dim pathToOpen As String
With Worksheets(1)
nameOfWorksheet = .Range("A10") 'for example
pathToOpen = .Range("ClosedBookFile")
End With
Set ClosedBook = Workbooks.Open(pathToOpen)
ClosedBook.Worksheets(nameOfWorksheet).Activate
Range("A1").Select
End Sub
Furthermore, it is a good practice to refer the worksheet, whenever you are referring to a range. Thus, With Worksheets(1) refers the first worksheet in your current workbook.
Along #Vityata lines, I'd add you need explict reference of which workbook the worksheet with data belongs to, and avoid implicit reference to the currently active workbook
here's a compressed code with what above
Option Explicit
Sub OpenSesame()
With ThisWorkbook.Worksheets("myWorksheetWithFileInfoName") ' reference worksheet holding info of workbook and worksheet to activate
Workbooks.Open(Filename:=.Range("ClosedBookFile").value).Worksheets(.Range("A2").value).Activate ' open wanted workbook and activate wanted worksheet
'from now on the wanted worksheet in the wanted workbook is the active one
Range("A1").Select ' almost always not needed
End With
End Sub

VBA: How to address the correct workbook when giving a worksheet as an argument to a function?

I have a question regarding the correct address of Workbooks in VBA, which I am fairly new to.
Here is what I have done so far:
I have written a sub that, amongst other things, creates a worksheet with the CodeName "table10".
Then I defined a function to manipulate the contents of said sheet: this function
Text_To_Numbers(worksheet as worksheet)
expects a worksheet argument. I call the function from another sub using the following line:
Call Text_To_Numbers(table10)
Now, here is my issue:
The above works flawlessly when the only open workbook is the one I want to manipulate with my function. However, when I have multiple open workbooks, the function will try to manipulate a different workbook, resulting in an error.
I am quite certain that there must be a way to specify the workbook to be used, but I am unable to find it. That being said, there is another complication: The name of the workbook which I would like to manipulate is machine generated, so it always has a different name. This means that using an explicit reference to the same file name time and again is not an option.
Could anybody help me resolve this?
You need to fully qualify objects in VBA to avoid situations like this where it is ambiguous what the parent is.
In your situation, you want the sheet to be connected to its parent workbook, so make sure you specify that it came from a given workbook!
You cannot directly refer to worksheets in other workbooks by their CodeName, this can only be done to the ThisWorkbook object (the workbook containing the VBA code). See the question Fully reference a worksheet by codename for details on how to get the sheet by its codename from another workbook. I have included the function in the answer and how to use it in this context.
You created the sheet table10 in one of the following:
ActiveWorkbook
ThisWorkbook
WB (some workbook object)
So you can access it using that workbook object without a need for the name!
Using ThisWorkbook.table10 should give same behaviour as just table10, but here are two neater examples for calling the function.
' A neater way to call the function:
Text_To_Numbers worksheet:=ThisWorkbook.table10
' You could also call it simply using
Text_To_Numbers ThisWorkbook.table10
If your sheet is not within ThisWorkbook
' Get sheet (from the workbook object you are using, WB) and pass to your Text_To_Numbers
Text_To_Numbers GetSheetWithCodename("table10", WB)
Function GetSheetWithCodename(ByVal worksheetCodename As String, Optional wb As Workbook) As Worksheet
Dim iSheet As Long
If wb Is Nothing Then Set wb = ThisWorkbook ' mimics the default behaviour
For iSheet = 1 To wb.Worksheets.Count
If wb.Worksheets(iSheet).CodeName = worksheetCodename Then
Set GetSheetWithCodename = wb.Worksheets(iSheet)
Exit Function
End If
Next iSheet
End Function
Try assigning the workbook and sheet to a variable then calling it in this way when you need to do some work in it:
Dim WB As Workbook
Dim WS As Worksheet
'If you want to open the workbook before doing work
Set WB = Workbooks.Open("/Workbook path name goes here”)
Set WS = WB.Worksheets("Table‌​10")
Then you just need to pass a call to the WS variable from within your function to perform operations within the specified sheet.
Edit:
Apologies, didn't realise you were trying to reference the index name in the project editor when I first read your question. The code name can be referenced from an external workbook with the following example which shows how to select the workbook and sheet codename to perform a copy/paste from one workbook to another:
Sub UseCodeNameFromOutsideProject()
Dim WS As Worksheet
With Workbooks("MyWorkbook.xlsb")
Set WS = _
.Worksheets(CStr(.VBProject.VBComponents("Sheet1").Properties(7)))
WS.Range("A1").Copy
Selection.Copy
WS.Range("B1").PasteSpecial
End With
End Sub
Thanks to Enderland for the idea.

I have failed endlessly trying to write the code in VBA to insert this formula into a cell

The formula:
=IFERROR(IF(OR(E10=0,D9=0),0,NETWORKDAYS(D9,E9))," ")
An example of what I've tried in VBA:
Sub inputWorkdays()
Range("h9").Formula = "=IFERROR(IF(OR(E9=0,D9=0),0,NETWORKDAYS(D9,E9)),""Yes"")"
End Sub
I'm trying to add the formula from above into cell H9.
Select the cell with the formula and write the following:
Sub TestMe
debug.print Selection.Formula
debug.print Selection.FormulaR1C1
End sub
In your case it would give:
=IFERROR(IF(OR(E10=0,D9=0),0,NETWORKDAYS(D9,E9)),"YES")
=IFERROR(IF(OR(R[-4]C[-1]=0,R[-5]C[-2]=0),0,NETWORKDAYS(R[-5]C[-2],R[-5]C[-1])),"YES")
Take the first one and use it like this:
Range("h9").Formula = "=IFERROR(IF(OR(E10=0,D9=0),0,NETWORKDAYS(D9,E9)),""YES"")"
I gather from the comments that there is no error, just "nothing happens". I see nothing wrong with your code. Except...
Range("h9").Formula = "..."
When Range is unqualified like this, you implicitly refer to the ActiveSheet; if the active sheet isn't the sheet you're expecting to write to, then it's easy to conclude that "nothing happens" and that the code doesn't work.
If you have Rubberduck installed (full disclosure: I'm heavily involved with the development of this open-source VBE add-in), you will see that Range in this case is a member of Excel._Global, and an inspection result will tell you that you're implicitly referring to the ActiveSheet:
Range("H9").Formula = "..."
Implicit references to the active sheet make the code frail and harder to debug. Consider making these references explicit when they're intended, and prefer working off object references.
http://rubberduckvba.com/Inspections/Details/ImplicitActiveSheetReferenceInspection
To fix this, qualify the Range call with a Worksheet object - now the Range call is a member of the Excel.Worksheet class:
Dim sheet As Worksheet
Set sheet = ThisWorkbook.Worksheets("Sheet1")
sheet.Range("H9") = "..."
By qualifying Range calls with a worksheet object, you make sure that you're always writing to the worksheet you mean to write to - not the worksheet that happens to be the active one when the code runs.

Excel VBA copy Run-Time error '1004'

I can't figure out what's wrong with my VBA:
Private Sub CommandButton4_Click()
Sheets("Opgave").Select
Range("F9:G14").Select
Selection.Copy
Sheets("Reserve").Select
Range("E3").Select
End Sub
Excel says Range("F9:G14").Select is wrong!
You need to Activate the sheet, because Range is implicitly referring to the active worksheet, and you're wrongly assuming Selecting something will necessarily Activate it.
I've executed your code with "Sheet1" and "Sheet2" without any error being thrown, "Sheet1!F9:G14" selected for copy and "Sheet2!E3" selected, which seems to be what this code wants to achieve.
Still, I'd like to say...
Avoid problems, avoid Select and Activate in VBA code.
Sheets have a CodeName property that you can change from, say, Sheet1 to OpgaveSheet, or Sheet2 to ReserveSheet. Then this code is valid:
OpgaveSheet.Range("F9:G14").Copy ReserveSheet.Range("E3")
The Name of a worksheet is the text that's displayed in the tab for it in Excel. You can also use that to get a reference to a worksheet:
Dim opgaveSheet As Worksheet
Set opgaveSheet = ThisWorkbook.Worksheets("Opgave")
Dim reserveSheet As Worksheet
Set reserveSheet = ThisWorkbook.Worksheets("Reserve")
And when you want to work with a specific range, keep a reference to it instead of Selecting it and working with the Selection:
Dim source As Range
Set source = opgaveSheet.Range("F9:G14")
Dim destination As Range
Set destination = reserveSheet.Range("E3")
source.Copy destination
Code that doesn't constantly interact with worksheets (via Select and Activate) is going to perform better, will be easier to follow, debug and maintain, and will be much less error-prone.