I'm working through an Excel exercise in which I need to SUMPRODUCT two tables of related values. Unfortunately, I can't be sure the tables will always be ordered identically.
To get around this, I have looked up their values into a new third table; this works, however I'm now looking for a way to do it in one cell.
My code is currently
SUMPRODUCT(Resources_Used18[In House],OFFSET(Rate_comparison[Role],MATCH(Resources_Used18[Role],Rate_comparison[Role],0)-1,1))
For some reason however this doesn't seem to work and only ever returns zeros. The OFFSET(,MATCH()) is meant to reconstruct the second data array, this appears to work and when I test it with F9 it produces the array I'm expecting.
Additionally when I manually enter the array, it provides the correct answer.
So I think the error must be with SUMPRODUCT failing to recognise it as an array.
Where is the error and how can I correct my formula? Thanks for your help.
EDIT: Actually I need to correct myself, OFFSET produce the correct array when run in a cell of its however after I run the cell if I don't ctrl-shift-enter then produces an array of errors.
EDIT:EDIT: An example of the sort of data I'm looking is this,
Rate_comparison
| Role | Rate |
|------|------|
| 1 | 50 |
| 2 | 100 |
| 3 | 150 |
| 4 | 200 |
| 5 | 250 |
| 6 | 300 |
| 7 | 350 |
| 8 | 400 |
| 9 | 450 |
And
Resources_Used18
| Role | In house |
|------|----------|
| 9 | 23 |
| 8 | 24 |
| 4 | 25 |
| 3 | 26 |
| 1 | 27 |
| 7 | 28 |
| 6 | 29 |
| 5 | 30 |
| 2 | 31 |
I have seen this issue before, and cannot explain it. However, if you enclose the OFFSET function inside the N function, the actual values will be returned.
I did not check to see if the result (59,300) is correct however.
=SUMPRODUCT(Resources_Used18[ [ In house ] ],N(OFFSET(Rate_Comparison[ [ Role ] ],MATCH(Resources_Used18[ [ Role ] ],Rate_Comparison[ [ Role ] ],0)-1,1)))
According to Tushar Metar, The OFFSET function, when used with an array as the 2nd or 3rd argument, returns an undocumented data structure that is understood only by Excel. The N function converts the data from the internal structure into one that can be displayed or used for further analysis. Laurent Longre deserves the credit for discovering this capability of the N function.
Related
I have a question related to a kind of duplication I see in databases from time to time. To ask this question, I need to set the stage a bit:
Let's say I have a database of TV shows. Its primary table Content stores information at various levels of granularity (Show -> Season -> Episode), using a parent column to denote hierarchy:
+----+---------------------------+-------------+----------+
| ID | ContentName | ContentType | ParentId |
+----+---------------------------+-------------+----------+
| 1 | Friends | Show | [null] |
| 2 | Season 1 | Season | 1 |
| 3 | The Pilot | Episode | 2 |
| 4 | The One with the Sonogram | Episode | 2 |
+----+---------------------------+-------------+----------+
Maybe this isn't ideal, but let's say it's good enough to work with and we're not looking to change it.
Now let's say we need to build a table that defines air dates. We can set these at any level, and they must apply down the hierarchy (e.g., if set at the Season level, it applies to all episodes within that season; if set at the Show level, it applies to all seasons and episodes).
So the original air dates might look like this:
+-------+-----------+------------+
| airId | ContentId | AirDate |
+-------+-----------+------------+
| 71 | 3 | 1994-09-22 |
| 72 | 4 | 1994-09-29 |
+-------+-----------+------------+
Whereas the air date for a streaming service might look like:
+-------+-----------+------------+
| airId | ContentId | AirDate |
+-------+-----------+------------+
| 91 | 1 | 2015-01-01 |
+-------+-----------+------------+
Cool. Everything's fine so far; we're adhering to 4NF (I think!) and we can proceed to our business logic.
Now we get to my question. If we implement our business logic in such a way that disregards the referential hierarchy, and instead duplicates the air dates down the hierarchy, what is this anti-pattern called? e.g., Let's say I set an air date at the Show level like above, but the business logic finds all child elements and creates an entry for each one, resulting in:
+-------+-----------+------------+
| airId | ContentId | AirDate |
+-------+-----------+------------+
| 91 | 1 | 2015-01-01 |
| 92 | 2 | 2015-01-01 |
| 93 | 3 | 2015-01-01 |
| 94 | 4 | 2015-01-01 |
+-------+-----------+------------+
There are some pretty clear problems with this, but please note that my question is not how to fix this. Just, is there a specific term for it? I want to call it something like, "disregarding data relationship" or, "ignoring referential context". Maybe it's not strictly a database anti-pattern, since in my example there's an external actor inserting the excess rows.
Goal: Use SUMIFS to get the sum of value if color is Red or Yellow. Outcome should be 3.
+---+--------+-------+---+-----------+
| | A | B | C | D |
+---+--------+-------+---+-----------+
| 1 | Key | Value | | Condition |
| 2 | Red | 1 | | Red |
| 3 | Yellow | 2 | | Yellow |
| 4 | Green | 3 | | |
+---+--------+-------+---+-----------+
Problem:
It works if I hardcode the condition {"Red","Yellow"}. The result is 3.
=SUM(SUMIFS(B2:B4, A2:A4, {"Red","Yellow"}))
But if I reference the condition by cell D2:D3, I get 0.
=SUM(SUMIFS(B2:B4, A2:A4, D2:D3))
Question: How do I reference the condition dynamically by cell and make it work?
Use SUMPRODUCT() instead of SUM():
=SUMPRODUCT(SUMIFS(B2:B4,A2:A4,D2:D3))
One note:
This variation allows the expansion of the lists without the need to reapply the ranges:
=SUMPRODUCT(SUMIFS(B:B,A:A,D2:INDEX(D:D,MATCH("zzz",D:D))))
Alternatively, you can use SUMIF() together:
=SUMIF(A2:A4,"Red",B2:B4)+SUMIF(A2:A4,"Yellow",B2:B4)
Or make sure you're using CTRL+SHIFT+ENTER with your current formula attempt.
EDIT:
Here's what I have: An Access database made up of 3 tables linked from SQL server. I need to create a new table in this database by querying the 3 source tables. Here are examples of the 3 tables I'm using:
PlanTable1
+------+------+------+------+---------+---------+
| Key1 | Key2 | Key3 | Key4 | PName | MainKey |
+------+------+------+------+---------+---------+
| 53 | 1 | 5 | -1 | Bikes | 536681 |
| 53 | 99 | -1 | -1 | Drinks | 536682 |
| 53 | 66 | 68 | -1 | Balls | 536683 |
+------+------+------+------+---------+---------+
SpTable
+----+---------+---------+
| ID | MainKey | SpName |
+----+---------+---------+
| 10 | 536681 | Wing1 |
| 11 | 536682 | Wing2 |
| 12 | 536683 | Wing3 |
+----+---------+---------+
LocTable
+-------+-------------+--------------+
| LocID | CenterState | CenterCity |
+--- ---+-------------+--------------+
| 10 | IN | Indianapolis |
| 11 | OH | Columbus |
| 12 | IL | Chicago |
+-------+-------------+--------------+
You can see the relationships between the tables. The NewMasterTable I need to create based off of these will look something like this:
NewMasterTable
+-------+--------+-------------+------+--------------+-------+-------+-------+
| LocID | PName | CenterState | Key4 | CenterCity | Wing1 | Wing2 | Wing3 |
+-------+--------+-------------+------+--------------+-------+-------+-------+
| 10 | Bikes | IN | -1 | Indianapolis | 1 | 0 | 0 |
| 11 | Drinks | OH | -1 | Columbus | 0 | 1 | 0 |
| 12 | Balls | IL | -1 | Chicago | 0 | 0 | 1 |
+-------+--------+-------------+------+--------------+-------+-------+-------+
The hard part for me is making this new table dynamic. In the future, rows may be added to the source tables. I need my NewMasterTable to reflect any changes/additions to the source. How do I go about building the NewMasterTable as described? Does this make any sort of sense?
Since an Access table is a necessary requirement, then probably the only way to go about it is to create a set of Update and Insert queries that are executed periodically. There is no built-in "dynamic" feature of Access that will monitor and update the table.
First, create the table. You could either 1) do this manually from scratch by defining the columns and constraints yourself, or 2) create a make-table query (i.e. SELECT... INTO) that generates most of the schema, then add any additional columns, edit necessary details and add appropriate indexes.
Define and save Update and Insert (and optional Delete) queries to keep the table synced. I'm not sharing actual code here, because that goes beyond your primary issue I think and requires specifics that you need to define. Due to some ambiguity with your key values (the field names and sample data still are not sufficient to reveal precise relationships and constraints), it is likely that you'll need multiple Update statements.
In particular, the "Wing" columns will likely require a transform statement.
You may not be able to update all columns appropriately using a single query. I recommend not trying to force such an "artificial" requirement. Multiple queries can actually be easier to understand and maintain.
In the event that you experience "query is not updateable" errors, you may need to define other "temporary" tables with appropriate indexes, into which you do initial inserts from the linked tables, then subsequent queries to update your master table from those.
Finally, and I think this is the key to solving your problem, you need to define some Access form (or other code) that periodically runs your set of "sync" queries. Access forms have a [Timer Interval] property and corresponding Timer event that fires periodically. Add VBA code in the Form_Timer sub that runs all your queries. I would suggest "wrapping" such VBA in a transaction and adding appropriate error handling and error logging, etc.
I want to add a placeholder to a cell that includes a count of rows from that dataset that have that the same value.
Example:
| ID | Value |
| 1 | 123 (3) |
| 2 | 123 (3) |
| 3 | 456 (2) |
| 4 | 123 (3) |
| 5 | 456 (3) |
| 6 | 789 (1) |
This is what I have so far, but it obviously doesn't work:
Fields!cpt4_code.Value
Instead of it indicating how many times that value occurs, it simply count the number of rows return in that dataset.
Is this even possible with one dataset?
You should use LookupSet for this:
=LookupSet(Fields!fieldOne.Value, Fields!fieldOne.Value, Fields!fieldOne.Value, "DataSetNameHere").Length
LookupSet returns an array, hence the ".Length" at the end.
Think this kinda thing is what you need
=Sum(IIF(Fields!field name.value,1,0),"DatasetNameHere")
I have "components" which can be assembled in different ways into a "system". I want my database to hold all these "components", their type specific data and define how they are connected to each other to form a "system".
The systems are typically gearboxes and they can have rather complex branched designs. Let's start with an easy example:
This system is built up out of Masses (horizontal lines) and Stiffnesses (vertical lines). Gears and clutches are types of masses and come in pairs. Colors represent different branch speeds due to gear ratios. Here's a (bad) example of how I could store everything from this particular illustration:
ID | Type | Clutch | Ends | DrivenBy | NoOfTeeth| Mass | Stiffness
--- | ---- | ------ | ---- | --------- | -------- | ---- | ---------
1 | Mass | | Input1 | | | 5 |
2 | Stiffness | | | | | | 15
3 | Mass | 1.1 | | | | 2 |
4 | Mass | 1.2 | | | | 3 |
5 | Stiffness | | | | | | 20
6 | Gear | | | | 10 | 4 |
7 | Stiffness | | | | | | 30
8 | Gear | | | | 4 | 5 |
9 | Gear | | | 8 | 7 | 2 |
10 | Stiffness | | | | | | 40
11 | Mass | | | | | 4 |
12 | Stiffness | | Output1 | | | | 10
13 | Gear | | | 6 | 5 | 4 |
14 | Stiffness | | | | | | 20
15 | Mass | 2.1 | | | | 4 |
16 | Mass | 2.2 | | | | 3
17 | Stiffness | | | | | | 30
18 | Mass | | Output2 | | | 2 |
Obviously, this is not a very good way to store the data. This design pattern resembles somewhat of a "Repeated attributes" since each component type has a different attribute to be filled. I could create a table for each type of component, but things become more complex when looking at other examples, such as this 2-stage gearbox:
There are also examples with more than 1 input and several outputs, but I can't post more links due to low reputation.
Eitherway, you will see that the usual hierarchical data storage doesn't apply here because the data is not purely "tree-shaped" where everything branches off from 1 main branch.
I think that even though I could store data in the above mentioned way, I will get huge difficulties when it comes to the programming stage.
To add to the complexity, these gearboxes are actually sub-systems to a much bigger system.
So, any suggestions on a good way to store this type of data?*
Perhaps this is a possible way of doing it?
Here you will see that there is a "main" table called GearboxBranch, keeping track of all elements in the gearbox, giving them an id and to identify in which branch the element exists.
Then for the elements themselves, masses are defined in their dedicated table, so are stiffnesses. Gears and Clutches (which are types of masses) are then defined in their perspective tables. A recursive relationship is existing in the gear table, since one gear has to be driven by at least one other gear.
Furthermore, the table with Shaft Ends defines which of the elements in the gearbox are input or output and what number they have.
I can't seem to see any problems with this method, but I'm a little unsure how to get data out of the database. There will be considerable coding involved I'm afraid.