I have a MS Access database with about 1000 tables. The Tables are independent of each other, that is they are not linked to each other. Basically each table contains records of stock of a particular good. The Names of each table is the name of the item, for example 125 gm Soap, 200 ml Oil, etc. and contains the following columns : -
Date
Daily Opening Stock
Daily Sales
Daily Purchases
Daily Closing Stock
Each day, sales/purchases of all the goods are recorded in accounting software. The End of Day report summary is generated in Excel Format. This report is a consolidated report of daily Sales/Purchases of all the goods, row-wise. The Columns in Excel are :
Date
Item Name
Daily Opening Stock
Daily Sales
Daily Purchases
Daily Closing Stock
Presently I have to manually open each table in Access & copy-paste the respective daily sales/purchases data from the excel report. I want to automate this process so that the record is automatically appended to each of the respective table, basis the Item Name.
In summary, I want to update multiple tables in Ms Access database file, from data contained in 1 Ms Excel spreadsheet.
Is that possible ? Your help would be highly appreciated.
Thanks,
Thiru V. Klack
My first question to you is why can't the Access database match the data structure of the Excel spreadsheet? Updating 1 Access table from 1 spreadsheet is a lot simpler than what you're trying to do. Having 1,000 tables with the same data structure, where each table is named after a product, seems pretty fishy to me.
That being said, if you need to keep your 1,000 tables (I'm honestly surprised you're not hitting the DB maximum threshold for Access), there are ways you can make it work. I would suggest having a lookup table that matches the product (as it appears on the spreadsheet) to the table in Access it goes to. Then, you'd import the Excel data into a staging table, and run some VBA code to loop through the lookup table, running a query to append all the data from Excel into the appropriate Access table. Something like this:
private const STAGING_TABLE_NAME as string = "tDataFromExcel"
private Const LOOKUP_TABLE_NAME as String = "tGoodsToTableNames"
public sub AddData()
Dim db as DAO.Database
Dim rsItemLookup as DAO.Database
Dim strSQL as string
Dim GoodName as string, TableName as string
set db = CurrentDB
set rsItemLookup = db.OpenRecordset("select good_name, table_name from " & LOOKUP_TABLE_NAME)
do while not rsItemLookup.EOF
GoodName = rsItemLookup.fields("good_name").Value
TableName = rsItemLookup.fields("table_name").value
strSQL = _
"insert into " & TableName & " (" & _
"[date], " & _
"[Daily Opening Stock], " & _
"[Daily Sales], " & _
"[Daily Purchases], " & _
"[Daily Closing Stock]) "
"select " & _
"[date], " & _
"[Daily Opening Stock], " & _
"[Daily Sales], " & _
"[Daily Purchases], " & _
"[Daily Closing Stock]) " & _
"from " & STAGING_TABLE_NAME & " " & _
"where [Item Name] = """ & GoodName & """"
db.Execute strSQL
rsItemLookup.MoveNext
loop
end sub
Again, I'm certainly not advocating you take this approach: If you can, I would strongly implore you to refactor your database to not have 1,000 virtually identical tables.
Zack's answer provides a way to do what you're asking, but recommends that you do something else. I'm going to try to demonstrate that what he recommends would work for your situation, and show you how to achieve it.
You want to transfer data in an excel spreadsheet into a relational database that holds the same data - usually to give better access/manipulation. The data is in a big table of one day, with a separate line for each product, and you want to be able to view the entire history of a single product, so you have separated out the tables.
This is going to significantly slow down the automatic transfer process - that long loop that re-writes and processes the SQL over and over. You can look at the data in that way without this setup though. Lets call this tblProductDetails
One table has your product information - things like the name of the product, how much it costs... The other has the in/out records of what was bought and sold, keeping track of stock on hand at any point. This second table is going to have a LOT of records, as it's a new record for each product that was bought and/or sold each and every day. We might call this tblInOut.
With a Select query you can save in Access, you can look at the history of any one product at any time - you can even set this as a variable so that when you open the only query you save it prompts you for the name of the product you want to look up.
I've mocked up a 4 product sample schema for you with a query to show all the data, and another to show just the one product's history. You can use the second query exactly as is in Access' query builder (SQL view) where '125g Soap' (on the second last line) is mentioned in the query name so you know which query is which.
If you want to use just one query, do the same thing with one exception: on the second last line, where it says '125g Soap' replace the whole thing with Product_Name (without the inverted commas) and when you open the query, Access will give you a message box asking you to type in a product name.
This feature will only work if you type the name exactly right though, so you might prefer just to build a form so you can give the user a combo box with which to select the exact product name.
Related
I have the following two Access tables
Employees
id Name
1 bob smith
2 james bird
3 jane big
Events
id emp_id Notes
1 1 fell down the stairs
2 3 paper cut in the break room
I also have the following Excel file that I would like to 'suck' (import) into the Events table. The problem is the data needs to be correlated on the name/emp_id field and I'm not sure the best way to do this.
Excel_sheet
Employee Name Notes
bob smith feel asleep while driving
The access table uses references to the Employees table, whereas the Excel sheet is using names. What are some options for me to bring this Excel sheet into Events table and convert the names (bob smith) into their associated id's from the Employees table?
Assuming names are consistently spelled in both datasets and only one person exists for each name, try:
INSERT INTO Events(emp_ID, Notes) SELECT ID, Notes FROM excel_sheet INNER JOIN Employees ON Employees.Name=excel_sheet.[Employee Name];
Build that SQL in a query object or run in VBA:
CurrentDb.Execute "INSERT INTO Events(emp_ID, Notes) " & _
"SELECT ID, Notes FROM excel_sheet " & _
"INNER JOIN Employees ON Employees.Name=excel_sheet.[Employee Name];"
Suggest you test with a copy of database.
Name is a reserved word and really should not use reserved words as names for anything.
I am trying to fetch data from my Access table into Excel sheet. The below mentioned SQL query is throwing an error "Data type mismatch in criteria expression" while the execution reaches Open query.
I googled for all possible fixes. All are saying the number might be passed in quotes. i checked for it still clueless, The query is pretty simple where i am trying select data from a userform text box in DD-MMM-YYYY format (03-OCT-2018) and comapring with date portion of timestamp field and order by my customer id field
SELECT * FROM Master_Intrpay_Cash where DateValue(LAST_UPDATE_TIMESTAMP)>=#" & Trim(startdate.value) & "# and DateValue(LAST_UPDATE_TIMESTAMP)<=#" & Trim(enddate.value) & "# ORDER BY CUSTOMER_ID
Below Shown is the msgbox showing the query being passed. if it helps.
Also the crazy part is the above query was copy pasted from an existing working query, just changed the table name and timestamp field name. Rest everything is exactly the same.
Try without DateValue:
SELECT *
FROM Master_Intrpay_Cash
WHERE LAST_UPDATE_TIMESTAMP >= # " & Trim(startdate.value) & " #
AND LAST_UPDATE_TIMESTAMP <= # " & Trim(enddate.value) & " #
ORDER BY CUSTOMER_ID
DateValue expects a String as an argument, your column as Date/Time
Also, a preferable format for the date is #mm/dd/yyyy# (US date format), otherwise you may have problems with different locales.
I am new to Excel VBA. I used VBA to extract data from SQL-Server and was able to extract data using text filters but when I started filtering by date, it didn't work anymore. I think my mistake was the formatting of date. I tried using all the samples on this site but I'm beginning to be hopeless. It would be great if you guys can assist me with this hurdle. Thanks a million.
Here's the code: (Please take note that I am skipping the connection and close codes to focus only on the problematic source code).
What I want to achieve here in this code is to extract all the records (using SQL query in a VBA environment) based on date criteria which is greater than or equal to January 1, 2018.
query = "SELECT (Worktype), count(*)" & _
"FROM dbo.InteractionSummary WHERE [Worktype] IN ('" & MAC & "')" & _
"GROUP BY [Worktype]"
With this query, I had no issue. It has generated the figures perfectly. What these codes do is to count all the records from "Worktype" column that has "MAC" value.
My issue is when I add the below date criteria.
Dim dTheDate As Date
dTheDate = #1/1/2018#
query = "SELECT (Worktype), count(*)" & _
"FROM dbo.InteractionSummary WHERE [Worktype] IN ('" & IMAC & "')" & _
"GROUP BY [Worktype] AND [StartDateTimeUTC] > " & dTheDate & " "
StartDateTimeUTC is a DateTime2 column (datetime2(3),notnull). I'm trying to extract only based on the dTheDate. I tried every format but it's not letting the code through.
Thanks,
Skywalker
I have got a requirement to reconciliation the records between excel sheet & MS access 2010 table with same data in different columns.. Need to validate the excel sheet based on the values from MS access with the help of unique id and to generate the error message for that unique id like below format in MS access reports.
Currently I have created one table based on below schema and mapped it to reports.. Now I need to compare the records and populate the error message in below table..
I'm new bie to VBA , Please help me with the best approach with no performance tolerance like avoiding much looping..
Table Schema: Employee
Employee ID, Employee Name, Employee Salary
1,Tester,5000
Excel Sheet Schema: Employee
ID, Name, Salary
1,Tester,4000
Required Output Report: Ms ACCESS 2010
File Name, Unique ID, Column Name, Difference
Employee, 1, Salary, access salary <5000> is different from excel sheet salary <4000>
You can achieve your desired outcome without using any VBA at all. Start by creating a Linked Table in Access that points to your Excel data. Detailed instructions can be found here:
Import or link to data in an Excel workbook
I named my Linked Table [ExcelData], so when I open it in Access it looks like this:
To perform the reconciliation all we need to do is create a query like this:
Note that the Field: value for the fourth column is
Difference: "Access salary <" & [Employee].[Employee Salary] & "> is different from Excel sheet salary <" & [ExcelData].[Salary] & ">"
For reference, the entire SQL statement for that query is
SELECT
"Employee" AS [File Name],
Employee.[Employee ID] AS [Unique ID],
"Salary" AS [Column Name],
"Access salary <" & [Employee].[Employee Salary] & "> is different from Excel sheet salary <" & [ExcelData].[Salary] & ">" AS Difference
FROM
Employee
INNER JOIN
ExcelData
ON Employee.[Employee ID] = ExcelData.ID
WHERE (((Employee.[Employee Salary])<>[ExcelData].[Salary]));
That query returns the following:
I'm using ADODB connection in VBA excel file with Microsoft.Jet.OLEDB.4.0 provider.
The file with which I'm establishing connection is .csv file which looks like:
Date and time, Last name, First name
2011-08-29 05:48:50,lname1,fname1
2011-08-29 05:49:50,lname1,fname1
2011-08-29 05:55:50,lname2,fname2
2011-08-29 16:11:50,lname1,fname1
2011-08-29 17:55:50,lname2,fname2
2011-08-30 9:11:50,lname1,fname1
The point is that my data is sorted by Date and time which is in one field, and user names are not in any order.
What I really need to do is create a query to fill Recordset.
I need this query to select first, second and last hour for each day for each user name.
Is it even possible to split Date and time column just using a query?
I've got general idea how to select what I want, but the thing is too complicated for me, because of that Date and time in the same field.
Would you give me any suggestions?
Let us say your file is called Dates.csv, you can try:
SELECT
[Last name] & ", " & [First Name] AS FullName,
Format([Date And time],"yyyy/mm/dd") AS WorkingDay,
First(Format([Date And time],"hh:nn:ss")) AS FirstHour,
Last(Format([Date And time],"hh:nn:ss")) AS LastHour
FROM [Dates.csv]
GROUP BY [Last name] & ", " & [First Name], Format([Date And time],"yyyy/mm/dd")
I am a little suspicious of the double space between date and time. I would get rid of the spaces in the column names, if I were you. It will make things easier.