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

UDF triggering twice

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

    UDF triggering twice

    Hello

    I am trying to write a UDF to write to a log file when a button is pressed however the UDF is trigging twice and therefore I get two entries. If I test the UDF in the interactive window I get only a single entry. I have been able to reproduce the problem and attach an example. From the form reportip pressing either button calls the UDF. Looking at the logname table shows the double entry. Logref is a time stamp. I am trying to keep a log when a form is printed (using a report copy of the form)

    Is a bug with the operation of the button or my code?
    (I also get double entries when using the Onprintinit event on the report on the main database - Not included in the example)

    Thanking you in advance for any help

    Dave

    #2
    Re: UDF triggering twice

    Dave, I think this behavior results from the way Alpha implemented your first "action" statement for you. Alpha produced the following code when you told it to assign the function's return value to your variable:

    Code:
    Reportno = convert_type(a5_eval_expression("=Logrptip(\"Report1\")",local_variables()),"c")
    Notice that the function call is inside a nested expression. I think the UDF is being called by both the a5_eval_expression() function, and by the convert_type() function. Hence, two records are written to the table.

    I've attached a revised form of the database, to show you a simpler approach using standard Xbasic code. Check out the script beneath the Print Report3 button.

    -- tom

    Comment


      #3
      Re: UDF triggering twice

      Thank You I will modify the master database

      Comment


        #4
        Re: UDF triggering twice

        Hi Tom,

        Originally posted by Tom Cone Jr View Post
        Dave, I think this behavior results from the way Alpha implemented your first "action" statement for you. Alpha produced the following code when you told it to assign the function's return value to your variable:

        Code:
        Reportno = convert_type(a5_eval_expression("=Logrptip(\"Report1\")",local_variables()),"c")
        Notice that the function call is inside a nested expression. I think the UDF is being called by both the a5_eval_expression() function, and by the convert_type() function. Hence, two records are written to the table.
        I think the reason for the two firing is that 1st, the function is not a "Pure" function, and because of that, every time Alpha calls it, it's results are not the same (in other words, it creates a new record). The reason for this is that eval_valid(), along with eval() both cause the code to be executed, and it is very typical to check validity before actual running the code for final results. But this has unintended consequences for this case.

        The proper way would be to do error trapping and just run the code once, which can be done in many cases. This is just another example of Action Scripts having unintended consequences or not working as expected per my tips here.
        Regards,

        Ira J. Perlow
        Computer Systems Design


        CSDA A5 Products
        New - Free CSDA DiagInfo - v1.39, 30 Apr 2013
        CSDA Barcode Functions

        CSDA Code Utility
        CSDA Screen Capture


        Comment


          #5
          Re: UDF triggering twice

          Thank you

          I have it working now using Tom's code on the Onprintinit event on the report.

          Comment


            #6
            Re: UDF triggering twice

            Dave, I'm glad you have it working.

            I write again because, after considering Ira's post and giving the matter a bit more thought, I think I reached the right conclusion but misunderstood why. Your UDF is being called twice by the code generated by your action scripting "action". But the convert_type() function has nothing to do with it.

            Here's the code that action scripting supplied:
            Code:
            Reportno = convert_type(a5_eval_expression("=Logrptip(\"Report1\")",local_variables()),"c")
            The expression that the function "a5_eval_expression()" tests includes another function, namely your UDF. So, Alpha runs your UDF first (because it's the most deeply nested component in the expression), and then the a5_eval_expression() runs it again. Oridinarly, this is a matter of no consquence since a classic or "pure" function Ira references would return the same result no matter how many times it is run. But... in this case your function writes records to a table, so you get multiple copies.

            So, in my previous post I reached the right conclusion, but gave you a faulty explanation. Anyway, good luck with your project!

            -- tom

            Comment


              #7
              Re: UDF triggering twice

              Thanks Tom! As I use UDFs quite often (and for some unusual things at times I might add!), this will be something I had better be aware of as well.
              Mike
              __________________________________________
              It is only when we forget all our learning that we begin to know.
              It's not what you look at that matters, it's what you see.
              Henry David Thoreau
              __________________________________________



              Comment


                #8
                Re: UDF triggering twice

                Hi Tom,

                Originally posted by Tom Cone Jr View Post
                ....The expression that the function "a5_eval_expression()" tests includes another function, namely your UDF. So, Alpha runs your UDF first (because it's the most deeply nested component in the expression), and then the a5_eval_expression() runs it again.
                That's not correct either. It has no relevance to the nesting of the expressions. The only executions occur within the a5_eval_expression() function.

                (As a side note, Alpha executes expressions from right to the left, which is really confusing in a few cases where items to the left depend on values created by items to the right - this is very rare (happens for a use of a non-pure function of mine), and never happens with pure functions).

                Below, I am showing you a script of what Alpha basically does, as opposed to a better way Alpha could do it. But it comes down to this. Eval_valid() and similar testing functions are generally followed up by an eval() or similar, and this is what a5_eval_expression() does internally.

                For non-pure functions, it always will execute twice for good code with the side effects of the non-pure function (writing a record each time for this case). Non-pure functions are OK, but you must be aware of side effects.

                Code:
                dim testcode as c
                dim codeok as L
                dim result as n
                
                testcode="ui_msg_box(\"Test 1\",\"Test\")"
                
                ' This executes the code in test code as a consequence
                ' of testing it being runnable without errors
                codeok=eval_valid(testcode)
                
                ' This executes the code in test code
                result=eval(testcode)
                '============================================================
                ' This is kind of what what Alpha does in A5_eval_expression()
                ' If the code is good, it will run twice.
                ' If bad code, it will run the code up to the point of the 1st error
                testcode="ui_msg_box(\"Test 2\",\"Test\")"
                IF eval_valid(testcode)
                    result=eval(testcode)
                END IF
                '============================================================
                ' This is kind of what what Alpha does in A5_eval_expression()
                ' If the code is good, it will run twice.
                ' If bad code, it will run the code up to the point of the 1st error
                testcode="ui_msg_box(\"Test 3\",\"Test\")"
                result=a5_eval_expression("="+testcode)
                '====================================
                ' This is what Alpha should have done
                ' (and is essentially what happens in eval_valid(), except the result
                ' is thrown away, and just the logical flag that indicates it ran is
                ' returned)
                ' If the code is good, it will run once
                ' If bad code, it will run the code up to the point of the 1st error
                
                testcode="ui_msg_box(\"Test 4\",\"Test\")"
                
                ' Set code OK initially to false
                codeok=.f.
                
                ' Turn on error trapping
                ON error goto finish_error
                
                result=eval(testcode)
                codeok=.t.
                
                finish_error:
                ' Turn off error trapping either way
                on error goto 0
                
                ' eval() would return result 
                ' whereas eval_valid() would return codeok
                Does this explain it more clearly?
                Regards,

                Ira J. Perlow
                Computer Systems Design


                CSDA A5 Products
                New - Free CSDA DiagInfo - v1.39, 30 Apr 2013
                CSDA Barcode Functions

                CSDA Code Utility
                CSDA Screen Capture


                Comment

                Working...
                X