I have an MS Access database we're going to use at our swimming pool to scan family passes and log usage.
Currently I have three tables, one for the Family Name and Contact Info (tblFamilyPass), another for First Names, Photos, and a unique barcode (tblPassHolders), and a third which logs usage (tblCheckIn).
I have one query that selects the Surname, Phone# and Address from tblFamilyPass that I use to create a relationship between tblPassHolders and tblFamilyPass and associate individuals with their respective Family Pass, and I'm using a form that uses a macro to scan barcodes and filter through tblPassHolders to show the record that corresponds to the barcode.
I have another query that grabs the First name and Family name from tblPassHolders that I'm using in tblCheckIn, which only has two fields: The First/Last name of the individual, and the time they check in.
Now what I'm trying to do, is modify my macro so that each time I scan a barcode, it adds a new record to tblCheckIn.
I'm pretty new to Access, so I'm still doing everything with the macro builder. So far I've only managed to get the table open and select a new record. But my attempts at using SetValue:
Returns the error:
The object does not contain the automation object 'tblCheckIn'
Inserting the time should be the easy part, my efforts to insert the name of the individual have been even less successful.
How do you insert data into one table while browsing data from another? Will I be able to insert two fields into tblCheckIn from a tblPassHolders form using macros?
Using the Macro Builder didn't work out, the solution that worked was the following bit of code using the code builder rather than the macro builder:
DoCmd.OpenForm "CheckIn"
Forms!CheckIn![PASSHOLDER] = Me![BARCODE]
Forms!CheckIn![CHECKINTIME] = Now()
DoCmd.GoToRecord , , acNewRec
There is a point where you have to move past relying on the macro builder.
Related
Access 2016, table with a AfterInsert datamacro.
In a comment to a previous question that I can no longer find, Albert D. Kallal (user:10527) noted that if one uses the Set LocalVar approach to call a user-defined function in vba, that vba "session" does not see the newly inserted record.
Even if one passes in the identity of the newly added record, any queries referencing the table where the record was just added won't see the newly inserted record.
Has anyone developed a work around so that for example in building a closure-table, the newly added record is visible or can be used?
This is very similar to the problem Alberta Kallal has nicely shared solutions for of copying over an existing record using the "after update" approach to get around being unable to create a record within a for each loop. However, in this case I would like to use the result of a query as the basis for copying / inserting, not just copying over an existing row or 'hard coding' the business logic for the modifications into the datamacro (hence would be easy to do if vba approach could see the just added row).
Specific use case is trying to create a way of inserting "induced" records in an accounting application. One earns some money that has no tax deducted, so it is nice to have an automatic journal entry created showing a future liability to pay the tax. In other words, the presence of a record in a table should automatically generate additional records - and the business logic of those additional records is defined through queries.
Even more specifically, given a "transactions" table with fields RegisterID, AccountID, Amount, TrDate, and a "Induced Transaction Queries" table that specifies the queries to provide the induced transactions with fields AutoNumberId, QueryThatDefinesAdditionalTransactions (and multiple rows, e.g. "Query That adds self", "Query That Adds Tax Liability", "Query That Computes Sales Tax Portion"),
how can a datamacro create rows in a "Transactions For Analysis" Table based on iterating over the "Induced Transaction Queries" table and inserting the results of the query in each row applied to the newly added row in the original "transactions table"
Thx
Well, while calling VBA from the macro after insert event can’t get the row just inserted, that VBA routine can read + update as many OTHER rows as you please. And if that new row or data you write out in VBA has to include the data from the row just inserted?
Well pass the columns to the VBA routine. So it now can go add up all the other rows, and THEN include the values just passed from the data macro.
So the data macro (after insert) can look like this:
And the VBA code thus can look like this:
Public Function AfterU(vid As Variant, Amount As Variant)
Debug.Print vid, Amount
Dim rst As DAO.Recordset
' open table, sum data
' add Amount passed.
' write out data to some table.
' caution - don't add reocrds to this table that has the trigger
' else you wind up in a endless loop
End Function
The above of course has to be placed in a standard code module (not forms), and has to be defined as public as per above.
So while you find that the record JUST added is not yet committed to the table (it is about to be), you can still run + call some VBA code. You just not get your hands on the record just (about to be) inserted.
However, since you can pass the needed columns such as amount etc. to include in the final total? Then you are free to write as much VBA update and insert code as you wish. So you can pull some records, build a total, and now update some existing record, or even add a new record. Just include the new amount passed also.
As noted, you don’t want to “tangle” up writing to a table that has such a trigger with VBA inserts since you can easy get stuck a endless loop.
However, for adding up, or updating, or inserting to another table, you should be fine to do what you please in the VBA code.
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 database in Access 2010, and have run into a bit of a problem. I currently have two tables, EarlyStageListResults & ESDailyTotals. Each of these tables has a field named Records, with ESDailyTotals being a summary of multiple entries in EarlyStageListResults. What I need to do is have the Records field in ESDailyTotals be the sum of multiple Records fields in EarlyStageListResults. For example, given the following records in EarlyStageListResults:
Date Records
4/22/16 2000
4/22/16 3000
4/22/16 1500
4/21/16 1200
4/21/16 2700
the records in ESDailyTotals should be:
Date Records
4/22/16 6500
4/21/16 3900
I know this can be calculated later through VBA and a form event, but optimally I'd like to be able to have it update as soon as any of the Records fields in EarlyStageListResults changes. It looks like there may be a way to do this using the Access Macro Editor (not sure of the name, but the tool where you can create a macro through a series of combo boxes rather than through VBA), but I've never gotten an understanding of using that tool, so have always relied on Forms and VBA instead. Basically if there's an event that triggers when a field is updated, and a way to enter VBA code into that event handler like you can with Access Forms, then I can do it with either DLookup or an SQL statement I think, but I don't know how to grab that event handler.
This does all need to be done within Access itself, I can't use an external program to update the records in an Access database file. This is for work, and (officially at least) any custom programs are a big no-no. :)
Thanks in advance everyone!
You're making this way too complicated. You just need one table and a database view (called a query in Access, I think) that is defined as
select Date, sum(Records) as Records from EarlyStageListResults
group by Date
Name the query ESDailyTotals.
So, i have 2 tables, let's say : Customers and Activity. Customers containing only customers and activity containing customers but also other pieces of information.
I have a form to write data in the Customers table.
What i need is the Activity table to auto-update itself each time I write an entry in the Customers table.
Is it possible to create a relationship between the two tables to do that? Or should I write something at the end of the code I use for the form?
Is it possible for instance to create a function that i call at the end of the code i use for the form?
Thanks.
If you're wanting to automatically update, independently of any form, a table based on changes made to another table, I would recommend a data macro which is new to MS Access 2010. They're pretty cool and are similar to triggers in enterprise level relational database management systems.
Open your Activity table. Under table tools create a named macro called NewRecord. Create a parameter called prmCustomer. Your macro could look like this:
Create a Record In Activity
Alias
SetField
Name Customer
Value = [prmCustomer]
Then open your Customer table. Under table tools create an After Insert Event. Your event could look like this:
RunDataMacro
Macro Name Activity.NewRecord
Parameters
prmCustomer = CustomerID
You'll have to do some playing around since you haven't given much info, but that's the gist of it.
I work with a product that comes in a 2000lb sack and placed on a pallet. When this product is made it has many different elements that are tested and each test has a field that the numerical data is placed in. Each of these records of tests are then assign a number, for example, L20444.
Now we have the ability to take that 2000lb sack and convert it into 80 20lb bags. Only 40 20lb bags can fit on one pallet, taking now the one pallet L20444 and making two pallets that have the number L20444. This causes a problem with inventory because the number L20444 can only be assign one warehouse location, not two.
So my bosses what to create a number that is almost the same, but different enough to place the second pallet in the warehouse. The second pallet will now be L20444B. It will still have all the same tested numbers and is a "copy" of the original L20444.
My question is can I take the record L20444 and copy all the data for that record and then save it as L20444B so that it can be placed in the warehouse.
So is it possible for VBA to copy a record, rename it, and then save it in the same database as a new record?
Any help would be appreciated, Thanks.
If I'm reading you right it sounds like you want a SQL statement to create a new record.
You're using Microsoft Access? I would recommend first creating a query that does this in the query editor. It will be an Append query, something along the lines of:
INSERT INTO TableA ( ID,col1, col2 )
SELECT [ID] & "B" AS NewName,col1, col2
FROM TableA
WHERE (([ID]="L20444"));
Test this first to make sure it's doing what you want, and make "L20444" into a parameter ([OldID], or something). Then add some code in your VBA script that executes this query. It should pop up asking you for OldID when you run it.
Then you'll need to learn how to execute parameterized queries from VBA.
Something like this:
Set qdf1 = CurrentDb.QueryDefs("myQuery")
qdf1.Parameters("OldID") = theOldID
qdf1.Execute
Not tested, search VBA help for QueryDefs if my syntax isn't quite right.
Why don't you create a new table, which tracks the location of the two pallets (and the new number(s)), which links back (with a foreign key) to the single record for the stock in the original table?
That should work, and will avoid what will otherwise become a nightmare of redundant data.