I'm using a form to populate a sheet in Excel. In the form, the date-related boxes are broken up by day-month-year combo boxes, which are concatenated to populate a single cell in the sheet. My question is whether there is a way to "unconcatenate" a date in a single cell and populate each individual combo box with the appropriate information (day, month, or year). This is because I want to be able to add new information in one form, then update what already exists in the table in another form.
Code to update form based on given parameter below (focus in Bold):
Private Sub txtstudynm_Change()
Dim StudyName As String
Dim WrdString As String
Dim text_string As String
If Me.txtstudynm.Value = "" Then
MsgBox "Study Name can not be blank", vbCritical
Exit Sub
End If
StudyName = txtstudynm.Value
On Error Resume Next
Me.cmbprojman.Value = Application.WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 2, 0)
On Error Resume Next
Me.cmbstudtyp.Value = Application.WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 3, 0)
On Error Resume Next
Me.cmbprogtyp.Value = Application.WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 4, 0)
On Error Resume Next
Me.cmbfundtyp.Value = Application.WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 5, 0)
On Error Resume Next
Me.txtbudget.Value = Application.WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 6, 0)
On Error Resume Next
Me.txtencumb.Value = Application.WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 7, 0)
On Error Resume Next
Me.cmbpath.Value = Application.WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 8, 0)
**On Error Resume Next**
**text_string = Application.WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 9, 0).Value**
**WrdString = Split(text_string, "/")(0)**
**Me.tssdcmb1.Value = WrdString**
On Error Resume Next
Me.tssdcmb2.Value = WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 9, 0)
On Error Resume Next
Me.tssdcmb3.Value = WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 9, 0)
End Sub
Instead of all those references to the worksheet, use a Variant array:
Private Sub txtstudynm_Change()
If Me.txtstudynm.Value = "" Then
MsgBox "Study Name can not be blank", vbCritical
Exit Sub
End If
Dim StudyName As String
StudyName = txtstudynm.Value
Dim lkp As Variant
lkp = Sheets("Study Summary").Range("A3:AJ3000").Value2
Dim i As Long
For i = 1 To UBound(lkp, 1)
If lkp(i, 1) = StudyName Then
Me.cmbprojman.Value = lkp(i, 2)
Me.cmbstudtyp.Value = lkp(i, 3)
Me.cmbprogtyp.Value = lkp(i, 4)
Me.cmbfundtyp.Value = lkp(i, 5)
Me.txtbudget.Value = lkp(i, 6)
Me.txtencumb.Value = lkp(i, 7)
Me.cmbpath.Value = lkp(i, 8)
Me.tssdcmb1.Value = Day(lkp(i, 9))
Me.tssdcmb2.Value = Month(lkp(i, 9))
Me.tssdcmb3.Value = Year(lkp(i, 9))
Exit For
End If
Next i
End Sub
Try this (not sure which Combo Box you set to Day/Month/Year)...
Dim StudyDate as Date
If IsDate(text_string) Then
StudyDate = CDate(txt)
Me.tssdcmb1.Value Day(StudyDate)
Me.tssdcmb2.Value Month(StudyDate)
Me.tssdcmb3.Value Year(StudyDate)
End If
Declare text_string as a proper Date value (and this is why you don't encode a variable's data type in its name). Then the VLOOKUP will yield a Date value:
text_string = Application.WorksheetFunction.VLookup(StudyName, Sheets("Study Summary").Range("A3:AJ3000"), 9, 0).Value
If what you have is a proper Date, then you use the VBA.DateTime.Year, VBA.DateTime.Month, and VBA.DateTime.Day functions to get each part:
Me.tssdcmb1.Value = Year(text_string)
Me.MonthBox.Value = Month(text_string)
Me.DayBox.Value = Day(text_string)
Notice how meaningful, pronounceable names make the code easier to read/follow.
If what you have is really a string that looks like a date, then... you better hope that the format is consistent, and then using the VBA.Strings.Split function like you did wasn't a bad idea - just use the 3 indices you got:
Dim dateParts As Variant
dateParts = Split(text_string, "/")
Me.YearBox.Value = dateParts(0)
Me.MonthBox.Value = dateParts(1)
Me.DayBox.Value = dateParts(2)
Related
I am starting my first user form in Excel.
I have a ComboBox, which uses a dropdown list to select a value. Once this value is selected it uses VLOOKUP to display the rest of the data in textboxes.
Upon using my reset button on the form, or trying to take out the data in these textboxes, it gives the VLOOKUP runtime error because the data is no longer there.
What do I have to do to stop this from happening?
Private Sub ComboBox1_Change()
Dim MyTableArray As Range, MyEmpID As String
Set MyTableArray = Sheets("CompressorData").Range("A:D")
Me.txtName.Value = WorksheetFunction.VLookup(Me.ComboBox1, MyTableArray, 2, 0)
Me.TextBox3.Value = WorksheetFunction.VLookup(Me.ComboBox1, MyTableArray, 1, 0)
Me.TextBox1.Value = WorksheetFunction.VLookup(Me.ComboBox1, MyTableArray, 4, 0)
End Sub
If it's the error you're trying to avoid (and just that), then include on 'On Error' statement like so:
Sub DropDown1_Change()
Dim MyTableArray As Range, MyEmpID As String
Set MyTableArray = Range("A:D")
On Error GoTo err_trap
DropDown1.txtName.Value = WorksheetFunction.VLookup(DropDown1.ComboBox1, MyTableArray, 2, 0)
DropDown1.TextBox3.Value = WorksheetFunction.VLookup(DropDown1.ComboBox1, MyTableArray, 1, 0)
DropDown1.TextBox1.Value = WorksheetFunction.VLookup(DropDown1.ComboBox1, MyTableArray, 4, 0)
err_trap:
MsgBox ("Caught the error - delete msgbox in VB code and replace with 'Exit Sub' to avoid seeing this message box! hardy har captain")
Exit Sub
End Sub
I am facing an issue in excel VBA. It says that it is unable to get the vlookup property of the WorksheetFunction class
Private Sub cmb_Product_Change()
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("Product_Master")
If Me.cmb_Product.Value = "" Or Me.cmb_Type.Value = "" Then Me.txt_Rate.Value = ""
emphasized text[enter image description here][1]
If Me.cmb_Type.Value = "Sale" Then
Me.txt_Rate.Value = Application.WorksheetFunction.VLookup(Me.cmb_Product, sh.Range("B:D"), 2, 0)
ElseIf Me.cmb_Type.Value = "Purchase" Then
Me.txt_Rate.Value = Application.WorksheetFunction.VLookup(Me.cmb_Product, sh.Range("B:D"), 3, 0)
End If
End Sub
This is the normal behavior of WorksheetFunction.VLookup if the lookup value cannot be found.
You have 2 possibilities:
(a) Ignore the error
Dim rate As Double ' Or String, not sure what your data is.
On Error Resume Next
rate = WorksheetFunction.VLookup(Me.cmb_Product, sh.Range("B:D"), 2, false)
On Error Goto 0
Me.txt_Rate.Value = rate
If your product is not found, rate will be empty
(b) Use Application.VLookup instead. This will not throw a runtime error, but it will return an Error as result if no match is found. Note that you need to declare the result as Variant, else you will get a Type Mismatch error (Error 13).
Dim rate As Variant
rate = Application.VLookup(Me.cmb_Product, sh.Range("B:D"), 2, false)
if not isError(rate) then Me.txt_Rate.Value = rate
Update: For more details see this article: https://rubberduckvba.wordpress.com/2021/02/15/worksheetfunction-and-errors/
I am doing a quick game in Excel VBA, in a userform and a button should use a value from a cell that I input with variable but everytime I got the error 1004.
The weird thing is that when I put a normal number instead of the second variable. the error doesn't appear.
Private Sub CommandButton13_Click()
Dim types(2 To 19, 2 To 19, 2 To 19, 2 To 19), ataques(2 To 19, 2 To 19, 2 To 19) As Double
Dim tipo12, tipo21, tipo22, ataque11, ataque12, ataque13, ataque14, ataque21, ataque22, taque23, ataque24 As Integer
Dim tipo11 As Integer
Dim ataq1a2 As Integer
tipo11 = Label19.Caption
tipo12 = Label20.Caption
tipo21 = Label21.Caption
tipo22 = Label22.Caption
ataque11 = Label23.Caption
ataque12 = Label24.Caption
ataque13 = Label25.Caption
ataque14 = Label26.Caption
ataque21 = Label27.Caption
ataque22 = Label28.Caption
ataque23 = Label29.Caption
ataque24 = Label30.Caption
MsgBox tipo21
'MsgBox Worksheets("Hoja1").Cells(2, 2).Value
MsgBox Worksheets("Hoja1").Cells(tipo11, tipo21).Value
End Sub`
I'm trying to build a file to compare the working time for every worker vs their scheduled time.
I've build some classes to achieve that, but I'm having problems when giving times as keys for the dictionary classes.
Here you can see I already have a key #2:30:00# (item 4) and I'm giving a key #2:30:00# but the code wants to add it as a new one:
Once I add it:
Now I have 2 items with the same value (item 4 and item 17).
This is the code for the class:
Option Explicit
Private m_Tramo As Object
Property Get Tramos(ByVal Key As Date) As Tramos
With m_Tramo
If Not .Exists(Key) Then .Add Key, New Tramos
End With
Set Tramos = m_Tramo(Key)
End Property
Private Sub Class_Initialize()
Set m_Tramo = CreateObject("Scripting.Dictionary")
End Sub
Private Sub Class_Terminate()
Set m_Tramo = Nothing
End Sub
Public Property Get Keys() As Variant
Keys = m_Tramo.Keys
End Property
Public Property Get Count() As Long
Count = m_Tramo.Count
End Property
There is more to it, but it doesn't matter here.
Now the code to add the keys for the first time:
Sub CalculaTramosProgramados(arr As Variant, Agentes As Buca, Horario As String, AgenteHoy As Dias)
Dim HoraI As Date
HoraI = Left(Horario, 5)
Dim HoraF As Date
HoraF = Right(Horario, 5)
If HoraF < HoraI Then HoraF = HoraF + 1
Dim TramoInicial As Date
If Minute(HoraI) < 30 Then
TramoInicial = TimeSerial(Hour(HoraI), 0, 0)
Else
TramoInicial = TimeSerial(Hour(HoraI), 30, 0)
End If
'Vamos a rellenar con 30 minutos todos los tramos
Dim i As Long
Dim TramoActual As Date
For i = 0 To Application.RoundUp(DateDiff("n", HoraI, HoraF) / 30, 0) - 1
TramoActual = TramoInicial + TimeSerial(0, 30 * i, 0)
AgenteHoy.Tramos(TramoActual).Programado = 30
Next i
'Primer tramo no completo
If Minute(HoraI) <> 0 Or Minute(HoraI) <> 30 Then
If Minute(HoraI) < 30 Then
AgenteHoy.Tramos(TimeSerial(Hour(HoraI), 0, 0)).Programado = 30 - Minute(HoraI)
Else
AgenteHoy.Tramos(TimeSerial(Hour(HoraI), 30, 0)).Programado = 60 - Minute(HoraI)
End If
End If
'Ășltimo tramo no completo
If Minute(HoraF) <> 0 Or Minute(HoraF) <> 30 Then
If Minute(HoraF) < 30 Then
AgenteHoy.Tramos(TimeSerial(Hour(HoraF), 0, 0)).Programado = Minute(HoraF)
Else
AgenteHoy.Tramos(TimeSerial(Hour(HoraF), 30, 0)).Programado = Abs(30 - Minute(HoraF))
End If
End If
End Sub
The parameters are an array full of data, a initialized instance for the main class(which contains this one), schedule and shortcut reference for the parent class for this one (to clean a bit the code).
This procedure fills everything up allright, but when I come back here, then the code tries to add the new time when it already exists.
Sub CargarReales(arr As Variant, Agentes As Buca)
Dim i As Long
Dim Login As String
Dim Centro As String
Dim Dia As Date, Tramo As Date
Dim CargarTramo As Boolean
Dim AgenteHoy As Dias
For i = 2 To UBound(arr)
Dia = arr(i, 1)
Centro = arr(i, 2)
CargarTramo = compruebaTramo(Dia, Centro)
If Not CargarTramo Then GoTo Siguiente
Login = arr(i, 4)
Tramo = Mid(arr(i, 3), 4, 8)
Set AgenteHoy = Agentes.Logins(Login).Dias(Dia)
AgenteHoy.Tramos(Tramo).Real = arr(i, 5) / 60
Siguiente:
Next i
End Sub
Again, parameters are an array full of data and the main class.
I made sure that everything the code was providing to the class was the right type of variable, in this case Date variables holding only time, not dates.
Any clues on why is VBA doing this?
I'm having a problem populating a userform. I found some code online that does exactly what I want and the 'example' file works perfectly. When I modify it to my needs, it gives me an error message on the following line:
frmModifyData.Skill.Value = Application.VLookup(cmbItemName.Value, Sheets("Enrolled").Range(vrange), 1, False)
Here's the entire code I'm working with:
Dim NotNow As Boolean
Private Sub cmdCancel_Click()
Unload Me
End Sub
Private Sub cmdOkay_Click()
NotNow = True
N = Application.Match(Me.cmbItemName.Value, Range("AB:AB"), 0)
Cells(N, 1).Value = Me.frmEnterData.Skill.Text
Cells(N, 2).Value = Me.frmEnterData.txtCLASS.Text
Cells(N, 3).Value = Me.frmEnterData.LastName.Text
NotNow = False
End Sub
Private Sub cmbItemName_Change()
If NotNow Then Exit Sub
vrange = "FirstField"
'LINE WITH THE PROBLEM
frmModifyData.Skill.Value = Application.VLookup(cmbItemName.Value, Sheets("Enrolled").Range(vrange), 1, False)
'END OF LINE WITH THE PROBLEM (though it could affect the two lines of code below...)
frmModifyData.txtCLASS.Value = Application.VLookup(cmbItemName.Value, Sheets("Enrolled").Range(vrange), 2, False)
frmModifyData.LastName.Value = Application.VLookup(cmbItemName.Value, Sheets("Enrolled").Range(vrange), 3, False)
End Sub
Private Sub UserForm_Initialize()
frmModifyData.cmbItemName.RowSource = "FirstField"
End Sub
'FirstField' is a named range that is defined this way
=OFFSET(Enrolled!$AB$3,0,0,COUNTA(Enrolled!$AB:$AB)-1,3)
Column AB holds the "Full Name" of the user. This is what I'm using to find an individual. Once I pick a name using a drop-down box on the userform, it gives me the message Could not set the Value property. Invalid property value.
How do I fix this so it works?
Try breaking your code down a little and make sure your vlookup is working...
Dim v
v = Application.VLookup(cmbItemName.Value, Sheets("Enrolled").Range(vrange), 1, False)
If Not IsError(v) Then
frmModifyData.Skill.Value = v
Else
Msgbox cmbItemName.Value & " was not found!"
End If