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)>=DateAdd("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.Application")



'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_records_for_prod_id").Activate
'objExcel.ActiveSheet.UsedRange.Select
objExcel.Sheets("all_records_for_prod_id").Select
objExcel.ActiveSheet.UsedRange.Select
objExcel.Selection.Copy
objExcel.Windows(Combo0.Value & ".xls").Activate
objExcel.Sheets.Add
objExcel.ActiveSheet.Paste
objExcel.Application.CutCopyMode = False
objExcel.Sheets("Sheet1").Select
objExcel.Sheets("Sheet1").Name = "all_records_for_prod_id"

'objExcel.Sheets("all_records_for_prod_id").Copy Before:=objExcel.Workbooks("J101-1888A.xls"). _
        Sheets(1)
'objExcel.Sheets("all_records_for_prod_id").Copy Before:=Workbooks(Combo0.Value & ".xls").Sheets(0)
objExcel.Workbooks("X_" & Combo0.Value & "_detail.xls").Close
End If
objExcel.Sheets("all_records_for_prod_id").Activate
objExcel.ActiveSheet.UsedRange.Select
'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").Activate
Set objRange = objExcel.ActiveSheet.UsedRange
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.Text = 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.Save

'close the prod id spreadsheet
objExcel.ActiveWorkbook.Close

'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.SetFocus
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)=[Forms]![Chart_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_week_year_week, [range_as_zero's].DataPoints, [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_week_year_week = 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  
 
programming4us programming4us