I am trying to use a module as of of my fields for a query that looks up the frequencies of a training and how long until it is due for a certain employee. I have a table which holds all the employee info (Workday_Excel_Update) as well as the training course number, when he was enrolled and if it was completed. I also have a second table with all the training numbers (CourseNumbers), the month-day when the training should be complete and the frequency in months.
I wrote the code in the module to use as field but I keep getting the following error:
"The expression you entered as a query parameter produced this error:
'Microsoft Access cannot find the name 'CourseNum' you entered in the
expression'"
the reason for the dlookup is to find the corresponding date and frequency for the course number.
the CourseNumbers table has the following fields:
-CourseNumber
-CourseName
-Frequency (which is the month-day)
-Months (The frequency in months until the training is required again)
If anyone can tell me why and if you have a solution I would greatly appreciate it.
Image of my query with the module
Function getDueDate(CourseNum As String)
Dim yearCounter As Integer
Dim yearStart As Date
Dim yearNow As Integer
Dim monthFreq As Integer
Dim daysDue As Integer
If Not IsNull(DLookup("[Months]", "CourseNumbers", "CourseNumber = CourseNum")) Then
monthFreq = DLookup("[Months]", "CourseNumbers", "CourseNumber = CourseNum")
yearStart = DLookup("[Frequency]", "CourseNumbers", "CourseNumber = CourseNum")
yearCounter = Year(yearStart)
yearNow = Year(Date)
While yearCounter <= yearNow
yearStart = DateAdd("m", monthFreq, yearStart)
yearCounter = yearCounter + (monthFreq / 12)
Wend
daysDue = DateDiff("d", Date, yearStart)
Else
daysDue = 0
End If
getDueDate = daysDue
End Function
CourseNum is a variable. You do not include variables inside of quotes.
You also do not specify if the field CourseNumber is a text field or a numeric field, so depending on that, you want to:
Replace "CourseNumber = CourseNum" (in all 3 places):
If it's a number field, replace it with:
"CourseNumber = " & CourseNum
If it's text field, replace it with:
"CourseNumber = '" & CourseNum & "'"
Unrelated: If your field is text, then you should probably not name it something that has the word "number" in it.
Related
When looking at the possible PjAssignmentTimescaledData options (here), one that is missing that I need to extract is the Remaining Work field. Has anyone ever been able to figure out how to use VBA to extract out weekly assignments based on remaining work?
What I have is in a section of my VBA is:
ass.TimeScaleData(tsk.Start, tsk.Finish, pjAssignmentTimescaledActualWork, pjTimescaleWeeks)
but I would imagine i could replace
pjAssignmentTimescaledActualWork
with
pjAssignmentTimescaledRemainingWork
but that does not work.
Am I asking for something that just doesn't exist or looking at this whole operation in a backwards way?
Unfortunately, pjAssignmentTimescaledRemainingWork does not exist (which is annoying). To get the time phased remaining work, you need to take the value you get from pjAssignmentTimescaledWork and subtract the value you get from pjAssignmentTimescaledActualWork. Here's some sample code to get the time phased remaining work of selected tasks:
Public Sub GetTimeScaledRemainingValues()
Dim a As Assignment
Dim t As Task
Dim totalTSVs As TimeScaleValues
Dim actualTSVs As TimeScaleValues
Dim totalTSV As TimeScaleValue
Dim actualTSV As TimeScaleValue
Dim remainingValue As Double
For Each t In Application.ActiveSelection.Tasks
For Each a In t.Assignments
'get the total TSV values and store in a variable
Set totalTSVs = a.TimeScaleData(t.Start, t.Finish, pjAssignmentTimescaledWork, pjTimescaleWeeks)
'get the actual TSV values and store in a variable
Set actualTSVs = a.TimeScaleData(t.Start, t.Finish, pjAssignmentTimescaledActualWork, pjTimescaleWeeks)
'Loop through the total TSVs and try to find and substract the actual values
For Each totalTSV In totalTSVs
'Use this loop to find the actual TSV that has the same start date as the total TSV value we are currently looking at. These values will cover the same period
For Each actualTSV In actualTSVs
If actualTSV.StartDate = totalTSV.StartDate Then
'If the actual value is zero the property returns an empty string, so we have to check for this because we cannot subtract an empty string from a number, it will cause a VBA error.
If actualTSV.Value <> "" Then
'subtract the actual value from the total value to get the remaining
remainingValue = totalTSV.Value - actualTSV.Value
Else
remainingValue = totalTSV.Value
End If
'the Value property of TSV returns in minutes. divide by 60 to get the remaining hours
remainingValue = remainingValue / 60
Exit For
End If
Next actualTSV
'print out the remaining value information
Debug.Print "There are " & remainingValue & " remaining hours of " & a.ResourceName & " on " & t.Name & " between " & totalTSV.StartDate & " to "; totalTSV.EndDate
Next totalTSV
Next a
Next t
End Sub
Here's a sample of what my output looks like:
There are 16 remaining hours of Security Engineer on Create Security Requirements Traceability Matrix (SRTM) between 3/7/2021 to 3/14/2021
I have been given a list of enrollment dates for some sources for an assignment.
They want me to change the dates using vba
The question is:
"As with the previous assignment that the Director gave you, the enrollment date is in a “not normal” format. The director wants the date changed into the “normal” Danish format “DD-MM-YYYY”. You, therefore, must create a sub/function that changes the date in the field to the “correct” format. As the function needs to be able to run multiple times you should use the appropriate selection statements to check that the date is in the “not normal” format before converting it."
I have attached a picture of the excel
This function appends a 20 before the year part if its only 2 characters.
Function DateConvert(BtVal dt As String) As String
Dim parts As String()
parts = Split(dt, "-")
dd = parts(1)
mm = parts(2)
yy = parts(3)
DateConvert = dd & "-" & mm & "-" & IIf (Len(yy) = 2, "20" & yy, yy)
End Function
You might want to extend this logic, for example "65" can be replaced with "1965" instead of "2065", but I leave that part to you.
The function will test whether the string matches the pattern. If it does, it returns formatted date, otherwise it returns same cell's value.
Function GetDate(cell)
With CreateObject("VBScript.RegExp")
.Pattern = "^(\d{2})-(\d{2})-(\d{2})$"
With .Execute(cell)
If .Count > 0 Then
With .Item(0)
GetDate = Format(DateSerial(.SubMatches(2), .SubMatches(1), .SubMatches(0)), "dd-MM-yyyy")
End With
Else
GetDate = cell
End If
End With
End With
End Function
I am trying to pull all data entries that are within a userform selected month and year. I can get the code to run fine when I hard code the year but I want the year to come off of a text box. I converted the Textbox value to an integer using Cint() and dim'd it to "Year" in my if statement. I can get it to work if I write Cdate("3/1/2016"), but I want see if there is a way to run it like: Cdate("3/1/Year"). I tried it this way and get a typematch error on the Cdate Im pretty new to VBA so excuse my stupidity.
Ignore the "Month" variable I was just using that to put a stop on the code and step it through to see if it would enter my if statement.
Thanks in advance.
My Code
Private Sub OKBtn_Click()
Dim Sales As Range
Dim Year As Integer
Dim Month As Integer
Dim i As Integer
Year = CInt(YearText.Value)
Set Sales = Worksheets("Sales").Range("A4")
i = 0
If Sales.Offset(i, 1).Value >= CDate("3/1/2016") And Sales.Offset(i, 1).Value <= CDate(" 3/31/2016 ") Then
Month = 1
End If
In order for the CDate to work, you need to seperate the stings inside the brackets to 2 parts
1.The constant, in your case "3/1/".
2.And the variable, CInt(YearText.Value).
Option Explicit
Private Sub OKBtn_Click()
Dim DDate As Date
DDate = CDate("3/1/" & CInt(YearText.Value))
' for debug only
MsgBox "Date entered is :" & DDate
End Sub
I have an excel sheet, one of the columns is mixed with Dates and Dates that has been copied to it as text ( see below ).
I dont manage to convert the text type to Date type, i need to do it though VBA to add it to some automation im working on. is there a way to do this at all ?
I noticed excel is looking for format like this 03/09/2016 23:39:57 and it doesn't like 3/21/16 11:07:22 PM, apparently this is my case :) every look i run i get ( obviously data mismatch ), in the image bellow the spoken column is "C"
thx :)
ExcelSheet bad Date format
Assuming wvery bad dates are MM/DD/YYYY, then you could use the following code that I wrote for you:
Sub main()
Dim celda As Range
Dim s_date As String
Dim s_time As String
Dim validate_date As String
Dim valid_date As String
Dim date_arr() As String
Dim rango As Range
Dim limit As Long
limit = Columns("B").Find("", Cells(Rows.Count, "B")).Row - 1
Set rango = ActiveSheet.Range("B2:B" & limit)
' works only for date values, another value would return non expected values
For Each celda In rango
validate_date = Left(celda.Value, 1)
If validate_date <> "" Then
If Not celda.Rows.Hidden Then
If validate_date <> "0" Then
s_date = Trim(Mid(celda.Value, 1, InStr(1, celda.Value, " ") - 1))
s_time = Trim(Mid(celda.Value, InStr(1, celda.Value, " "), Len(celda.Value) - InStr(1, celda.Value, " ")))
date_arr = Split(s_date, "/")
valid_date = date_arr(1)
valid_date = valid_date & "/0" & date_arr(0)
valid_date = valid_date & "/" & date_arr(2)
valid_date = valid_date & " " & s_time
celda.Offset(0, 1).Value = CDate(valid_date)
End If
End If
End If
Next celda
End Sub
In order to use this code you should insert one empty column to the right from target. Second, you should to select entire C column and run the macro.
Edit 1. Ok, this macro autoselect column B. Select column dates is not necessary now.
Excel has parsed the dates according to your Windows Regional Settings short date format. Those that it could not parse (where the month>12) it left as text. Since there was initially a difference between the date format in the text file, and the date format in your Windows Regional settings, it is likely that many of the dates that appear as dates (or as unformatted numbers) were converted incorrectly.
You have a few options:
Import the text file using the Get External Data tab From Text option on the Data Ribbon. This will open up the text import wizard and allow you to specify the date format of the data being imported.
Change your Windows Regional settings short date format to match that in the text file.
Those are probably the two simplest options. The first can be automated through VBA. The second, not so much.
Hello I am using MS Access 2007
I have a table called Extraction Line it is similar to an order line table , within this table are the two fields of concern:
Field: Tonnage:Number data type
Field: worth:Currency data type
What I want to happen is
As soon a user enters the tonnage value
In the afterupdate event for the tonnage field a Dlookup will
look at the Resource table and find the Price field (currency data type)
It then multiplies the Resource table Price value with the tonnage amount field (e.g) $50 x 5 etc, the $250 value is then added to the worth field.
So far I cannot even get success on using dlookup to get a value from the resource table
My code is in the extraction line form at the afterupdate event for the tonnage field:
Private Sub Tonnage_AfterUpdate()
Dim X As Currency
X = DLookup("[Price]", "[Resource]", "Atomic Number" = "076")
'X= Nz(DLookup("[Price]", "[Resource]", "Atomic Number" = "076"), 0)
'X = DLookup("[Price]", "[Resource]", "[Atomic number] = Form![Atomic number]") * [Worth]
I wanted to test the simple part of get a value first before doing the multiply and the rest of the requirements but keep getting Null value errors.
I think I am getting Null value errors due to this explanation
Null Value is due to...
But of course there will be no value or nothing there as I want dlookup to go get the value first then carry out the maths.
Prior to this way I tried various validation rules within the Extraction Line form but received ?Name errors.
What is the best way to achieve the above. If I can get help to point me in the right direction I can go away and attempt this.
How about:
Private Sub Tonnage_AfterUpdate()
''It is probably best not to use Currency when you do not know what will
''be returned
Dim varX As Variant
varX = Nz(DLookup("[Price]", "[Resource]", "[Atomic Number] = 076"),0) * [Worth]
If you want to refer to the look-up as a field or control and [Atomic Number] is a numeric field:
varX = Nz(DLookup("[Price]", "[Resource]", "[Atomic Number] = " _
& MyNumber),0) * [Worth]
In parts:
varX = DLookup("[Price]", "[Resource]", "[Atomic Number] = " & MyNumber)
If varX > 0 then
MyAnswer = VarX * Me.Worth
End If