Multiple Queries in One Report - MS Access - ms-access

To keep this simple, lets say I have two tables.
The first is called Employees. It contains an id field and an employee_name field.
The second is called Pay. It contains an id field, an employee_id field and an amount field.
Now, I want to run a report on Pay that shows me how much each employee got paid by showing me only the Employee.employee_name and the Pay.amount.
Obviously, I'm going to have to take the employee_id field from the Pay table and match it up with the the id field from Employees, but I have no idea how to do that.
I know a little VBA and am pretty knowledgeable with SQL, but MS Access has me so confused I'm about to kill myself. I hate Access so much, I want to take it outside behind the middle school and get it dead.
This seems like a relatively easy problem, so someone has to know how to do this. Any help would be hugely appreciated.

You are looking for a query like this
SELECT Employees.Id,
Employees.employee_name,
Sum(Pay.amount) AS SumOfamount
FROM Pay INNER JOIN
Employees ON Pay.employee_id = Employees.Id
GROUP BY Employees.Id,
Employees.employee_name;
If you wish to make this as part of a list box, you can either save the sql as a query and set the Listbox property under the Data Tab called RowSource to the Saved Query Name, or you can set the sql string as the RowSource.
Remember to have a look at the Properties called Column Count ( something like 0;3;3 0 being to hide the first column ) and Column Heads (to include column headers, default NO )
If you widh to craete a Report using the data, you can go about this the same way ( Saved Query or Use the Sql String ). The Query/Sql String can be set in the Data Tab in the Record Source property. Now you can add the fields to the report from the Existing Fields window.

Related

Data filtering on form generates "Could not find field"

I spent half day trying to figure out why appears an error messagebox
Could not find field 'TransactionTypeID'
in my
database. If you open Form1, then apply any filter on column TransactionTypeID using header (for instance, uncheck Blanks) and then try to open sorting/filtering for second column, appears error message.
Error disappears if I convert combobox to text box or remove from form select table Tenants1. I use Access 2010 32 bit. In this example I simplified tables as much as possible, database created from scratch, data imported, compact/repair doesn't help.
Do you have any ideas?
I found the problem. The built-in datasheet form filtering works in a wrong way if tables joined this way:
SELECT VouchersMain1.VDate, VouchersMain1.TransactionTypeID
FROM Tenant1 INNER JOIN VouchersMain1 ON Tenant1.TenantID = VouchersMain1.TenantID;
If I reverse tables join direction, built-in filtering works fine:
SELECT VouchersMain1.VDate, VouchersMain1.TransactionTypeID
FROM VouchersMain1 INNER JOIN Tenant1 ON VouchersMain1.TenantID = Tenant1.TenantID;
Looks like this is another Access bug.
Also, thanks #Munsterlander, problem disappears if form's recordsource replaced by saved query instead of SELECT
Try referencing your field as Forms!FORMNAME!CONTROLNAME. I assume, based off what you wrote, you are trying to filter a query based on what is selected in the combobox.
Delete the table Tenants1 from your form RecordSource (this table is not necessary and do not exposes fields in the resulting query).
You would also note that your recordsource is set (by Access) ReadOnly (bad design, no join defined). Try to add a couple of Records in the Tenant1 table, say it David and Nathan.
You will find that now your query will output 6 records (and not 2), because the query (with no joins) list one row for all records of table Tenant1 (3) and one row for each record of table VouchersMain1 (2), giving a total of 2*3=6 rows.

Update single records in query with form based textbox

I am working with Access2013 and I have a query called PaidOrderQ with columns "SalesRep", "Customer" and "PaidAmount". I need to calculate the SalesRep's commission which isn't always the same percentage for each record. After reading through similar questions here I still haven't figured it out yet.
The way I thought doing it is to have a form called PaidOrderF with soucre is PaidOrderQ, a textbox called "CommRate" and a calculated field "Commission". The "Commission" gets calculated by "AmountPaid"*"CommRate".
I'm not sure how the percentage for commission is calculated, but there are a few ways this can be done depending on how the percentage is calculated. The first would be if you can calculate the percentage that will be used automatically. Then you can add everything automatically (even if the percentage changes based on the item). If this is possible you can open the query up in DESIGN view. Then click onto a blank field and you can make a calculated field for example:
Commission: [AmountPaid]*[CommRate]
Now you can add the calculation for CommRate for example:
CommRate: IIf([AmountPaid]>200,.15,.2)
Which would make any the comm rate 15% over $200 and 20% under.
If not you can make Text boxes in a form (which would be unbound and add an after update vba code to multiply them together and change the value of a third text box, label etc.)
You may also want to add a column to the original table to show commission rate so the information would be stored for future reference.
Let me know if anything is unclear or you would like to see an example of the vba code
EDIT::
Storing information to a table:
This one will be very basic and you probably know most of this, but just in case I will include it because it is the most straight forward.
Add a column to the table you are working from by opening up the table in Design view (you can also make a temporary table by using a make table query if you are using a liked table or do not want to modify the structure, but it is better to put it in the main table if possible). Here you could make a query that includes all of the fields plus the additional calculated field that shows amount paid * commission. Then when you make a form based on the query you will enter in the commission rate and the form will both save the information and automatically update the field to give commission.
Linking another table by Primary ID -
If neither of those options work you could also create another table that shares a primary ID. This option will be more complicated, but is possible. (I would recommend not making it a true primary ID for the second table so it is easier to modify (Or have a true primary ID and the ID you will use to link ie. 3 total columns)). If this is the option you need I can go into more depth, but the disadvantage of this method is if there is no CommRate listed for a given record it will automatically hide the information (it is possible to avoid this, but again will be more complicated) so it will be easy to make a mistake.
VBA coding
VBA will be the most complicated solution, and has the largest disadvantages. First - You will have to loop all of the records at one time (or at least for one employee) and when you close the form you will lose everything. If there is any way to avoid this I would suggest doing so, but you could theoretically store the information in an array.
The Standard Way -
As I understand it your table looks like this:
SalesRep Customer PaidAmount
John Eric 2040
Stacy Brian 1020
Stacy Eric 2004
etc.
You will want to open up your table in Design view and add a column "CommRate"
so it will look like:
SalesRep Customer PaidAmount CommRate
John Eric 2040
Stacy Brian 1020
Stacy Eric 2004
etc.
The data type for CommRate should be Number - type Double - Now I would use Comm rate as a percentage - ie 10.2 = 10.2%, but you could also do .102 = 10.2% either one is fine (more on that later) save and close the table.
Now with the table selected use the create query wizard add all of the fields to the query, give the query a name and click modify the query at the end (or save it then open it up in design view). Now you will see each field in a column with the table listed below. Copy and paste the entry below to your query in one of the bank "field" locations:
for percentage ie 10.2=10.2%
Commission: [CommRate]*[PaidAmount]/100
for .102 = 10.2%
Commission: [CommRate]*[PaidAmount]
Now save and close the query.
Lastly you will select the query then click on create form. This will make a form based on the query. With this form you can add the CommRate individually and it will be saved for the future. You will see that when you add the CommRate the Commission field will automatically update and the table will get updated with the new value.
This is the standard way of doing this. Does this work for what you are doing?
Alright well that is good news! The primary key will help a lot:
Ok here is how you can solve this with two tables.
First create a new table with three columns:
"ID" - Primary Key "RelatedID" - Number Long Int "CommRate" - Number Double
This table will basically just be used to "add on" the CommRate without changing the linked table.
Next you will make a query that includes "SalesRep", "Customer" and "PaidAmount" from the linked table AND the "RelatedID" and "CommRate" from the new table.
When you view the query in design view you will see both tables above the list of the different fields and you will click on the primary key from the linked table and drag it to the "ReatedID" in the new table. From here it will open up a dialog asking about the relationship join. This part is the most important - You want to make the relationship a LEFT JOIN - You do this by saying you want to show ALL records from the Linked table and only the record from the New table that match. Basically this makes it so it will always show the records from the new table even if there is no entry that matches in the new table.
After you have that created you will just make a calculated field as before by copying:
Commission: [CommRate]*[PaidAmount]/100
to a new field on the query design
From here everything is set up and you can create a form based on the query you just made - I would delete the field "RelatedID" from the FORM (or the Query the relationship is what links it so its not necessary it is just a good double check) so you don't change it.
How it works - Now when you cycle through the entries you can add the commission rate directly to the form. - This will make a new entry in your new table that shows the primary ID of the transaction and the commission rate for that sale. This will update the calculated field and show you the commission. Then when you view it it will save the values individually without changing your original table.
Keep me posted if you need more help on how to do this. It can be a little tricky the first time you do it.

Abbreviate values in report field in Access

I have a 2010 Access database that tracks volunteers for a charity group.
One of the columns in the VOLUNTEER table is called AVAILABILITY and the possible values are "seasonal" and "year-round".
I have created a report that lists out all the volunteer information, and it includes this column. The only problem I have is that I'd like to have the report abbreviate the values. Ideally "S" for seasonal and "YR" for year round in order to save space on the report. Is this possible?
Yes, of course. You can either do it in a query and base the report on that or in the report itself:
SELECT IIF([AVAILABILITY] = "Seasonal","S","Yr") As Avail
FROM MyTable
If you wish to set the control in your report, make sure to rename it to something other than Availability, say txtAvailability:
= IIF([AVAILABILITY] = "Seasonal","S","Yr")
You could use an IIF function, but this only allows for two availability options. To allow for more in the future I would create a second table to look-up the abbreviations that are going to be displayed in your report.
Copy and paste this into the SQL Editor in Access to create such a table:
SELECT "Seasonal" AS Availability, "S" AS Abbreviation INTO tblAvailabilityOptions;
You are then going to create a query that your report will be based on that combines your main table with the new table you just created, joining on the "Availability" column:
SELECT tblMain.ID, tblMain.Volunteer, tblMain.Availability, tblAvailabilityOptions.Abbreviation
FROM tblMain INNER JOIN tblAvailabilityOptions ON tblMain.Availability = tblAvailabilityOptions.Availability;
If you know how to use the combobox lookup feature on your main table, this will be even easier.

Access Form Field Logic

I'm trying to make access conditionally only show rows that meet a certain condition, allow me to give you some background info before I proceed :
I've created an Access form and linked it to a test DB on my machine. The particular table I am interested in contains the following (important) rows :
ID , Office, Name, SecurityNumber
The thing is, ID is not unique. There are two Office locations, and each Office has it's own set of unique ID numbers. This means that ID 10 here and there may or may not be the same person. (this data comes out of a legacy security system we're not looking to change yet, so I cannot change it)
But ID -is- unique to each Office.
SO! I created an Access form with TABS! Two tabs, one for each office. What I am trying to achieve now is :
Have the ID/Name/SecurityNumber fields for each tab populate with only rows that match it's particular 'Office' value.
Thank you for reading and thank you for helping! :D
If you want the data for the office locations presented in separate tab page controls, you could use subforms on the pages which differ only in the WHERE clause of the queries used as their record sources. So for the Office1 subform, the query could be:
SELECT ID, Office, [Name], SecurityNumber
FROM YourTable
WHERE Office = 'Office1'
ORDER BY [Name];
Then for Office2, the query would be the same except for the WHERE clause:
WHERE Office = 'Office2'
As I understand your question, that approach would do what you're asking for.
However, that's not really the easy "Access way" to do it. Instead consider a combo box control to allow your users to choose which office they want to view. In the code for the combo's after update event, either modify the SELECT statement used as the form's record source or create a filter expression an apply it.
Also, since you're pulling the form's data from SQL Server, consider whether you want your form to load every record for the selected office location. It may not be much concern if you have only a few to moderate number of rows for each location, but if you'll be dealing with multiple thousands of rows it could be. In general, you should try to avoid pulling copious amounts of data across the wire; pull sparingly instead ... only what you need for the immediate task at hand.

Copying a record in VBA

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.