I have a list of names in my database that should have a corresponding Table named after it. I would like to have a check in the adjacent column that checks if the Table actually exists.
I could technically achieve this through code but was just wondering if a calculated field can achieve the same results.
ID TableName Exist
1 Cat TRUE
2 Dog TRUE
3 MooMoo FALSE <---Table does not exist in db
You can't.
You'll need a user defined function, UDF, to check for the table, while only native functions can be used in the expression for a calculated field.
Related
I have a two table scenario with a typical parent / child relational setup:
tblGroup - idGroup (autonumber, PK); GroupName (Short Text), Rank (Number)
tblRange - idRange (autonumber, PK), idGroup (FK -> tblGroup.idGroup), RangeName (Short Text), Rank (Number)
What I am doing on the parent (tblGroup) table is using a data macro to add the rank using the BeforeChange event:
IF
IsInsert
SetField - Rank
- DMAX(Rank, [tblGroup])+1
This works nicely and I can happily use a parametized INSERT query to add rows to the table and not have to worry about duplicate ranks and so forth.
What I would like to be able to do but cannot figure out how, is to have a data macro do the same thing for the child (tblRange) table, with the rank being set to the new highest for the parent group the child record belongs to.
If I use the same DMAX approach as I have above I am supposed to be able to set a criteria as a third option, acting like a where clause, to limit the lookup / calculation. How can I refer to the specific idGroup I am working with in tblRange in the macro? I cannot seem to figure out how to reference the new records value for this in the macro.
Something like DMAX(Rank, [tblRange], ???How_to_refer_to_idGroup_Properly???)+1
Any help greatly appreciated
Cheers
The Frog
I figured out a way to do this. Thankyou caffeinated beverages!
The reason for the strange error messages is due to limitations in the Data Macro processing, specifically in the BeforeChange event. The solution is as follows:
Create a query that selects MAX rank (MaxRank) and GROUP BY for the idGroup (ParentID)
The resultant query produces two columns of data: [MaxRank] and [ParentID]
There will be a row for every idGroup with the maximum Rank for each
Create a BeforeChange data macro
Set the following:
IF IsInsert
LookupRecord
Lookup Record In - qryGetMaxRank (or whatever you called your query)
WHERE - [qryGetMaxRank].[ParentID] = [tblRange].[idGroup]
Set Field
Name - [tblRange].[Rank]
Value - [MaxRank] + 1
The BeforeChange event cannot handle parameters for a query, and I am guessing that this applies in some form the to DMAX function here too. The use of a query that does not use any parameters, and then using the LookupRecord WHERE clause to do the filtering provided the single row result needed. The [MaxRank] value from the returned result is then able to be used to set a new value for the field.
Bit of a workaround but it does allow someone to work with the data either through a form or through the datasheet view and not create a problem.
**In answer to if this is a multi-user DB - it is not. It is just me working with it. If / when the solution is scaled up to something requiring multi-user I will likely recreate the BE in SQL Server or MySQL and use stored procedures for all data I/O. Happy to keep Access as the FE and compile into an application (using the runtime for clients), but I am a fair way off from having to do that yet. Very early stages of development at this time.
Cheers to everyone for the pointers. They helped me figure this out. Hopefully this will be of use to someone else in the future.
PS: If you need to use a parametrized query in a data macro it looks like the best bet is with the AfterInsert event or AfterUpdate event as they can support parameters.
I am using a SSIS Data Flow Task to transfer data from one table to another. Column A in Table A contains a number, the last 3 digits of which I want to store in Column B of Table B.
First I'm trying to grab all of the data in Column A and store in a variable via a simple SELECT statement SELECT COLUMN_A FROM TABLE_A. However, the variable stores the statement as a string when I want the result set of the query. I have set the EvaluateAsExpression property to False but to no avail.
Secondly I want to be able to use the result of this query in the Derived Column of my Data Flow to extract the last 3 digits and store the values in Column_B in the destination. The expression I have is:
(DT_STR,3,1252)RIGHT(#User::[VariableName],3)
I want to store this as a string hence the (DT_STR,3,1252) data type.
All I'm getting so far in Column_B of Table_B is is the last 3 characters of the SELECT statement "E_A". There is a lot of useful information on the web including YouTube videos for things like setting file paths and server names as parameters or variables but I can't see many relevant to the specifics of my query.
I have used an Execute SQL Task to insert row counts from flat files but, in this example, I want to use the Derived Column tool instead.
What am i doing wrong? Any help is gratefully appreciated.
I prefer to do all the work in SQL if you aren't doing anything else with that number.
select right(cast(ColA as varchar(20)),3) from tableA
-- you can add another cast if you want it to be an int
use that in an execute sql to result set = single row.
Map that to a variable.
In a derived column in data flow you can set that variable to the new column.
Thanks KeithL thats one solution I will use in future but I found another.
I dropped the variable and in the Expression box of the Transformation Editor did:
(DT_STR,3,1252)RIGHT((DT_STR,3,1252)Column_A,3).
In my question, I failed to cast Column_A from Table_A as a string. The first use of (DT_STR,3,1252) simply sets the destination column as a string so as not to use the same data type as the source which in my case was int.
Its the 2nd use of (DT_STR,3,1252) that actually casts Column_A from int to a string.
Hoping someone can assist here, I'm fairly new to SQL but yet the most experienced person in the office so this job has fallen to me.
I'm trying to build a form that will insert customer orders into production scheduling. The form allows users to select a machine from the machine list table, however what I need it to do after that is find the last job number for that specific machine and show the next sequential number in a text box; and that's where I'm stuck. The goal is that when the production user is adding an order to the database, by selecting their machine the next available job number is automatically populated. The information entered will be saved to a master scheduling table.
I've got a query built that pulls the entire list of machine and job combinations, as my goal was to build a macro that could search from that list, but so far I haven't gained any traction. Any help/advice would be appreciated!
Welcome to SO.
My suggestion would be to create a table to hold the sequence numbers. For the sake of this example, let's call it ProdSeq, which means Production Sequences. As part of this table definition, I would use Data Macros (Access 2010 and up) in order to assign the sequences as records are added. I would use a Unique index in order to ensure no duplicates are created.
Table: ProdSeq (Field Definitions)
MachineID (Number - Long) - References Machine ID in Machines Table
ProdSeq (Number - Long) - Incremented for each machine
OrderID (Number - Long) - References Order ID in Orders Table
Indexes
Under the Design ribbon tab when designing the ProdSeq table, click the Indexes button.
Create an Index called UniqueKey
Row 1: Index Name = UniqueKey, Field Name = MachineID
Row 2: Index Name = Leave Blank, Field Name = ProdSequence
Click on Row 1, Column 1 and set the following Index Properties:
Primary = Yes
Unique = Yes
Ignore Nulls = No
Data Macros
Under the Design ribbon tab when designing the ProdSeq table, click the Create Data Macros button, and then the Before Change button. Enter the following data macro: (Pastebin link)
Create the Before Change data macro and set it as follows:
If [IsInsert] Then
SetLocalVar
Name LatestProdSequence
Expression = 0
Look Up A Record In ProdSeq
Where Condition =[ProdSeqLookup].[MachineID]=[ProdSeq].[MachineID] And
[ProdSeqLookup].[LatestSeq] = True
Alias ProdSeqLookup
SetLocalVar
Name LatestProdSequence
Expression =[ProdSeqLookup].[ProdSequence]
SetField
Name ProdSeq.ProdSequence
Value = [LatestProdSequence]+1
SetField
Name ProdSeq.LatestSeq
Value = True
End If
Pay special attention to the fact that only one SetLocalVar is within the LookUpRecord clause. Use the collapse / expand (-/+) button on LookUpRecord to make sure.
Create the After Insert data macro and set it as follows: (Pastebin Link)
For Each Record In ProdSeq
Where Condition = [ProdSeqFlagFix].[MachineID]=[ProdSeq].[MachineID] And
[ProdSeqFlagFix].[LatestSeq]=True And
[ProdSeqFlagFix].[ProdSequence]<>[ProdSeq].[ProdSequence]
EditRecord
SetField
Name ProdSeqFlagFix.LatestSeq
Value = False
End EditRecord
Test it Out
You can create this in a blank database in order to see what I am talking about. You should be able to adapt it to your specific situation.
Form
On your form, when the user selects a machine and order, you can use VBA in order to check for an existing record in ProdSeq, and fetch the ID. If no record exists, then you can create one, and then return the ProdSeq ID to the form.
Note: Depending on your design, you may also need to create a Data Macro on the Schedules table. Suppose someone creates a schedule with a specific machine and order and reserves a production slot. Now assume they change the Order ID .. we have a production slot reserved in error. So if this applies, you'll also need an AfterUpdate data macro on the Scheduling table that checks to see if [old].OrderID <> [Schedule].OrderID - and if they do differ, to remove the Production slot from the schedule table and the Prod Sequence table.
As I understand, you need to add suggested value for job number when you add new record to the table. If so, you can use, for instance DMax function. Here is example of VBA code for this, it can be called when you add new record:
Me.MyTextBox = DMax("JobField", "JobsTable") + 1
I supposed that JobField, which contains job numbers has Number data type.
Also you can use this function inside any query as a calculated field.
I'm trying to create a validation rule in Access 2010 to set the value of a true/false field to True...
More details, I have a table with several yes/no fields and one true/false field and I want the true/false field to change to true only if all the yes/no fields are yes.
I'm trying to make it that it is set automatically after updating the fields and without the user changing it...
A Validation Rule can not alter a field's value. It can only indicate whether or not that value should be considered valid.
If you want a field which automatically updates itself to indicate whether other fields are all True, consider a calculated field or a data macro. Since you're using Access 2010, both those options are supported.
However, a simpler approach would be to decide you don't need that summary field to exist in your table design. You could use a query to derive it whenever you need to see it.
For example, with two Yes/No fields Fld1 and Fld2, a simple field expression will tell you whether both are True ...
SELECT Fld1, Fld2, (Fld1=True AND Fld2=True) AS all_are_true
That would present True as -1 and False as 0. If you want the query to show those values as True or False, you can use a Format expression ...
SELECT Fld1, Fld2, Format((Fld1=True AND Fld2=True), 'True/False') AS all_are_true
That computation is a trivial workload for the db engine. And computing the field expression each time you run the query ensures all_are_true reflects the latest changes to the other fields.
I've got two tables binded to two different datasets. I'm trying to reference one of the rows from one of the tables (Table A) from Table B.
Since it's outside the scope of the table, I can't use ReportItems![Textbox name].Value
Any ideas?
You can use the SSRS Lookup() or LookupSet() function to retrieve the data directly from the other dataset.
I found the MSDN pages a bit unclear, the syntax goes like this:
=LOOKUP(Fields!sourceMatchingField.Value,
Fields!targetMatchingField.Value,
Fields!targetReturnField.Value,
"Name of Second Dataset"
)
Fields!sourceMatchingField.Value is from the dataset that is
currently in scope.
Fields!targetMatchingField.Value is from the other data set you need to get information from and equals Fields!sourceMatchingField.Value.
These two parameter values for the Lookup function make the join criteria for the two datasets. They can be more complicated than simply two field references (such as using functions to manipulate on or both), but I'm just showing the simplest way to do it.
Fields!targetReturnField.Value is the field from the second dataset that you want to return. This should just be a reference to a field.
"Name of Second Dataset" is just what you've named the other dataset that you're joining to.