Load combobox with range of another sheet - excel

I have one combobox in one sheet named extraçao with a combobox,
and I have written this code:
Sub Validar_Idades()
Dim aba1 As Worksheet
Set aba1 = Sheets("IDADE")
Dim aba2 As Worksheet
Set aba2 = Sheets("EXTRAÇÃO")
aba2.ComboBox1.Clear
aba2.ComboBox1.List = aba1.range("A2:A" & aba1.range("A" & aba1.Rows.Count).End(xlUp).Row).Value
End Sub
Why don't I see combobox1?

There is an important distinction between Worksheet objects and Sheet objects:
Worksheet can contain only data (in cells)
Sheet can contain data, and other objects like Charts, combo boxes, list boxes, etc
To declare a Worksheet variable use Worksheet type
To declare a Sheet variable use its CodeName, that appears before the name in brackets:
.
Try one of the 2 options bellow
Option Explicit
Sub Validar_Idades()
Dim aba1 As Worksheet 'Worksheet contain only data (no objects)
Set aba1 = Worksheets("IDADE")
'To declare a variable of type Sheet you need to use its "CodeName"
Dim aba2 As Sheet2 'Sheet can contain data and other objects
Set aba2 = Sheets("EXTRAÇÃO") 'like ListBoxes, Charts, ComboBoxes, etc
aba2.ComboBox1.Clear
aba2.ComboBox1.List = aba1.Range("A2:A" & _
aba1.Range("A" & aba1.Rows.Count).End(xlUp).Row).Value
End Sub
Sub Validar_Idades2()
'or simply use its code name instead of a variable
Sheet2.ComboBox1.Clear
Sheet2.ComboBox1.List = Sheet1.Range("A2:A" & _
Sheet1.Range("A" & Sheet1.Rows.Count).End(xlUp).Row).Value
End Sub

The Worksheet class does not have a combobox1 property - since of course not every worksheet has that control on it - which is why the compiler objects to your code. In addition to using the codename, as Paul Bica suggested, (though there is no generic Sheet object - each sheet is effectively its own class), you could simply declare your variable as Object rather than Worksheet so the code is late bound and the compiler won't object. Alternatively, you can access the control through the OLEObjects property of the Worksheet class:
aba2.OLEObjects("ComboBox1").Object.List = aba1.Range("A2:A" & _
aba1.Range("A" & aba1.Rows.Count).End(xlUp).Row).Value

Related

Formula to Value Macro [duplicate]

I am trying to copy data from one worksheet to another. I have a workbook that has about 62 worksheet tabs.
The part that is especially tricky for me is that the worksheet the data needs to be copied to will not always be the same.
I have a dropdown menu that lists 62 different pieces of equipment. This is shown in G1 in the worksheet named "HOME". I want the text to copy over to the correct tab based on the selection.
I figured out how to copy over specific text, when I do this I see the word "TEXT" show up on the specified worksheet.
Sheets(Range("g1").Value).Activate
Range("a1").Value = "TEXT"
I cannot figure out how to copy over G4:G24 from my "HOME" worksheet to another worksheet based on the same drop-down menu.
This is what I tried.
Private Sub CommandButton1_Click()
Worksheets("HOME").Range("g4:g24").Copy
Sheets(Range("g1").Value).Activate
Range("a1").Value = "TEXT"
Sheets(Range("g1").Value).Activate
Range("f4").PasteSpecial
End Sub
Be explicit about workbook and worksheets - never use Range/Cells without qualifying a worksheet (though you can get away with it in a worksheet code module if you're referring to the associated worksheet).
Private Sub CommandButton1_Click()
Dim wb As Workbook, ws As Worksheet
Set wb = ThisWorkbook 'or ActiveWorkbook?
With wb.Worksheets("HOME")
Set ws = wb.Worksheets(.Range("G1").Value) 'create a worksheet reference
ws.Range("A1").Value = "TEXT" '...and use it
.Range("g4:g24").Copy ws.Range("f4")
End With
End Sub
See for example: What is the default scope of worksheets and cells and range?
Generally speaking you have a good start there, but it can be accomplished in much fewer lines with much more speed like this:
Sub ExampleSub()
Dim SheetName As String
SheetName = Worksheets("HOME").Range("A1").Value
Worksheets("HOME").Range("G4:G24").Value = Worksheets(SheetName).Range("G4:G24").Value
End Sub
It's not even necessary to use the variable SheetName, but it can help keep things simple, it can also now be reused later in the subroutine.
An alternative to reference sheets is to make the variable a worksheet:
Sub ExampleSub()
Dim SheetName As Worksheet
Dim HomeSheet As Worksheet
Set HomeSheet = Worksheets("HOME")
Set SheetName = Worksheets(HomeSheet.Range("A1").Value)
HomeSheet.Range("G4:G24").Value = SheetName.Range("G4:G24").Value
End Sub

How can I add sheets from an excel file to another?

So I am trying to write a Macro for Excel, that adds 2 worksheets from an excel file to a new one.
Therefore, I try this:
Sub addfile()
Dim sheet1 As Worksheet
Dim sheet2 As Worksheet
Set sheet1 = Sheets.Add(Type:="C:\Users\Helge\AppData\Roaming\Microsoft\Templates\page1.xltx")
Set sheet2 = Sheets.Add(Type:="C:\Users\Helge\AppData\Roaming\Microsoft\Templates\page2.xltx")
End Sub
When I test it, it imports the first page, but the 2nd page gives me a Runtime error 1004.
Why does this happen?
And is there another way to get 2 sheets from one excel file to another via vba?
Much to my surprise this version of your code actually worked for me.
Sub addfile()
Dim Sheet1 As Worksheet
Dim Sheet2 As Worksheet
Set Sheet1 = Sheets.Add(Type:=Environ("Userprofile") & "\OneDrive\Desktop\Template1.xltx")
Set Sheet2 = Sheets.Add(Type:=Environ("Userprofile") & "\OneDrive\Desktop\Book2.xlsx")
Debug.Print Sheet1.Name, Sheet2.Name
End Sub
The reason for my surprise is that Sheet1 and Sheet2 are the default CodeName for the first and second worksheets in any workbook. Therefore there is a conflict of naming between the Sheet1 in the workbook and the Sheet1 you declare which should come to the surface not later than Debug.Print Sheet1.Name. In fact, it may have. I didn't check which name was printed. But the code didn't crash. Since it crashes on your computer, perhaps you have an older version of Excel. Try to stay clear of variable names that Excel also uses. Or there is something wrong with the path & file name, which is hard to tell in that syntax and therefore kept me fooled for quite some time too.
In fact, I discovered the above only after finding out that my Desktop was on OneDrive and not before I had written the function below which is designed to avoid the use of Sheets.Add. It also has some extras such as being able to specify the sheet to take from the template (you could have one template with 2 or more sheets). You can specify an index number or a sheet name. And the function will give a name to the copy, too, if you specify one.
Private Function AddWorksheet(ByVal Template As String, _
TabId As Variant, _
Optional ByVal TabName As String) As Worksheet
Dim Wb As Workbook
Dim Path As String
Dim FileName As String
Set Wb = ThisWorkbook ' change to suit
' make sure the path ends on "\"
Path = "C:\Users\Helge\AppData\Roaming\Microsoft\Templates\"
With Workbooks.Open(Path & Template)
.Sheets(TabId).Copy After:=Wb.Sheets(Wb.Sheets.Count)
.Close
End With
Set AddWorksheet = ActiveSheet
If Len(TabName) Then ActiveSheet.Name = TabName
End Function
You can call the function from a sub routine like this:-
Sub AddWorksheets()
Dim Tab1 As Worksheet
Dim Tab2 As Worksheet
Application.ScreenUpdating = False
Set Tab1 = AddWorksheet("Page1.xltx", 1, "New Tab")
Set Tab2 = AddWorksheet("Page2.xltx", "Sheet1", "Another new Tab")
Application.ScreenUpdating = True
End Sub
Please observe the difference between the two function calls.

Refereshing formula in workbook when two workbooks are open fills data in incorrectly

Problem with workbooks that share user formula names in excel 2016/excel 365.
I have two workbooks open that both specify a user function GetData.
This function is defined in both workbooks and is not public.
Lets use workbook 1 and workbook 2.
I refresh all formula in workbook 1 using ctrl-shift-alt-F9
All cells using the user defined function in workbook 1 update correctly.
All cells using the custom functions in workbook 2 update using data from workbook 1.
Problem is reversed if using ctrl-shift-alt-F9 in workbook 2.
If I update each cell individually by selecting and pressing enter then the cell uses the correct data. The problem only happens when I force excel to update formula, which is required as its the only way to get multiple formula to update.
I have made sure none of my data tables are defined publicly, my functions are not defined publicly.
Both sheets are identical and use the same code, but with different data.
Here is the code from ThisWorkBook
Sub workbook_Open()
If Worksheets("Background").Cells(1, 1).Value = 1 Then
'Define worksheets for use in workbook'
Dim PersonData As Worksheet:
Set PersonData = Worksheets("Person")
CreateTableReference PersonData, "PersonDataTable"
End If
End Sub
here is the code from the module
Function TableExistsOnSheet(ws As Worksheet, sTableName As String) As Boolean
TableExistsOnSheet = ws.Evaluate("ISREF(" & sTableName & ")")
End Function
Sub CreateTableReference(ws As Worksheet, sTableName As String)
If TableExistsOnSheet(ws, sTableName) Then
ws.ListObjects(sTableName).Unlist
End If
If ws.Cells(1, 1).Value <> "" Then
xLastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
xLastRow = ws.Cells(ws.Columns.Count, 1).End(xlUp).Row
ws.ListObjects.Add(xlSrcRange, ws.Range(ws.Cells(1, 1), ws.Cells(xLastRow, xLastCol)), , xlYes).Name = sTableName
End If
End Sub
Function GetData(dataType As String, fieldName As String) As String
Application.Volatile
Select Case dataType
Case "PersonData"
GetData = WorksheetFunction.VLookup(fieldName, Range("PersonDataTable"), 3, False)
End Select
End Function
EXAMPLE OF USE
=GetData("PersonData","Surname")
Expected result would be when ctrl-shift-alt-F9 is pressed that each workbook is updated correctly using the result of the formula using data from its own workbook.
Worksheet Person has the sample data
Data Desription Value
Surname Surname Thomas
my functions are not defined publicly
Even though you did not use the word Public, your functions in the module are still public. i.e they are available within the project containing the module and also to other applications or projects.
You may want to see this Function statement
In scenarios where you have same funciton names in other Excel Applications/Projects, I recommend using Option Private Module
You may want to see Option Private statement
So your code in 1st file will be
Option Private Module
Function Sample()
MsgBox "Blah"
End Function
and in the other as
Option Private Module
Function Sample()
MsgBox "Blah Blah"
End Function
Now each function will refer to it's own module.

How to use Count If function inside of a sub?

I am trying to count the number of times the string shows up in the range and return to worksheet 1. I am assuming this can be done in a Function () but I'm don't know how to write out the syntax.
Sub DistributedApps()
Dim LastRow As Long
Dim Dist As Long
LastRow = Worksheets(3).Cells(Rows.Count, 25).End(xlUp).Row
Dist = Application.Worksheets(3).WorksheetFunction.CountIf(Range("Y1:Y" & LastRow), "Distributed Apps")
Worksheets(1).Range("N66:P69").Value = Dist
End Sub
Object doesn't support this property or method
Dist = Application.Worksheets(3).WorksheetFunction...
The Worksheets property is returning an Object that could be either a Sheets collection (if given an array of sheet names) or a Worksheet object (if given one sheet name, or a sheet index), so you're getting a Worksheet object, but VBA only knows this at run-time.
Move that knowledge to compile-time by introducing a local Worksheet variable; note that Application.Worksheets will give you the sheets collection of whatever workbook is currently active, so it might be a good idea to make that more explicit by qualifying the member call with an actual Workbook object:
Dim sheet As Worksheet
Set sheet = ActiveWorkbook.Worksheets(3)
Now that VBA knows what interface this object has, the editor can help you: when you type the dot in sheet., you'll get a list of all members of the Worksheet interface - and see that none of them is WorksheetFunction: that is why error 438 is raised at run-time, the object doesn't support this property.
The Application object does have a WorksheetFunction member though, so this will work.
lastRow = sheet.Cells(sheet.Rows.Count, 25).End(xlUp).Row
dist = Application.WorksheetFunction.CountIf(sheet.Range("Y1:Y" & lastRow), "Distributed Apps")
Note that the Range member call inside the CountIf argument list is also explicitly qualified with the sheet object. Without this qualifier, Range would be referring to whatever the ActiveSheet is1, and since you don't want to need to Activate any sheets for this to work, using an explicit worksheet object as a qualifier ensures you're computing the count off the correct sheet.
1Unless that code is written in the code-behind for a Worksheet module - in which case the implicit qualifier is Me and the unqualified Range call is referring to that worksheet.
I think this will work.
Sub DistributedApps()
Dim LastRow As Long
Dim Dist As Long
LastRow = Worksheets(3).Cells(Rows.Count, 25).End(xlUp).Row
Dist = Application.WorksheetFunction.CountIf(Worksheets(3).Range("Y1:Y" & LastRow), "Distributed Apps")
Worksheets(1).Range("N66:P69").Value = Dist
End Sub

Initialize a variable to denote worksheet

I have a snippet which throws an error, I assume because the variable s is not initialized. How would I declare the variable s?
Dim X As Integer
Dim WS As Worksheet
'Look for existing sheets named "For Export
'If found, delete existing sheet
For Each s In ActiveWorkbook.Sheets
If s.Name = "For Export" Then
Application.DisplayAlerts = False
' s.Delete
End If
Next s
Probably the easiest way is to search for Option Explicit in your code and to delete it. Then you would not be forced to declare every variable. However, if you are not fan of writing ugly & dirty code try with the following:
Dim s as Sheet
In general, it is better to use the Worksheets collection, instead of the Sheets. Thus:
Dim s as Worksheet
For each s in ActiveWorkbook.Worksheets
The Sheets collection contains both Charts and Worksheets, thus it is better to be more specific.

Resources