VBA function call - ms-access

Is there a way to call a function, where the call is stored in a table
**Record 1 task Function call**
124567 Email customer Call function emailcus(a,b,c,d)
434535 AddCost Call function addcost(a,b,c,d)
Cheers
Graham

Yes, you can use the Eval() function for that.
Syntax:
Dim ReturnValue As String
ReturnValue = Eval("MyFunction(1, 2)")
Note that you have to provide the exact function call including parameters.
I'm pointing this out because I'm not sure if the parameters a, b, c, d in your example are only dummy values for your example, or if you expect VBA to fill in the values of some variables named a, b, c, d automatically.
The Eval function does not do this, so if you need variable values as parameters, you would have to do something like this:
Dim ReturnValue As String
Dim EvalString As String
EvalString = "MyFunction(" & Variable1 & ", " & Variable2 & ")"
ReturnValue = Eval(EvalString )

This is a variation on the answer already given by haarrrgh, so if you find it useful be sure to upvote that one as well.
There's another way to deal with placeholders in your DB-stored function calls. First, change your data thusly:
**Record 1 task Function call**
124567 Email customer Call function emailcus([TokenA],[TokenB])
434535 AddCost Call function addcost([TokenA],[TokenB])
Note that the [SquareBrackets] are not actually required syntax in this example, just something that I tend to use in this situation. The important part is to make the parameter tokens something that doesn't appear elsewhere in the string value (including other tokens). You can use as many parameters as you need, just make sure that the calling code knows about how many are expected by each function-call string (I cut it down to shorten my following code).
Then when it's time to call your function, do this:
Dim ReturnValue As String 'or as appropriate for individual the function's return
Dim EvalString As String
EvalString = 'code to fetch from table
EvalString = Replace(EvalString, "[TokenA]", strValueA) 'strValueA passed in?
EvalString = Replace(EvalString, "[TokenB]", strValueB) 'strValueB passed in?
ReturnValue = Eval(EvalString)
In VB6, at least (so I assume it's true in VBA), Replace is faster than concatenation. I also find this more readable, but that may be because I'm used to it from using a similar technique to build SQL commands in code (using Const declarations rather than DB storage, but that would work too).
EDIT
As I reread my "finished" post just after submitting it, I realized that there's a gotcha lurking in there. Because you're doing substitution before submitting the string to Eval, these are actual values that are being put into the string, not variables. The code I presented above works fine if your parameters are numeric, but if they're String type you have to include the quotes, either in your data or in your Replace call. I prefer the former, so change your data to this:
**Record 1 task Function call**
124567 Email customer Call function emailcus('[TokenA]','[TokenB]')
434535 AddCost Call function addcost('[TokenA]','[TokenB]')
This works as tested with a Const. Stored in a DB record, you might need this instead:
**Record 1 task Function call**
124567 Email customer Call function emailcus(""[TokenA]"",""[TokenB]"")
434535 AddCost Call function addcost(""[TokenA]"",""[TokenB]"")
(which also works with a Const...).
The alternative is to leave the data as it is in my first part, & change the Replace calls:
EvalString = Replace(EvalString, "[TokenA]", """" & strValueA & """") 'strValueA passed in?
'or maybe
EvalString = Replace(EvalString, "[TokenB]", "'" & strValueB & "'") 'strValueA passed in?
A couple of other potential gotchas: These must be Functions, not Subs, and they must be declared Public in a module, not in a Form's code.

Related

Why am I getting error 3078 on my SELECT query?

I've started to try and write some VBA to execute some queries and I've got stuck at the first hurdle. This is giving an error 3078 which apparently means it can't find the table or query. The table definitely exists and is spelt properly. Indeed the SQL runs fine - I tested it. What am I doing wrong?
Public Function Tester()
str_tbl = "tblGames_atp"
str_mkvrec = "SELECT * FROM " & str_tbl
dbl_fs_pct = DSum("FS", str_mkvrec)
End Function
Cannot reference SQL statement in domain aggregate function, not even a variable set to that statement. Must reference table or query object name. Could reference variable with name string but variable not really needed in this code. If you want function to return a value to calling source, then need to set function value.
Public Function Tester()
Tester = DSum("FS", "tblGames_atp")
End Function

Use Split, Join, and another function in SSRS

I have a field in SQL Server that contains an comma separated list. Here are 2 examples:
select 'ex1,ex2,ex3' as str union all
select 'ax1,ax2'
In my report, I have to transform all of these values (5 in this case) using a function. In this question I will use Trim, but in actuality we are using another custom made function with the same scope.
I know how I can split every value from the string and recombine them:
=Join(Split(Fields!str.Value,","),", ")
This works great. However, I need to execute a function before I recombine the values. I thought that this would work:
=Join( Trim(Split(Fields!VRN.Value,",")) ,", ")
However, this just gives me an error:
Value of type '1-dimensional array of String' cannot be converted to 'String'. (rsCompilerErrorInExpression)
I can't personally change the function that we use.
How do I use an extra function when dealing with both an split and a join?
You can use custom code to include all the logic (Split->Custom Code->Join).
Make adjustments inside the loop to call your custom function instead of trim
Public Function fixString (ByVal s As String) As String
Dim mystring() As String
mystring = s.Split(",")
For index As Integer = 0 To mystring.Length-1
mystring(index) = Trim(mystring(index))
Next
Return Join(mystring, ",")
End Function
To call the custom code use the following expression
Code.fixString( Fields!VRN.Value )

Call stored procedure with an output parameter using ExecuteDataset

I need to call a stored procedure in a MySQL (5.7) database from a VB.NET application. Said procedure makes a SELECT statement at the end which I need to retrieve in my app as a DataSet. Previously it worked fine, but I added an output parameter to the stored procedure, and I get the following error when I call it:
{"Incorrect number of arguments for PROCEDURE my_database.SP_MY_PROCEDURE; expected 3, got
2"}
Here's my current VB.NET code:
Public Shared Function CallStoredProcedure(ByVal stringParam As String,
ByVal intParam As Integer) As DataSet
Try
Dim ds As New DataSet
Dim params As New List(Of MySqlParameter)
Dim arrayParams() As MySqlParameter
params.Add(New MySqlParameter("#param1", stringParam))
params.Add(New MySqlParameter("#param2", intParam))
arrayParams = params.ToArray()
ds = MySqlHelper.ExecuteDataset(connString,
"CALL SP_MY_PROCEDURE(#param1, #param2);",
arrayParams)
Return ds
Catch objException As Exception
Return Nothing
End Try
End Function
I tried adding a third parameter to the CALL statement in the string, like this:
ds = MySqlHelper.ExecuteDataset(connString,
"CALL SP_MY_PROCEDURE(#param1, #param2, param3);",
arrayParams)
but that just returns a different error:
{"OUT or INOUT argument 3 for routine gw_my_database.SP_MY_PROCEDURE
is not a variable or NEW pseudo-variable in BEFORE trigger"}
How can I accomplish this? Maybe ExecuteDataset can't be used with output parameters; at least I haven't found examples or anything. It that's the case, what's a good alternative?
You can definitely use ExecuteDataset() with output parameter. You need to make sure all the mandatory parameters are added to your parameter list including output parameter. You need to confirm the type and size where applicable and set the direction of each parameter correctly. After executing ExecuteDataset() you can retrieve the value from our output parameter.
I could not see adding the third parameter in your code (or perhaps you haven't showed that part), setting direction/type/size.

SSIS Convert Blank or other values to Zeros

After applying the unpivot procedure, I have an Amount column that has blanks and other characters ( like "-"). I would like to convert those non-numberic values to zero. I use replace procedure but it only converts one at the time.
Also, I tried to use the following script
/**
Public Overrides Sub Input()_ProcessInputRows(ByVal Row As Input()Buffer)
If Row.ColumnName_IsNull = False Or Row.ColumnName = "" Then
Dim pattern As String = String.Empty
Dim r As Regex = Nothing
pattern = "[^0-9]"
r = New Regex(pattern, RegexOptions.Compiled)
Row.ColumnName = Regex.Replace(Row.ColumnName, pattern, "")
End If
End Sub
**/
but i'm getting error.I don't much about script so maybe I placed in the wrong place. The bottom line is that I need to convert those non-numberic values.
Thank you in advance for your help.
I generally look at regular expressions as a great way to introduce another problem into an existing one.
What I did to simulate your problem was to write a select statement that added 5 rows. 2 with valid numbers, the rest were an empty string, string with spaces and one with a hyphen.
I then wired it up to a Script Component and set the column as read/write
The script I used is as follows. I verified there was a value there and if so, I attempted to convert the value to an integer. If that failed, then I assigned it zero. VB is not my strong suit so if this could have been done more elegantly, please edit my script.
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
' Ensure we have data to work with
If Not Row.ColumnName_IsNull Then
' Test whether it's a number or not
' TryCast doesn't work with value types so I'm going the lazy route
Try
' Cast to an integer and then back to string because
' my vb is weak
Row.ColumnName = CStr(CType(Row.ColumnName, Integer))
Catch ex As Exception
Row.ColumnName = 0
End Try
End If
End Sub

Removing non-alphanumeric characters in an Access Field

I need to remove hyphens from a string in a large number of access fields. What's the best way to go about doing this?
Currently, the entries are follow this general format:
2010-54-1
2010-56-1
etc.
I'm trying to run append queries off of this field, but I'm always getting validation errors causing the query to fail. I think the cause of this failure is the hypens in the entries, which is why I need to remove them.
I've googled, and I see that there are a number of formatting guides using vbscript, but I'm not sure how I can integrate vb into Access. It's new to me :)
Thanks in advance,
Jacques
EDIT:
So, Ive run a test case with some values that are simply text. They don't work either, the issue isn't the hyphens.
I'm not sure that the hyphens are actually the problem without seeing sample data / query but if all you need to do is get rid of them, the Replace function should be sufficient (you can use this in the query)
example: http://www.techonthenet.com/access/functions/string/replace.php
If you need to do some more advanced string manipulation than this (or multiple calls to replace) you might want to create a VBA function you can call from your query, like this:
http://www.pcreview.co.uk/forums/thread-2596934.php
To do this you'd just need to add a module to your access project, and add the function there to be able to use it in your query.
I have a function I use when removing everything except Alphanumeric characters. Simply create a query and use the function in the query on whatever field you are trying to modify. Runs much faster than find and replace.
Public Function AlphaNumeric(inputStr As String)
Dim ascVal As Integer, originalStr As String, newStr As String, counter As Integer, trimStr As String
On Error GoTo Err_Stuff
' send to error message handler
If inputStr = "" Then Exit Function
' if nothing there quit
trimStr = Trim(inputStr)
' trim out spaces
newStr = ""
' initiate string to return
For counter = 1 To Len(trimStr)
' iterate over length of string
ascVal = Asc(Mid$(trimStr, counter, 1))
' find ascii vale of string
Select Case ascVal
Case 48 To 57, 65 To 90, 97 To 122
' if value in case then acceptable to keep
newStr = newStr & Chr(ascVal)
' add new value to existing new string
End Select
Next counter
' move to next character
AlphaNumeric = newStr
' return new completed string
Exit Function
Err_Stuff:
' handler for errors
MsgBox Err.Number & " " & Err.Description
End Function
Just noticed the link to the code, looks similar to mine. Guess this is just another option.