Microsoft
Software
Hardware
Network
Question : Weekly price averages for 5000+ items as charts saved as graphic
Dear all,
First post for me here. I am a weekend MS Access user who has a very specific need:
I have a MS Access database with historic price information for 5000+ products in the format:
Product ID, Date/Time, Price
(Text), (Date/Time), ($.$$)
What I would like to do is create a chart for every unique product in the database, that shows price averages, highest as well as lowest prices for the past 52 weeks as well as how many data points contributed to the averages and saves the charts as graphic using the product name as file name. Below some sample data:
%ID% %Date/Time% %Price%
J101-1888A 9/8/2005 20:45 101
J10-1890J 9/6/2005 22:19 10.06
J10-1891F 9/4/2005 20:00 10.7
J10-1892G 9/1/2005 18:15 10.51
J10-1893D 9/6/2005 18:50 1
J10-1893F 9/4/2005 17:26 9.5
J10-1895F 8/31/2005 19:36 7.29
J10-1895J 9/9/2005 20:30 1
J10-1896F 9/6/2005 18:48 1
J10-1897A 9/9/2005 20:30 3.07
J10-1900J 9/1/2005 19:26 3.07
J10-1902G 9/4/2005 20:00 12.05
J10-1903D 9/7/2005 19:06 6.13
J10-1903F 8/30/2005 18:44 6.03
J10-1904A 9/9/2005 20:31 1
J10-1906D 9/2/2005 21:08 1.99
J10-1916J 8/31/2005 21:24 3.53
J102-1892A 8/29/2005 20:54 131.05
J102-1896A 9/9/2005 20:01 14.72
J102-1896A 9/4/2005 11:00 9.5
J102-1898A 8/31/2005 19:20 25.5
J102-1898A 9/5/2005 18:35 16.44
J102-1899A 9/3/2005 12:57 8.62
J102-1899A 8/31/2005 19:03 7.01
J102-1899A 9/3/2005 15:45 13.38
J102-1900A 8/31/2005 19:06 7.5
J102-1900A 9/4/2005 21:24 26.27
J102-1900A 8/29/2005 11:58 12.5
J102-1902A 9/2/2005 12:49 8.6
J102-1902A 9/8/2005 17:53 8.55
J102-1902A 9/2/2005 19:47 6.44
J102-1903A 8/31/2005 14:50 7.09
J102-1904A 8/30/2005 19:51 9.75
J102-1904A 8/29/2005 20:58 5.5
J102-1904A 8/31/2005 19:01 11.6
J102-1904A 9/4/2005 21:15 7.01
J102-1904A 9/1/2005 19:19 7.9
J102-1904A 9/3/2005 16:15 8
J102-1904A 8/30/2005 19:29 5.04
J102-1905A 9/7/2005 8:59 4.39
J102-1905A 9/4/2005 23:01 5
J102-1905A 8/31/2005 19:08 6.55
J102-1907A 9/2/2005 19:47 5.27
J102-1907A 9/9/2005 18:17 9.16
J102-1908A 9/2/2005 19:47 8
J102-1912A 9/4/2005 18:58 11.1
J103-1908A 9/3/2005 15:00 11.05
J103-1908A 8/30/2005 15:31 56.99
J103-1908A 8/29/2005 14:02 5.6
J103-1908A 9/4/2005 10:47 7
J103-1908A 8/31/2005 20:00 3.53
J103-1908A 9/4/2005 17:30 6.05
J103-1909A 9/1/2005 9:21 4.76
J103-1909A 9/2/2005 22:29 7.1
J103-1909A 8/30/2005 14:14 9.09
J103-1909A 8/30/2005 16:55 8.5
J103-1909A 8/29/2005 14:28 2.65
J103-1909A 9/6/2005 23:19 8.51
J103-1909A 9/4/2005 11:39 5.62
J103-1909A 9/4/2005 20:15 4.55
J103-1909A 8/29/2005 10:20 5.55
J103-1909A 9/4/2005 18:15 5.17
J103-1912A 9/2/2005 14:32 4.5
J103-1912A 8/31/2005 19:33 10
J103-1912A 8/29/2005 14:34 3.6
J103-1912A 9/4/2005 18:56 6.5
J103-1912A 9/4/2005 18:55 6
J103-1912A 8/29/2005 20:42 6.01
J103-1912A 9/4/2005 18:30 7.4
Greatly appreciate your input. If you need more points or other compensation (within reason) to get this solved for me we can talk about it.
Stefan
Answer : Weekly price averages for 5000+ items as charts saved as graphic
Ok, well i did quite a bit of work on this off Experts exchange, so here is the synopsis of the solution for any future users.
the data set is by individual sales.
the management view of the data is required by wek with quantity, min, max and average.
i gathered these using a make table query. which is run when the DB is opened ( button click by user, this also opens up the extract form.)
DataTable is the table detailing the main data set.
SELECT DataTable.productID, Count(DataTable.Date) AS CountOfDate, Min(DataTable.price) AS MinOfprice, Max(DataTable.price) AS MaxOfprice, Avg(DataTable.price) AS AvgOfprice
INTO chart_store
FROM DataTable
WHERE (((DataTable.Date)>=DateAd
d("ww",-52
,Now())))
GROUP BY DataTable.productID;
the extract form will output the required stock chart graph for the selected product in a combo box....if no product is selected it outputs all products. the form included a textbox for output path and also a check box for show/hide excel during extract.
The outputs for the form will be a master spreadsheet containing the aggregated dataset, the chart generated from it, and the actual core data for that product.
The project was further complicated by user request to have the weeks where no sales occured populated with a 0 value, so that all the last years weeks would appear on the graph.
The onclick for the button on this form does the following:
works out the current week.
finds out if user is running for specific product or all products
if all, it runs the same code but inside a loop...
set up save addresses for the aggreg and full data ( and image path)
calls the sub procedure for exporting to excel
'set the running flag
DoCmd.Hourglass True
aborted = "no"
'work out what the current week number is
DoCmd.SetWarnings False
DoCmd.OpenQuery "1_set_current_yr_week"
DoCmd.SetWarnings True
If IsNull(Me.Combo0.Value) Then
'user has selected to run for all product id's
VBQuest = MsgBox("You are about to run the chart maker for " & Me.Combo0.ListCount & vbCrLf & _
" product id's. Are you sure?", vbYesNo, "Warning")
If VBQuest = vbYes Then
For Lcount = 0 To Combo0.ListCount - 1
If aborted = "no" Then
'keep running
'get first product
Combo0.Value = Combo0.ItemData(Lcount)
'set up products target file path name
save_aggreg = get_file & Combo0.Value & ".xls"
save_full = get_file & "X_" & Combo0.Value & "_detail.xls"
DoCmd.SetWarnings False
'output and run graph maker / exporter
excel_process
DoCmd.SetWarnings True
Else
'aborted = yes, so stop running
Lcount = Combo0.ListCount - 1
End If
Next Lcount
End If
Else
'user has selected to un for a single productID
DoCmd.SetWarnings False
'set up products target file path name
save_aggreg = get_file & Combo0.Value & ".xls"
save_full = get_file & "X_" & Combo0.Value & "_detail.xls"
'output and run graph maker / exporter
excel_process
DoCmd.SetWarnings False
'
DoCmd.Hourglass False
End If
End Sub
the excel subprocedure encoutnered several errors which needed trapping along the way, it also calls two further subprocedures - get full years data - which uses find unmatched to populate the weekly gaps ( where no sales occured) and getfile - which makes sure there is a "\" at the end of he file save path
Public Sub excel_process()
On Error GoTo err_trap
' make this product_id's Data
GET_full_years_data
'output the current product to excel
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "source_2_export", save_aggreg
DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "all_records_for_prod_id",
save_full
'declare necessary objects
Dim objExcel, objRange, colCharts, objChart As Object
Dim objsheet As Worksheet
Dim found_arfpi As String
found_arfpi = ""
'create an instance of excel
Set objExcel = CreateObject("Excel.Applic
ation")
'make the excel window visible if check is selected on form
objExcel.Visible = Me.Check7.Value
'open the recently created xls file of the data for the product for the last 52 weeks
objExcel.Workbooks.Open Filename:=save_aggreg
'Set objSheet = objExcel.Sheet
For Each objsheet In objExcel.Worksheets
'objExcel.Workbooks.Open Filename:=save_full
'MsgBox objsheet.Name
If objsheet.Name = "all_records_for_prod_id" Then
found_arfpi = "True"
End If
Next objsheet
'Selection.Columns.AutoFit
on data sheet'
If found_arfpi <> "true" Then
found_arfpi = ""
objExcel.Workbooks.Open Filename:=save_full
'objExcel.Sheets("all_reco
rds_for_pr
od_id").Ac
tivate
'objExcel.ActiveSheet.Used
Range.Sele
ct
objExcel.Sheets("all_recor
ds_for_pro
d_id").Sel
ect
objExcel.ActiveSheet.UsedR
ange.Selec
t
objExcel.Selection.Copy
objExcel.Windows(Combo0.Va
lue & ".xls").Activate
objExcel.Sheets.Add
objExcel.ActiveSheet.Paste
objExcel.Application.CutCo
pyMode = False
objExcel.Sheets("Sheet1").
Select
objExcel.Sheets("Sheet1").
Name = "all_records_for_prod_id"
'objExcel.Sheets("all_reco
rds_for_pr
od_id").Co
py Before:=objExcel.Workbooks
("J101-188
8A.xls"). _
Sheets(1)
'objExcel.Sheets("all_reco
rds_for_pr
od_id").Co
py Before:=Workbooks(Combo0.V
alue & ".xls").Sheets(0)
objExcel.Workbooks("X_" & Combo0.Value & "_detail.xls").Close
End If
objExcel.Sheets("all_recor
ds_for_pro
d_id").Act
ivate
objExcel.ActiveSheet.UsedR
ange.Selec
t
'Selection.Columns.AutoFit
'the bug was the line above, i had pasted the excel macro
'code to widen the columns in the core data to display the date field
'but had forgotten to add the word to reference the excel object:
objExcel.Selection.Columns
.AutoFit
'declare and store the range of data for use in the chart
objExcel.Sheets("source_2_
export").A
ctivate
Set objRange = objExcel.ActiveSheet.UsedR
ange
objRange.Select
'add a chart
objExcel.Charts.Add
Set objChart = objExcel.Charts(1)
objChart.Activate
objChart.ChartType = xlStockVHLC
'~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~
~~~~~~~~~~
~~~~~~~~~~
#
'# this is where we will add code for your type of chart#
'~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~
~~~~~~~~~~
~~~~~~~~~~
~
With objChart
.Activate
.ChartType = xlStockVHLC
.HasTitle = True
.ChartTitle.Characters.Tex
t = Combo0.Value
.Axes(xlCategory, xlPrimary).HasTitle = False
.Axes(xlValue, xlPrimary).HasTitle = False
.Axes(xlCategory, xlSecondary).HasTitle = False
.Axes(xlValue, xlSecondary).HasTitle = False
End With
objExcel.DisplayAlerts = False
'export the chart as filename.gif
objExcel.Charts(1).Export Replace(save_aggreg, "xls", "jpg", 1, 1), "jpg"
'save the source spreadsheet for that product id
objExcel.ActiveWorkbook.Sa
ve
'close the prod id spreadsheet
objExcel.ActiveWorkbook.Cl
ose
'trap for errors
err_trap:
Select Case Err.Number
Case 3010 ' the excel file already exists at the specified location
MsgBox "Please select a new folder to write the new data to" & vbCrLf & _
"or empty the current folder. Processing aborted"
aborted = "yes"
Forms!chart_maker!Text4.Se
tFocus
GoTo false_start
Case 0
Case 1004
'only one row of data
GoTo false_start
Case Else
MsgBox Err.Number & vbCrLf & Err.Description
objExcel.Visible = True
'no other erors found worth trapping yet
Resume Next
End Select
objExcel.Quit
'free up the object
Set objExcel = Nothing
false_start:
End Sub
Public Function get_file() As String
'get pat to save the files too
If Right(RTrim(Text4.Value), 1) = "\" Then
get_file = Me.Text4.Value
Else
get_file = Me.Text4.Value & "\"
End If
End Function
Public Sub GET_full_years_data()
' procedure to run the queries for the current product to populate non sale weeks
DoCmd.SetWarnings False
'get the data for the current product ID
DoCmd.OpenQuery "2_Make_source2_export"
'SELECT DISTINCTROW Format([date],"yyyy") & "-" & Format([date],"ww") AS Week, Count(DataTable.Date) AS 'DataPoints, Min(DataTable.price) AS [Min], Max(DataTable.price) AS [Max], Avg(DataTable.price) AS Avr INTO source2
'FROM DataTable
'GROUP BY Format([date],"yyyy") & "-" & Format([date],"ww"), DataTable.productID
'HAVING (((DataTable.productID)=[F
orms]![Cha
rt_maker]!
[Combo0].[
value]));
'create years worth of missing data
DoCmd.OpenQuery "3_show_all_dates_in_range
_as_0"
'SELECT year_week.year_week, year_week.id, 0 AS DataPoints, 0 AS [Min], 0 AS [Max], 0 AS Avr INTO [range_as_zero's]
'FROM get_range_of_dates, year_week
'WHERE (((year_week.id) Between [current] And [prev]))
'ORDER BY year_week.id DESC;
'Add in the 0 value missing data
DoCmd.OpenQuery "4_range_as_zero's Without Matching source2"
'INSERT INTO source2 ( Week, DataPoints, [Min], [Max], Avr )
SELECT [range_as_zero's].year_wee
k_year_wee
k, [range_as_zero's].DataPoin
ts, [range_as_zero's].Min, [range_as_zero's].Max, [range_as_zero's].Avr
FROM [range_as_zero's] LEFT JOIN source2 ON [range_as_zero's].year_wee
k_year_wee
k = source2.Week
WHERE (((source2.Week) Is Null));
DoCmd.SetWarnings True
End Sub
so there it all is. turned out to be a biggy...
the questioner has asked about the rounding in the chart but i have not yet been able to master that aspect.
Random Solutions
iPhone 3G and SBS 2003/Exchange Activesync
Winscp - SSH, canoot get real path
Disabling Tintsetp.exe, ImScInst.exe, IMJPMIG.exe
BOOT.INI for Win98 on partition 2
Using IsDate In VB.Net 2005
Redirect to an PHP script from ASP.NET?
How define combo box control source for multiple fields?
customizing access 2003 menus
Limiting a DataGrid in WPF with ComboBoxes...
Denied GPO