Access-VBA - Compile Error with ConcatRelated - Previously worked - ms-access

I'm receiving a compile error attempting to run a query using Allen Browne's ConcatRelated function.
Compile error: in query expression 'SELECT MbrNbr, EventIndex, ConcatRelated("EventIndex", "PlayerResults", MbrNbr = 123456)'.
The mystery is I know this executed successfully previously.
Note: This is my first time using MS Access for a project, so it's my first time using Allen's ConcatRelated function. I have to assume there is something obvious I'm missing. I've coded in MS Excel VBA for about 10 years.
I do have a query that is more complex than the example below but I put together this very basic query just to test if there is something amiss with my setup all of a sudden.
I've googled all I can to attempt to resolve this and all code examples seem to show I have it correct.
Setup:
ConcatRelated is saved as a function named Concat_Related_Data. I've read the function name cannot be ConcatRelated.
The simple query receiving the error is:
SELECT MbrNbr, EventIndex, ConcatRelated("EventIndex", "PlayerResults", MbrNbr = 123456)
FROM PlayerResults;
Note: I copied Allen's example and simply edited it with a call to one of my tables. Field MbrNbr is defined as "Number".
Any insights would be greatly appreciated!

After taking a look here http://allenbrowne.com/func-concat.html I saw that the third parameter is defined as a string parameter too (as expected) and not as a boolean.
So I think you should use this:
SELECT MbrNbr, EventIndex, ConcatRelated("EventIndex", "PlayerResults", "MbrNbr = 123456") FROM PlayerResults;
Info: The third parameter of ConcatRelated also is a string here, containing your condition.

In addition to the answer provided by #UnhandledException; where you state:
ConcatRelated is saved as a function named Concat_Related_Data.
I've read the function name cannot be ConcatRelated.
For clarity: the code for the function should be copied "as is" from Allen Browne's site into a new VBA module, without changing the function name.
However, when saving the VBA module, the module should be named something different to ConcatRelated, else you will receive a type-mismatch error when trying to invoke the function.
Note that if you are using the code within SQL code that is represented using a string in VBA, you will need to either escape the double-quotes (to ensure that they remain in the SQL code), or use single-quotes instead, i.e.:
CurrentDb.OpenRecordset("SELECT MbrNbr, EventIndex, ConcatRelated('EventIndex', 'PlayerResults', 'MbrNbr = 123456') FROM PlayerResults")
Or:
CurrentDb.OpenRecordset("SELECT MbrNbr, EventIndex, ConcatRelated('EventIndex', 'PlayerResults', 'MbrNbr = 123456') FROM PlayerResults")

Related

Access 2010: How to convert erroneous value to null or blank?

I am doing a simple select query in Access 2010 using the design view. My source file is an excel worksheet that I have linked to a table in Access. I can view the source, but am not able to modify it in any way.
One of the columns in the source file can have the following error: "#NAME?"
When I see an error, I just want to read the value in as an empty string "", but when there isn't an error, I just want the value. I've researched different variations of using Nz, IIF, Switch, and IsError but haven't had any success yet.
I am trying the following code in the "Field" parameter in design view.
Program_Temp: IIf(IsError([Program]), "", [Program])
This fails because IIf evaluates both the "truepart" and the "falsepart" so even if the error is properly detected, the function will be in error because "[Program]" is still evaluated.
Is there a way to achieve this?
The Excel will pass the values as string to the access.
Now you just have to use the replace the error with empty string.
Replace ( string1, find, replacement, [start, [count, [compare]]] )
Replace ( Program_Temp, "#NAME?", "" )
or
Replace ( Program_Temp, "#NAME?", vbnull )
Also I will suggest the same thing as #serakfalcon. Import the table, not link it, and when new info is needed, delete the data and import new data. A nice side-effect of this is that errors will be replaced by null.

failed to lock variable during move and rename of files in SSIS

Newbie question. I believe this is one of the most common errors. I found several of them on msdn forum itself but probably there are many ways on achieving this error? Please help.
I am trying to move and rename some images from one folder to another (and yes I have seen the blog by Rafael Salas and many others but none of them helps).
Like moving from \server1\images\123-456.jpg to \server2\images\123456.jpg
I am using a foreach.
Source variable is built dynamically. In the first iteration #imagePath = \server1\images\123-456.jpg ( i checked using messagebox.show)
I have defined #remoteImagePath = \server2\images\ (which never changes) and #revisedImageName = 123456.jpg (built dynamically in script task using string replace - also checked using messagebox.show)
In FileSystem Task, I am using SourceVariable as #imagePath and using Expressions to define Destination as in #[User::remoteImagePath] + "\" + #[User::revisedImageName]
Dont know for what reason, I am getting this error
Failed to lock variable "\server2\images\123456.jpg" for read access with error 0xC0010001 "The variable cannot be found. This occurs when an attempt is made to retrieve a variable from the Variables collection on a container during execution of the package, and the variable is not there. The variable name may have changed or the variable is not being created.".
Set the IsSourcePathVariable to True and set the SourceVariable to a SINGLE variable.
If you use the expression editor to set Source using multiple variables, or anything else apart from a SINGLE variable it will not work. If you want to concatenate hard-coded strings to variables, or multiple variables, do this by creating a new variable in the package, and use the Expressions tab in the variables tab to build the variable as a single variable.
I believe expressions editor needs syntax
#[User::remoteImagePath] + "\\" + #[User::revisedImageName]

VBA functions not working, returns error

I have a problem that I have been trying to solve for a couple of days with MS Access and a VBA function.
To start I have a table as follows
Name = Team
fields are mostly text bases, unless stated otherwise
ID(autonumber primary key)
Non
Prenom
Location
TeamID (created by concatenting the Nom, Prenom and Location fields)
On my form I would like to extract the partial details entered into the Nom, Prenom, and Location fields. Then pass this back to the Database to enter into the TeamID field for the individual.
The extraction should take the form of
TeamID = mid(Location,0,4) & mid(Prenom,0,2) & mid(Nom,0,2à)
However I realise that I can't put this into the 'controle source' section of the properties for any field.
So after much searching I decided that I should use a function in a separate module (I do this concatenating quite often for creation of 'sensible' index values on a large number of my tables, I find the autonumber primary key not very user friendly, or self explanatory.
So in my database file I created a module (called getInfo) with the public function
Public Function getID() As String
Dim r As String
Dim i As String
i = "Twenty"
Below are some of the options I have tried....
'r = VBA.Strings.UCase$(String:=i) 'turning the value of i to uppercase
getID = r 'returns "TWENTY" as expected
or
'r = VBA.Strings.Mid$("TWENTY", 0, 2)
getID = r 'error and highlights above line?
or
'r = StrReverse(i)
getID= r 'again error and highlights above line
getID = VBA.Strings.Mid$(String:="TWENTY", Start:=0, Length:=2)
End Function
I then opent eh 'execution' window and run the function.
I seem to be only able to convert the value to upper or lower case, any searching or manipulation of the string just gives me a message bow with the following error
Execution Error '5'
argument or procedure call incorrect
(please bear with me I am working on a french terminal and so my translation of this error may not be very acurate).
However all the functions come up correctly when I type them, as do the parameters being passed. when I search the net the info is also the same
http://www.techonthenet.com/excel/formulas/index_vba.php
So I am lost as to where I am going wrong.
I guess I am not declaring the value of my variables correctly, but I can't see why.
This code doesn't work elsewhere (other terminals) either, so I'm sure it must be my error!
But what is it.
I feel that this is a reallybasic problem, but just can't get the function to work when manipulating a string.
Do I need to call this function from a sub only, and not directly, will this be the same on my form page?
I can create a minidatabase with just this code in if required.
You should not need the VBA.String namespace prefix, and the ArgName:= syntax is optional so long as you follow same-order rules for optional paramaters.
Mid$("TWENTY", 0, 2) fails because in VBA strings start at index 1, so Mid$("TWENTY", 1, 2) would return TW

Is there an equivalent to the SUBSTRING function in MS Access SQL?

I want to do something like this within an MS Access query, but SUBSTRING is an undefined function.
SELECT DISTINCT SUBSTRING(LastName, 1, 1)
FROM Authors;
You can use the VBA string functions (as #onedaywhen points out in the comments, they are not really the VBA functions, but their equivalents from the MS Jet libraries. As far as function signatures go, they are called and work the same, even though the actual presence of MS Access is not required for them to be available.):
SELECT DISTINCT Left(LastName, 1)
FROM Authors;
SELECT DISTINCT Mid(LastName, 1, 1)
FROM Authors;
I think there is MID() and maybe LEFT() and RIGHT() in Access.
I have worked alot with msaccess vba.
I think you are looking for MID function
example
dim myReturn as string
myreturn = mid("bonjour tout le monde",9,4)
will give you back the value "tout"
I couldn't find an off-the-shelf module that added this function, so I wrote one:
In Access, go to the Database Tools ribbon, in the Macro area click into Visual Basic. In the top left Project area, right click the name of your file and select Insert -> Module. In the module paste this:
Public Function Substring_Index(strWord As String, strDelim As String, intCount As Integer) As String
Substring_Index = delims
start = 0
test = ""
For i = 1 To intCount
oldstart = start + 1
start = InStr(oldstart, strWord, strDelim)
Substring_Index = Mid(strWord, oldstart, start - oldstart)
Next i
End Function
Save the module as module1 (the default). You can now use statements like:
SELECT Substring_Index([fieldname],",",2) FROM table
I used an update query as follows: I added to my access table one empty column for the string element I needed. Then I filled the new column with an update query with this logic in the "UpdateTo" line: "Mid([TABLE].[FIELD],3,1)" as I needed exactly the 3 character of the field. The preceding answers took me here (thanks).

Custom code in Reporting Services report

In Reporting Services I would like to add a parameter that contains data from a custom code block. Ideally, I would be able to run the following code (this is a simple testing example):
Function GetPeriods() As String()
Dim values As System.Collections.ArrayList =
New System.Collections.ArrayList()
For i as integer = 1 to 24
values.Add(i)
Next
Return values.ToArray()
End Function
and put the following in the "Text Field" of the parameter:
=Code.GetPeriods()
However, when I run the report, the parameter I apply this to is disabled and empty. Is there a different technique that should be used? Or am I doing something wrong?
If you're using SQL 2008 Reporting Services then you can have a look at this page which introduces the concept of using custom assemblies.
If you're using SQL 2005 Reporting Services then this link is the one you want.
It's a mostly trivial thing, simply compile your code into a class library and follow the instructions provided to allow your report to reference it.
You are returning an array item (an array of strings) into a text field. Instead, try returning a plain string. That should work. If you would still like to return an array list, you must basically bind it to a list control in your RDL. You can definitely do that with dataset extensions. However, I am not sure if there is any other easy way. Check the proprties of the list control and see if it allows you to directly bind to an array list.
You can create the same stored procedure on SQL Server and load parameter values from that procedure.
To access your members/functions implemented in custom code of SSRS report you should set the access modifier to "Public":
Public Function GetPeriods() As String
...
see article Writing Custom Code in SQL Server Reporting Services
I've been trying to do this same thing, set a simple list of parameter values from report code. None of the links in any of these answers shows how to do this and after quite a bit of digging around I don't think it's even possible. Yes it is possible to get the values from a database query, from a web service, or from a custom assembly, but each of these creates a lot of overhead compared to getting the list from a simple function call like =Code.GetValues(), where the function uses a For loop to create the values.
msvcyc is correct in pointing out that the parameter is expecting a string value, but the function is returning an array. I changed the return type to Array as suggested by prashant sable, but the select list is still grayed out, it does not work. And coldice is correct in saying that the access modifier should be Public.
In my digging around I found an article by James Kovac from 2005 that pointed out why this is not possible. The Parameters class has a get method, but no set method. In the VS 2008 object browser for SSRS 2008 the object name has changed, but it still does not contain a set method (see Microsoft.ReportingServices.Interfaces.IParameter.Name or .Value).
My current workaround is to just hard code the list of values, but if your value list needs to be dynamic then your only choices are database queries, web services, or custom assemblies. I think the easiest workaround of these three is to get the values from the database engine, as suggested by oleksiy.t, as long as you can write a query to return the value list you want. Your list of integers, or my list of time intervals, would both be easy queries to write. Otherwise you will need to use one of the other two workarounds.
I checked your code. The only thing that's wrong is your function returns String(). When I changed your method signature to return Array, it worked fine, in my report.
Change the signature to Function GetPeriods() As Array
Everything I've seen requires parameters and their respective settings to be part of the RDL.
That being said, if you're going to "hardcode" the values, you could create a dataset just for the report, perhaps in XML, or if it needs to be programmatically driven, do it in a web service.