8 Replies Latest reply on Feb 25, 2014 11:53 AM by RoelfWoldring

    managing large solutions

    RoelfWoldring

      Title

      managing large solutions

      Post

           I am in a bit of confusion, and I am convinced that I am confusing myself.

           I am working on a very interactive app for a client.

           I am about 1/2 through and although the number of Tables and TOs is manageable,

           I am getting lost in the relationships between scripts, layouts and buttons.

           I have over 150 layouts now, and over 200 scripts. Because it is a very interactive application, may of the layouts contain button whichs trigger scripts which move to different layouts.

           Following all of this through is beginning to be painful, especially since FM does not seem to have a easy way to list all my buttons, tell me which scripts they trigger and which layouts they are on.

           I am struggling with naming conventions for all of this.

           I "use predecessor" codes (1st characters)  in my script names which tell me something about the nature of the script, stringing them together as required. I try to make sure that my script names tell me what they do, even though that leads to long script names.

                bbb = script fired by button 
                ccc = called by script script
                hhh = help screen script
                nlr = script no longer required 
                     ppp = partial script 
                sas = start up app script
                sts = script trigger script
                ttt = script to be tested 
                www = script to be written
                uuu = script to be updated
                 
                I try to keep my layouts organized in logical folders and the same for my scripts.
                 
                But I keep getting lost on the buttons, which are the interactive glue between the layouts and the scripts.
                 
                Does anyone have an insight into how they manage this problem?
                 
                I seem be able to keep track of it all when the numbers are below about 100 to 125 each of layouts, scripts, and buttons, but after that, I seem to get more and more lost, especially as I try to take an agile approach to this development (code a little, test a lot, and then code some more).  Of course this is all aggravated by the fact that my client, when they see some functionality, immediately get new and better ideas about how they want to do things. I can push some of this into future releases, but not all.
                 
                Although I have written a fair number of small to medium sized FM apps, this is really the first one that I would classify as on its way to becoming large.
                 
                Roelf

            

        • 1. Re: managing large solutions
          philmodjunk

               Do you have FileMaker Advanced? If not that should be the next thing that you acquire and you should get it today. The value added tools for developing a database will save you hours of time. And one of the tools is a database design report that can list every layout and every button on those layouts. There are also third party developer tools you can purchase that take the data from a database design report and provide even better tools for visualizing and tracking the design of your solution.

          • 2. Re: managing large solutions
            RoelfWoldring

                 Yes

                 I have advanced.

                 I also have clip manager express and developer assistant.

                  I would be dead without them.

                 I find the DDR report almost impossible  to use in convenient dynamic way.

                 There is a way to search for buttons in it. I have certainly gone to the static listing to try to get around this frustration.

                 I have tried several ways, there is no easy in the moment way to see the link up between layouts, buttons and scripts. And it is not dynamic.

                 Make a change, and I have to run the DDR again. Make another change, and I have to run the DDR again.

                 It is better than nothing, but really does not work "well" as a development tool. It is a static, after the fact documentation tool.

                 I have not really tried to use either of the 3rd party "DDR" analysis tools, mostly because they are again after the fact, and not real time.

                 When I look at a script, I need to ask 'now what buttons on which layouts are invoking this script", as I am working on the script, so that I don't do something to the script that creates problems somewhere else in the solution. It is inability to answer these questions dynamically, as I am programming that is frustrating me. I can remember all of this stuff in smaller solutions, but not in this larger one. When I look at a button I am working on a layout, I want to know the answer to this question right there and then, without having to go through a series of 'design" screens inside FM requiring 5 to 8 mouse clicks which give me part, but not all of the answer I need. Or without having to back out of the work I am doing to spend 5 to 10minutes  running a DDR report and then trying to use a browser search tool to find what I need in the endless screens of detailed information.  By the time I have done that, I have lost the sense of what  I was working on.

                 This is the first time that I am experiencing this level of frustration with what I think of as "lacks" in FM of support for developers of large, interactive applications. FM13 invites us to build these.

                 If somebody has insight and experience into how to use them to track this the dynamically changing relationship between buttons, scripts and layouts, I would appreciate the guidance.

                  

            • 3. Re: managing large solutions
              philmodjunk

                   Frankly, I'm having trouble understanding why this is such a major concern. I've got solutions with hundreds of layouts and many buttons on each--I usually hide the status tool bar and provide my own "button bar" that saves space--so I have a lot of buttons on each layout.

                   And I've never felt the lack here.

                   What exactly are you trying to accomplish here in terms of "keeping track of your buttons"?

              • 4. Re: managing large solutions
                MarcMcCall

                     I think if you are getting to the point where you are forgetting what buttons invoke what scripts, and you need to edit a script and arent sure if it is going to mess it up on another layout, I would make a new script for your button that isn't used by another button.

                      

                     Personally I make few scripts that are used over and over again from start to finish. I may however call a script within a script and the script within the script is used over and over, but the main script is used only once.

                • 5. Re: managing large solutions
                  philmodjunk

                       From a layout, you can double click a button and "drill down" to script that is performed by it--a very useful feature added in FileMaker 11.

                       If you have a script you are about to edit and you are wondering "what the heck elements perform this script", you can generate a DDR limited to scripts and layouts and perform a text search for that script name--tedious but it works.

                       You can also use comments at the head of the script to list each layout/button or script trigger that performs that script. Each time you add a new button that performs the script, you can "drill down" to the script, open it for editing and update the comments to list the new button. (And I really, reallly wish that I could "drill down" into a sub script performed by the Perform Script script step.

                       You may already be familiar with this concept but.... I try to set up a "button bar" of standard controls to use on each layout. The buttons most frequently used on all layouts--such as a "main menu" button to take you back to a main layout are listed to the left, buttons that are more likely to be layout specific are listed on the right or in a row below the "main" button bar. This enables me to copy and paste a standard set of buttons--possibly updating some to pass a different script parameter and then "customize" it by adding additional buttons on an as needed basis.

                       This not only reduces the "developer management load" for the buttons but provides the user with a standardized set of buttons that makes the entire solution easier to use. It also enables me to hide the tool bar, having replaced it with layout buttons that have the same function but use about 25% of the same space--freeing up more layout space for other purposes in my layouts.

                  • 6. Re: managing large solutions
                    RoelfWoldring

                         Thanks Phil

                         From a layout, you can double click a button and "drill down" to script that is performed by it--a very useful feature added in FileMaker 11.

                                     It brings up the Button Setup specify script dialogue on my screen. Is this what you mean by drill down?  I use it all the time. Or is there some other way to drill down that I don’t know how to do. I am on Window FM Pro Advanced 12.

                    I have put in a feature request that allows this to happen without having to go through the specify script screens, avoiding all kinds of mouse clicks. It would be nice if we could just right click on the button and see the script that is performed. And then immediately click on the name of that script in the window which comes up to go into into the script n the script editor.

                         If you have a script you are about to edit and you are wondering "what the heck elements perform this script", you can generate a DDR limited to scripts and layouts and perform a text search for that script name--tedious but it works.

                                I am starting to do this. Thanks.

                         You can also use comments at the head of the script to list each layout/button or script trigger that performs that script. Each time you add a new button that performs the script, you can "drill down" to the script, open it for editing and update the comments to list the new button. (And I really, reallly wish that I could "drill down" into a sub script performed by the Perform Script script step ( me too - FM is so flexible in some ways - scripts on buttons and on script triggers - scripts called by scripts etc that it is endlessly powerful - part of my problem with this app is that is has grown over the past months in ways that I did not anticipate - so I am refactoring in order to get it back under control.  )

                                     I am systematically going through the app doing this. It is not ideal, since layout change names etc, but it is better than nothing. Again, it sounds like I don’t really understand how to drill down from buttons to scripts in the way that you are suggesting. I double click, get the button setup menu, click specify script to see the script, and then find it in the manage script windown to go to it in order to open it and then add this information.

                    Some fundamental ways of doing things have also changed in this app - ie. the user has changed their mind, which has created some issues in table design and table relationships which is causing some of need to follow all of this through in detail. That is part of the reason why getting an right in the moment answer to "what scripts are performed by this button and on what other layouts have I got this button doing what with this script based on the parameter I enter on that layout - would be so useful - it would allow me a planned approach to making these changes. which I will have once I have do all of this commenting.

                         You may already be familiar with this concept but.... I try to set up a "button bar" of standard controls to use on each layout. The buttons most frequently used on all layouts--such as a "main menu" button to take you back to a main layout are listed to the left, buttons that are more likely to be layout specific are listed on the right or in a row below the "main" button bar. This enables me to copy and paste a standard set of buttons--possibly updating some to pass a different script parameter and then "customize" it by adding additional buttons on an as needed basis.

                    I do something similar, although I have not hidden the normal tool bar for this user, who will take advantage of it more and more over time. I do hide it in other apps.

                         This not only reduces the "developer management load" for the buttons but provides the user with a standardized set of buttons that makes the entire solution easier to use. It also enables me to hide the tool bar, having replaced it with layout buttons that have the same function but use about 25% of the same space--freeing up more layout space for other purposes in my layouts.

                    Thanks again - the solution seems to roll up my selves and work through this stuff and make sure that I do a better job building this kind of documentation into this script comments in a standardized way sot that I can search for them using Developer Assistant.

                    • 7. Re: managing large solutions
                      philmodjunk

                           To drill down into the script with the current systems:

                           a) enter layout mode

                           b) double click a button object or select it and choose "Button setup..." from the Format menu

                           c) click the specify button

                           d) pull down the gear menu and select the edit option and you now have your script open in the script editor.

                      • 8. Re: managing large solutions
                        RoelfWoldring

                             Amazing what you forget once you develop a set of key strokes.

                             Thanks Phil

                             So I started to think about as it was doing it manually, asking myself, how could I use FM to automate at least part of this and make it easier to update in the future. 

                             First step some data modeling, first in English and then partly as a schematic  (green sentences only for now).

                              

                              

                             Then building the tables / TOs / Relationships in FM - just the relationship graph here

                              

                             <img alt="" src="data:image/png;base64,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