Getting the value not the ID - ms-access

I have a table tblInvestigators which contains a lookup field to display a list of names
A grant may have more than 1 investigator.
A requirement of my project is to list all investigators in a single cell next to the grant details, so i'd have:
Grant A | Name A, Name B, Name C
etc.
I have a VBA module that concatenates the investigators into 1 cell as follows:
'Concat Returns lists of items which are within a grouped field
Public Function c(strID As String, strAddMe As String) As String
Static prevID As String
Static strFinal As String
Static strLastAdded As String
If (strID = prevID And strAddMe <> strLastAdded) Then
strFinal = strFinal & ", " & strAddMe
Else
prevID = strID
strLastAdded = strAddMe
strFinal = strAddMe
End If
c = strFinal
End Function
And an access query that calls it (SQL):
SELECT g.grant_id, Max(c(g.grant_id,tblInvestigators.investigator)) AS Expr1
FROM tblGrants AS g LEFT JOIN tblInvestigators ON g.grant_id = tblInvestigators.grant_id
WHERE (((g.grant_id)=6))
GROUP BY g.grant_id;
When I run this, it returns a comma separated list, but it is a list of the ID numbers from the look up column (tblInvestigators.investigator)rather than the names. How can I get the names?
Chris

It is never a good idea to use look-up fields: http://www.mvps.org/access/lookupfields.htm
It is disguising the standard way of getting the results you want, which is to use a query to join the ID to the look-up table and return the description.
Have a look at this Does MS access(2003) have anything comparable to Stored procedure. I want to run a complex query in MS acceess

Related

How to sort values in a Join function with LookUpSet in SSRS?

How can I sort the values returned from a LookUpSet function inside a Join function?
Example data:
TransNo MasterTran Item Category ModifierLevel
1001000 1001000 ItemA CategoryB 0
1002000 1001000 ItemB CategoryC 1
1003000 1001000 ItemC CategoryC 1
End result I'd like to get is "CategoryB ItemB ItemC". When I use the following combination of Join and LookUpSet, I end up getting "ItemB CategoryB ItemC".
=Join(LookUpSet(Fields!MasterTransNo.Value, Fields!MasterTransNo.Value, Iif(Fields!ModifierLevel.Value > 0, Trim(Fields!ItemDescription.Value), Trim(Fields!CategoryDescription.Value)), "LineItemDetails"), " ")
This is an expression on a cell in a table. The Row Group is set to Group on TransNo, sort by TransNo. I've tried a variety of different approach to sorting for the group, but always get the same result.
Any ideas on how I can force the order of data from LookUpSet so that it's joined in the order I want?
I ended up figuring this out by seeing other questions looking to pull distinct values only from the Join(LookUpSet()) functions and modifying it. This code is based off the useful answers from this other SO question.
Go to Report Properties
Enter the Code editor and past the following function into the Custom Code box:
Public Function JoinSortAlpha(arr As Object(), delimiter As String) As String
System.Array.Sort(arr)
Dim result As String = String.Empty
For i As Integer = 0 To arr.Length - 1
If Not arr(i) Is Nothing And arr(i) <> String.Empty Then
If result = String.Empty Then
result = arr(i)
Else
result = result + delimiter + arr(i)
End If
End If
Next
Return result End Function
Go to your expression and replace the Join() function with your new function by calling JoinSortAlpha(). My new expression looks like this:
=JoinSortAlpha(LookUpSet(Fields!MasterTransNo.Value, Fields!MasterTransNo.Value, Iif(Fields!ModifierLevel.Value > 0, Trim(Fields!ItemDescription.Value), Trim(Fields!CategoryDescription.Value)), "LineItemDetails"), " ")
Here's a breakdown of what the function is doing:
Create a new function called JoinSortAlpha which will have values passed into it from the expression. In this case, the values from the LookUpSet() function.
Sort the array passed from the function's argument. It's this sort that will make it alphabetical by default.
Create a String object called result to pass the final values to.
Evaluate the array arr and write a value to the result string for each value contained in the arr array. Values in an array are given a numeric value starting at 0 and increasing by 1. Here, we're telling the array to continue populating the result string from the first value in the array (at 0) until the last value in the array which is determined by the length of the array minus 1 (because the array starts at 0 rather than 1).
If your LookUpSet() function doesn't return any values, SSRS will show an error if we don't account for that in this JoinSortAlpha function. To deal with any potential blanks being returned, we're using an If statement to determine if the string is empty in which case it just returns nothing. Otherwise, it will return the value plus the delimiter from the end of the function (a space " " in my case).

Return Unique Records for Field

We have an access database create a csv list in an access table for each userid that logs into a computer. The problem is that if a userid logs in multiple times on one computer, than the userid is duplicated.
SO let's say this is what the table structure looks like
computer DailyUsers
ABC-123 ml12, rs12, ml12, ml12, ee13
DEF-456 zx44, aa33, zx44
And this is what I want a query to return
Computer DailyUsers
ABC-123 ml12, rs12, ee13
DEF-456 zx44, aa33
I tried using both Group By and Distinct but that looks on a row by row basis, not a field basis
How can this be achieved in Access 2013?
You can create a custom function in VBA to return only the unique users.
Add this in a VBA module:
Option Compare Database
Option Explicit
Public Function DistinctOnly(txt As String)
Dim arr, v, rv As String
Dim d As Object
arr = Split(txt, ",")
If UBound(arr) > 0 Then
Set d = CreateObject("scripting.dictionary")
For Each v In arr
d(Trim(v)) = 1
Next v
rv = Join(d.keys, ",")
Else
rv = txt
End If
DistinctOnly = rv
End Function
Usage:
SELECT Table1.[ID], Table1.[Users], DistinctOnly(Table1.[Users]) as UsersX
FROM Table1;
Input data and query results:

Expanding a number range from Access data entry form into table

I am building an inventory database that needs to track individual items. Each item has a unique number associated with it. However, we receive these items in bulk quantities, and distribute them likewise. I have set up a data entry form to input the start of the item number range, and the end of the item number range. For example, the item range would look something like this -- 1056-56701 through 1056-56800. The item number is always 4 digits followed by a dash and 5 digits. I am looking to expand the range that is put into my data entry form, so that each individual item number within the range is saved to my table. In this case-- 1056-56701, 1056-56702, 1056-56703, 1056-56704....156-56800. I also need to save the corresponding info for each item range as it is saved as an individual number. That would include things like 'date received', 'size', etc.
I have read some other responses to similar problems, but I still can't get this to function properly. Any thoughts?
An example of the design you might need:
MASTER
------
Prefix Int (primary key)
SuffixBegin String
SuffixEnd String
ItemDescription String
DateReceived Date
Size String
. . . more columns for any other data common to the entire "batch"
DETAIL
------
ID Int (primary key)
Prefix Int (foreign key, related to the same-named column in the Master table)
Suffix String (values such as "56701", "56702", etc.)
. . . more columns for whatever data you need to store about unique suffix items
You could then find data for a specific item something like this (pseudo-SQL, untested):
SELECT M.ItemDescription, D.SomeSuffixSpecificData
FROM MASTER M, DETAIL D
WHERE M.Prefix = (the Prefix you're interested in)
AND D.Suffix = (the Suffix you're interested in)
JOIN M.Prefix = D.Prefix
You can use a function like this to list and add your items:
Public Function AddBulk(ByVal First As String, ByVal Last As String) As Integer
Dim Items As Integer
Dim Item As Integer
Dim BulkId As String
' Open your inventory table.
' Set rs = CurrentDb.OpenRecordset("Select Top 1 * From Inventory")
For Item = Split(First, "-")(1) To Split(Last, "-")(1)
BulkId = Split(First, "-")(0) & "-" & Item
Debug.Print Items, BulkId
' Insert code to add one record to your inventory table.
' rs.AddNew
' rs!BulkId.Value = BulkId
' rs!OtherField.Value = somevalue
' rs.Update
Items = Items + 1
Next
' rs.Close
AddBulk = Items
End Function

MS-Access: Split content on delimiter and join with other table

I am using MS-Access 2007 and need to make a query.
I cannot modify the architecture to achieve the required result.
I need to split and join the mainTable's "RelatedMaster" (comma separated IDs) to the "Name" field (as comma separated Names in the result) in masterTable.
Table 1 : masterTable
ID Name
1 N1
2 N2
3 N3
Table 2 : mainTable
ID Name RelatedMaster
1 M1 1,2
2 M2 1,3
3 M3 2,3
Required Result : resultQuery
ID Name RelatedMaster
1 M1 N1,N2
2 M2 N1,N3
3 M3 N2,N3
Please guide on how can i solve the problem.Thanks
As you realize at this point, it is bad design, but you can use a helper function:
Public Function GetNs(ByVal MasterIds As String) As Variant
Dim MasterValues As Variant
Dim Item As Integer
MasterValues = Split(MasterIds, ",")
' Lookup Name one by one.
For Item = LBound(MasterValues) To UBound(MasterValues)
MasterValues(Item) = DLookup("[Name]", "[Table 1]", "ID = " & MasterValues(Item) & "")
Next
GetNs = Join(MasterValues, ",")
End Function
Of course, for a large Table 1, you would open it as a recordset and find the values.

parsing the first 2 parts of a string

I have a field called 'Specimen' that has entries formatted like 'CM-Z-01', 'TOR-XY-03', etc. I want to populate 2 additional fields in the same table, called 'TestType' and 'Axis', with the first two sections of the 'Specimen' entry, respectively. So 'TestType' would have 'CM' and 'TOR'; Axis would have 'Z' and 'XY'
I can do the first one just fine, with
UPDATE MechanicalData
SET MechanicalData.TestType = Left(Specimen,InStr(Specimen,"-")-1);
Is there an easy way to grab the middle portion?
You can use the Split function which returns an array with the string parts:
firstPart = Split("TOR-XY-03", "-")(0)
secondPart = Split("TOR-XY-03", "-")(1)
Make a function that you can call in your query based on this function. You cannot use Split directly as it is not supported in SQL.
Public Function SpecimenPart(ByVal s As Variant, ByVal partNo As Long) As Variant
If Nz(s) <> "" Then
Dim parts As Variant
parts = Split(s, "-")
If partNo - 1 <= UBound(parts) Then
SpecimenPart = parts(partNo - 1)
End If
End If
End Function
The parameter partNo is one-based (1 for first part).
UPDATE MechanicalData SET
TestType = SpecimenPart(Specimen, 1),
Axis = SpecimenPart(Specimen, 2);