Dynamic Lists & the Advanced Part
Every table in DimSum (lumber sizes, steel shapes, boxes, price lists) is a Dynamic List in the Material Library; a property can take its choices from a list or a table, and an Advanced Part filters one table down to the right row — Item #, cost, supplier and the rest — from the answers on the tool's Form.
Overview
- Feed dropdowns (a Beam's size dropdown lists the distinct Nom. Width × Nom. Depth values).
- Supply defaults (list-linked properties): a property like Waste % links to a list row, with the list's default row at the top.
- Feed formulas with
LOOKUP()andMATCH(), including decision tables that replace long IF chains. Coming - Fill an Advanced Part: the part filters its table by the item's answers — Stock Length equals Height, Call Size equals Stud Size — and the row first in line fills every column of the part. If nothing is left, it is flagged No material matches these conditions. This was List Matching (The Advanced Part).
Lists are what make a part "real". DimSum ships no hard-coded material rules. A "Studs" part under a wall is just a formula until it's loaded from, or matched to, a table row such as STUD-92, 2x4 Stud 92-5/8 SPF. That's how DimSum stays trade-agnostic and how every company builds its own setup.
— dropped. A price is a column of a table; re-import the table's CSV and the update screen offers the new number.
What is built so far: simple lists. A simple list is a named set of values, one per line — no columns, no prices, no matching.
- Each is marked below.
Where to find it
- Tools tab → Material Library: two tabs, Lists — the same lists, moved in — and Tables, under a read-only DimSum Defaults heading (empty for now, and saying so) and Custom, which holds one folder per
.tsumin your tools folder, each with its tables — and Lists grouped the same way. The buttons under the folders name the folder of whatever is selected — Table in My Tools, Import… into My Tools, Create a CSV template…. Folders are made from the Tools tree's right-click Custom → New folder… (Tool Designer → Folders). This is where the entry below went. Custom is one folder per.tsumin your materials folder (Documents\DimSum Materials) instead, apart from the Tools tree; right-click Custom here offers New folder…, Show the materials folder and Add a .tsum to the materials folder…, and the buttons read Table in My Tools, Import… into My Tools and, under Lists, List in My Tools. - Tools tab → Lists & Tables: the rail of list names, + List, the Values, one per line box and Save values — and below them the library's own Tables, with + Table and Import…. Both rails rename in place — double-click a row, or press F2, and still do in the Material Library. See Tool Designer → The Material Library. Gone — a job has no tables of its own; tables and lists live only in the Material Library.
- Any property → Settings… → Lists / Tables → a table: the property becomes a dropdown of one column and fills in the rest. This is where Set from a table… went; that entry is gone.
- Any property → Settings… → Lists / Tables: its own typed-in values, one of those shared lists, or a table.
- — lists with columns are tables, in the Material Library above; the Pricing page was dropped.
- Tool Designer → a tool → Parts → + → Advanced part: the + drops down New part · Advanced part · Load part…; the new part is called Advanced part until you rename it. Its table, filters, sort and Try it sit in a pane at the top of the part, above its properties (The Advanced Part). (This replaces Part → List Match, which never had a settled place on a part.)
- A job → a placed Advanced Part → Properties panel: the same pane, read-only, under the part's properties — what it matched and why, the filters in words, the sort, and Filters are set on the tool, in the Tool Designer.
- Estimating tab → Needs attention: an Advanced Part with no match is a Warning row — where it is, the property Material match, and the part's own sentence, No material matches these conditions — … The part's pane says the same, and its row in the parts tree carries a ⚠.
- Project → Refresh Center for everything that has changed in your libraries since this project took its copy.
- Built-in masters live in Behind the scenes; editable copies are in your
.tsumlibraries.
How to use it
Make a simple list, and point a property at it
- Open the Tools tab and click Material Library on the left rail, then Lists. The left side is a rail of the list names — every folder's at once, each under its folder's name (or, in a job, the job's).
- + List makes one, named and straight into rename. Click a list's name later to rename it; Delete removes it and says what happens to any property pointing at it.
- The right side is one box, Values, one per line. Type the values and click Save values. One
Ctrl+Zputs the whole list back as it was. - Now open any property's Settings… → List and point it at that list. The row reads "Choices from the Wall Side list".
- Only allow choosing from list works exactly the same on a shared list as on typed-in values: with it on, anything else is refused; with it off, the list is a shortcut and what you type is kept.
Division and Trade are no longer hard-coded. They ship as real lists in every job and every library, and their properties point at them:
- Their values were yours — you opened Division and changed the 35 CSI divisions to your own numbering. they couldn't be edited in the Tool Designer, because they showed only under DimSum Defaults, which is read-only.
- Their names are not. Rename and Delete are on screen but greyed, each with the reason: "Division is one of DimSum's own lists, so it can't be renamed — its values are yours to change" and "…so it can't be deleted".
Where a list lives. In the same file as the property pointing at it: a job's lists are in the .dsum, a library's in the .tsum, and nothing in a job ever reaches into a library. No screen edits them in a job; edit the list in the Material Library and the job's choices follow while that folder is on this machine. A table does not.
One to look at: DimSum Defaults ships a list of its own, Wall Side (Ext / Int), with the example wall's own Wall Side property pointing at it.
A list holds up to 10,000 values.
Tables
A table is a list with columns: Framing with a row per wall type, and columns for Stud Spacing, Plate Count, Height, Colour. It does three things, and no more:
- Pick a row and it sets your properties. Every column whose name matches a property (capitals ignored) sets that property.
- A column with no property creates one, with the column's type, unit and format — which is why a column carries all three.
- Pull one column out as a list. A copy, not a link, so the list keeps working when the table is edited or gone.
Make one. Tools → Material Library → Tables. + Table asks for the table's name and its first column — "First column — it names each row" — because a table with no columns has nothing to name a row by, and DimSum will not invent one for you. Then add columns (name, type, unit, format), add rows, and type into the cells. Every rename is an inline box; every change is one Ctrl+Z.
The label column names the row — it sets nothing. A row needs a readable name (2x6 @ 16"), and that is its label column's value. That column is tagged names the rows, is never matched against a property, and is why a column called Name is an ordinary thing to have. Name rows by this on another column moves the label; the label column itself cannot be deleted — deleting it would leave the table silently naming every row by whichever column came next.
Set from a table… — and it tells you first. Right-click an item (or a part row, or the Properties panel's menu) → Set from a table…, pick the table, pick a row. Before the button, it says what will change, what will be created and what it will read afterwards. A table that sets eleven properties is the one place a single click can rewrite a screenful, so it says so first. One Ctrl+Z puts every property back, including the ones it created.
Gone with the job's own tables — a job holds no table to follow, so every pick in a job is a copy of a Material Library row, frozen, and its update screen offers newer values. Kept below for the record. A property set from a row is not a copy: it reads {Table > Framing > Stud Spacing}, "that column of the row this item follows", and its row says Follows Framing — 2x6 @ 16".
- Edit the table and every follower follows, live, in the same job.
- Type your own value and that one property stops following. Its siblings carry on, because they follow the same row.
- Clear it (the ↺ on the row, or Clear — back to following Framing on its menu) and it followed again — the menu reads Clear — back to its default.
- Stop following the Framing table, on the row's menu, stopped the whole item following and kept every number it last read —.
- Pick a different row and every following property re-reads at once.
All of that holds in one file — a library following its own table.
Height, Colour and Line Width follow too — to the drawing. Height, Thickness, Line Width, Colour, Opacity and Description follow a row exactly like any other property, and the canvas, the Project Tree and the lists show what the row says, not just the Properties panel. A value the drawing cannot use — a blank, a negative height, a colour that is not a colour — leaves the drawing alone; the property still follows and still shows what the row says.
Name and Type are refused, with the reason. A part's Type decides what the part is, not what it is worth.
Locked refuses the whole row, and says which property: a table that half-applied would be worse than one that did not apply.
Deleting a row, a column or a whole table first freezes everything following it — the formula goes, the number stays, and the row says it stopped following — in the same Ctrl+Z. Renaming a table or a column rewrites every formula that names it.
The row bin asks first. Deleting a row always froze its followers correctly; what was missing was the question. It now asks in the column bin's own second clause, word for word, because the consequence is word for word the same — and the bin's hover says all of it rather than half. No changes nothing.
Rename in place on both rails. Double-click a table or a list in the rail, or press F2, and the row itself becomes the box. It is the same rename as the editor's title, not a second route — one command, one Ctrl+Z, and the same warning on hover: "Every formula following this table is rewritten with it." for a table, and "Every formula naming this list as a table is rewritten with it" for a list. A preloaded list and a read-only library refuse there exactly as they refuse at the title. The Material Library's own rail renames the same way, for the same reason and with the same warning.
Import and export. Import… on a table (or on the Tables rail, for a new one) ran the same five-step wizard as the Materials Library: key column, each column linked / created / ignored, required columns, and a preview of every count before anything is written. Export… writes the table back out as a CSV. A list that was imported — one with a key column — also shows as a section of the Materials Library.
a library's import asks nothing. Import… in Material Library → Tables, choose a CSV, and the headers decide: a header matching a known property — the material standard and the offered set, by their spellings, with or without the unit — is that property (Material is Made Of); every other header becomes a custom Text property in a Custom group; the key is Item #, else the first column; the column that names each row is Name, else Description, else the key. A file named like a table already in the folder it goes into — the one Import… into ‹folder› names — re-imports into it on the key; any other file makes a new table named after the file. A table's own Import… — top right of the open table, beside Export… — re-imports into that table whatever the file is called, on its own key: rows updated in place, new keys added, missing ones kept and flagged (Tool Designer → Import into a table you already have). One Ctrl+Z, and one line back — "Lumber2: 30 rows — 14 columns matched, no new custom properties, keyed on Item #." Every column then has its own settings from Settings… on its head — type, units (with $ under Money; a $ column reads $3.48) and group — one undo each, and a type change says by count what it could not convert and leaves those cells as they were, marked. Settings… opens a dialog, Column settings, with the column's name beside it; Esc closes it. Full detail: Material Library → Import a table.
Settings rows in the file
A table's CSV may carry each column's settings in the rows under its names: Row 1 Name (always), Row 2 Type, Row 3 Units, Row 4 Group.
- Row 2 is Type only if at least one cell is filled and every filled cell is a type word — Number, Percentage (or Percent), Slider, Text, Yes/No (or Yes / No, Checkbox, Boolean), Color (or Colour); capitals, spaces,
/,-and_don't matter. Otherwise there are no settings rows and the file imports as before, row 2 its first row of data. - Row 3 is Units after a Type row, when every filled cell is a known unit — DimSum's units with
$and%, the standard'slb,psi,in4andin3, your own units from System Settings → Units, and any unit a column in that folder already uses. An all-blank row 3 counts. A row 3 that is plainly units — every filled cell under a Number, Percentage or Slider column, short, no digits except a power likem2— is read as units even with one DimSum doesn't know: the known ones are set, and the unknown one is left unset and named in the answer (row 3: "bdft" isn't a unit DimSum knows, so Volume has none — add it in System Settings → Units and import again). - Row 4 is Group after both, any text; an all-blank row 4 counts too.
- A blank cell leaves that column's setting as the import would have made it.
- The one-line answer ends …; types from row 2, …; types and units from rows 2–3 or …; types, units and groups from rows 2–4, plus …; N cells could not be converted when any didn't fit.
- One
Ctrl+Ztakes the table and its settings together. Re-importing such a file into a table sets the settings on its columns, converting cells the way a column's Settings… does — what will not convert is left as it was, marked, and counted — and a setting the column already has isn't applied again. - A Material Library table's Export… writes all four rows — Type as the Settings… dialog labels it (Number, Percentage, Slider, Text, Checkbox, Color), Units as stored, Group, blank where there is none — so an exported table re-imports with its settings. Create a CSV template… writes plain names, then the three rows, then its example row.
- A column's Settings… is unchanged — And a job's own Project Settings import and export were unchanged — removed them.
For example, samples\Lumber3.csv — the same 30 boards with the three rows added — has Item #, Description, Cost Each, Width among its columns, typed Text, Text, Number, Number, with units (blank), (blank), $, in and groups Product, General, Cost, 3D; its first board is STUD-92, 2x4 Stud 92-5/8 SPF, 3.48, 1.5. Worked through in Material Library → Settings rows.
On an ordinary part you still pick the row.
Lists / Tables — a property that takes its values from a table
· "It should ask, list or table when we drop down the list settings. Call it Lists/ Tables" · "We select the Table, 'Common Animals'. It asks us what column, Description should link to… Then it asks, what property each column links to… Action: … just select, create new property." · "There should be an ignore this column button." · "Everything should be editable later on."
- The row is called Lists / Tables — and Material Library: Lists / Tables, Its dropdown groups say where each choice comes from: Its own values (typed below); Lists; in a job Tables in this job; Material Library → Custom → ‹folder› for each folder that has tables; and Material Library → DimSum Defaults once it has tables. no folders — the dropdown has two groups, Lists (Division (35), Trade (20), Wall Side (2) …) and Tables (Common Animals (3), Lumber (30), Lumber2 (30)), a folder name appearing only when two share a name. Any property's Settings… offers Its own values, every shared list, and every table — the file's own, and in a job every library's on this machine (Tables in Critters). A list works exactly as before.
- A table asks two questions, in the same dialog. Which column does this property link to? — the one called what the property is called, or the first, already picked (the label column may be the one). Then what each other column sets: an existing property of this owner, pre-matched by name (Name included), Create new property, or Ignore this column — a button on every row — with Ignore all and Match by name above them. The label column names the row and sets nothing. A line under the list says what a pick will do.
- The property becomes a dropdown of that column. Description offers Frog / Fox / Cricket; picking Frog sets Color and whatever Action links to, as one undo; picking Fox later switches them. A property answered Create new property is made, with the column's name and unit, the first time a row is picked and never twice. In the Tool Designer the tool follows the row (
{Table > Common Animals > Color}) when the table is in the tool's own folder; a table in another folder is copied in — the pick writes the values, frozen, with the folder's, the table's and the row's names kept beside them, so the tool keeps them even where that folder isn't, and its dropdown offers the rows while that folder is in your tools folder. a tool folder holds no tables or lists, so every link is the another folder kind — a list the same as a table: choices while its material folder is on this machine, a pick copying the values in (Undo Choose Fox in Framing), the value kept always, newer values on the update screen. Nothing is followed live across files. The dropdown's groups are Lists → DimSum Defaults, Lists → Custom → ‹folder›, Material Library → Custom → ‹folder› and Material Library → DimSum Defaults, and under a linked row: Choices from the Common Animals table in My Tools — sets Color, Action. In a job the pick writes the numbers, frozen, and the update screen offers the row again when it moves on in the library. - A table with every other column ignored is a list. "We can use a table as a list, by not setting any of the other properties/ columns in a table." — Ignore all does it, and the row reads Choices from the Common Animals table — used as a list.
- Everything is editable afterwards. Settings… reopens on the table with the answers as saved; change them and Save. Set the row back to Its own values or a list and the property is an ordinary box again — a list or a table, never both.
- A table whose folder is not in your tools folder leaves the property its value and no choices, and says so: "Common Animals is in My Tools, which isn't in your tools folder — the value is kept". Never an error. it reads "Common Animals is in My Tools, which isn't in your materials folder — the value is kept".
- A column can set Name: the pick renames the item under the ordinary rename rules, and a name a sibling already has refuses the whole pick.
What went: Set from a table… and its prompt. Every route it had — pick a table, pick a row, a property the item has not got pulled in with its name and unit, one undo — is reachable through the row above, and the per-column answers say what a pick will do before any row is chosen. Stop following the … table stayed on the item's ⋯ menu for a row of the job's own table, removed the job's tables and the entry with them.
Bind a property to a table row
*Kept for the record.
The grain is the item and the row — it always was.
- Where it lives. A property's Settings… → List row — the one that points at a shared list — grows a second kind of answer: a list, or a table.
- The prompt, in order. Picking a table closes Settings and opens Set from a table… in its prompt shape: Which column sets O.C.?, then What else should this row set? — every column of the table against the properties the item already has, pre-matched by name, with All and None as one click each.
- The prompt says which is which before you press it: sets Species, or new property, in in, in Framing.
- One gesture, one undo. The whole bind — every property it set and every property it made — is one command and one
Ctrl+Z. - Everything is editable afterwards.
Where the pairing lives is the formula. Saying Stud Spacing sets O.C. writes {Table > Framing > Stud Spacing} onto O.C., and that is the whole record of the pairing. So the update screen looks for the property already following a column before it falls back to matching by name — without that, the first Update after a prompt would have re-matched Stud Spacing by name and made a second property beside O.C.
Refused before anything is written, the same way Locked is: a pick naming the label column, a column of another table, or a property this item does not have.
What does not change: the formula a bind writes, the refusals Set from a table… already had, the column pass that writes an answer into a column-backed built-in, and Unlink, which still keeps the number.
The honest limit. The List row is only drawn for a property type that can have a list — text, number and the list-ish kinds. A Colour or a Yes/No has no List row to grow, so those are still bound from Set from a table… on the item itself. Making the List row appear on every type is a change to the List row, not to the bind, and it is not in this package.
The update screen
Titled Update from the Material Library (it was Update from the library).
Inside a job, a row keeps following live, and nothing asks. The update screen is for the other distance: a table that came into the job with a tool, and has since moved on in the library.
- It opens by itself when you open a job with something to review, and any time from Refresh in the top bar — the badge says how many places are waiting.
- Grouped by table row, with old value → new value for every property an update would change.
- Mass selection: tick one item, tick a whole group, or Select all; then Update selected or Skip. Skip is remembered for that version, so it does not ask twice about the same change — a later change asks again.
- One
Ctrl+Zputs the whole batch back, however many items it touched. - A property you typed over is never offered. It stopped following on purpose, and offering it would undo that decision.
- Locked refuses, and the screen says which, in the same words the rest of the app uses.
What it offers. A change made in the same job reaches every follower live, so it is never offered here. It offers two things: structural changes — a column added to a table after items were set from it — and a newer library number, for a part that was placed from a library and holds its numbers frozen. It finds that row again by name, among whatever libraries are open, matching the three names the part carries — library, list, row key — and lists every instance of that row as old → new. A library that is not open is simply not among the rows it can offer: no error, no path to mend, nothing to say. Skip writes nothing and remembers a version nobody took. Parts are offered and updated like anything else — before it, a job's parts came through the screen labelled wrong and could not be updated.
An unticked instance keeps its number, and is offered again next time. There is no shared cell now. An unticked instance keeps its number because the number is its own, and it comes back the next time that library is open: "keeps the number it has now, and the update screen will offer this again."
In the Tool Designer
The same screen asks the Tool Designer too. A part loaded into a tool from a table row keeps its folder, table and row names — a frozen copy, linked — and when the row or its table changes it is offered here. (A row picked on a linked property, Critter's Frog, is linked the same way.) The head says it: "1 place to review" — "1 part or tool in your tool folders came from a Material Library row that has changed since — a price, a size, or a column's Type, Units or Group. Nothing is written until you say so, and the Material Library itself is never changed from here."
- What counts as a change: a cell of the row (Cost Each 3.48 → 3.79); a column's settings — Type, Units, Group (Item # — Type: Text → Number); a column added (a new property on the part) or removed (offered as removed; the part keeps its value unless you take it). A value that won't convert to the new type is kept — Item # STUD-92 stays.
- Grouped by row, with the table, its folder and its version — 2x4 Stud 92-5/8 SPF · Lumber2 in My Tools · version 6 — then per place (PART IN FRAMING).
- Select all, Update selected (1), Skip (remembered per version) and Close. One Undo per update, in each tool folder it touched — Undo Update 1 part from Lumber2 in Framing. A material folder is never written. With nothing left: "Nothing to review — Every part loaded from the Material Library is up to date…"
- Unlink at the top of a linked part — Linked to Lumber2 → STUD-92 · Unlink — stops it being asked (Tool Designer → Parts stay linked).
A job is asked on its own screen, as above, for the numbers it froze when a tool was placed; and a tool changed in the designer reaches the jobs that placed it, below. A new price a linked part took here from its Material Library row reaches a job only under its row — never a second time under the tool (A changed tool).
A changed tool
Placing a tool copies it into the job (Tool Designer → When you change a tool). So when you later edit the tool in its folder, nothing in a job changes by itself — not the items already drawn, not their numbers.
When it asks. Every placed item remembers which tool it came from and which version of it. Open a job with anything behind and the screen opens by itself; it compares each item with the tool in its folder on this machine. With any tool behind, the screen is titled Updates (with only rows behind, still Update from the Material Library), and it holds both kinds of group: a changed row, as before, and a changed tool. The top bar's Refresh counts rows and tool items together — 2 waiting.
What a tool's group shows. Its head names the tool, its folder and the versions — Critter · Framing · version 28 → 31 — 2 items. Then what changed, listed once for the tool:
- a formula, old → new, named by where it is — Studs › Qty;
- New part: Top Plate, Removed part: Blocking, and a part renamed;
- a setting — Stud Spacing · Group, Color #00AA00 → #CC5500; an Advanced Part's table, filters or sort, Studs · Filters, never the values its own match wrote;
- a property added or removed.
Values are written the way the Properties panel writes them — 8' → 10'. Under the changes, every item placed from that tool, each with a tick — named with a number when two share a name, with its sheet beside it: Critter 2 · A-101 · Foundation — and under each item, what it keeps: Height — kept, you set 9'.
Update, Skip, and one Undo.
- Update selected takes everything ticked — rows and tools together — as one Undo, labelled Update 2 items from Critter.
- Skip is per tool version: it skips that version for every item placed from that tool, and its tooltip says so. The job is asked again when the tool changes again.
- Nothing is written until you say so. The job's values move only when you accept, so the Properties panel never shows a change the screen is still asking about.
- If the tool has changed again since the screen was drawn, Update is refused with a line saying so; Refresh offers the newer version.
What you changed on a placed item stays yours. A value you typed or picked on the item — the ones the Properties panel tints, set here — is kept, and so is any value that no longer matches the version you placed from; the screen says so under the item: Height — kept, you set 9'. A part you deleted from the item comes back only if the tool adds it new. A part you renamed keeps your name.
A tool whose folder isn't on this machine is never offered. DimSum can't compare against a tool it can't find, so nothing in the job changes. A tool deleted from its folder is the same. A folder that is there but won't read is named on the screen.
How it fits with row updates.
Not offered. Changes to the and input defaults aren't listed on the screen — they do come into the job's copy of the tool when you accept. a changed label template is listed like any other setting, as Label: changed; taking it changes the job's copy of the tool, never the items, which follow it (the Label tab). And taking the tool's value for a property you edited is a later build: today your value is kept.
What a job stores: the numbers, frozen
A job opened with its library gone shows the numbers it was given, frozen.
- Placing copies values, not a list. A part placed from a library arrives holding literal numbers, not
{Table > … > …}formulas. It reads the same numbers on any machine, with no library present, forever. - No table reaches the job — not the
.dsum, and not its journal either: the freezing happens while the command is being planned, so the payload that lands, and every redo that reads it back, has no table in it. - A formula is frozen too, not just a bare reference.
{Table > Lumber > Cost}lands as the number it last read, and{Table > Lumber > Cost} * 2lands as8.42 * 2— the reference replaced where it stands, the arithmetic left alone. With no table in the job, a formula still naming one would be a screenful of ERROR. - It remembers where it came from, by name: the library's name, the list's name and the row's key — a key, not an id, because it has to mean the same thing in a file that has never seen the row. Nothing resolves it; it exists so the update screen can find the row again while that library is open.
- Nothing in a job changes by itself, ever. The update screen is the only way a newer number arrives, with the same per-instance ticks and the same one undo.
- Nothing was dropped to do it.
A library is untouched. .tsum → .tsum still carries its tables: copy a saved part or a tool into another library and the table comes with it, because a library is self-contained and its parts follow their rows live. A library has no update screen, so one that already has the table keeps its own cells and gains only what it lacks, and a table is matched by its id, so the same one is never pulled in twice. Only the .dsum hop changed.
- Renaming a table in a library rewrites every saved part, and every part of a tool, that follows it; deleting a row, column or table freezes them at their number — in a library as in a job.
- Save as tool… on a frozen part carries the three names back out to the library, not a row.
- Known, and not built: a tool copied into a second library follows that library's own copy of the table.
Create or edit a list
This was the plan for lists with columns. Excel import was dropped — CSV is the only import and export.
Use a list for defaults (list-linked properties) Coming
Kept here as designed.*
Instead of a pile of global settings, common values come from lists with a default row at the top.
- Open the Waste % list. It has rows 10% (default), 5%, 20%, 25%. The default row is the one at the top (drag to reorder, or right-click → Set as default).
- In a tool (or on an instance, or a part), click the Waste % property → Link to list → Waste % → pick a row, or leave it on Default.
- Walls stay on Default (10%). On the Roof tool, pick the 25% row: roofs now always place with 25%.
- Need 15%? Add a 15% row to the list. Want a new company default? Drag 5% to the top. Every property linked to Default follows; properties linked to a specific row keep that row.
- Decouple: right-click the property → Unlink (custom value) and type 18% for this one tool or instance. It shows ◆ until you re-link it.
The same pattern works for labor rates, markups, tax rates, plate heights, wall types and anything else. Tax is never applied unless the user sets a default (in Settings or a list).
Where a value comes from when several places could supply it: Shape override → Instance → Tool → list default row → Settings → Behind the scenes.
Replace IF chains with a decision table
Designed, not built. Since the matching half of this is an Advanced Part: put the rules in a table and let the part filter it.
Many of them are really a table:
- Make a table Stud Length Rules in the Material Library, with columns Wall Height, Plate Count, Stud Item.
- Rows: 8'-1 1/8" / 3 / "2x4x92 5/8 Stud"; 9'-1 1/8" / 3 / "2x4x104 5/8 Stud"; 10'-1 1/8" / 3 / "2x4x116 5/8 Stud".
- Make the Studs part an Advanced Part on that table, with two filters: Wall Height equals {Item > Height} and Plate Count equals {Item > Plate Count} (custom properties you added to the wall tool). One table, no nested IFs, and a new wall height is one new row.
For logic that isn't a table, use the Condition Builder (If / Else-If / Else rows) in the formula editor. See Formula language.
The Advanced Part — List Matching
"The core function is, we take a property, lets call this custom property, Height. We write a function that says, if Height = x then filter the table by column y by x."
"This is a very complicated part, lets actually create its own Part and call it Advanced Part. … "Advanced Parts" MUST be connected to a table/ library. That way it can seach/ filter for its part. Only the properties we have in the table should populate, anything else should be set like a regular part."
List Matching was planned as a setting on any part. It is now a kind of part of its own, the Advanced Part: a part tied to one Material Library table, which filters that table down to one row and fills itself from it. Regular parts — your own, and the ones loaded from a table row with Load part… — are unchanged.
What an Advanced Part is
- A part, with a table, filters and a sort added. Its Type is still Part. It is made in the Tool Designer from the Parts tab's +, which drops down New part · Advanced part · Load part…, and starts out named Advanced part. In the parts tree its row carries a small filter icon; hover it for what it matched — Advanced part — Matched Lumber3 → 2X6-10 (1 of 6).
- It names one table in the Material Library — Lumber3 in My Tools. Until it does, its Table box reads Pick a table… and the part says Pick a table from the Material Library — until it has one, this part matches nothing. — never a silent blank. Add filter and Sort stay greyed until there is a table.
- From the table: every column of that table is a property of the part, filled from the matched row — the column that names the row included. Only a column called Name is left out: the part keeps its own name. These are the only properties the match writes.
- Its own: everything else on the part — its Qty and Qty formula, a custom property, a note — is set exactly as on a regular part.
- No Linked to … · Unlink strip. A part loaded from a row shows one at the top; an Advanced Part's link is its match, said in its own pane, and it picks again by itself.
Where you set it: the part's own pane
Open the part in the Tool Designer's Parts tab. At the top, above its properties, is the Advanced part pane — matches one row of a Material Library table:
| Line | What it shows |
|---|---|
| Table | One flat list of every table in the Material Library, by name with its row count — Lumber3 (30) — the folder added only when two tables share a name. A table that isn't on this machine reads Lumber3 · My Tools — not on this machine |
| The answer | What it matched, with a tick — Matched Lumber3 → 2X6-10 (1 of 6) — or the flag, with a warning sign — No material matches these conditions — Stock Length equals Height left nothing. Under it, each filter as it went and how many rows it left: 1. Stock Length at least Height (9 ft) → 22 left, 2. Call Size equals Stud Size ("2x6") → 6 left |
| Filters — all of them, in order | One row per filter (below), each read in plain words above its boxes, with a bin to remove it; + Add filter under them. With none: No filters yet — with none, the first row of the table (by the sort) is the match. |
| Sort | A column, or The table's own order; then Smallest first or Largest first |
| Try it | Sample inputs, and the row they would match (When it matches) |
Every change is one Undo, and the part matches again inside it. A text box takes effect on Enter or when you leave it; Esc puts it back. In a read-only folder (DimSum Defaults) every control is greyed, with the reason on hover.
In a job the same pane sits under the placed part's properties, read-only: the table, the answer and its trail, the filters in words (with whose property each reads), the sort, and Filters are set on the tool, in the Tool Designer.
Filters
A list of filter rows on the part, empty to start. Each row has four fields:
| Field | What it is |
|---|---|
| Column | A column of the part's table — Stock Length, Call Size. A new filter starts on the first column that isn't the one naming the row |
| Compare | equals (the default) · at least · at most · contains |
| Input | Property or Value — a switch on the row, so it is never a guess which. Property: Pick… opens the same Property Picker formulas use, and the row then says whose property it reads — This item › Height, This part › Grade, The job › Labor Rate. Value: typed in the box — 10', 2x6 |
| Only when | Optional: a condition, written as a formula — {Stud Size} <> "" — and the filter applies only while it is true. Blank means always |
- Filters combine. A row has to pass every filter that applies, in order.
- The part's own copy of a column can't be an input. Lumber3 has a Height column, so the part's own Height is what the match writes; a filter reading it would read its own answer. Pick This part › Height and it is refused: Height is this part's own, and the match writes it — pick This item › Height instead.
- Numbers as numbers, in the column's unit. An input in other units is converted first —
10'equals120 in— and two numbers a hair apart count as equal. A typed value is read in the column's unit, so on Stock Length (ft)10'and10are the same. - Text ignores capitals and spaces at either end — 2X6 equals 2x6. contains finds the input anywhere in the cell. at least and at most on text compare alphabetically.
- A blank input works as it does in Excel: equals blank matches only blank cells, and at least / at most count a blank as zero.
- An input that can't be compared — in ERROR, a length on a page with no scale yet, or the wrong kind of number for the column (an area against a length) — matches nothing, and the part is flagged with the reason: No material matches these conditions — Height is ERROR, so Stock Length at least Height can't be checked.
- An Only when that is false skips its filter, and the trail says — skipped, Only when is false. One in ERROR skips its filter too (— skipped, Only when is ERROR) rather than stopping the match.
- Sort (optional): a column and a direction — Stock Length, smallest first — so at least picks the shortest board that fits. Blank means the table's own row order. Rows that tie keep the table's order, and blank cells — and words in a number column — go last, whichever way it runs.
The match: one, several or none
- One row left: that's the part.
- Several: the first in line — first by the sort, or by the table's own order when there is no sort.
- None: the part is flagged — No material matches these conditions — Stock Length equals Height left nothing. — in its pane, with a ⚠ on its row in the parts tree, and as a Material match warning in the Estimating tab's Needs attention. Its table properties keep what they last were, and the sentence names the filter that emptied the list.
- It always says which row it picked, and the filters that got it there — Matched Lumber3 → 2X6-10 (1 of 6), the first of the six rows left — so a surprise can be explained.
When it matches
- At placement, after the tool's Form questions are answered.
- Again whenever an input changes on that item — Height edited, Stud Size picked. The part re-matches at once, inside the same Undo as your edit, so one
Ctrl+Ztakes back both. A notice says what changed — Studs matched Lumber3 → 2X6-12 (1 of 5), or Studs: no material matches these conditions. - Not when the table changes. A changed table is offered on the update screen instead (below).
- In the Tool Designer, Try it — under the pane: a box for each property the filters read, labelled with whose it is (This item › Height) and showing what it reads now. Type a sample —
9'— and it says what would match, Matched Lumber3 → 2X6-10 (1 of 6), with the trail. Nothing is placed or saved, and a blank box uses what the property reads now. With no property inputs it says No filter reads a property, so every item matches the same row.
Linked, frozen, and the update screen
- The Tool Designer's own update screen does the same for a tool's Advanced Part.
- A different row now comes first — a board added, a length changed — it is offered under the row it would move to, led by Matched row 2X6-12 → 2X6-11. Update moves the part to that row and takes its values.
- Nothing would match any more after a table change — nothing is offered. The part keeps its row until its own inputs change.
- When the item's own inputs change, it re-matches at once, with no question: that is your edit to the item, not a change to the table.
- The folder or the table isn't on this machine — the part says My Tools isn't in your materials folder, so this part can't be matched; the values are kept. (or Lumber3 isn't in My Tools any more, …) and keeps its values. It is not flagged: nothing is wrong with the job.
- When the tool changes (A changed tool), a change to the part's table, filters or sort is offered as one line, Studs · Filters, old and new in words — Lumber3: Stock Length at least Height, Call Size equals Stud Size; Stock Length, smallest first. Values the item's own match wrote are never offered or overwritten by a tool update.
Worked through, in the terms: the studs.
What the old List Matching plan had, and the Advanced Part does not
The plan this replaces had more.
- a quick-create or pick an existing row prompt when nothing matches, with one prompt for a batch of misses — an Advanced Part flags the miss and names the filter instead;
- Pin a specific row (◆) until reset;
- cheapest or preferred supplier when several rows match — it takes the first in line;
- choosing which columns to pull — every column of the table is the part's;
- pulled values live-linked to a project's copy of the list — a job holds frozen values and an Advanced Part's are no different.
Keep a project up to date (Refresh Center)
A project keeps its own copy of every list row, price, setting and tool it uses, so opening a .dsum on another machine never changes its numbers by itself.
| Row | Example | Action |
|---|---|---|
| Settings & user/company values | Company address changed; Default Waste is now 12% | Refresh / keep |
| List & price updates | 41 lumber prices changed since 8/02 | Re-price, with before/after |
| Tool updates | "Ext Wall 2x6" changed in your library | Update from Tool, with a diff |
| Report template updates | The Count Sheet in your library gained a column | Update from library |
| Page versions | Page A-102 has a newer revision loaded | Switch / compare |
| Missing or unmatched items | 3 parts didn't match a list row | Fix now |
- Open Project → Refresh Center. A badge on the button means something is out of date.
- Apply the rows you want, or Dismiss them. Nothing ever updates silently.
the Tool updates row came early, without the rest of the panel — a changed tool is offered on the job's update screen when the job opens, listed once for the tool, with the values you changed on an item kept (A changed tool).
The plan read:* Values pulled from a list stay live-linked to the project's copy of that list. Re-pricing or editing that copy updates every part that matched it, immediately. What it does not do is follow the library on its own — that's what the Refresh Center is for, and the panel tells you when the project is behind.
Part of the List Matching plan; not in the Advanced Part, which takes the first row in line and says which. Right-click the part → Pin list row… and choose a row. It stays pinned (◆) and ignores the criteria until you click Reset.
*The Pricing page — bulk price edits, supplier price-sheet import, price history, stale-price warnings and Re-price open project — was dropped.
Options & settings
Simple lists
| Setting | Options | Default |
|---|---|---|
| Where a property's choices come from | Its own values, typed into Settings… → List, or a shared list from Lists & Tables | Its own values |
| Only allow choosing from list | On (anything else refused) / off (the list is a shortcut) | Off |
| A list's values | Values, one per line, up to 10,000, committed with Save values | |
| A list's name | Click it to rename. Division and Trade are preloaded: names fixed, values yours | |
| Where a list is stored | The same file as the property pointing at it — a job's in the .dsum, a library's in the .tsum; a list a tool points at travels with the tool; no screen edits them in a job — edit the list in the Material Library and the job's choices follow while that folder is on this machine | |
| Tables | Columns with type, unit and format; a label column; rows; Set from a table…; following; pull a column out as a list; import and export — Tables | |
| A property's List row | Answers a list or a table; a table opens the bind prompt, which asks which column sets this property and what else the row should set — Bind a property to a table row | |
| What a job keeps of a library's table | Nothing. Frozen numbers, plus the library, list and row names — What a job stores | |
| Rename in place | Double-click a tables or lists rail row, or press F2 — the same command, undo and warning as the editor's title. A preloaded list and a read-only library refuse | |
| The row bin | Asks first, in the column bin's own words; No changes nothing | |
| Where lists and tables live in the designer | The Material Library: Lists, and Tables in DimSum Defaults and Custom | |
| Importing a table | Asks nothing: header → property, else a custom Text property in Custom; key Item # else the first column; a same-named file re-imports; one line back | (a job's import unchanged: the wizard) |
| A column's settings | Settings… on the column head: type, units (with $ under Money), group; one undo each | |
| Settings rows in a CSV | Rows 2–4 under the names as Type, Units, Group, read only when row 2 is all type words; written by a Material Library table's Export… and Create a CSV template…; a job's import and export unchanged — Settings rows in the file | |
| A changed tool | Offered to a job when it opens, on the update screen (titled Updates): a group per tool, what changed listed once, a tick per placed item with what it keeps, Update selected with rows as one Undo, Skip per tool version for every item; values you set on an item kept; a tool not on this machine never offered, a folder that won't read named; built-in properties' own settings, label formats and input defaults not listed — A changed tool |
Advanced Part settings
| Setting | Options | Default |
|---|---|---|
| Name | Any | Advanced part |
| Table | One table in the Material Library, from one flat list | None — Pick a table…; the part says so and matches nothing |
| Filters | Rows of Column · Compare · Input · Only when, combined: a row must pass every filter that applies | None |
| Compare | equals · at least · at most · contains, by the column's type (numbers with their units; text ignoring capitals and end spaces) | equals |
| Input | Property — This item › …, This part › … or The job › …, from Pick… (the Property Picker); never a part's own property that the match writes — or Value, typed | Value, blank |
| Only when | A condition formula; the filter applies only while it is true, and is skipped while it is ERROR | Blank — always |
| Sort | A column, then Smallest first or Largest first | The table's own order |
| Several rows left | The first in line | |
| No row left | Flagged No material matches these conditions; its table properties kept as they last were; the filter that emptied the list named | |
| Its own properties | Qty, its Qty formula and anything else that is not a column of the table — as on a regular part | As a new part |
This replaces the List Match settings (List, Criteria, Pull columns, a quick-create prompt on no match, cheapest or preferred supplier on several, a pinned row, live-linked values) — see What the old List Matching plan had.
List-linked property settings
| Setting | Options | Default |
|---|---|---|
| Link | Default row / a specific row / Unlinked (custom value) | Default row |
| List | Any single-value list (Waste %, Labor Rates, Markup %, Tax Rates, Plate Heights, Wall Types…) | Set by the tool |
| Default row | The top row of the list | First row |
Built-in default lists
Division and Trade ship as real lists in every job and every library — they replace the hard-coded lists and the old Report Sections list — with their names fixed and their values yours to change, and DimSum Defaults adds one of its own, Wall Side (Ext / Int).
Masters are read-only in Behind the scenes; copies are editable.
The optional example libraries (pre-checked in First-Run Setup, removable any time) add sample rows such as "2x4x92 5/8 Stud" so a new user has a working starting point. They're clearly labeled as examples; nothing in them is baked into the core. The libraries span the CSI divisions 01–14, 21–28, 31–35 and 40–48, with framing first and deepest; see DimSum Defaults.
Dropped, with its bulk edit, supplier price-sheet import, price history, stale-price warning, extra supplier price columns and Re-price open project. The Properties Toggle that would have hidden it was dropped the same day. A price is a column of a table: re-import the CSV and the update screen offers the new number.
Examples
Framing: the studs, an Advanced Part
The table is Lumber3 in My Tools — samples\Lumber3.csv, thirty boards with Call Size (Text) and Stock Length (Number, ft) among their columns. the Length is this table's Stock Length.
The tool is a Linear tool, Ext Wall, with two Input properties on its Form — Height (ft) and Stud Size (Text: 2x4, 2x6) — and an O.C. as in Parts → an exterior wall. Its part Studs is an Advanced Part on Lumber3, with its own Qty ROUNDUP({Item > Linear} / {Item > O.C.}, 0) + 1.
1. Two equals filters — the own example. "Lets say we had the custom property Height, we set that to be 10. Then we write the filter function to filter the selected table by its Length column, by 10."
| Column | Compare | Input |
|---|---|---|
| Stock Length | equals | the item's Height — {Item > Height} |
| Call Size | equals | the item's Stud Size — {Item > Stud Size} |
Place a wall and answer the Form: Height 10', Stud Size 2x6.
- Stock Length equals Height (10 ft) leaves four rows: 2X4-10, 2X6-10, 4X4-10, 6X6-10.
- Call Size equals Stud Size ("2x6") leaves one: 2X6-10, 2x6x10 SPF #2.
- One row left, so that is the part: Matched Lumber3 → 2X6-10 (1 of 1). Studs reads Item # 2X6-10, Call Size 2x6, Stock Length 10, Cost Each 7.95 and every other column of the row. Its Qty is still its own formula.
Now place one at 9'. No board in the table is exactly 9', so the first filter leaves nothing: Studs is flagged — No material matches these conditions — Stock Length equals Height left nothing. — and listed in Needs attention as Material match. Its table properties keep what they last were.
2. At least, with a sort — the shortest board that fits.
| Column | Compare | Input |
|---|---|---|
| Stock Length | at least | {Item > Height} |
| Call Size | equals | {Item > Stud Size} |
Sort: Stock Length, smallest first.
The 9' wall again. Stock Length at least Height (9 ft) keeps 22 rows; Call Size equals Stud Size ("2x6") leaves six — 2X6-10, 2X6-12, 2X6-16, 2X6-16DF, 2X6-12PT and 2X6-16CD (10', 12', 16', 16', 12', 16'). Sorted smallest first, 2X6-10 is first in line: Matched Lumber3 → 2X6-10 (1 of 6), Cost Each 7.95. Make the wall 11' and it re-matches at once — Studs matched Lumber3 → 2X6-12 (1 of 5) — and one Ctrl+Z takes the height and the match back together. Pick Stud Size 2x4 on the 9' wall and it re-matches the same way: of the 2x4s, at least 9' keeps 2X4-10, 2X4-12, 2X4-16 and 2X4-16SS, and the first is 2X4-10, Cost Each 5.24 — Matched Lumber3 → 2X4-10 (1 of 4).
Without the sort, first in line is the table's own order — 2X6-10 here as well, because it comes first in the file.
⚠ Pick the item's Height, not the part's. Lumber3 has a Height column of its own — the dressed size, 5.5 in on a 2x6 — and every column of the table is a property of the part. So the filter's Input is {Item > Height}, picked under the item in the Property Picker; the row shows it as This item › Height. Pick This part › Height and the pane refuses it: Height is this part's own, and the match writes it — pick This item › Height instead.
Waste % list in action
ComingWaste % list: 10% (default), 5%, 20%, 25%. Roof tool linked to the 25% row; wall sheathing on Default.
- Roof shingles, 2,400 sf of roof:
{Item > Area} * (1 + {Waste %}) / 100= 2,400 × 1.25 ÷ 100 = 30 squares. - Wall sheathing, 1,297 sf:
RoundUp({Item > Net Wall Area} * (1 + {Waste %}) / 32, 0)= 1,297 × 1.10 = 1,426.7 ÷ 32 = 44.58 → 45 sheets. - The company changes its default to 5% (drags 5% to the top): the sheathing becomes 1,297 × 1.05 = 1,361.85 ÷ 32 = 42.56 → 43 sheets. The roof stays at 25% because it's linked to that specific row.
Formula alternative
An Advanced Part does the matching for a part (above).*
Inside any formula: MATCH("Dimensional Lumber", "Nom. Width", 2, "Nom. Depth", 10, "Length", 12) returns the row; read fields as {Match > Species}. LOOKUP("Lumber", "2x6 PT", "Price") returns one value.
Tips & shortcuts
- For a length, filter with at least and sort smallest first rather than rounding the length yourself: the Advanced Part takes the shortest stock length that fits (the studs).
- Keep one row per purchasable item (size + length), so a match lands on something you can order.
- Read the Needs attention list before bidding: an Advanced Part flagged No material matches these conditions still holds the values of its last match, or none.
- Pick an Advanced Part's inputs from the item (This item › Height) when the table has a column of the same name — every column of the table is a property of the part, and the pane refuses the part's own.
- Use Try it in the Tool Designer before placing anything: a sample Height of
9'shows which board a 9' wall would get. - Import supplier sheets by SKU/Item # so rows update in place instead of duplicating.
Rules, limits & edge cases
- Division and Trade cannot be renamed or deleted: both commands stay on screen, greyed with the reason, because tools and jobs find those two lists by name. Their values have no such rule — change all 35 divisions if you like.
- A list never crosses a file boundary: a job's lists are in the
.dsumand a library's in the.tsum, and a list a placed tool points at is copied into the job with it. So a job opens whole with its library gone. A job opens whole with its library gone for the stronger reason that there is nothing to point at. - Deleting a shared list says what happens to the properties pointing at it before it goes.
- An Advanced Part that stops matching after an edit is flagged — No material matches these conditions, on the part, in the tree and in Needs attention — and its table properties keep what they last were; it names the filter that emptied the list, so the miss is never silent.
- An Advanced Part with no table says so and matches nothing.
- An Advanced Part whose folder or table isn't on this machine keeps its values and says it can't be matched; it is not flagged.
- A placed Advanced Part's filters can't be changed in the job: they are the tool's — change them in the Tool Designer, and the job is offered the change.
- and — both dropped with the Properties Toggle.
- Deleting a list row that properties are linked to: those properties fall back to the list's Default row and are listed under Needs attention.
- Company lock (later): when Workspaces with roles arrive, an admin can lock lists and tools so estimators can use but not modify them.