Hi Matt
You sure know how to issue a challenge, don't you? <grin>
First off, you *are* committing spreadsheet! Badly!!
You need to recite "Hail E.F.Codd" 50 times and your database needs a good
wash with Holy Water ;-)
Seriously, you would make life much easier for yourself with a better
normalised design. At the moment, besides the calculation problems that you
have described, you have the following problems:
1. At the start of every month, you need to "shuffle along" every MnnXXX
field into the previous one.
2. This loses any history (maybe you don't want history!)
3. You can never project further than 12 months (maybe you don't want
to!)
I suggest you have a single StockAdjustments table with 6 fields:
SKU *
Month *
ExpectedSales
ExpectedProduction
ActualSales
ActualProduction
* SKU and Month would form a composite primary key
For as many months as you wish in the future, you add a new record for each
SKU with the expected sales and production. At the end of each month you
update each SKU record for that month with the actual sales and production.
You main Products table has, for each SKU, and OnHand quantity and an
OnHandAt field, being the start of the month that the OnHand value was
valid.
The actual stock on hand at the start of any given month up to the present
is then easy to calculate from a single query:
OnHand + Sum(ActualProduction) - Sum(ActualSales)
for the months from OnHandAt to the given month
Your projected stock for a given month in the future is:
[Calculated OnHand for the start of the current month]
+ Sum(ExpectedProduction) - Sum(ExpectedSales)
for the months from the current month to the given month
For the report you describe, you may be able to do it in SQL, but it would
get fairly heavy-duty.
I would prefer to do it in VBA code in the Format event of your report. For
each SKU:
1. Get the OnHand quantity for the start of the current month
2. Open a recordset of StockAdjustments for the next 12 months and load
the ExpectedSales and ExpectedProduction values into two arrays.
3. Calculate the expected OnHand for the start of each of the next 12
months, and story these values in a third array
4. For each of the 12 months, start with the expected OnHand and
subtract the ExpectedSales, counting the months, until the next month's
sales exceeds the remainder. Then divide the remainder by the next month's
sales and add that fraction to the month count. Write the result into the
corresponding month's textbox.
If you want to show only the "bad things" then decide the criteria for a
"bad thing" (e.g. months' stock on hand is <1.5 or >3) and if there are no
figures for the current SKU that are "bad" then you can simply cancel the
Format event for that section.
Have a go at digesting these random thoughts and let me know what you think.
--
Good Luck
Graham Mandeno [Access MVP]
Auckland, New Zealand
Thanks for the code. But I am having trouble with the part before I
use this code. I thought it would be easy but I now see it is just too
difficult to do with IIf statements in the query itself.
What I have is a section in my database where users enter Projections
for certain SKUs (Style, Color, Size, and some other keys) for each
garment, usually panties, by the way.
I gave them a nice report that shows them what production should be
moved up and what production should be moved out. Production is what
is coming in to the ware house, of course, and once in, will be added
to the On Hand, or the inventory.
Though this is all they really need to know what to do, management
would like to see the report filtered to only the bad things, that is,
when we are going to be short or when we are holding too much On
Hand. Both costs too much money, stocking costs gained and
opportunity costs lost.
What I need is a number that simply tells us how many months of
inventory we will be holding at the beginning of each month (given the
entered projections and the known On Hand and production coming in).
Sounds easy, but it is kind of difficult to do in the query itself.
The Projections are in these fields:
M01Adj, M02Adj, M03Adj…M12Adj (with M01Adj always being the present
month)
The production are in these fields:
M01ProdAdj, M02ProdAdj, M03ProdAdj… M12ProdAdj (with M01ProdAdj always
being the present month.
The On hand is in this field: OnHandAdj.
The fields stop at M12.
So, given this data we should be able to figure out the number of
months inventory we have at the beginning of each month.
Let’s take this example, and though I will just type it out, please
understand that all the data is on one record (in a query called
Map_DS380qry_NeedAndActl):
Projection: 2000, 0500, 1000, 1000, 5000, 2000, 1500, 2000, 0500,
1000, 1000, 2000
Production: 0000, 0000, 2000, 0000, 3000, 0000, 1000, 0000, 0000,
0000, 0000, 0000
On Hand: 8000
First off, the Projection for the first month should be adjusted for
the current day of the month it is. So if it is the 15th day of the
month, let’s say, we should adjust it to 2000 * 15/30, or 1000. The
reason for this is that the On Hand has been adjusted for selling in
the month but the projection remains the same.
With this in mind, I want to report these numbers (figured out in my
head) for the number of months inventory we will be carrying if the
projections are correct (for the first day of each month):
Mths/Ivn: 4.9, 3.9, 2.9, 2.75, 1.75, 2.5, 1.5, 1, 0, 0, 0, 0
How did I derive these numbers? The 4.9 derives from the fact that
the 8000 inventory will last for 4 months ( 1000 (the 2000 adjusted
down of the first month) + 500+1000+1000 = 3500). I can’t add the
next month 5000 (1000+500+1000+1000+5000 = 8500) because it would go
over 8000 inventory. But it does go into that month 0.9 of the way.
So I get 4.9. The 2000 production in M03 does not come into play as
it is not carried for the M01 month. M01 has 4.9 months of inventory.
The 3.9 and the 2.9 for M02 and M03 are figured in the same way. The
2.75 for M04 takes into account the 2000 production of M03. You see,
I don’t include the M03 production coming in in the M03 figure because
I am reporting the months inventory for the Beginning of the month and
the production is presumably coming in sometime after the first. It
is true that it may come in on Day 01 or Day 02. But I do not need to
be so picky and it is safer to report lower numbers than higher
numbers.
Do you want to crawl into a hole now? It is a bit difficult to
explain but it is commonsense too. If you wish to tackle it, please
let me know. If you do not want to, believe me, I understand.
Thanks so much,
Matt