Copying a record in VBA - ms-access

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.

Related

Complex fill in the blanks query in MS Access 2010

I have looked and haven't found a method on here to do this. I am assuming my search is skewed and I just missed it, if this is the case, please let me know.
Anywhooo, I have a large and unwieldy report coming out of SAP every day. Because it will often have some strangeness, we import that into an Access database so we can keep an eye on the stuff we need in our department. I am using a combination of 6 fields to create a primary key in Access. The information in those fields is about the only thing consistent I get out of this SAP report, but the remainder of the data can be considered dynamic and can change from day to day. Usually this is a matter of filling in a few blanks, Occasionally this is changing existing data, and on rare occasions, it may involve deleting data out of a handful of fields.
The SAP report is around 130 columns of data, So I'm looking for an efficient way to roll in the changes without overwriting what folks put in there manually.
EDIT:
Here is the way this is used. SAP (for reasons I'm not going to go into) sometimes will have bad data show up in the daily report. We are using Access to track and put the correct data in to something that we can generate much more accurate summaries. What the users put in is to be considered true and accurate.
The transactions we are tracking can take a long time to complete. Most take around 30 days to complete. That's why I will have blank fields on one day, and several of them to be filled in on the next. We might not get any for the next few days and then a bunch more are filled in later. That is the normal flow.
What I have to account for is the odd occasion where a mistake is made early in the process. At a certain point, an error will break SAP's ability to update anything at all in the report we have to use.
I have 3 fields set up that trigger what my users daily work is going to be. There is a logical flow so that user 1 completes what he needs to do and then that record will show up on User 2's report. These fields will also stop the general update process in an exception report if there is a difference in what is coming in from SAP, and what is already in my database.
What I am looking for is some way to systematically fill in blank fields, on existing records in access. I do not want to overwrite if something is in a field, only the null values. I can do this on one field at a time, but each record has about 130 fields. I'm wondering if there is a way I could do this in just 1 query?
Thanks all! I hope the edit makes more sense now
A simple google for "Access SQL update null values" could have yeilded you what you need. But if all you need to do is fill constant values into empty fields then something like:
UPDATE Table SET Table.field1 = VALUE
WHERE Table.field2 is NULL;
Now if this data is different for each record based on; say data from another field, then you may need to write some VBA to build that value/string for you. But otherwise if you are JUST updating null fields to include data, then a simple UPDATE statement will do
EDIT Based on new info:
So if I'm understanding correctly: you have two tables. One table with the blank fields and another table that contains the values you need.
If this is the case, you can use a similar UPDATE statement, but use an inner join to get the data you need from table B to fill in table A
UPDATE TableA INNER JOIN TableB ON TableA.KeyField = TableB.KeyField
SET TableA.NullField = TableB.NotNullField
WHERE TableA.NullField Is NULL;

Creating a global variable in Talend to use as a filter in another component

I have job in Talend that is designed to bring together some data from different databases: one is a MySQL database and the other a MSSQL database.
What I want to do is match a selection of loan numbers from the MySQL database (about 82,000 loan numbers) to the corresponding information we have housed in the MSSQL database.
However, the tables in MSSQL to which I am joining the data from MySQL are much larger (~ 2 million rows), are quite wide, and thus cost much more time to query. Ideally I could perform an inner join between the two tables based on the loan number, but since they are in different databases this is not possible. The inner join that is performed inside a tMap occurs after the Lookup input has already returned its data set, which is quite large (especially since this particular MSSQL query will execute a user-defined function for each loan number).
Is there any way to create a global variable out of the output from the MySQL query (namely, the loan numbers selected by the MySQL query) and use that global variable as an IN clause in the MSSQL query?
This should be possible. I'm not working in MySQL but I have something roughly equivalent here that I think you should be able to adapt to your needs.
I've never actually answered a Stackoverflow question and while I was typing this the page started telling me I need at least 10 reputation to post more than 2 pictures/links here and I think I need 4 pics, so I'm just going to write it out in words here and post the whole thing complete with illustrations on my blog in case you need more info (quite likely, I should think!)
As you can see, I've got some data coming out of the table and getting filtered by tFilterRow_1 to only show the rows I'm interested in.
The next step is to limit it to just the field I want to use in the variable. I've used tMap_3 rather than a tFilterColumns because the field I'm using is a string and I wanted to be able to concatenate single quotes around it but if you're using an integer you might not need to do that. And of course if you have a lot of repetition you might also want to get a tUniqueRows in there as well to save a lot of unnecessary repetition
The next step is the one that does the magic. I've got a list like this:
'A1'
'A2'
'B1'
'B2'
etc, and I want to turn it into 'A1','A2','B1','B2' so I can slot it into my where clause. For this, I've used tAggregateRow_1, selecting "list" as the aggregate function to use.
Next up, we want to take this list and put it into a context variable (I've already created the context variable in the metadata - you know how to do that, right?). Use another tMap component, feeding into a tContextLoad widget. tContextLoad always has two columns in its schema, so map the output of the tAggregateRows to the "value" column and enter the name of the variable in the "key". In this example, my context variable is called MyList
Now your list is loaded as a text string and stored in the context variable ready for retrieval. So open up a new input and embed the variable in the sql code like this
"SELECT distinct MY_COLUMN
from MY_SECOND_TABLE where the_selected_row in ("+
context.MyList+")"
It should be as easy as that, and when I whipped it up it worked first time, but let me know if you have any trouble and I'll see what I can do.

Access 07 VBA Get Table by Path

Is it possible to reference (in VBA) a non-linked Access table by its full path?
For instance, say you're building a form that draws from a set of tables, but your user needs to add tables as time goes on; you might start with tableA, tableB, and tableC, but a year down the line tableZ might exist.
The goal then becomes finding a way to reference the newly-added tables without needing to add them as external data sources if possible; [how] can this be done? (My particular case involves using the tables as RowSource values, if that's significant.)
I was thinking something along the lines of
control1.RowSource = "X:\database\databaseName.accdb" & [???]
might work, but I really have no idea what would go in the brackets.
Within an Access query, there are 2 ways to reference an unlinked table in a different Access database.
SELECT YourTable.some_field
FROM YourTable IN 'X:\database\databaseName.accdb';
or ...
SELECT YourTable.some_field
FROM [X:\database\databaseName.accdb].YourTable;
I think you can get what you want if you use a similar query as your RowSource. (Control.RowSource = "SELECT ...")

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.

The best way to manage database (ACCESS)

What is the best way to organize a big database.
The way it works is that only I am allowed to touch or modify the database but interns help sometimes to collect data, we used to have the whole system excel based, back than we had the macro which by choosing 2 files it will integrate and mark in colors the changes.
How can I create something friendly to use which will update by pressing a button and also will show changes!! I am familiar with the update query, however:
it doesn’t track any changes.
I want to know other options.
To sum up the way of processing is:
I have the database and I need to split some data to smaller files so other employees will work on.
Then I will collect the files and integrate with the existing database, but since we are all human mistakes can happened that’s why I want to be able to track easily changes.
The updates are going to happen often. When I will give the intern a temp. table The possible changes are for example: address, phone number, price, they will do those researches based on current data which they will find online which information has been changed, and they will change the info which is on the temp. table, That is why I want to be able to know what exactly did they found out. Lets say if Product A (product ID1234) used to cost 10$ and today its 12$ from the same supplier. I just want to know and to see that the price for product ID1234 has been changed. Not only to have it updated to the back end database. For quality assurance I need to track which new input they did in relation to the product ID. (some times input by someone else which was done in wrong format or wrong column could affect big time on the quality of the reports)
So this was the explanation for what I need the reports
So in order to make those temp. tables, I want to create a form for it that by choosing region, category etc. and then clicking on a button it will automatically select the relevant records from the database, create a new table/access-file and then copy the selected records to the temp. table. So someone else could work on it...
Next thing is that it would be nice to know how can I create a template for tables, by template I mean to standardize by validation rules. some fields I'd like to have dropbox menu, some fields ready mask for phone number.... etc.
Final part, after they made the changes and saved the file (the temp. table which they were working on), I want to be able to update the back-end database via clicking on a button...
Looking forward to get the best solution!
Thanks in advance J
Michael
Okay for the temp tables thing:
why not split your database in a backend part (having all the tables) and a frontend part which contain the forms and tables the interns need? I'm guessing mostly it is going to be the same so you can even create multiple different frontend's to give to different interns incase they need other tables. There are a lot of articles out there about splitting a database and linking tables.
Then the thing about the record changes not sure is this is what your looking for but it could help, i haven't used it myself so not sure what it exacly does. But this may help you a bit.
http://support.microsoft.com/kb/197592
I would consider taking a look at the BeforeUpdate event for the form. You can trap the old and new values of textboxes if the form is bound to a table. You could loop through all the controls on your form and check for Me.Control <> Me.Control.OldValue. If they don't match, write both values to an auditing table so you can go back and check whenever you want to. I would include the following fields in your auditing table:
ChangeDate
TableName
ControlName
OldValue
NewValue
Then you can query that table any time you want to see what has changed.