Writing a VBA makro to sum a nested bill of materials - vba

Hi I have looked around extensively on the web but have not been able to find a way to calculate a nested table of totals.
My data is pictured below.
What I am looking for is a way to add up all of the sub items of an item and put that total in the cost of the original item.
so for instance the total of line 6 will be the sum of lines 7,8,9, and 10. but the total of line 2 will be the totals of lines 5,6,11, and 12 each of which needs to be seperatly subtotalled.
I have tried excels subtotal function, but it is clumsy and not a generalised solution. I may need to add or subtract components over time and have the totals calculated again.
I have tried a few if then and for loop combinations, as well as an attempt at a function that calls itsself, with very limited success.
I think I have a block in how to approach this, as well as some programming knowledge gaps, like can a function call its self, and if it does, will it automatically create an independant set of function instance variables, or will the new call overwrite the old instances variables.
Any help with methodology and knowledge would be great.
Thanks

Does this formula work for you? In a new column, say E, starting in E3 and copied down:
=SUM(IF(LEFT(B3:B$999,LEN(B3))=B3,D3:D$999,0))
Here 999 is a dummy last row --- change it to suit your situation.
Columns B and D are assumed to hold Outline and Bom Cost, respectively. The logic is: sum up all rows below (and including) the current row if and only if Outline starts like the current row's Outline. So if Outline in the current row is 1.2.3 it sums up all Bom Costs found below where Outline start with 1.2.3 (1.2.3.1, 1.2.3.2, 1.2.3.2.1, etc.).
This formula assumes that the outline is properly ordered.
It is also assumed that the Outline values are text. If they are not, the formula above will fail when Outline is a whole number (1, 2, ...). This longer formula converts whole numbers to text and should work:
=SUM(IF(LEFT(B3:B$999,LEN(B3))=IF(LEN(SUBSTITUTE(B3,".",""))<LEN(B3),B3,TEXT(B3,"0")),D3:D$999,0))
Hope this helps.

Related

Complex IF. formula in Excel

I checked various posts on IF formulas but I cannot find a way to receive the correct result in my report. I manage deliveries and I would like to calculate the delay days basing on the data from delivery report. The trick is that the delay will depend on the status of delivery, as in each case I have to consider a different date and column in Excel. These are the data:
Status of delivery:
Confirmed
Unloaded
Unloading
Not confirmed
Started
In route
Pick-up pending
Prepared
This delivery status is updated in C column in my Raw Data report. For each, I will have to calculate the delay in a different way therefore I figured that IF formula could be of use.
Below you can see the columns that contain the relevant dates for the calculations:
Status of delivery and reference date:
Confirmed - D
Unloaded - D
Unloading - D
Not confirmed - S
Started - D
In route - S
Pick-up pending - E
Prepared - S
I made this formula as below, sadly, only the first record is calculated correctly, the rest of the delays is "null".
=IF(C2="Confirmed";(TODAY()-D2);IF(C2="Unloaded";(TODAY()-D2);IF(C2="Unloading";(TODAY()-D2);IF(C2="Not confirmed";(TODAY()-S2);IF(C2="Started";(TODAY()-D2);IF(C2="In route";(TODAY()-S2);IF(C2="Pick-up pending";(TODAY()-E2);IF(C2="Prepared";(TODAY()-S2);"null"))))))))
Do you happen to have any idea where am I making the error which I don´t see? I will be grateful for any help. If it´s also relevant, I am using Excel 2016.
Breaking it down so the long line becomes readable.
=IF(C2="Confirmed";
(TODAY()-D2);
IF(C2="Unloaded";
(TODAY()-D2);
IF(C2="Unloading";
(TODAY()-D2);
IF(C2="Not confirmed";
(TODAY()-S2);
IF(C2="Started";
(TODAY()-D2);
IF(C2="In route";
(TODAY()-S2);
IF(C2="Pick-up pending";
(TODAY()-E2);
IF(C2="Prepared";
(TODAY()-S2);
"null"
)
)
)
)
)
)
)
)
At first glance, what I'm looking at is basically a vertical lookup schedule here.
So, I created these two colums. One is the text status we're looking for.
The other is the calculated date.
Single date VLOOKUp
Assuming D2, S2 and E2 are fixed fields I made the formula =TODAY() - $D$2
Then it's a simple matter of doing the VLOOKUP in the correct field.
Because we're working with a date type field we need to convert the number to text to get a meaning full date. (I used JJ in the screenshot for years because I have a dutch locale)
Then we also need to handle when VLOOKUP can't find anything, for that we use IFERROR.
=IFERROR(TEXT(VLOOKUP(F6;$A$2:$B$9;2);"MM-DD-YY");"NULL")
And now you have an easy to expand lookup table you can put anywhere, hide on a worker tab, etc.. where you can calculate your values, where you can add and remove values.
Many rows, many dates
But, say you have many rows with different statusses and dates, and you wish to know the number of days it'll take. Then this vertical lookup doesn't look so useful because it can only be used for one row.
We can still leverage VLOOKUP to make our life a bit easier
Assuming there are dates in colums D, E and S
=IFERROR(DATEDIF(TODAY();INDIRECT(ADDRESS(ROW();VLOOKUP(F2;$A$2:$B$9;2;FALSE)));"d");"NULL")
We use VLOOKUP to see which column we need to look in. We use a number here for column, not a letter.
We then use ADDRESS to get an excel address reference for the current ROW(), and the column we found via vlookup
We funnel that through INDIRECT so we can get the value from that targeted cell.
Then we get a DATEDIFference in days from offset today.
We wrap it all in an IFERROR to keep things clean.
You could use an INDEX($D2:$S2;0;VLOOKUP($F2;$A$2:$B$9;2;FALSE)) to get the same effect, as pointed out by Dirk Reichel but you have to mindful then that the index used is from the start of the matrix range. So here the matrix starts on row D. So D2 is index 1 instead of 4 it is with my original method, so you'd need to adjust the lookup table accordingly.

Excel formula not working as expected

I have a sheet that shows max values spent anywhere. So I need to find most expensive place and return it's name. Like this:
Whole sheet.
Function.
Function in text:
=IFS((A6=MAX(D2:D31)),(INDEX(C2:C31,MATCH(A6,D2:D31,0))),(A6=MAX(H2:H31)),(INDEX(G2:G31,MATCH(A6,H2:H31,0))),(A6=MAX(K2:K31)),(INDEX(K2:K31,MATCH(A6,L2:L31,0))))
Basically I need to find a word left to value, matching A6 cell.
Thanks in advance.
Ok.. Overcomplicated!
Firstly, why the three rows? it's a lot easier if you just have one long row with all the data (tell me if you actually need 3 I'll change my solution)
=LOOKUP(MAX(D2:D31);D2:D31;C2:C31)
The MAX formula will lookup the biggest value in the list, the Lookup formula will then match it to the name.
Please note: If more than one object has the maximum price, it will only return the first one. The only way I can think of to bypass that would be to build a macro.
EDIT:
Alright.. Multi Column solution is ugly and requires extra columns that you can just hide.
As you can see you'll need 2 new columns that will find the highest for each row, 2 new columns that will find the value for each of these "highest" (in this case tree and blueberries) and then your visible answer will simply be an if statement finding out which one is bigger and giving the final verdict. This can be expanded with an infinite number of columns but increases complexity.
Here are the formulas:
MAX(H2:H31)
LOOKUP(A5;H2:H31;G2:G31)
MAX(L2:L31)
LOOKUP(C5;L2:L6;K2:K6)
IF(A5>C5;B5;D5)

Get excel to create groups of data based on cell values

I have a question that has me stumped. I feel like I am very close to the answer, but cant ever create an adequate solution. I have tried nested IF statements, incorporating the AND function, incorporating the OR function, and I cant come up with something robust enough to answer this question
Here is my question
I am creating a program that automatically analyzes a stock using a oscillator equation. The results of these equations (in theory) predict how the stock will perform over the near term.
In this equations formula, a stock is considered underbought if the calculated oscillator is below 30 and overbought if it is above 80. I would like to group the cells by the contents of the calculated oscillator value.
The beginning of the period starts with the first instance of a value at or below 30 following the previous occurrence of a value at or over 80.
The period is closed with the first occurrence of a value at or over 80 occurring after the previously identified =<30 value.
There will be times that a value doesn't fit in to a period. For example, a value of 50 sandwiched between the end of the last period and the beginning of the next period will not have a group.
I have attached 2 pictures.
The first picture is a example of what the data could look like. The %D column is the calculated oscillator result. It is important to note that I would like to extend this solution to multiple stocks each having varying data. I will be using it to analyze stocks over varying times (say a 6 month period or a 12 month period). Therefore, the solution needs to be dynamic enough to fit varying amounts of cells and different distributions of data.
The second picture is a example of what I would like the result to look like. I have added a comments section to explain the reasoning behind the grouping in case my description above didn't make sense.
Image 1
Image 2
Please let me know if I can clarify anything for you. Any ideas or assistance is GREATLY appreciated
Put this in B2 and copy down:
=IF(AND(NOT(ISNUMBER(B1)),A2<=30),MAX($B$1:B1)+1,IF(MAX($B$1:B1)=0,"",IF(AND(ISNUMBER(B1),A1>=80),"",B1)))

SSRS MAtrix/Tablix

I have a report in SSRS report builder 2008 that has a chart that is a definitive size. I would like to make the matrix table fit neatly under the report as it would in excel. However it expands way past the report. I have tried turning can grow can shrink to false did not work. I have tried putting a rectangle and placing the matrix in there with no success. I tried setting the size in the tablix properties but it extends or shrinks below based on the data in the tablix. The tablix is just 6 lines the top line is a expression for the date and then there is previous year previous cumulative current yeat and current year cumulative and receipts %to last year. i have included the expresssions I used in the tablix not that I think it is causing the issue Any help will be greatly appreciated
=Sum(Fields!ID2013_Inventory.Value)
=Sum(Fields!ID2013_Inventory.Value)
=RunningValue(Fields!ID2014_Inventory.Value,Sum,"RECEIPTS_IND_DEC")
=SUM(Fields!ID2014_Inventory.Value)/SUM(Fields!ID2013_Inventory.Value)
Sorry I didn't follow up your comment earlier, it's been busy here...
There is a sledgehammer approach to this that will work, not sure if there is a more elegant way but here goes.
Fist some basics...
Determine how wide your matrix needs to be, let's say 25cm
Let's assume you have a couple of columns on the left that are both fixed at 2cm each. That gives us 21cm to put our varying columns in.
For now assume we only have 28 days, so we need to set the column width of the column group to 0.75cm (21/28).
Test and make sure everything looks OK.
Now here's comes that sledgehammer!
Make another 3 copies of your matrix and adjust the column widths for the next three number of days (so 29,30 & 31).
Now set the visibility of the of each matrix so that it only shows when the related number of days are returned in the dataset.
I don't know what your dataset looks like so I can't give much advice on determining the number of days returned but I often create another dataset that gets the value, in your case something like
SELECT COUNT(DISTINCT MyDateColum) as DateCount FROM MyDates
Or I guess you could probably base visibility on the month and whether its a leap year or not.
Hope that helps, if any of it is unclear let me know and I'll try to get back a little quicker this time.

Count unique string variants

There could be quite a simple solution to this, but I am trying to find the number of times a unique variant (i.e. non-duplicates) of a string appears in a column. However this string is only part of the text contained in a cell, and not the entire cell. To illustrate:
EuropeSpainMadrid
EuropeSpainBarcelona
AsiaChinaShanghai
AsiaJapanTokyo
EuropeEnglandLondon
EuropeSpainMadrid
I would like to find how many unique instances there are of a string that contains "EuropeSpain". So using this example, I would find that a variant of "EuropeSpain" appears only twice (given that the second instance of "EuropeSpainMadrid" is a duplicate).
A solution to this is to use pivots to summarise the data and remove duplicated; however given that my underlying dataset changes often this would require manual adjustments and corrections. I would therefore like to avoid adding any intermediate steps (i.e. PivotTables, other data sets etc) between my data and the counts.
UPDATE: I now understand to use wildcards to solve the first part of my question (counting the occurrences of "EuropeSpain"), however I am not yet clear on the second part of my question (how to find the number of unique occurrences).
Is there a formula or VBA code that could do this?
Using wildcards:
=COUNTIF(A1:A6,"="&"*"&C1&"*")
For without VBA but with some versatility, I suggest with Text in ColumnA (labelled), ColumnB labelled Flag and EuropeSpain in C1:
=FIND(C$1,A2)
in B2 copied down.
Then pivot A:B with Flag for FILTERS (and 1 selected), Text for ROWS and Count of Text for Sigma VALUES.
Apply Distinct Values if required (and available!), alternatively a formula of the kind:
=MATCH("Grand Total",E:E)-4
would count uniques.