I am using the DateDiff function, but I would like for it to give me 3 decimal places. How should my query be altered to achieve such result? -- I need this done via the query itself not a VBA function.
Date123: DateDiff('d', [startdate], [enddate])
For a line that you can just put into a query, I'd use something like the following.
Format(DateDiff("s",[DateOne],[DateTwo])/60/60/24,"#.###")
Better practice would be to create a function in a module in your db like the following. Then call it through the query. The code is more maintainable, testable and understandable.
Public Function DateDiffInFractions(DateOne As Date, DateTwo As Date) As String
Dim SecondsDiff As Double
SecondsDiff = DateDiff("S", DateOne, DateTwo) / 24 / 60 / 60 'Days/hours/minutes/seconds
DateDiffInFractions = Format(SecondsDiff, "0.000") 'Format to 3 Decimal points. Return string
End Function
Related
In MS Access I have a table with a Short Text field named txtPMTaskDesc in which some records contains numbers, and if they do, at different positions in the string. I would like to recover these numbers from the text string if possible for sorting purposes.
There are over 26000 records in the table, so I would rather handle it in a query over using VBA loops etc.
Sample Data
While the end goal is to recover the whole number, I was going to start with just identifying the position of the first numerical value in the string. I have tried a few things to no avail like:
InStr(1,[txtPMTaskDesc],"*[0-9]*")
Once I get that, I was going to use it as a part of a Mid() function to pull out it and the character next to it like below. (its a bit dodgy, but there is never more than a two-digit number in the text string)
IIf(InStr(1,[txtPMTaskDesc],"*[0-9]*")>0,Mid([txtPMTaskDesc],InStr(1,[txtPMTaskDesc],"*[0-9]*"),2)*1,0)
Any assistance appreciated.
If data is truly representative and number always preceded by "- No ", then expression in query can be like:
Val(Mid(txtPMTaskDesc, InStr(txtPMTaskDesc, "- No ") + 5))
If there is no match, a 0 will return, however, if field is null, the expression will error.
If string does not have consistent pattern (numbers always in same position or preceded by some distinct character combination that can be used to locate position), don't think can get what you want without VBA. Either loop through string or explore Regular Expressions aka RegEx. Set reference to Microsoft VBScript Regular Expressions x.x library.
Function GetNum(strS AS String)
Dim re As RegExp, Match As Object
Set re = New RegExp
re.Pattern = "[\d+]+"
Set Match = re.Execute(strS)
GetNum = Null
If Match.Count > 0 Then GetNum = Match(0)
End Function
Input of string "Fuel Injector - No 1 - R&I" returns 1.
Place function in a general module and call it from query.
SELECT table.*, GetNum(Nz(txtPMTaskDesc,"")) AS Num FROM table;
Function returns Null if there is no number match.
Well, does the number you want ALWAYS have a - No xxxx - format?
If yes, then you could have this global function in VBA like this:
Public Function GNUM(v As Variant) As Long
If IsNull(v) Then
GNUM = 0
Exit Function
End If
Dim vBuf As Variant
vBuf = Split(v, " - No ")
Dim strRes As String
If UBound(vBuf) > 0 Then
strRes = Split(vBuf(1), "-")(0)
GNUM = Trim(strRes)
Else
GNUM = 0
End If
End Function
Then your sql will be like this:
SELECT BLA, BLA, txtPMTaskDesc, GNUM([txtPMTaskDesc] AS TaskNum
FROM myTable
So you can create/have a public VBA function, and it can be used in the sql query.
It just a question if " - No -" is ALWAYS that format, then THEN the number follows this
So we have "space" "-" "space" "No" "space" "-" -- then the number and the " -"
How well this will work depends on how consistent this text is.
SSRS 2008r2
I'm trying to perform an aggregate (Sum) on a field within a GROUPing that contains an expression.
The field where I want to SUM to appear is within a different GROUPing.
I've created the following Function within Report Properties
Dim public tot_OT_Hrs As Decimal
Public Function Add_OT_Hrs(ByVal OT_Hrs As Decimal) AS Decimal
tot_OT_Hrs = tot_OT_Hrs + OT_Hrs
return OT_Hrs
End Function
Public Function GetTotal()
return tot_OT_Hrs
End Function
I've added a call to the "Add_OT_Hrs" function in the field where the expression is and this works fine.
=Code.Add_OT_Hrs(
IIF(Sum(Fields!HrsWorked.Value) > Parameters!StdWorkingHrs.Value,
Sum(Fields!HrsWorked.Value) - Parameters!StdWorkingHrs.Value + Sum(Fields!Rate1Hrs.Value)
, Sum(Fields!Rate1Hrs.Value )
)
)
Fields!Rate1Hrs.Value is the field in which the expression resides in and Fields!HrsWorked.Value is an adjacent field
However, the field where I want to total to appear I've added the following
=Code.GetTotal()
All that is returned here is 0 (zero) on every row in the GROUPing. If I initialise the Dim public tot_OT_Hrs As Decimal variable to say 1.2 then 1.2 is returned on every row in the GROUPing. The Add_OT_Hrs function isn't working as expected.
Where am I going wrong?
Thanks in advance.
Looks to me that you are converting in the wrong order and also to the wrong data type. In the code example that you used you were converting the sum to a double which is not the correct data type. There is a notable difference between a double and decimal when using custom functions.
I tested this with a very small dataset as follows
select '1.2'
union all
select '1.8'
Then applied the following custom code
Dim public total as decimal
Public Function AddTotalr(ByVal r AS decimal) AS decimal
total = total + r
return r
End Function
Public Function GetTotalr()
return total
End Function
The order of your explicit conversion is vital. You have to convert the value before you sum the total so that you are working with consistent data types.
=code.addtotalr(sum(cdec(Fields!ID.Value)))
Even with the correct data type the this will produce an error because you are attempting to sum what is, most likely, being interpreted as a character string.
=code.addtotalr(cdec(sum(Fields!ID.Value)))
-----------edit ------------------------
As a test to see what the return on the function is change your function to
Dim public total as decimal
Public Function AddTotalr(ByVal r AS decimal) AS decimal
total = total + r
return total
This should give you a running total of the items processed and the last value in the list should match what your total should be.
I decided to do this in the proc.
It works out quite well now.
I am trying to create a custom function by referencing the Excel Object Model. By first going to Create/Module/Tools/References/ and selecting Microsoft Excel 15.0 Object Library (Access 2010) I was able to allow Access to bring-in the Excel Object Model. From there, I created a basic function in Acces using the Excel functions ACOS and COS. I was then able to run this function in my Query without issue. Here is the function:
Public Function myTestFunction(x As Double) As Double
myTestFunction = Excel.WorksheetFunction.Acos(Cos(50))
End Function
This test function is generally meaningless to me, but was a good first step in achieving my ultimate goal. The next step was to reference a column in my Query within the function itself. Basically, I want to replace the 50 value with each row in my Query column [LAT]. Here is what I've tested:
Public Function myTestFunction(x As Double) As Double
myTestFunction = Excel.WorksheetFunction.Acos(Cos([Queries].[Data Query]![LAT]))
End Function
After attempting to run this function in my Query I receive the following error:
Run-Time Error 424
Object Required
My question is, how can I reference the Query column [LAT] within my function?
Revise your function to operate on its x argument.
Public Function myTestFunction(x As Double) As Double
'myTestFunction = Excel.WorksheetFunction.Acos(Cos(50))
myTestFunction = Excel.WorksheetFunction.Acos(Cos(x))
End Function
Then you can use the function in a query and give it your [LAT] field value.
SELECT dq.[LAT], myTestFunction(dq.[LAT])
FROM [Data Query] AS dq;
In short: I have a user-created function (gettargetTemp(targetTemp_input) with one input that, upon function evaluation, I would like to be able to call the function in an Access query (design view) criteria field and have it represent the criteria string that I want evaluated when the query is run.
i.e. targetTemp_input = 1450 - this value is assigned from a form (and can vary)
Access Query
Field: Pad Temp
Criteria: gettargetTemp("targetTemp_input")
Criteria possibilities:
- Records within 100 degrees of the targetTemp_input value which
typically in Access query design is: Between 1350 and 1550 Or Is Null
- All of the records
The code that makes sense to me is:
Public Function gettargetTemp(targetTemp_input)
If Forms![Parameter Confirmation].tempCheck = True Then
gettargetTemp = "Between " & (targetTemp_input - 100) & " AND " _
& (targetTemp_input + 100)
Else
End If
End Function
The outcome of this typically results in a data mismatch error from Access. Is there a way to accomplish what I'm trying to do? Or maybe do it better? I'm not a programmer, but I have a pretty good technical background.
At present, you're trying to have the VBA function form an expression that does the wanted test, rather than doing the test itself. You need to change that:
Function IsTempOK(Temp) As Boolean
Dim ParamForm As Access.Form, TargetTemp As Long
Set ParamForm = Forms![Parameter Confirmation]
If ParamForm.tempCheck Then
If IsNull(Temp) Then
IsTempOK = True ' or False, if that's what you want
Else
TargetTemp = ParamForm.TargetTemp ' or wherever this is defined
IsTempOK = (Temp >= TargetTemp - 100) And (Temp <= TargetTemp + 100)
End If
Else
IsTempOK = True
End If
End Function
In the query definition, the WHERE clause should now use IsTempOK, passing the Temp field as the parameter.
Can anyone tell me how to display all the selected value of my multi value parameter in SSRS report. When giving parameter.value option it gives error.
You can use the "Join" function to create a single string out of the array of labels, like this:
=Join(Parameters!Product.Label, ",")
=Join(Parameters!Product.Label, vbcrfl) for new line
I didn't know about the join function - Nice! I had written a function that I placed in the code section (report properties->code tab:
Public Function ShowParmValues(ByVal parm as Parameter) as string
Dim s as String
For i as integer = 0 to parm.Count-1
s &= CStr(parm.value(i)) & IIF( i < parm.Count-1, ", ","")
Next
Return s
End Function
Hopefully someone else finds this useful:
Using the Join is the best way to use a multi-value parameter. But what if you want to have an efficient 'Select All'? If there are 100s+ then the query will be very inefficient.
To solve this instead of using a SQL Query as is, change it to using an expression (click the Fx button top right) then build your query something like this (speech marks are necessary):
= "Select * from tProducts Where 1 = 1 "
IIF(Parameters!ProductID.Value(0)=-1,Nothing," And ProductID In (" & Join(Parameters!ProductID.Value,"','") & ")")
In your Parameter do the following:
SELECT -1 As ProductID, 'All' as ProductName Union All
Select
tProducts.ProductID,tProducts.ProductName
FROM
tProducts
By building the query as an expression means you can make the SQL Statement more efficient but also handle the difficulty SQL Server has with handling values in an 'In' statement.