-
Posts
33 -
Joined
-
Last visited
Reputation
1 NeutralAbout BradAtHarmony
- Birthday 07/18/1964
Contact Methods
- Website URL
Profile Information
-
Gender
Male
-
Location
Ontario, Canada
Recent Profile Visitors
2857 profile views
-
Jason - it does the opposite here, and I spent an hour figuring it out. Chief groups on the note object's own properties, not on what the macros render. Every note in these schedules is identical as an object: same note type, same Macro Input strings. The thing that makes row 3 differ from row 4 is %schedule_number%, which isn't resolved until the row is drawn. So with Group Similar Objects checked, all 31 notes collapse into a single row with Qty 31 - not 24 populated rows plus one blank. I had exactly that on screen and couldn't work out why duplicating a note wasn't adding rows. Unchecking it is what makes the schedule iterate at all. Which leaves the overshoot to deal with some other way, hence the layout box crop.
-
Rene — worth an update, because you were right on both counts and I've rebuilt accordingly. The Scripts folder is gone. No .rb file, no require, no install step. It's two macros now — a JSON parser written in the macro itself, plus a three-line shim — and a label to hand Ruby the plan folder. Nothing outside the plan except the export. That removes the support liability you flagged, and you were right that it was one; I was defending a setup I'd normalised because I'd built it. I've also moved to real Chief schedules. One note per member, over-provisioned, cropped with the layout box edge — your video. Thank you for posting it; it solved the blank-row problem I'd given up on. A couple of things that fell out of the rebuild and may be useful to you regardless of what I do with it: Column headings and schedule titles evaluate macros. So the headings aren't typed text — they're read from the export at render. Change what a column shows and its heading follows. And the export declares its own unit system. The macro reads it and pulls millimetres or inches, kN or pounds, to match — headings included. One template plan serves a metric designer and an imperial one with nothing to change. Our JSON also carries deflections, utilisation, governing load case, bearing and hanger schedules that the default columns don't show. The note type carries the field mapping, so a designer surfaces any of it without touching a macro. On the Pro Plan offer — I appreciate it and I'm not saying no. Let me get the template finished and see what it looks like in someone else's hands first.
-
Jason — thanks for the suggestions. I went a different way in the end: the JSON is parsed directly in a Chief text macro, with no external file and no import step, into standard Notes schedules. One import, then it reads whatever export is in the project folder. Appreciate you thinking it through with me.
-
Appreciate the warning, and I don't take it lightly — support cost eating a year of profit is the kind of lesson I'd rather learn from your scar tissue than my own. That said, I think the install is more surmountable than it looks. The .rb doesn't have to live in the default Scripts folder. Save it to a local-only folder and point Chief's Scripts setting at it, and the OneDrive problem disappears — no Files On-Demand, no placeholder that looks installed and isn't, no redirected Documents folder. That turns "find your Chief data folder" into "put this file somewhere and browse to it once." Still a support surface, just a much smaller one. On the broader point though, you're preaching to the choir. I've been in IT support, personally and professionally, for over forty years. I'm intimately familiar with the user who followed the instructions to the letter, skipped three of them, and freelanced the fourth. PEBKAC is alive and well and it has my phone number. I also tested storing the macros inside the plan file rather than using the .rb. It works, but the .rb was more efficient for me, so that's where I landed. On schedules — I didn't write them off, I built it. Two things stopped me. Over-provisioning left 90 blank rows for 10 members, and the only way I found to get rid of them was deleting the 90 notes, which puts per-project note management right back where it started. If there's a way to suppress rows whose content evaluates empty, I never found it. My read is that schedule filters work on object properties, and my row content doesn't exist until the macro evaluates at display time, so there's nothing for the filter to match against. Setup was the other one. A note type per schedule, then a schedule pointed at each note type, times nine categories. That's a lot of template construction, and a lot of steps that can be completed almost correctly — which is your own argument, and it lands harder on nine note types and nine schedule definitions than it does on a plan file I hand someone already built. It also puts me further from the user, not closer: someone who wants one more column out of the JSON, or a Chief field mixed in, is now editing note type and schedule definitions. Either correctly, or on the phone with me. Underneath both is that macros render but don't mutate. No script can add or remove a note, so the row count is always something a person sets in advance and maintains. That's what pushed me to the text table. Not cleverness — it's just the only thing I found that produces exactly as many rows as there are members without anyone managing objects. Worth mentioning on the extensibility point: the JSON already carries more than the schedules show by default. Deflection, utilisation, load cases and reactions are all in the payload. Working out how to expose those optionally is on my list, and it's a presentation problem rather than a data problem — which is part of why I'm cautious about moving the presentation layer into something I don't control. So here's the question I'd genuinely like answered, and you're better placed than most to answer it: is there any way to populate a Chief schedule from external data without notes as the row source? If that exists, everything you listed about inheriting Chief's native functionality becomes worth the rebuild, and I'd do it.
-
The versioning is a convention, not something I create or enforce. I suggest copying all the files — plan, layout, images, JSON, PDFs — into a new folder so everything locks at once. Your approach of duplicating the plan with a new name works just as well. The rb file always reads the most recently added JSON, so both behave identically. Pile everything into one folder with naming conventions, or use version folders. Either works. On formats, the user picks JSON or Excel depending on what they need. And if someone wants to write their own parser against the JSON, nothing stops them. The included plan file is optional too. The rb sits in the Scripts folder, so the inline scripts can be copied out of my plan into the user's own plan or layout template and my plan discarded entirely. A lot of my users already keep a separate details plan rather than holding details in the user library, so an extra plan file isn't unusual — but nobody's tied to it. It's a starting point, not a dependency. Noted on the Project Information fields. Same read behaviour as text macros, nicer entry GUI. That's the split I'm after: the JSON carries the data in a standard portable format, the rb file handles presentation. Data stays platform-neutral, formatting stays in one place that can be easily updated.
-
The JSON travels with the backup. In unmanaged mode a folder is created per version holding both the STRUCSync plan and the JSON for that version, so restoring a version restores a matched pair — the JSON from three revisions ago matches the plan from three revisions ago. It takes folder discipline, but the coupling you're after is there, just at the folder level rather than inside the plan file. What closes it on my end is that the plan file and the JSON aren't loose in a shared folder. In unmanaged mode a folder is created per version, and both the STRUCSync plan and the JSON for that version live in it. So they're coupled — just at the folder level instead of inside the plan file. Restore a version, you get the pair that shipped together. Managed mode is still an open question and I don't have a clean answer for it yet. There is more "manual" work to keep the JSON files sorted. The reason I won't move the payload into a macro file is portability. The JSON isn't a Chief file, it's the product's output format. There's an XLSX export off the same data today for the Revit and SoftPlan crowd, and SketchUp and ArchiCAD are on the table. A CA macro file is a CA-only artifact — going that route means maintaining a separate payload format per platform instead of one, and Chief happens to be the one platform where I can parse the neutral format natively. On your last point, I think you're right. There's no way that I know of to have CA notice the plan changed and blank the table, and chasing it is the wrong problem. The better move is to stop hiding the question. The export carries its own date and the name of whoever generated it, and the parser can already read them. Print that in the schedule header. It doesn't keep anything in sync — nothing does, in either design, if the user doesn't re-export. It just means the drawing says when its numbers came from, which is the thing a reviewer can actually check against the plan revision.
-
Simpler than that on their end. The schedules come pre-built — they drop the plan in their project folder alongside the JSON and send whichever schedule they need to the appropriate layout page. One-time install of the Ruby library into the Scripts folder is the only setup. No macro names to learn, no directory to set. And yes, re-downloading multiple times per project is not unusual. Client wants something changed - beam grows, footing changes, re-export, schedules update. On the macro import idea: it would delete my hardest problem, which is finding the file at all. No path, no Project Management gap. What stops me is that it copies the data into the plan. Open that plan from a backup, or one a colleague sent last month, and it renders confident structural numbers with nothing to say they're stale. An external file at least carries a modification date. A blank schedule is recoverable, a plausible wrong one isn't. Where I think you're onto something is using a macro to hold the path rather than the payload. Persistent, travels with the plan, survives Project Management, and the JSON stays the single source. I'm doing a version of that now for the Project Management case — a Project Information field holding the export folder — but a persistent macro would generalize it and drop the custom-field step entirely.
-
Hi all, I'm Brad Moore, a BCIN residential designer in Ontario (Harmony Design) and a long-time Chief user. For years my structural workflow was the same as a lot of yours: size members in one tool, then retype the results into Chief by hand. Beam and header schedules, ICF lintel reinforcement, wall notes. It was slow, and it's where mistakes crept in. So I built SmartSTRUC (smartstruc.ca), a structural design platform for Canadian residential work, and STRUCsync, which carries the results into Chief. What SmartSTRUC does Part 9 prescriptive and Part 4 engineered design under OBC, BCBC and NBC, with CSA O86 for wood Joists, beams, headers, posts and columns, wood walls (including tall walls), ICF/ICFMA lintels, decks and footings Load paths from the roof all the way down to the footings, not just to the main floor Works with any manufacturer's product, not just one supplier's EWP Calculation reports ready for a permit submission What STRUCsync does You export your project from SmartSTRUC and run the STRUCsync macro in Chief. It builds gridded schedule tables on your plan: framing sizes and spans, ICF lintel reinforcement, wood walls, wall openings, hold-downs and reactions. If you change a design, you re-export and the tables rebuild. Nothing gets retyped. You can also export the same data to Excel. Part 4 stamping for Ontario users Does your project have a Part 4 element (a long-span beam, a tall wall, a point load that no Part 9 table covers)? I hold the BCIN Building Structural designation, so I can review and seal Part 4 designs done in SmartSTRUC. You lay out the load paths, SmartSTRUC produces the design and the calculations, and I stamp it. The fee is kept low and depends on the scope of work. For many small jobs, that means you don't need to bring in an engineer. IRC version in development For the US folks: an IRC version is underway. We have a working first version that sizes floor joists from the IRC span tables, and more members will follow. If you design in the States and want early access, reply here or send me a message. Your replies will help me decide what to build next. Try it The fastest way to see it is a 20-minute screen share, where I run one of your own plans through SmartSTRUC and into Chief. [DEMO / BOOKING LINK] I'm happy to answer questions here, including the structural ones. Brad
-
Rene, Jason, thanks both. Answering all of it. THE SECURITYERROR - you were right, and I can now say exactly why Rene, your instinct that something in my script was creating the condition was correct. Here is the relevant chunk you asked for, reduced: def self.find_file(directory) dir = directory.to_s.strip.gsub('\\', '/').sub(/\/$/, '') matches = Dir.glob("#{dir}/*_Keynotes_*.json") matches.max_by { |f| File.mtime(f) } # <- this line raised end My export filename carries a timestamp, so I do not know the exact name. I glob for it and then stat every match to pick the newest. The strings coming back from Dir.glob are the tainted ones, and File.mtime on one of those raises. That is Ruby behaviour, not Chief behaviour. Neither of you ever globs. You join a static root to a known filename and open it, which is precisely why you have both been doing this for years without tripping it. Jason's setup is the control case. I had also been asserting that $ss_doc_dir itself was tainted, because I pick it up through a doc-dir polyline label. I had never actually tested that, so I did: % require 'smartstruc_keynotes'; "#{$ss_doc_dir.to_s.tainted?}" % Returns false. Chief is handing back a clean string. My source comment naming $ss_doc_dir as a taint source is wrong and I am correcting it. Dir.glob was always the only source. For anyone who lands on this later: SecurityError is not a StandardError, so a macro's rescue "ERR" will not catch it and you get raw macro text on the sheet instead of a graceful failure. That part is still worth knowing. PROJECT FOLDER - your first reading A normal filesystem folder, nothing to do with the Project Browser: /Projects/26-104 Smith Residence/ Smith Residence.plan Smith Residence.layout 26-104_Keynotes_2026-09-12.json SmartSTRUC writes the JSON there. Nothing is imported into Chief. I put it beside the plan because it made the lookup trivial, not because it has to live there. Which is exactly why Project Management breaks it. MANAGED MODE Your framing is the piece I was missing. Stop asking where Chief physically put the plan and ask which project this is, then resolve the external data from something I control. Stated that way it is obviously right. Two constraints on my end that shape the answer. SmartSTRUC is browser-based. It downloads the JSON, it cannot create folders or write to a chosen path on the user's disk. There is a File System Access API that would allow a one-time directory grant and a direct write, but it is Chromium only, so it can be an upgrade for some users and never the mechanism. And the file has to live with the rest of the project documentation. Leaving it in Downloads is not an option, since those get swept. So where I have landed is a fallback chain rather than one lookup: 1. $ss_doc_dir. In non-managed mode the plan's folder IS the project documentation folder, so this already works and needs no configuration. Most people never get past step 1. 2. If that finds nothing, read an explicit project folder path from a Project Information field. One paste per project, and it works identically in managed and non-managed mode. Step 2 is where your BuilderTrend/JobTread work is directly relevant, since cleaning and parsing a pasted Windows path into the form Chief actually wants is the fiddly part and you have already solved it. I will read the manual page before I ask you anything specific about it. The static root plus derived subfolder approach would also work, but it assumes the user's folder naming matches a rule I define, and I would rather not hand anyone a convention they have to keep to. A pasted path makes no assumptions about how they organise their projects. Either way the doc-dir polyline goes away, which was the part I actually wanted. Reading both your threads properly, particularly the Carrick one. WHY THE GLOB DOESN'T CONFLICT WITH THAT Worth separating, because I conflated these myself for a while. There are two independent questions: 1. How do you find the DIRECTORY 2. How do you find the FILE inside it Your solution is entirely (1). My glob is entirely (2). They compose. My find_file already takes the directory as an argument and only defaults to $ss_doc_dir, so adopting your approach is one new resolver returning a directory, and nothing downstream changes. The glob runs inside whatever folder it is handed. The taint and the cost of globbing fifteen times per evaluation pass are properties of (2) and I will deal with those on their own merits. They were never what stopped managed mode working. WHY NOT CHIEF SCHEDULES Not formatting, and not headings. Row count. Every plan has a different number of members. Twelve beams on one job, thirty-one on the next, four footings here, eleven there. With Notes Schedules that means adding or removing notes on every schedule on every plan to get the right number of rows showing. Occasionally on a multi-storey plan is fine. Every single project is not. Which is also why your Area Analysis works and mine would not. Your row structure is fixed, the same rows every time. Add a third floor and you would be doing exactly what I was doing. The second problem is that the binding is positional. Each row resolves through %schedule_number%, so the macro is reading by index into my JSON. Add a beam, delete a footing, re-export in a different order, and every row below the change is quietly showing another member's data. On a permit drawing that is the one failure mode I am not willing to carry. table() renders whatever rows are in the JSON in JSON order into one text box. Four members and sixty are the same amount of setup, which is none, and there is no index to break. The custom monospaced font came afterwards, to make that output sit properly in the set. Your stacked-schedules approach is a real answer to the headings problem and I would use it anywhere the rows come from model objects rather than an external set of unknown length. Jason - the layout box pointed at a PDF or image that a watcher regenerates is a nice trick and I had not considered it. It also gets full typographic control, which the text box route does not. The cost for me is a background service on every user's machine, which is more support burden than I want to take on for a drawing schedule. Filing it though, because for a single-user setup it is clean. And Rene, not a hijack. Leave it.
-
Rene, thanks for the detail. A few clarifications since you flagged you were working from incomplete information. There's no variable path. The JSON is written into the project folder, so there's no variable folder portion and no naming convention to derive. The SecurityError came from Chief handing me the document directory at runtime, which arrives tainted, and File.mtime on it raised before anything was constructed. Not a StandardError, so the rescue missed it. Both of your path approaches solve a case I don't have. You're right on the mtime and restart framing. Staleness until restart is my cache design, not a Chief limitation, and I should have written it that way. On what these are: text boxes, not Chief schedules. I tried the notes/object route and disliked it. No object parameters feeding a schedule, so the rebuild cost you measured doesn't apply. They also don't live in a modelled plan. There's a dedicated schedule-only plan file connected to the layout, so nothing is triggering evaluations from drawing walls or placing windows. For #4, the piece that made text boxes viable was making a monospaced font that matches my layout font. Box characters line up and the tables sit in the set without looking like a terminal dump. That's the part I'd pass on to anyone trying this. One real gap: none of this works in the project management version, since there's no project folder to write into. I don't use it, but if I wanted to support it, that's where a user-supplied static path would actually be the right call. Have you found a reliable way to resolve a plan's location in managed mode?
-
I have been automating my structural schedules by having Chief read a JSON file that another program writes into the plan folder. One text macro renders a whole schedule as a gridded table in a single text box. The screenshot is a test project: 15 schedules on one sheet, none of them typed by hand. Posting the mechanics because four of these took me a long time to work out and I have not seen them written down anywhere. 1. CA's Ruby runs with taint checking on File.read on a tainted path raises SecurityError. That is NOT a StandardError, so a plain `rescue` will not catch it and your schedule renders raw macro text instead of failing gracefully. Untaint the path first, and rescue Exception rather than StandardError around any file operation. 2. Key your cache on path + mtime, not path If you cache the parsed file keyed on the directory string, that string never changes between exports, so Chief serves you stale data until the Ruby interpreter dies on an app restart. Key it on file path plus File.mtime and any re-export invalidates it. Refresh the view and you have new numbers. (File.mtime on a tainted path has the same SecurityError problem as #1.) 3. Editing the .rb still needs a CA restart Ruby caches require'd files for the life of the process. The mtime cache above handles new DATA without a restart, which is the day to day case, but changing the macro code itself means restarting Chief. 4. Grid tables need a monospace font and a non-fixed-width box Box drawing characters only line up in Menlo, Consolas or Courier New, and if the text box is set to a fixed width the grid wraps and falls apart. Two more things I would do differently if starting over: Give each table an explicit column list rather than deriving columns from the first record's keys. The moment your data source omits a field a record did not produce, the first row silently decides the columns for every other row. Have the table drop a column that is empty on every row. A spacing column on a beams-only job should disappear rather than print a column of blanks. Happy to answer questions on any of it. EDIT - correction to #2 and #3, thanks to Rene below. I framed the staleness as Chief behaviour. It isn't. Chief can reread an external file continuously during normal plan operations, and it does not need mtime or a restart to do it. Serving stale data until restart is what MY cache architecture does, not a limitation of Chief. The more useful way to put it, which I did not separate clearly the first time, is that there are three independent things: Chief re-evaluating the macro the external file being reread your stored cache being rebuilt Those do not have to happen together. You can have all three continuous, or a continuously evaluating macro over a deliberately stale cache, or a cache that only rebuilds on a condition you choose. mtime is one possible trigger. So is an explicit revision value, a Project Information field, or simply reopening the plan. Worth knowing that evaluation frequency depends heavily on what kind of plan this lives in. If your schedules sit in a dedicated non-model plan, very little is firing evaluations because nothing is being drawn, which is good for performance and bad for freshness. Decide which you want. The #3 point about require stands as written. That's Ruby's code-loading behaviour and is separate from data refresh. #1 also stands. The SecurityError is real and reproducible: Chief hands you the document directory at runtime, that string arrives tainted, and File.mtime on it raises before any path is constructed. It isn't a StandardError so a plain rescue misses it. SmartSTRUC_X18.pdf
-
Our work is primarily in the central part of Ontario, Canada, where the Canadian Shield defines our terrain. I am trying to make a deck skirting to use around the base of decks that are of uneven height above the ground yet still maintains the same geometry. The skirting consists of 5-1/2" wide boards placed horizontally with a 1" space between them. I have tried a variety of things including making an exterior fixture and using garage door panels, however everything I try changes the height of the horizontal board and space when I change the height of the panel, rather than adding more boards.... Other than making fixed height panels and stacking them for higher or lower skirting or doing each one as custom poly line solids, does anyone have any suggestions about how I could make these panels? Thanks for any and all suggestions.
-
I didn't.... The app said I was up to date, but found there was a newer version online. Thanks!
-
Huh.... I don't have that menu option on my Mac... I have the most up to date version. I'll have to contact support
