BradAtHarmony Posted September 14 Share Posted September 14 (edited) 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 Edited September 15 by BradAtHarmony Link to comment Share on other sites More sharing options...
Renerabbitt Posted September 14 Share Posted September 14 (edited) First off, congrats on even getting this far with it. Building something like SmartStruc and getting Chief talking to an external data source is quite an endeavor. A few things jumped out at me because I’ve spent a pretty ridiculous amount of time working through this exact behavior in Chief. 1. I don’t think the security issue is actually what you think it is The SecurityError is most likely coming from the (assumption) that you’re trying to construct an entirely variable filesystem path. I am guessing because all of the information isn't here, but that's where I would look first. Chief/Ruby will let us read external files, but the path needs to be structured correctly. You can’t simply derive the entire path from variable information and expect it to pass the security parameters. IOW, a completely variable path is something that can potentially be manipulated, which is why it gets flagged. I've actually used two different approaches to this over time. My older external CSV system used a static address combined with a variable system address. Conceptually: static trusted root + variable project-specific portion + known lookup filename That allowed Chief to automatically locate the correct project-specific CSV without making the entire filesystem path variable. That system was live. Chief could continuously parse the CSV and rewrite the cached information as you worked in the plan. The newer BuilderTrend/JobTread system works differently. That system ultimately uses a fully static resolved address. Instead of Chief dynamically constructing the filesystem path every time, the end user can copy the path directly from Windows and paste it into a note. The macro then automatically cuts, cleans and parses that pasted Windows path designation into the properly formatted static address Chief actually uses for the lookup. So there are at least two ways I've already implemented this successfully: static + controlled variable path or fully static path with automated parsing of a copied Windows path Neither requires broadly untainting every filepath. I believe you may actually have a version of my Pro Plan containing the older CSV system, and I believe you also have the current version containing the newer BuilderTrend/JobTread implementation. You can look at the current implementation here: https://renerabbitt.github.io/ppx18-manual/?chapter=jobtread-buildertrend-spreadsheet-linking And take this response as explicit permission from me to reverse engineer/adapt that particular lookup system for SmartStruc if it helps you finish what you're building. Chief also has a Ruby Safe Level setting directly in Preferences. If you completely trust everything being executed through Chief, you could also change that setting and remove some of those restrictions. Personally I’d rather structure the path correctly than globally lower the security level, but the option exists. 2. mtime isn't what makes Chief capable of seeing new data mtime is simply the file's modified timestamp. It can absolutely be used as a trigger. Joe uses it in some of his macros as well. I personally wouldn't consider it ideal as the default mechanism because timestamps can be somewhat volatile, but that's really an architectural decision for you to make depending on exactly what you want this system to do. The important distinction is that Chief does NOT need mtime in order to reread an external file. My earlier CSV implementation proves that. That system was essentially live. Chief would reevaluate the macro during normal plan manipulation, reread the CSV information and continually rewrite the cached information. Draw a wall, move something, place a window, etc. and those calls execute again. So Chief absolutely can continuously reread external data without restarting the Ruby interpreter. In that implementation the amount of information I was producing was relatively small, so the performance penalty wasn't substantial enough to make that architecture a problem. Where I would be more cautious with what you're doing is the word schedule. I don't know from your post whether these are actually Chief schedules generated from notes/objects or whether they're text boxes populated with characters and simply made to LOOK like schedules. Those can be very different performance scenarios. A text box populated by a macro essentially needs to evaluate the macro and display the resulting text. If you're manipulating a note/object that subsequently drives an actual Chief schedule, Chief potentially has considerably more to evaluate because now the parameters of that object are feeding the schedule and that schedule has its own evaluation/rebuild process. I've measured situations in my own development where those evaluations were adding somewhere around 350ms. 350ms isn't particularly meaningful once. It becomes VERY meaningful when drawing a wall, placing a window, moving an object, etc. causes the same evaluation repeatedly throughout normal drafting. So mtime may be perfectly acceptable for what you're building. Or you may decide you don't want the cache rebuilding automatically every time the external file changes. That part is really up to you and depends on exactly what these “schedules” are and how expensive their regeneration actually is. 3. Restarting Chief is one refresh mechanism. It isn't the required refresh mechanism. This is where I think the difference between the systems I've built may help. I've actually used BOTH approaches. My original external CSV system was effectively live. Chief continually reread that external CSV information and rewrote the stored information during normal plan operations. Later, when I built the BuilderTrend/JobTread lookup system, I intentionally chose a different architecture. That lookup is purposely allowed to become stale. Not because Chief requires a restart before it can reread the file. It doesn't. I chose that behavior because this was going into a product being used by end users, and I didn't trust every end user to understand some complicated cache invalidation system or remember which obscure trigger they needed to manipulate. The simplest possible refresh mechanism is: Restart Chief. Everybody understands that. Restarting Chief clears the existing global state and the lookup gets rebuilt when the system initializes again. But restarting Chief is only ONE possible trigger. You could use mtime. You could use an explicit revision value. You could use a timer. You could place an object. You could move an object from one XY coordinate to another. You could change a Project Information field. You could create a dedicated refresh control. There are any number of ways to intentionally cause that data to rebuild. So when you say the parsed data remains stale “until the Ruby interpreter dies on an app restart,” you're describing what your particular cache architecture currently does. You're not describing a limitation of Chief. Chief can continuously reread and rebuild external data. My older CSV system did exactly that. Your scripting decides whether you actually WANT it to. And that's really the important distinction here. There are three different things: Chief reevaluating the macro external data being reread your stored/global cache being rebuilt Those do not have to happen together. You can make all three occur continuously. You can make Chief continuously evaluate while leaving the cache intentionally stale. Or you can create some completely separate deliberate event that invalidates the cache only when you want it refreshed. Your .rb comment is also a separate issue again. If you're bringing the Ruby file in with require, then you've specifically chosen a Ruby mechanism intended to load that code once. That's a code-loading decision. It doesn't establish a requirement that the external DATA itself can only be refreshed by restarting Chief. One other thing I should probably disclose This isn't meant as a brag or some kind of ownership claim. It's just a potentially relevant truth of how I think this very specific information made its way into the AI knowledge you're using. I can't prove model provenance from the outside, obviously, but I'm fairly confident that at least some of the connections being made here originated with work I did developing these systems. And I don't mean that I was “training my AI.” I mean that over roughly the last 3½ years and thousands of hours of scripting, I was feeding the AI systems themselves Chief-specific information they did not otherwise know, correcting their assumptions and showing them how these particular behaviors could be connected. This wasn't broadly documented or open-source information when I started doing it. There were only a few other relevant sources I knew of doing remotely similar things. The important part is that some of what I taught those systems represented earlier iterations of my own development. I hadn't solved every piece yet either at the time that I SHUT DOWN the option to train open source. IOW the current models are still missing some more information that I had solved, especially when it comes to utilizing schedule numbers, which was an expansion on knowledge I gained from Mike and Joe, and the ruby team at chief. So the models can potentially have fragments such as: external file → global lookup → cache information → avoid unnecessary parsing while missing later information about: static + variable path construction → fully static paths parsed automatically from copied Windows addresses → continuous live rereading when appropriate → intentionally stale data when appropriate → performance consequences of repeated schedule evaluation → deliberate cache invalidation when you actually want it That particular combination of correct concepts and missing context is what I'm recognizing in your post. Again, I'm not mentioning that to make some braggart claim to it. It's useful because I know where some of those earlier ideas came from, what problems I subsequently ran into with them and how I eventually worked around those problems. The broader architecture You really have several choices here depending on what you want SmartStruc to do. You can use a static root combined with a controlled variable project-specific address, which is how my older CSV system operated. You can use a completely static resolved path, which is how the newer BuilderTrend/JobTread implementation works, and simply make entering that address easier by automatically parsing a Windows path the user copies and pastes into Chief. Once you've reached the file, you can make the lookup completely live if the performance is acceptable. Chief can continuously reread the external file and rewrite your stored information as the plan changes. I've done that. Or you can cache the parsed information and deliberately allow it to remain stale until some chosen condition tells it to rebuild. I've done that too. Restarting Chief seems easy enough, though I bet if we really were faced with the task of making something better we could do it. It isn't a technical requirement. For your application, I would decide that part based on how expensive those 15 schedules actually are to regenerate and how often the underlying engineering information genuinely needs to refresh while somebody is actively drafting. On #4 I don't have enough information to comment on that one. I'd need considerably more context about how you're constructing the table, what exactly you mean by a schedule here, how the text is being generated, the text box setup and exactly what behavior you're trying to solve before I'd make any assumptions. Happy to help you work through any of this here in the thread if that was part of the intent of the post. I know you're building SmartStruc and I'd genuinely like to see what you do with it. I'm happy to be an audience for it and help where I can. BTW, my big pro tip here is this...if all you're doing with this data is generating schedules, then pull the training wheels off entirely. You don't necessarily need to cache anything at all. Use either the static + variable path method or a fully static path and just let Chief continuously read the external file every time the schedule evaluates. Then create a separate non-model plan whose only purpose is to hold all of these schedules. Nothing gets modeled there, nothing gets drawn there, and you aren't constantly triggering evaluations from drawing walls, placing windows, moving objects, etc. That means the performance hit from continuously reading the external file should be negligible compared to doing the same thing inside an actively modeled plan. So that plan basically becomes a catch-all schedule sheet. Generate all of your schedules there, then send them to Layout through linked views/layout boxes. Now the external data can stay completely live with no cache or stale-state management at all, while the actual working model remains completely unaffected by whatever evaluation cost those schedules have. Edited September 14 by Renerabbitt Link to comment Share on other sites More sharing options...
BradAtHarmony Posted September 15 Author Share Posted September 15 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? Link to comment Share on other sites More sharing options...
Renerabbitt Posted September 15 Share Posted September 15 Ahh okay, that fills in some of the missing context, but I still think there’s one piece I need clarified before I completely accept the SecurityError explanation. I still don’t believe Chief is natively handing you something that is tainted simply because you’re obtaining it at runtime. I’ve been reading external files from Chief at runtime for years without needing to broadly untaint the path, so I still suspect something in the way the directory/path is initially being established in your script is creating the condition. For example, something as basic as this is perfectly capable of reading an external file: path = "C:/Users/rener/Dropbox/DROPBOX PROJECT DIRECTORY/file read.txt" a = open path b = a.read a.close b And I’ve also used systems where I start with a known static root and combine that with information Chief is providing: base_path = "C:/Users/rener/Dropbox/DROPBOX PROJECT DIRECTORY" path = File.join(base_path, $document, "file read.txt") a = open path b = a.read a.close b So runtime evaluation itself isn’t inherently producing the problem. If you post the small initial chunk of code where you obtain the document directory and then hand it to File.mtime, I could probably identify where that security condition is actually being introduced. The other thing I need clarified is what you mean when you say: “The JSON is written into the project folder.” Chief calls these Projects regardless of whether Project Management is turned on or off. The plan/layout still live as a Project in the Project Browser either way. I currently use Project Management and I don’t want to switch it off just to test this, so what I DON’T know is whether Chief has added some functionality in the non-Project-Management workflow that lets you actually bring an arbitrary external file such as a JSON file into the Project Browser itself. If that exists now, that would be new to me. So when you say project folder, do you mean a normal Windows folder outside of Chief, something like: C:/Projects/Smith Residence/ containing: Smith Residence.planSmith Residence.layoutSmartStruc.json and another application is simply writing SmartStruc.json into that Windows folder? Or are you saying the JSON is actually being imported/stored somehow as part of the Chief Project itself through the Project Browser? I’m assuming you mean the first one, but that distinction matters quite a bit in understanding why you’re running into the error. If the JSON is simply an external file on the Windows filesystem, there is no requirement that it physically live beside the Chief plan at all. It can live anywhere on the machine that Chief has permission to read. And that leads into your question about Project Management. Yes, I’ve solved the managed-mode lookup problem You don’t actually need to know where Chief is physically storing the managed .plan. Instead, leave the JSON outside Project Management in a normal filesystem location and use information Chief DOES expose about the current project to locate the corresponding external file. This is actually very similar to a system I used in an older version of Pro Plan. If you still have that version, there was an external CSV-reading system in there that you could probably reverse engineer pretty easily with the additional information I’m giving you here. The basic concept was: static master directory combined with a Chief-derived project-specific directory combined with the known external filename So for example, suppose you maintain projects externally like this: C:/Dropbox/Projects/Main Folder/Folder 1/Example.json You can establish: C:/Dropbox/Projects/ as the known/static root. Then Chief only needs to determine: Main Folder Folder 1 Example from information already associated with the project. You can derive that from Project Information, NVPs, the project name, document name, or whatever naming convention you decide makes sense. So you're not trying to determine: “Where did Project Management physically hide this plan?” You're asking: “Which project am I currently working in?” and then using that identity to resolve an entirely separate external data location that YOU control. I went into this concept in a couple ChiefTalk discussions. This one gets into using project/client information and expanding the available information: https://chieftalk.chiefarchitect.com/topic/45226-designerclient-information-extended/page/2/?tab=comments#comment-337659 And this one gets directly into using a static project root and rebuilding a project-specific path in the Project Management workflow: https://chieftalk.chiefarchitect.com/topic/46157-new-idea-to-export-and-backup-x17-project-files-within-the-project-manager/?tab=comments#comment-329669 That second discussion with Joe Carrick is basically the architecture I’m describing here. Conceptually you can do something like: $dir = "C:/Users/rener/Dropbox/Projects" and then build everything underneath that from Chief’s project information. So if Chief knows: Client = Smith Project = Kitchen Remodel Version = Design A you can resolve something like: C:/Users/rener/Dropbox/Projects/Smith/Kitchen Remodel/Design A/SmartStruc.json without ever knowing or caring where Chief’s managed .plan is physically located. You can make the naming convention whatever you want. For example, you could use: 12345-Smith-Addition and establish a rule that each - represents some directory or subdirectory level. Or you could use separate Project Information values. Or project number + project name. Or client + project + version. There are a bunch of ways to do it. If you post what you would LIKE the external hierarchy to look like, for example: C:/Projects/Smith Residence/Structural/SmartStruc.json and tell me which portions you want Chief to derive automatically, I’m happy to post either the relevant portion of the Ruby or just write the complete lookup for you here. Your JSON would still live outside Project Management just like any other external resource. We’re simply using the Chief project to identify WHICH external JSON should be read. One other option you already have access to I believe you may also have the older Pro Plan version containing my original external CSV lookup system. If you still have that, feel free to reverse engineer the lookup portion. Take this response as explicit permission from me to adapt that particular system for SmartStruc if it helps you get to the final result. The newer BuilderTrend/JobTread implementation in Pro Plan went in a slightly different direction and uses a fully static resolved path. The convenience part is that the user can copy a Windows path and paste it into Chief, and the macro cleans/parses that pasted path into the static address it needs. That implementation is documented here: https://renerabbitt.github.io/ppx18-manual/?chapter=jobtread-buildertrend-spreadsheet-linking So I’ve used both approaches successfully: static root + controlled variable project path and fully static path with automated parsing of a copied Windows address Which one makes more sense really depends on how automated you want SmartStruc to be. Also, why didn’t you like Chief schedules? Now that I know you’re already putting all of this into a dedicated non-model plan, I’m curious what specifically pushed you away from actual Chief schedules. Was it formatting? The inability to create section headings? Control over columns? Something else? The performance issue I mentioned before becomes MUCH less important when the schedules live in a dedicated plan where nobody is actually modeling. If you’re not drawing walls, inserting windows, moving objects, etc. in that plan, you aren’t repeatedly paying the same evaluation cost throughout the normal modeling workflow. And I’ve been able to make actual Chief schedules look very similar to the output you’re generating. I’ll post a screenshot of my Area Analysis as an example. It’s completely schedule based. One obvious advantage your text solution has is that you can insert subsection headings directly into the text output. A single Chief schedule obviously doesn’t give you that same freedom. But you can reproduce essentially the same visual result by splitting the information into multiple schedules and stacking those schedules together. So instead of one schedule with: FOUNDATION ... BEAMS ... HEADERS ... you use multiple smaller schedules, each representing one section, and visually assemble them into the same overall table. That lets you get the headings/divisions while still using actual schedule formatting. It's also way easier to scale into sales and/or additional functions and even calculators derived from a model And if your primary reason for building the custom monospace font was getting the box-drawing characters to align while also matching your drawing set, using actual schedules could potentially eliminate that requirement entirely. That may or may not be useful to you — the custom font approach is clever and obviously already working — but since this is all contained in a dedicated schedule-only plan anyway, I’d be curious what limitation made you abandon the native schedule route. Either way, I think the managed-mode portion is very solvable. And before we completely write off the original SecurityError as Chief simply providing a tainted directory at runtime, post that first little chunk where you establish the directory. I still think there’s a good chance the security condition is being scripted into the lookup somewhere rather than being an unavoidable property of the directory Chief is returning. Also, no way shape or form am i trying to hijack, this thread, if you want me to edit anything out for historical data just lmk, happy to Link to comment Share on other sites More sharing options...
SHCanada2 Posted September 15 Share Posted September 15 (edited) I've been writing text files(i write to a log file for a couple macros) for years using a static root + dynamic ca provided filename and have not had the security error. I use the same full path from that variable for a key in my hash as well, with no issues. actually i checked I dont even have a static root logfile=File.dirname(filepath)+"/log.txt" filepath comes from CA's macro I looked at how I read files, and it is similar. the only other thing related to security that I can think of is the Ruby execution level Edited Tuesday at 04:55 PM by SHCanada2 Link to comment Share on other sites More sharing options...
SHCanada2 Posted September 15 Share Posted September 15 (edited) If this is just static text(static in that CA does not use the values for anything) for a layout box, and if you are not using PM mode, another possible option, is because CA will let you link a layout box of a pdf or image to an actual file on disk, you could have that layout box point to an image or pdf (easiest would be the same filename everytime) in the plan/layout directory. And then write a windows service that monitors the directory or all directories for modified json timestamps, and then have the program, spit out an image or PDF formatted to how you like. The layout box updates when you change pages, or goto print. You could also likely do it in PM mode by looking up where the PDF is stored on disk, but non PM mode is a lot simpler in knowing where the files are. From a user perspective for a new layout on a new project, they would have to go into the layout box and select the "prettytext.pdf" (or copy paste the path) in the directory of the layout. but once they do that, CA will show the updated pdf/image if it changes behind the scenes (on a page change or print). I've pondered doing this before, but I have so little external data, its not worth it, but I am surprised no one else has done it given AIs ability these days. P.S. I was also like Rene in thinking you got this into a CA schedule (directly at that I thought), had me all flustered as to how. it was short lived as I read the replies Edited September 15 by SHCanada2 Link to comment Share on other sites More sharing options...
BradAtHarmony Posted September 15 Author Share Posted September 15 (edited) 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. Edited September 15 by BradAtHarmony Link to comment Share on other sites More sharing options...
SHCanada2 Posted Tuesday at 04:51 PM Share Posted Tuesday at 04:51 PM (edited) 9 hours ago, BradAtHarmony said: 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. agree that stacked schedules is more of a headache for managing real estate, than text boxes....but in looking at your example, what are you doing if you need another 5 rows in any of those text boxes? They would then overlap no? Edited Tuesday at 04:51 PM by SHCanada2 Link to comment Share on other sites More sharing options...
BradAtHarmony Posted Tuesday at 06:30 PM Author Share Posted Tuesday at 06:30 PM 1 hour ago, SHCanada2 said: agree that stacked schedules is more of a headache for managing real estate, than text boxes....but in looking at your example, what are you doing if you need another 5 rows in any of those text boxes? They would then overlap no? That PDF was just an example of the different schedules. I would never do that in a plan set! The tables go on appropriate pages on the layout with room to grow if needed Link to comment Share on other sites More sharing options...
SHCanada2 Posted Tuesday at 07:36 PM Share Posted Tuesday at 07:36 PM (edited) hmm interesting, so from the user use case perspective, they have their layout, they put in these text boxes where they want them. They then download a JSON file from your website stick it in a directory on their computer, and you tell them the particular macro name that parses out the information for that specific layout sheet? And for them to get this working they specify the directory in a variable, and then your macro uses that to find the file? And the end customer may change parameters and download that file multiple times for the same project? The other way you could have done it, is to format that JSON file as a CA text macro JSON file, and then the customer imports it. CA text macros are persistent, stored with the plan or layout file, so you only have to go read the file once on demand. I suggest this method because if the user has to go download it anyway, then they are the ones that know that it changed. They could just reimport when it changes. The advantage: No global variables, user uses a standard windows file selection box, no performance hit, no CA/ruby programming(assuming it is all just formatted text) Edited Tuesday at 07:46 PM by SHCanada2 Link to comment Share on other sites More sharing options...
BradAtHarmony Posted Tuesday at 09:09 PM Author Share Posted Tuesday at 09:09 PM 1 hour ago, SHCanada2 said: hmm interesting, so from the user use case perspective, they have their layout, they put in these text boxes where they want them. They then download a JSON file from your website stick it in a directory on their computer, and you tell them the particular macro name that parses out the information for that specific layout sheet? And for them to get this working they specify the directory in a variable, and then your macro uses that to find the file? And the end customer may change parameters and download that file multiple times for the same project? The other way you could have done it, is to format that JSON file as a CA text macro JSON file, and then the customer imports it. CA text macros are persistent, stored with the plan or layout file, so you only have to go read the file once on demand. I suggest this method because if the user has to go download it anyway, then they are the ones that know that it changed. They could just reimport when it changes 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. Link to comment Share on other sites More sharing options...
SHCanada2 Posted Tuesday at 10:03 PM Share Posted Tuesday at 10:03 PM 36 minutes ago, BradAtHarmony said: 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. hmmm I'm not sure I understand . If I understand correctly, you are giving the customer a .plan file with the macros in it to read your json file They are responsible for opening up that file and sending the tables to their .layout file. They then get the json file from your website and place it in the directory . In the import a macro file use case I suggested, their layout would show nothing if they had not yet imported the file, it would show something if they imported a json file, and it would show something new if they imported another. If you had them import into the plan(instead of the layout), you would be guranteed what they chose to import reflects the plan (as they would have imported what they just downloaded from you) if they open a plan from a backup, then you are guranteed the tables reflect what was in that plan at the time. In your implementation, if they opened up a backup plan, how could it possibly know which JSON file to use, unless they created copies of your plan file as well? it would have to go look at other version of the backups and find the next latest date, and then find the JSON that is between those two dates. Not to mention if the customer deleted a backup, then there would be no possible way. but either way the backup cannot be guaranteed. suppose they just finished adding a beam, and had yet to download your file, but a backup occurs, but then they add another beam and download another one of your files so now there are two more changes. If one brought the backup back to life, how would the macro know which to use, Not to mention sometimes one has to use the CA backup file located elsewhere. ...I must be missing something? I would think if you want to guarantee them to be in sync, you would have to have some sort of thing where as soon as something is changed in the CA plan, the structural tables disappear, telling the user they need to go get another one. If not, and one is relying on the user to download, then it would seem to have same holes in trying to keep them in sync whichever way one chooses Link to comment Share on other sites More sharing options...
BradAtHarmony Posted Tuesday at 10:26 PM Author Share Posted Tuesday at 10:26 PM 8 minutes ago, SHCanada2 said: hmmm I'm not sure I understand . If I understand correctly, you are giving the customer a .plan file with the macros in it to read your json file They are responsible for opening up that file and sending the tables to their .layout file. They then get the json file from your website and place it in the directory . 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. Link to comment Share on other sites More sharing options...
SHCanada2 Posted Wednesday at 01:47 AM Share Posted Wednesday at 01:47 AM (edited) 4 hours ago, BradAtHarmony said: The JSON travels with the backup. ok so I think I am getting it....maybe... You are forcing the user to use a specific backup mechanism, where they must copy your .plan file and the JSON file into a separate directory when they make a backup? vs for instance in non PM mode I would make a back up or create a new version of the plan simply by copy and pasting the plan in the same directory or what exactly does this mean. Is this done by what the user downloads (MSI or something)? 4 hours ago, BradAtHarmony said: In unmanaged mode a folder is created per version 4 hours ago, BradAtHarmony said: 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. uhmm you are actually doing two formats? xlsx and JSON I dunno, copying around 2 files, requiring specific backup directories from the user, writing macros to read(which may impact performance), making sure the right .plan is linked, vs creating a specific JSON file for CA that the user just imports, presumably same as the workflow for the revit and softplan people...seems like a headache, not to mention the user has to maintain the links to your plan file. You might even want to ask your customers the question: If we had a standlaone utilitity to change the JSON file to a CA JSON file, would you rather run it through that and import the CA JSON file, or would you rather this setup where there is a seperate .plan file you have to link and maintain the JSON and .plan file. In my view of the world, which I will admit is far from the average person, I would pick the utility and keep with one .plan file. but and there is always a but, the CA macro import just brings in the text, you have a lot of grid lines. If these are just text boxes with lines, then the user would need to create those. If I was your company and went the CA JSON file route, I would then provide the example .plan file with those boxes and the text macro names and then the person could just put those on their own template file. BTW, the new feature of the "Project Information" where you can create your own fields, is exactly the same as the existing text macro functionality with respect to behaviour to read from them. The Project Information features implements a nice GUI to enter the data, vs the text macro which (if not imported from a JSON) needs to be entered via TMM. or...if your XLSX is already formatted pretty, the user could just make a pdf of that and import to their plan file. one and done Edited Wednesday at 02:26 AM by SHCanada2 Link to comment Share on other sites More sharing options...
BradAtHarmony Posted Wednesday at 02:34 AM Author Share Posted Wednesday at 02:34 AM 44 minutes ago, SHCanada2 said: ok so I think I am getting it....maybe... You are forcing the user to use a specific backup mechanism, where they must copy your .plan file and the JSON file into a separate directory when they make a backup? vs for instance in non PM mode I would make a back up or create a new version of the plan simply by copy and pasting the plan in the same directory 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. Link to comment Share on other sites More sharing options...
SHCanada2 Posted Wednesday at 03:27 AM Share Posted Wednesday at 03:27 AM 40 minutes ago, BradAtHarmony said: Your approach of duplicating the plan with a new name works just as well. hmmm I dont think it would work in the restoring a backup or simply opening up a backup(which in this scenario is stored in the same dir), as the macro always reads the latest JSON, no? Or Consider the case where I create two different floor plan options in the same directory, if it always reads the latest, then both would show the same when I open them up, even though they should be different. to each his own, but I would see the tradeoff of that risk, vs simply creating a PDF of your XLSX (assuming it is pretty), and importing, as the least risk, easiest to manage, guaranteed accurate for backups & multiple option plan scenarios. 50 minutes ago, BradAtHarmony said: the rb file handles presentation hmmm, I thought the rb just brought the data into variables, and the CA text box with its grid lines is presenting that data(font, size, bold, etc).i.e. the RB would be more of an ETL process, where it extracts the data from the JSON, transforms it into the format you would like, and then loads it into variables. I suppose if you are adding tabs or the like as part of that to make it look pretty, then I suppose it is a bit of a mix never a dull moment in the CA automation topics... Link to comment Share on other sites More sharing options...
SHCanada2 Posted Wednesday at 03:37 AM Share Posted Wednesday at 03:37 AM (edited) oh the other thing to add, if you are using global variables to store the data, be careful as opening up two different plan files at the same time will execute the same. I use a global hash which includes the path/name of the .plan file for every NVP in the hash, in an attempt to mitigate this. ie. in order to show the contents of the variable, I check that it matches the current plan file name in the current active window. If you are doing it on the fly and returning data directly from a function, then not an issue Edited Wednesday at 03:41 AM by SHCanada2 Link to comment Share on other sites More sharing options...
Renerabbitt Posted Wednesday at 05:19 PM Share Posted Wednesday at 05:19 PM 14 hours ago, BradAtHarmony said: The rb sits in the Scripts folder, I'm in a pretty unique position on the installation side of this because I've installed thousands of versions of my products for people over the years, and having the user put an .rb file in the Scripts folder is a BIG pain in the arse once this gets out into the real world. I'm going to play the "trust me bro" card pretty hard on this one. I would never even attempt to document every installation problem I've seen because the list would be ridiculous, but here's the reality: a LOT of users cannot successfully follow four written instructions, four recorded instructions, or sometimes four written AND recorded instructions. I'm not trying to insult anybody either...this is just what happens when you sell software/tools to a large enough group of normal users. I've had users who couldn't figure out how to download the product after purchasing it. I've had users who couldn't unzip the downloaded folder. Asking somebody to locate the correct Chief data folder, find the Scripts directory and install a Ruby file into it? That actually used to be part of my system and it generated a shocking amount of support. It became enough of a problem that I wrote actual Mac and Windows installers whose entire purpose was basically to put the required files where they belonged. People still managed to break that. And here's another one you're going to run into immediately: the Scripts directory is very likely sitting somewhere inside a OneDrive-backed Chief data folder for a bunch of users. A lot of people have OneDrive set to Files On-Demand/selective sync, meaning portions of that folder can be online-only. So right out of the gate you're potentially dealing with a script that looks like it was installed correctly but isn't actually local when Chief goes looking for it. Now you're troubleshooting why Ruby isn't being read at all, why OneDrive hasn't hydrated the file, why one user's Documents folder is redirected and another user's isn't, why somebody's Chief data folder lives somewhere unexpected, etc. At that point you're no longer troubleshooting SmartSTRUC. You're troubleshooting everyone's individual Windows/OneDrive/file-sync configuration because you chose an installation method that exposes you to all of those system-level problems. Eventually this is one of the reasons I created an Assisted Install service. And I mean this very specifically: my year 3 garnered no profit. None. Technical support consumed all of the profit for that entire year. That wasn't "support reduced my margins." It wiped out the profit. So if you're planning to scale this beyond technically sophisticated Chief users, my biggest product-development advice would be:KEEP IT WAYYYYY SIMPLER than you think it needs to be. Every additional manual installation step, external dependency, folder somebody has to find, path somebody has to maintain, file somebody has to move, update somebody has to understand, or OS/cloud setting somebody can have configured differently eventually becomes a support ticket. The architecture can be technically brilliant and still become commercially miserable if the end user has to understand any of it. That's also why I'd still encourage you to spend a few minutes testing the schedule approach before completely writing it off. The current Pro Plan you already have is actually set up where you could test this with a CSV export in probably two minutes. And I think there's an important distinction between:dynamically creating exactly the number of Notes you need andpre-populating WAY more Notes than you could ever reasonably need and letting the external data determine what gets reported. If your maximum realistic beam schedule is 50 rows, put 100 Notes in there. Same for footings, headers, whatever. Now you don't have an end user adding and deleting Notes every project. The container already has more available schedule objects than the data could realistically consume. The external lookup populates the ones that have data and the unused ones simply don't need to report anything useful. That's much closer to how I would productize it. And I think it's worth testing because once you're using actual Chief schedules you inherit a ridiculous amount of functionality for free. You can change column widths, reorder columns, reorder or filter rows, add columns later without rebuilding a text-table generator, add information that isn't coming from SmartSTRUC, supplement the imported information with information coming from Chief, perform additional calculations, expose additional fields, create different schedules from the exact same underlying data, change formatting without rebuilding the table parser, and generally let the end user manipulate the output using tools they already understand inside Chief. That's the part I'd be reluctant to give up. Your single text-box approach is undeniably clever, and I completely understand why the unknown row count led you there. Four members or sixty members requires no additional setup on your end. That's a legitimate advantage. But my concern is what happens AFTER you sell it. Someone is absolutely going to say:"I just need one more column over here..." Then another person wants to move this column. Someone wants an extra calculation. Someone wants to add a field manually. Someone wants one piece of Chief information mixed into the structural data. Someone wants the footing schedule formatted differently from the beam schedule. And they're going to start hacking at those text boxes because that's what users do. Schedules give them a structured system for doing all of that without touching your underlying data mechanism. Also, using schedules does NOT mean giving up the external JSON/CSV as your single source of truth. You can still have the external data driving everything live. You're just changing the presentation layer from one generated text string into Chief schedule objects. So your portable JSON can absolutely remain the product output format and source of structural truth. Another reason I'd test this before dismissing it is that you've already made the best architectural decision for schedule performance: you're putting this into a dedicated non-model plan. You're not drawing walls there. You're not inserting windows there. You're not rebuilding the model there. It's basically a schedule container being sent to Layout. So you have a LOT more freedom to abuse schedule evaluation there than I would ever recommend inside someone's actual working model. Your concern about %schedule_number% being positional is also something I'd attack as a scripting problem before deciding schedules can't work. I would not want the integrity of a structural schedule dependent on:"row 17 means JSON record 17 forever." I agree with you completely there. I'd want a stable identifier/key involved so the schedule object asks for its member, not simply whatever happens to currently occupy its index. That's another place where I think there may be more room to develop this than it initially appears. And since you already own the current Pro Plan, you don't have to speculate about whether any of this feels workable. Export some dummy structural data as CSV, throw a ridiculous number of Notes into a schedule-only test plan and abuse the hell out of it for half an hour. Add members. Delete members. Reorder the source data. Add more rows than you think you'd ever need. Change columns. Add a calculated column. Mix a Chief value into it. See what breaks. If after that the text-table approach still clearly wins, then you've validated the decision. But I wouldn't make the decision solely because dynamically maintaining the exact number of Notes per project would be awful...because I wouldn't maintain the exact number at all. I'd massively over-provision the available Notes once in the template and never make the user think about them again. The same philosophy applies to the installer:If the end user has to understand how the clever part works, simplify it again. That's probably the single most expensive lesson I've learned selling Chief tools. Link to comment Share on other sites More sharing options...
SHCanada2 Posted Wednesday at 07:13 PM Share Posted Wednesday at 07:13 PM (edited) ..another reason for the user to create a pdf from the downloaded excel, import into CA plan file....simple no headache or just screenshot the excel file, even easier (but loss of pixel accuracy) ..or the user can format excel and print to pdf ...or the user can create a "view" in excel to replicate the same thing every time ....or ... if the data is static and does not change and the format as viewed in CA does not need to change, I dunno, why bother bringing it in as numbers into CA. Edited Wednesday at 07:40 PM by SHCanada2 Link to comment Share on other sites More sharing options...
BradAtHarmony Posted Wednesday at 08:37 PM Author Share Posted Wednesday at 08:37 PM 3 hours ago, Renerabbitt said: I'm in a pretty unique position on the installation side of this because I've installed thousands of versions of my products for people over the years, and having the user put an .rb file in the Scripts folder is a BIG pain in the arse once this gets out into the real world. I'm going to play the "trust me bro" card pretty hard on this one. 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. Link to comment Share on other sites More sharing options...
SHCanada2 Posted Thursday at 05:56 AM Share Posted Thursday at 05:56 AM (edited) 9 hours ago, BradAtHarmony said: 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 you can consoliate similar rows into one(not zero) row, thats how room area schedules can be made to look like only a couple rows, but it would only work if your other rows have unique atributes Edited Thursday at 06:04 AM by SHCanada2 Link to comment Share on other sites More sharing options...
SHCanada2 Posted Thursday at 06:16 AM Share Posted Thursday at 06:16 AM (edited) the other thing you could do, which I did originally for RSI calcs is put everything in one note for a single row schedule for each category. Given you want control and not have the user accidentally remove a row or have to do row management and looking at your example formatting, it might be an option: Edited Thursday at 06:25 AM by SHCanada2 Link to comment Share on other sites More sharing options...
Renerabbitt Posted Thursday at 07:51 AM Share Posted Thursday at 07:51 AM (edited) see video 260917 (3).mp4 I would write a rule so that they dump the location of the folder that contains all csv's, and your note parses the csv according to the note type, so that they dont have to setup different individual file locations for each note/schedule pair. Also if you did it this way, I would have no problem adding a schedule and note to the library that I include with My Pro Plan and adding a sub-chapter for Tru Struc integration. the note would inject a macro for the file reading bit I just mentioned, and I wouldn't mind writing the macro to read it. I would just need to know the csv output names from trustruc to parse that logic based on the note type Edited Thursday at 07:55 AM by Renerabbitt Link to comment Share on other sites More sharing options...
BradAtHarmony Posted Friday at 02:13 AM Author Share Posted Friday at 02:13 AM 19 hours ago, SHCanada2 said: the other thing you could do, which I did originally for RSI calcs is put everything in one note for a single row schedule for each category. Given you want control and not have the user accidentally remove a row or have to do row management and looking at your example formatting, it might be an option: 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. Link to comment Share on other sites More sharing options...
BradAtHarmony Posted Friday at 02:21 AM Author Share Posted Friday at 02:21 AM 18 hours ago, Renerabbitt said: I would write a rule so that they dump the location of the folder that contains all csv's, and your note parses the csv according to the note type, so that they dont have to setup different individual file locations for each note/schedule pair. Also if you did it this way, I would have no problem adding a schedule and note to the library that I include with My Pro Plan and adding a sub-chapter for Tru Struc integration. the note would inject a macro for the file reading bit I just mentioned, and I wouldn't mind writing the macro to read it. I would just need to know the csv output names from trustruc to parse that logic based on the note type 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. Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now