Question

I'm still very new to using VBA, so I apologize if I don't know all of the preferred terms.

I am attempting to write a userform to populate a spreadsheet allowing me to track employees PTO used. This spreadsheet is the X-axis (row 1) being the date and the Y-axis (column A) being the employee name.

The userform I've created has 5 pieces of criteria:

1)  Employee Name (ComboBox1; this is a drop down of multiple rows)
2)  Date of PTO (ComboBox2; this is supposed to be a drop down of multiple columns)
3)  Duration of PTO (OptionButton1 is 1 Day, OptionButton2 is 0.5 Day)
4)  Enter Data (CommandButton1)
5)  Cancel (CommandButton2)

I've completed criterion 1 by selecting and labeling the menu on the spreadsheet.

The rest is what's kicking me.

I cannot seem to get the dates (criterion 2), while in row format, to show up in the ComboBox2 drop down. If I transpose these items into a single column, I have been able to label the group and create the drop down menu. This is problematic as I will not be able to form a grid to populate.

My OptionButton1 and OptionButton2 items are intent to be the input values (1 and 0.5). At this time, I've been unable to give them values, simply names. This input is secondary to the major issue where I cannot get the grid format to work (paragraph above this).

The tertiary problem is the combination of criterion 4 and 5. My script is failing to execute CommandButton1, though I believe it's due to my extremely basic code:

Private Sub CommandButton1_Click()
    cmdOK
End Sub

CommandButton2 appears to work using this code:

Private Sub CommandButton2_Click()
    cmdCancel
End Sub

My end all be all question, having described my issues, would be "Is my end goal possible?" I only intend to use Excel for this, as many people already have access to it. If this is possible, then I would ask for either help identifying my error points and correcting, or a link to a coding manual where I can attempt to learn more about the functions (this is more of a long-term situation, which doesn't quite help the issue, but I would feel okay with).

Thank you in advance for responses.

Edit:

@ Seth

I've made it as far as ComboBox2 (the dates) selection. I cannot get the loop, suggested below, to access the values (1 row, 365 columns).

I tried modifying the code from Seth, but I really don't know anything about loops; I feel I most likely did not fill out a section appropriately (I'm looking at .Value <> ""):

Private Sub ComboBox2_Change() Dim i As Long

i = 1

Do While ThisWorkbook.ActiveSheet("Breakdown").Cells("A1:NC1", i).Value <> ""

Me.ComboBox1.AddItem (ThisWorkbook.ActiveSheet("Breakdown").Cells("A1:NC1", i).Value)
i = i + 1

Loop

End Sub

Using this code, I get the error "Run-time error '438': Object doesn't support this property or method"

I'm trying to find a general guide to understanding writing a loop, though I find no reference to some of the above statements, so I'm not positive how to correct my problem. I believe it might also have something to do with the properties of the box. I can enter "Dates" (my generic term for that range as defined by highlighting and labeling as such) under RowSource, though that is not looping the rows.

@ Alex D

I am also attempting the path of the second post I received; i get a runtime error when I try to use:

Private Sub UserForm_Initialize()
    For i = 2 To Sheets("Breakdown").UsedRange.Columns.Count
         comboDate.AddItem (Cells(1, i))
        comboDate.List(comboDate.ListCount - 1, 1) = i
    Next
End Sub

Possibly moving where that data is defined would make this work? In general, I have a button in the sheet (aka one selects a cell and the userform pops up), so possibly the initialize isn't necessary?

Cyril 20140127 (1700 UTC)

Was it helpful?

Solution

Ok, let's go in reverse order. To your last question, "Is my end goal possible?", the answer is "sure." I don't quite follow your reasoning, but if you prefer to use Excel, so be it. I do think, though, that this going to be a painful way of recording PTO. What if, for example, I take a week off? Do I have to fill out this form once for each day?

To continue moving in reverse, your buttons need to do something. It's unclear from what you've posted if cmdCancel and cmdOK are subs that you've defined elsewhere so let's pretend they aren't. In your Cancel button you need to do one basic thing, close the form. That should be as simple as this, Unload Me.

Your OK button is the crucial piece of your macro. It's where you stitch together the values the user has entered. It's also where you do something with your option buttons. You don't actually assign values to the option buttons, you check their Value properties. So, when you users click OK the code that runs will have something in it like this:

If OptionButton1.Value = True Then
     'Put 1 in the cell.
Else
     'Put .5 in the cell.
End if

Note that there's no need to explicitly check OptionButton2, since you only have two choices.

Finally, the dates. It sounds like the dates are already in your spreadsheet, in some particular row. What you need to do here is loop through the cells in that row and pull the values into the list of the combo box. This should get you started. Put it the UserForm_Activate form event:

Dim i As Long

i = 1

Do While ThisWorkbook.ActiveSheet.Cells(DateRow, i).Value <> ""

    Me.ComboBox1.AddItem (ThisWorkbook.ActiveSheet.Cells(DateRow, i).Value)
    i = i + 1

Loop

Now we return to the OK button. You need to get the selection that was made in the date combo box. To do that you need to read the ListIndex property of the combo box and add one to it. (Adding 1 accounts for the fact that the list in the combo box starts 0, not 1.) The number that is the returned will be the column in which you insert your data.

The complete code for the OK button would be something like:

Dim Col As Long
Dim Row As Long
Dim PTOValue As Long

Col = DateComboBox.ListIndex + 1
Row = EmployeeNameComboBox.ListIndex + 1

If FullDayComboBox.Value = True Then
     PTOValue = 1
Else
     PTOValue = .5
End if

ThisWorkbook.ActiveSheet.Cells(DateRow, i).Value = PTOValue

Hopefully this will get you started.

OTHER TIPS

Fills your criterion, and should be understandable. Assumes names start in cell(2,1) and Dates in cell(1,2). You might have to change some of the names of the elements depending on what you have. But I fully built something like you described and it works perfectly.

It does need some data validation to prevent errors, but you should be able to handle that.

'Ok button which sets the values
Private Sub CommandButton1_Click()
    Columns("A:A").Select
    If OptionButton1.Value = True Then
        Cells(Get_Name_Row(comboName.Text), Get_Date_Column(comboDate.Text)).Value = 1
    Else
        Cells(Get_Name_Row(comboName.Text), Get_Date_Column(comboDate.Text)).Value = 0.5
    End If
End Sub

'Cancel Button
Private Sub CommandButton2_Click()
    Unload Me
End Sub

'This loads the dates into your comboBox, make sure to update its name
'I assume you use RowSource for your names, so those should be fine
Private Sub UserForm_Initialize()
    For i = 2 To Sheets("Sheet1").UsedRange.Columns.Count
        comboDate.AddItem (Cells(1, i))
        comboDate.List(comboDate.ListCount - 1, 1) = i
    Next
End Sub

'Gets what row the name is from
Public Function Get_Name_Row(SearchString As String) As Integer
    Dim Rng As Range
    If Trim(SearchString) <> "" Then
        With Sheets("Sheet1").Range("A:A")
            Set Rng = .Find(What:=SearchString, _
                            After:=.Cells(.Cells.Count), _
                            LookIn:=xlValues, _
                            LookAt:=xlWhole, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlNext, _
                            MatchCase:=False)
            If Not Rng Is Nothing Then
                Get_Name_Row = CInt(Rng.Row)
            End If
        End With
    End If
End Function

'Gets what column the date is from
Public Function Get_Date_Column(SearchString As String) As Integer
    Dim Rng As Range
    If Trim(SearchString) <> "" Then
        With Sheets("Sheet1").Range("A1").EntireRow
            Set Rng = .Find(What:=SearchString, _
                            After:=.Cells(.Cells.Count), _
                            LookIn:=xlValues, _
                            LookAt:=xlWhole, _
                            SearchOrder:=xlByRows, _
                            SearchDirection:=xlNext, _
                            MatchCase:=False)
            If Not Rng Is Nothing Then
                Get_Date_Column = (Rng.Column)
            End If
        End With
    End If
End Function
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top