Alpha Software Mobile Development Tools:   Alpha Anywhere    |   Alpha TransForm subscribe to our YouTube Channel  Follow Us on LinkedIn  Follow Us on Twitter  Follow Us on Facebook

Announcement

Collapse

The Alpha Software Forum Participation Guidelines

The Alpha Software Forum is a free forum created for Alpha Software Developer Community to ask for help, exchange ideas, and share solutions. Alpha Software strives to create an environment where all members of the community can feel safe to participate. In order to ensure the Alpha Software Forum is a place where all feel welcome, forum participants are expected to behave as follows:
  • Be professional in your conduct
  • Be kind to others
  • Be constructive when giving feedback
  • Be open to new ideas and suggestions
  • Stay on topic


Be sure all comments and threads you post are respectful. Posts that contain any of the following content will be considered a violation of your agreement as a member of the Alpha Software Forum Community and will be moderated:
  • Spam.
  • Vulgar language.
  • Quotes from private conversations without permission, including pricing and other sales related discussions.
  • Personal attacks, insults, or subtle put-downs.
  • Harassment, bullying, threatening, mocking, shaming, or deriding anyone.
  • Sexist, racist, homophobic, transphobic, ableist, or otherwise discriminatory jokes and language.
  • Sexually explicit or violent material, links, or language.
  • Pirated, hacked, or copyright-infringing material.
  • Encouraging of others to engage in the above behaviors.


If a thread or post is found to contain any of the content outlined above, a moderator may choose to take one of the following actions:
  • Remove the Post or Thread - the content is removed from the forum.
  • Place the User in Moderation - all posts and new threads must be approved by a moderator before they are posted.
  • Temporarily Ban the User - user is banned from forum for a period of time.
  • Permanently Ban the User - user is permanently banned from the forum.


Moderators may also rename posts and threads if they are too generic or do not property reflect the content.

Moderators may move threads if they have been posted in the incorrect forum.

Threads/Posts questioning specific moderator decisions or actions (such as "why was a user banned?") are not allowed and will be removed.

The owners of Alpha Software Corporation (Forum Owner) reserve the right to remove, edit, move, or close any thread for any reason; or ban any forum member without notice, reason, or explanation.

Community members are encouraged to click the "Report Post" icon in the lower left of a given post if they feel the post is in violation of the rules. This will alert the Moderators to take a look.

Alpha Software Corporation may amend the guidelines from time to time and may also vary the procedures it sets out where appropriate in a particular case. Your agreement to comply with the guidelines will be deemed agreement to any changes to it.



Bonus TIPS for Successful Posting

Try a Search First
It is highly recommended that a Search be done on your topic before posting, as many questions have been answered in prior posts. As with any search engine, the shorter the search term, the more "hits" will be returned, but the more specific the search term is, the greater the relevance of those "hits". Searching for "table" might well return every message on the board while "tablesum" would greatly restrict the number of messages returned.

When you do post
First, make sure you are posting your question in the correct forum. For example, if you post an issue regarding Desktop applications on the Mobile & Browser Applications board , not only will your question not be seen by the appropriate audience, it may also be removed or relocated.

The more detail you provide about your problem or question, the more likely someone is to understand your request and be able to help. A sample database with a minimum of records (and its support files, zipped together) will make it much easier to diagnose issues with your application. Screen shots of error messages are especially helpful.

When explaining how to reproduce your problem, please be as detailed as possible. Describe every step, click-by-click and keypress-by-keypress. Otherwise when others try to duplicate your problem, they may do something slightly different and end up with different results.

A note about attachments
You may only attach one file to each message. Attachment file size is limited to 2MB. If you need to include several files, you may do so by zipping them into a single archive.

If you forgot to attach your files to your post, please do NOT create a new thread. Instead, reply to your original message and attach the file there.

When attaching screen shots, it is best to attach an image file (.BMP, .JPG, .GIF, .PNG, etc.) or a zip file of several images, as opposed to a Word document containing the screen shots. Because Word documents are prone to viruses, many message board users will not open your Word file, therefore limiting their ability to help you.

Similarly, if you are uploading a zipped archive, you should simply create a .ZIP file and not a self-extracting .EXE as many users will not run your EXE file.
See more
See less

Simple xBasic table pointer question....

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Simple xBasic table pointer question....

    OK, only simple if you fully understand exactly what is going on "under the skin."
    Button on layout calls a function and passes the forms table (as a parameter) to the function...... (DBF's)

    Best practice?:

    1.) Pass the name of the table (so that a new instance of the table is created) for manipulation within the function
    OR
    2.) Pass table.current() as the parameter (and work with the existing open table.)

    Either way you have to resync. But which way is preferable and WHY?????
    My thoughts on this are that it only really matters if you want to open the table as read write and the table on the form is read only. (only one example)
    And it's better to not open another instance for "performance sake."
    Robert T. ~ "I enjoy manipulating data... just not my data."
    It's all about the "framework." (I suppose an "a5-induced" hard drive crash is now in order?)
    RELOADED: My current posting activity here merely represents a "Momentary Lapse Of Reason."

    #2
    Re: Simple xBasic table pointer question....

    Using table.current() allows you to get a pointer to the open instance of the table with current filtering and ordering and positioned to the visible record(s). Opening a new instance gives you easy access to the whole table.
    There can be only one.

    Comment


      #3
      Re: Simple xBasic table pointer question....

      What work is the called function going to do?

      If you decide to use a pointer to the table supporting your form, you might need to check the mode of the form, and commit (or cancel?) pending changes, before the UDF begins its work.

      -- tom

      Comment


        #4
        Re: Simple xBasic table pointer question....

        Originally posted by Tom Cone Jr View Post
        If you decide to use a pointer to the table supporting your form, you might need to check the mode of the form, and commit (or cancel?) pending changes, before the UDF begins its work
        Originally posted by Stan Mathews View Post
        Using table.current() allows you to get a pointer to the open instance of the table with current filtering and ordering and positioned to the visible record(s). Opening a new instance gives you easy access to the whole table.
        @ Stan: ".....if you want to open the table as read write and the table on the form is read only. (only one example)"
        (Thanks Stan, confirmed one scenario.) ~ I was thinking about those/similar reasons. Good to know I'm "on the right track" with regards to my understandings of all this.

        Thanks guys, this both makes complete sense to me. Just wanted to make sure there were no other "considerations" or concepts I may have been missing.

        And yes, the form is "well behaved." Changes are controlled within the browse itself via "invisible buttons" which always commit() at the applicable level. ~ Nothing is left in a state of "unknown." (Yes, in addition to the other "issues", I've "para-mastered" some very effective workarounds for the browse bugs too lol.)

        @ Tom: Function is going to either "undo all changes" to the table. (Change state is maintained in a field for each record ;-)), or clear a "WIP" (Work in Progress) flag + one other field after processing the table. This table is only an "interim table" used to process a much larger table. ~ Function's specific action depends on one other parameter sent to the function.)

        FWIW: I've recently adopted "the habit" of designing multi-purpose (closely related) functions (and sometimes even forms.) They serve multiple (closely related) purposes, depending upon a SINGLE global variable. (set to the button's name, "this.name()) immediately prior to invoking) ~ Simple way (and elegant me thinks, lol) for a dialog form to "know it's purpose" and respond accordingly.
        Last edited by SNusa; 02-19-2015, 06:35 PM.
        Robert T. ~ "I enjoy manipulating data... just not my data."
        It's all about the "framework." (I suppose an "a5-induced" hard drive crash is now in order?)
        RELOADED: My current posting activity here merely represents a "Momentary Lapse Of Reason."

        Comment


          #5
          Re: Simple xBasic table pointer question....

          Interesting Robert
          Would you expand your explanation of these two please?
          Originally posted by SNusa View Post

          And yes, the form is "well behaved." Changes are controlled within the browse itself via "invisible buttons" which always commit() at the applicable level. ~ Nothing is left in a state of "unknown." (Yes, in addition to the other "issues", I've "para-mastered" some very effective workarounds for the browse bugs too lol.)
          ..........
          FWIW: I've recently adopted "the habit" of designing multi-purpose (closely related) functions (and sometimes even forms.) They serve multiple (closely related) purposes, depending upon a SINGLE global variable. (set to the button's name, "this.name()) immediately prior to invoking) ~ Simple way (and elegant me thinks, lol) for a dialog form to "know it's purpose" and respond accordingly.

          Comment


            #6
            Re: Simple xBasic table pointer question....

            Did this kind of thing change?


            save the form record(s) first
            dim tbl as P
            tbl = table.get("something", mode is usually rw shared)

            tbl.enter/change.begin

            and there are a couple other ways

            Are there new ways I don't know about??
            Dave Mason
            [email protected]
            Skype is dave.mason46

            Comment


              #7
              Re: Simple xBasic table pointer question....

              Originally posted by Ray in Capetown View Post
              Interesting Robert
              Would you expand your explanation of these two please?
              HIDDEN BUTTONS (multi-purpose layouts (forms) and functions expanded in next post above)
              Preface: I only write Xbasic code, so I don't touch action scripting. However, there's no reason you couldn't use A/S by right clicking within the buttons function and using the wizard right there......

              Either using a bound or unbound field, you can edit the display format of the field and make it look "not like a button" while displaying the data in the field in the form of a button, so that it looks like a regular field in the browse. (You mess around with the settings when you're editing the display format for the field in the browse.) While editing the button text field, there is a GUI bug. First time you try to setup the button, you don't have the ability to make it dynamic so that it displays data. There's a bug there.... You have to save the button as non dynamic first, exit, right click and re-edit the button. Second time in, a small xy button (next to the field) appears. From this point on, you get to the expression builder and can display any data you choose. (Including the data of the field itself if it's already a bound data field.) There are a few other GUI bugs here but they're easy to get around too. First (not really a bug) you have to set BOTH button width and height. Set only one, these fields don't work. (for kicks, try =8 and =1.8 including the equal sign.) The other (third bug) is similar to the first one. The first time you setup the text and background color (to mimic a field and not a button) you can't set background color the first time in. You have to save the button and edit it once more to get access to that dropdown list of colors. Finally, you probably want to set the border style to none. Wile the "bugginess" seems bad, it's not really. You just have to save and go back into editing the button several times to gain access to all the capabilities. Once setup properly, you end up with a "transparent button displaying data which works just like a normal button, but appears like just a field in the browse.

              To get the button to function, you use the event.event (right clicking on the browse field to edit this event. Why it's called the "events.events I have no idea. Never made any sense to me. Nevertheless (and even with having to work around a few simple GUI bugs), the results of using "hidden buttons" within a browse are IMO really sweet!

              When you right click on the browse column event, you see a bunch of functions. Each function USUALLY only corresponds to one of the headers in the browse and includes basic info on how to make it work. But once you create a button on a browse field, a FUNCTION MULTIPLIER_ButtonClick AS V ( event AS C, data AS C , row AS N ) is added for that field/button. From here you can code whatever you want to happen when the invisible (or normal/visible) button is clicked..... It's worth noting that when you're creating a button for coding in a browse like this, I was never able to figure out (or even get) the "Enable Expression" checkbox do anything. I don't know why it's even there. (That's a question I have been wondering for quite some time.... Bug? Not bug? What, how and why the checkbox is even there.)

              In the attached screen capture below, both the STATUS and MULTIPLIER fields are actually buttons dynamically displaying data. Neither look like buttons. The first one is unbound, the second one is bound to a record in the browse table. It looked just like a regular browse field until I modified the button to appear differently based on data from multiple fields within the browse.

              When each button fires, at the bottom/last line of each function (triggered by the button press) I have added this.commit() which saves the data to the underlying table within the browse. (You see the state change looking at the indicator at the bottom of the form when it's "running." (No dirty data, no reliance upon table based events/triggers etc.)

              PS: Once you "take control of the browse" in this fashion..... With the exception of the scroll bars possibly "acting up", there is no reason not to use a browse. (I can't think of one anyways.) The next part (next post) explains what I'm doing to use a form for multiple uses....

              Capture20150221.PNG
              Last edited by SNusa; 02-22-2015, 01:50 AM.
              Robert T. ~ "I enjoy manipulating data... just not my data."
              It's all about the "framework." (I suppose an "a5-induced" hard drive crash is now in order?)
              RELOADED: My current posting activity here merely represents a "Momentary Lapse Of Reason."

              Comment


                #8
                Re: Simple xBasic table pointer question....

                Originally posted by Ray in Capetown View Post
                Interesting Robert
                Would you expand your explanation of these two please?
                MULTI USE FORMS (and Functions): Simple in theory, but you do need to understand some Xbasic coding do this. (the more the better lol)
                (hidden buttons expanded in next post below)

                Functions: Just pass a parameter value to the function like vc_Action. Two choices I'm using in one multi-use function named FUNCTION PromoHouseClean_fnc AS C (vc_Action as C, vp_Table as P) is the parameter vc_Action. In this example, it designates whether to designate (RUN) "Update" or "Revert" code based upon the parameter value passed into vc_Action.

                Forms: One example is where a form is supposed to either pick one single record, or a bunch of records as is the case in this example. Either way, it returns the single value (or multiple values) in an enumerated list. A list which is then sent to a global function for further processing. (Should this form collect one record or numerous records in this enumerated list? And which records to display in the first place are two valid reasons/examples of why you might want to use one form in multiple ways, tied to multiple buttons.... ie with buttons named: find master, add master, add fobs, remove fobs)

                When each button is clicked....
                Just before the form.ViewQueried line of code is executed (by the button OnPush event), I added the following line of code: dim global vc_CurrentAction as C = alltrim(this.text)
                This sets a global variable to the name of the button pushed. I could have also used a session variable but chose not to in this case. Exactly why now, I can't even remember lol, but it was the right thing to do in this instance.

                If you want to do it with a session variable instead.... Within the new form you will have to capture this "out of session" (FORM_ONE) variable (in the about to be opened FORM_TWO) with a similar line of code: vc_Variable = session_Variables(obj("FORM_ONE").SESSIONHANDLE()).vc_SessionVar (Where vc_SessionVar is the variable in FORM_ONE form you want to gain access to in FORM_TWO.) There's a similar way to do it with local variables and also a way to capture the value when it's stored in a field on FORM_ONE too. (FORM_1:FIELD_NAME.value (or .text)

                TIP: If it's a text field, I typically suggest using .text because .text doesn't need to be alltrimmed.... .value does! The only reason this may not be the best solution is if the data is not yet committed. (I recall problems trying to capture field values using .value on uncommitted data.)

                When I "call" the form, I'm not specifying a filter on the data with the call (empty parameter within red quotes): vp_Form = form.ViewQueried("SubKeys_frm","","invert(keyfob)","dialog","center","center") A filter can be applied on the forms OnInit event instead based on a session variable that is set when the button is pushed.

                FWIW: I also have these "multi-use" forms displaying their current action/purpose at the top of the form, using the value stored in vc_CurrentAction.

                PS: I'm sure most of you all know this, but when you close a form that has been opened type "dialog", it's not really closed, only hidden.
                (So you can still get the data back from that form until you issue vp_Form.close(). (Something you probably should do as soon as feasible.)

                Hope this makes sense.....
                Last edited by SNusa; 02-22-2015, 01:51 AM.
                Robert T. ~ "I enjoy manipulating data... just not my data."
                It's all about the "framework." (I suppose an "a5-induced" hard drive crash is now in order?)
                RELOADED: My current posting activity here merely represents a "Momentary Lapse Of Reason."

                Comment


                  #9
                  Re: Simple xBasic table pointer question....

                  If any of this is still confusing, just ask. (Not sure I did a great job explaining it all.) I'll be back to explain more/better....
                  Concepts are rather simple. Just knowing exactly how is what's not.

                  I quickly became way too frustrated trying to learn/work with action scripting years back, so I feverishly studied "the fundimentals" of Xbasic.
                  Took a long time before things "really began to click." Xdialog though, forget it..... Looks like "hybrid java" to me, and I don't know java either lol....

                  PS: The nice thing about placing (assigning) this.name() to a variable on a buttons OnPush event (just before opening anything else etc.) is: Anything & everything else "knows" exactly why it's being opened.
                  Last edited by SNusa; 02-22-2015, 01:56 AM.
                  Robert T. ~ "I enjoy manipulating data... just not my data."
                  It's all about the "framework." (I suppose an "a5-induced" hard drive crash is now in order?)
                  RELOADED: My current posting activity here merely represents a "Momentary Lapse Of Reason."

                  Comment


                    #10
                    Re: Simple xBasic table pointer question....

                    Hidden buttons... Forgot to mention:

                    To "tame the browse" (read recent post below re. hidden buttons) one method I employ before adding the this.commit() to the events event is: I sometimes use some sort of UI_get function (with an OK / Cancel option) to capture user input. Then all I have to do is validate this input before assigning the value via this:Browse_Field.text. If you're only editing/entering one field of data, this method enables you to get the input without needing a separate form.....

                    The trick (even when moving from field to field on any row of the browse object) when using "hidden buttons" to display the data (instead of just a regular "non button" field) is: When and where to apply this.commit() Depending upon whether you're using "look-ups" in a browse field, you may need this.commit() attached to a browse event, and not a browse button event. ~ Hope that makes sense.

                    Optionally (instead of using "this.commit()", you could use the name of the browse etc. too. ie: Browse_Name.commit()... ~ Lots of different variations on how to reference the browse object.
                    Last edited by SNusa; 02-23-2015, 01:36 PM.
                    Robert T. ~ "I enjoy manipulating data... just not my data."
                    It's all about the "framework." (I suppose an "a5-induced" hard drive crash is now in order?)
                    RELOADED: My current posting activity here merely represents a "Momentary Lapse Of Reason."

                    Comment


                      #11
                      Re: Simple xBasic table pointer question....

                      Robert
                      For discussion..
                      If one were to have browse fields (in embedded browse) and the fields are calc'ed say, as text from multiple data sources, for example.
                      If I were to want to click on a field to call a function I currently use a double click, and interrogate the cell row and column details and call a function using the parameters.

                      I tried creating a button to display the same data, and use a single click, but cant get said button to be hidden. Describe how you create a HIDDEN BUTTON as you call it.
                      BTW offering users an action on any single click on a cell could be confusing as they would also click just to land on any cell no?

                      This is of interest for graphic/intuitive user interface which I use a lot.

                      Comment


                        #12
                        Re: Simple xBasic table pointer question....

                        Hi Ray;

                        I will try to get you an example tomorrow. (I took the weekend off to "not do much" lol.)
                        As for the double-click thing, I think a single click works awesome. Especially when it brings up an UI_GET box for input. (An OK and cancel style box works great with cancel being the default.)
                        Click on the field in the browse, the box comes up. Enter the data and hit OK, or just click cancel. Either way to go it takes 2 clicks tops to process! One to get the box up, and one to either process or cancel it.) ~ Made a mistake and hit cancel (or enter when default is set that way), nothing happens & you're back at the browse.

                        I guess it's all a matter of user preference, user experience. But in business, I don't really even have time to use the mouse in the first place, let alone have to double click anything.
                        (I'm seriously trying to remember a single piece of software that required a double click to get to a data entry field.) The one exception to this is the "classic" windows desktop. I keep that set for a double click. (Just seems right there. Because it can be used as a a program launch pad. And who spends much time there anyways lol.)

                        Come to think of it, if I can find it: I learned how to make these "Invisible buttons" while playing with the AlphaSports INVOICE form. I just have to find it and I will send it to you.
                        Just import the form into an instance of the Alpha Sports workspace and you can see how it works..... (What version of Alpha are you working with, AA?)

                        Honestly, I've never worked with a single piece of POS (or accounting software) that ever needed a second click to enter data. And I've worked with A LOT of small business accounting/POS software over the years...... One button/click and off I go..... A technique like this is FAST and efficient. No loading a form (for a single field.) And even if you want to enter several fields at once, you can optionally easily create a Xdialog box instead using the wizard by right clicking in the XBE.

                        With regards to X-Dialog.... (You know, the stuff that looks like hybrid Java to me lol.)... I do use it, but I leave all the "heavy lifting" up to Alpha.
                        (Only place I use wizards is when generating xDialog input.) Can't write it and don't want to learn. But it's easy to look at the code and know what you have to do with it to get what you want from the variables used. ~ After all, you get to name all the variables while working in the wizards.

                        PS: With a touch of "wizardry" I'll bet there's some way to add a snippet of code (within the buttons events.event attached to the "invisible button") that would either look for a second mouse click, or cancels the process so you're left back at the browse even before the UI_Get box appears!?!?
                        Last edited by SNusa; 02-24-2015, 12:58 AM.
                        Robert T. ~ "I enjoy manipulating data... just not my data."
                        It's all about the "framework." (I suppose an "a5-induced" hard drive crash is now in order?)
                        RELOADED: My current posting activity here merely represents a "Momentary Lapse Of Reason."

                        Comment


                          #13
                          Re: Simple xBasic table pointer question....

                          For Ray... (See pm. ~ Was unable to attach to message)
                          These photos show the screens relevant to setting up "invisible buttons."
                          Ray, if my PM confused you, sorry. Just PM me with questions. I was exhausted when I put it together. (Had to cut it back to fit 5000 chars.)

                          PS: I'll find the example of a Alpha Sports form using the invisible buttons and add it tomorrow. (A highly modified Alpha Sports form that I used to learn this stuff.)
                          Form is "trashy" but check out the invoice fields in the browse. (invisible buttons working)

                          UPDATE: Until I find that "workspace", here's a link to a post I made about the buttons years back. It was in v.10.5.
                          http://www.alphasoftware.com/alphafo...l=1#post663091

                          I don't have to find the example... In the next post (link above), someone else created a simple example of my "hidden buttons" and uploaded the zipped database. Go grab that. Much less cluttered than the practice form I was going to search for. ~ Your going to like this "hidden button thing." lol

                          I think from the screen captures in this post/thread you'll have all that you need.....
                          Worth mentioning that the red circle around the screen depicts a field that was conditionally displaying "a hidden field" but then a "weird button junk field" based on specific quantities within the bound field "QUANTITY." You can click on any record in that field and the "hidden button" will launch an input UI_GET. I believe that if the quantity equaled 2, then that ridiculous button with the google swirl would appear instead a button with hidden attributes.

                          20150224Capture.PNG20150224bCapture.PNG
                          Last edited by SNusa; 02-24-2015, 01:34 PM.
                          Robert T. ~ "I enjoy manipulating data... just not my data."
                          It's all about the "framework." (I suppose an "a5-induced" hard drive crash is now in order?)
                          RELOADED: My current posting activity here merely represents a "Momentary Lapse Of Reason."

                          Comment

                          Working...
                          X