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

Address Verify and Zip Code Look up

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

    Address Verify and Zip Code Look up

    Here is a function for your grids (and UX components with a change or two) to automatically lookup and verify address and add the 9 digit zip code. It is a modification of a process that I found on <broken link> about an article that Jay Talbott had written. Thank you Jay!

    For grid use, add a button under the address fields called 'Address Verify'. Then set up an Ajax Callback function called PostOffice that is called when you click the button. Then add the following function to the Xbasic Functions.

    You will probably have to rename field names in this function to reflect the actual field names in your grid. This function will also get the county for the address. If you don't have that field in your table, then be sure to rem out that line in the function.
    The nice thing about this is that the user only needs to enter the street address, city and state. This function will return and fill in or correct the street address, city, state and 9 digit zip code. It means that you will get the proper street address formatted in post office format and the proper zip code. If you enter in 3222 E Kristal for example, it will return 3222 E Kristal Way and fill in the field for you. It also checks for basic errors and for multiple addresses. What I mean by multiple addresses is this. Say you put in an address of 5225 N Central, Phoenix, AZ. You will get that error message. That address is composed of several suites, so it is telling you that you need to include the suite number in the address field in order for the post office to process it. That is particularly useful when people forget to give you that piece of information or the suite or apartment number is incorrect.

    Hope you find it useful.

    Mike


    function PostOffice as c (e as p)
    'change the next 3 lines as needed to match your actual field names
    vc_address1 = alltrim(e._currentRowDataNew.addr2)
    vc_city = alltrim(e._currentRowDataNew.city)
    vc_state = alltrim(e._currentRowDataNew.state)
    vc_zip = ""
    vc_zip4 = ""
    vc_county = ""
    error = ""


    'debug(1)
    'the url = must be on one line, not 2 as shown here
    url = "https://tools.usps.com/go/ZipLookupResultsAction!input.action?resultMode=1&companyName=&address1=" +vc_address1 + "&address2=&city=" + vc_city + "&state=" + vc_state + "&urbanCode=&postalCode=&zip=" + vc_zip
    result=http_get_page2(url,.f.)


    scanner=stringscanner.create(result)


    'check for muliple unit error
    scanner.SkipToString("Several addresses matched the information you")
    scanner.SkipOverString("&nbsp;")
    error = scanner.ScantoString("you didn't")
    if error = "Several addresses matched the information you provided. Perhaps " then
    PostOffice = "alert('" + js_escape("Several addresses matched the information you provided. Perhaps you didn't enter a street number or the building has mulitple units.") + "');"
    end
    end if




    'Start over to check for next error
    scanner.reset()
    'Check for invalid address
    scanner.SkipToString("Unfortunately, this address wasn't found.")
    error = scanner.ScanToString(".")
    if error = "Unfortunately, this address wasn't found" then
    PostOffice = "alert('This address cannot be found in the Post Office database, please check the spelling and try again.');"
    end
    end if




    'Start over to check for next error
    scanner.reset()
    'Check for invalid address
    scanner.SkipToString("The address you provided is not recognized")
    error = scanner.ScanToString("by")
    if error = "The address you provided is not recognized" then
    PostOffice = "alert('This address cannot be found in the Post Office database, please check the address and try again.');"
    end
    end if




    'Start over to retrieve address info
    scanner.reset()


    scanner.SkipToString("<!-- Begin zip-lookup-result-container-single.jsp-->")


    scanner.SkipToString("address1")
    scanner.SkipOverString("&nbsp;")
    scanner.SkipToString("range"")
    scanner.SkipOverString("range">")
    vc_address1 = scanner.ScanToString("</")


    scanner.SkipToString("class="city")
    scanner.SkipOverString("&nbsp;")
    scanner.SkipToString("range"")
    scanner.SkipOverString("range">")
    vc_city = scanner.ScanToString("</" )


    scanner.SkipToString("class="state" )
    scanner.SkipOverString("&nbsp;")
    scanner.SkipToString("range"")
    scanner.SkipOverString("range">")
    vc_state = scanner.ScanToString("</" )


    scanner.SkipToString("class="zip"" )
    scanner.SkipOverString("&nbsp;")
    scanner.SkipToString("style=""")
    scanner.SkipOverString("style=""")
    scanner.SkipOverString(">")
    vc_zip = scanner.ScanToString("</" )


    scanner.SkipToString("class="zip4"" )
    scanner.SkipOverString("class="zip4"")
    scanner.SkipOverString(">")
    vc_zip4 = scanner.ScanToString("</" )


    scanner.SkipToString("County</dt>" )
    scanner.SkipToString("<dd")
    scanner.SkipOverString("<dd")
    scanner.SkipOverString(">")
    vc_county = scanner.ScanToString("</" )


    vc_zip = vc_zip + "-" + vc_zip4

    'change the next 5 lines as needed to reflect your actual field names
    e._set.addr2.value = vc_address1
    e._set.city.value = vc_city
    e._set.state.value = vc_state
    e._set.zip.value = vc_zip
    e._set.county.value = vc_county
    PostOffice = ""


    end function
    Last edited by Lenny Forziati; 12-14-2021, 12:59 PM. Reason: removed broken link
    Mike Reed
    Phoenix, AZ

    #2
    Re: Address Verify and Zip Code Look up

    My updated version based on the new USPS WebService API. This only checks the zip code but adding the code to check the remainder of the address fields is quite simple. The code below is for a UX but could easily be adapted to a grid. Special thanks to David Kates for his JavaScript function that performs the same task and led me down the right path:

    Code:
    function PostOffice as c (e as p)
    	
    dim Response as c = ""
    dim ResponseTimeout as n = 30000 '30 seconds
    dim WebURI as c
    dim content as p
    dim vczip as c = ""
    dim vplus4 as c = ""
    dim USPS_Zipcode_Lookup2 as c
    
    WebURI= "http://production.shippingapis.com/ShippingAPI.dll?API=Verify&XML=<AddressValidateRequest USERID=%22YourUSPSUserID%22><Address ID=%221%22><Address1></Address1><Address2>%20"
    WebURI = WebURI+alltrim(e.dataSubmitted.mailing_address)+"</Address2><City>"+alltrim(e.dataSubmitted.city)+"</City><State>"+alltrim(e.dataSubmitted.state)+"</State><Zip5></Zip5><Zip4></Zip4></Address></AddressValidateRequest>"
    
    Response = http_post_page2(WebURI,"",.f.,ResponseTimeout)
    *property_from_xml(response,content,.t.)
    
    IF eval_valid("content.AddressValidateResponse.Address[1].Zip5[1].__A5_elementContent")
    	vczip = content.AddressValidateResponse.Address[1].Zip5[1].__A5_elementContent
    END IF
    	
    IF eval_valid("content.AddressValidateResponse.Address[1].Zip4[1].__A5_elementContent")
    	vplus4 = content.AddressValidateResponse.Address[1].Zip4[1].__A5_elementContent
    END IF
    
    USPS_Zipcode_Lookup2 = ""
    
    if vczip = ""
    	resultmsg = "Could not locate address.  No change made"
    else
    	if vplus4 = ""
    		USPS_Zipcode_Lookup2= vczip
    	else
    		USPS_Zipcode_Lookup2= vczip+"-"+vplus4
    	end if
    	resultmsg = "Address found.  Postal code has been verified."
            e._set.postal_code.value = USPS_Zipcode_Lookup2
    end if
    PostOffice = "alert('"+resultmsg+"');"
    
    END FUNCTION
    [/code]
    Brad Weaver, President
    ComputerAid International
    Ottawa ON Canada
    Versailles KY USA
    www.compuaid.com

    Comment


      #3
      I took a little of both of these and formed a function that does address verification and zip code lookup using the updated USPS Webservice API. Enjoy!

      Code:
      function PostOffice as c (e as p)
      dim vc_address1 as c
      dim vc_city as c
      dim vc_state as c
      dim vc_zip as c
      dim vc_zip4 as c
      dim error as c
      dim WebURI as c
      dim result as c
      dim scanner as p
      
      'change the next 3 lines as needed to match your actual field names
      vc_address1 = alltrim(e._currentRowDataNew.address)
      vc_city = alltrim(e._currentRowDataNew.city)
      vc_state = alltrim(e._currentRowDataNew.st)
      vc_zip = ""
      vc_zip4 = ""
      
      error = ""
      debug(1)
      WebURI= "http://production.shippingapis.com/ShippingAPI.dll?API=Verify&XML=<AddressValidateRequest USERID=%22913SKYLA1189%22><Address ID=%221%22><Address1></Address1><Address2>%20"
      WebURI = WebURI+alltrim(e.dataSubmitted.address)+"</Address2><City>"+alltrim(e.dataSubmitted.city)+"</City><State>"+alltrim(e.dataSubmitted.st)+"</State><Zip5></Zip5><Zip4></Zip4></Address></AddressValidateRequest>"
      result=http_get_page2(WebURI,.f.)
      scanner=stringscanner.create(result)
      'check for muliple unit error
      scanner.SkipToString("Default address: The address you entered was found but more")
      scanner.SkipOverString("&nbsp;")
      error = scanner.ScantoString("information")
      if error = "Default address: The address you entered was found but more" then
      PostOffice = "alert('" + js_escape("Several addresses matched the information you provided. Perhaps you didn't enter a street number or the building has mulitple units.") + "');"
      end
      end if
      
      'Start over to check for next error
      scanner.reset()
      'Check for invalid address
      
      scanner.SkipToString("Address Not Found")
      scanner.SkipOverString(".")
      error = scanner.ScanToString("<")
      if error = "Address Not Found. " then
      PostOffice = "alert('This address cannot be found in the Post Office database, please check the spelling and try again.');"
      end
      end if
      
      'Start over to check for next error
      scanner.reset()
      'Check for missing state
      scanner.SkipToString("Invalid State Code")
      scanner.SkipOverString(".")
      error = scanner.ScanToString("<")
      if error = "Invalid State Code. " then
      PostOffice = "alert('Invalid State Code. Address Verification requires an address, city, and state.');"
      end
      end if
      
      
      'Start over to retrieve address info
      scanner.reset()
      scanner.SkipToString("<!-- Begin zip-lookup-result-container-single.jsp-->")
      
      scanner.SkipToString("Address2>")
      scanner.SkipToString(">")
      scanner.SkipOverString(">")
      vc_address1 = scanner.ScanToString("<" )
      
      scanner.SkipToString("<City>")
      scanner.SkipToString(">")
      scanner.SkipOverString(">")
      vc_city = scanner.ScanToString("<" )
      
      scanner.SkipToString("<State>")
      scanner.SkipToString(">")
      scanner.SkipOverString(">")
      vc_state = scanner.ScanToString("<")
      
      scanner.SkipToString("<Zip5>")
      scanner.SkipToString(">")
      scanner.SkipOverString(">")
      vc_zip = scanner.ScanToString("<" )
      
      
      scanner.SkipToString("<Zip4>")
      scanner.SkipToString(">")
      scanner.SkipOverString(">")
      vc_zip4 = scanner.ScanToString("<" )
      
      
      vc_zip = vc_zip + "-" + vc_zip4
      
      'change the next 4 lines as needed to reflect your actual field names
      e._set.address.value = vc_address1
      e._set.city.value = vc_city
      e._set.st.value = vc_state
      e._set.zip.value = vc_zip
      PostOffice = ""
      
      
      end function

      Comment


        #4
        Thanks, Adrianne. I have also been updating my function to validate and update the full address. One note is that the post office is moving to secure connections so the WebURI should be changed to https:// for future compatibility.

        Here's my updated code as well:

        Code:
        FUNCTION PostOffice as c (e as p)
        
        dim Response as c = ""
        dim ResponseTimeout as n = 30000 '30 seconds
        dim WebURI as c
        dim content as p
        dim USPS_Address as c
        dim USPS_City as c
        dim USPS_State as c
        dim vczip as c = ""
        dim vplus4 as c = ""
        dim USPS_Zipcode_Lookup2 as c
        dim retstring as c = ""
        dim success as l
        
        WebURI= "https://production.shippingapis.com/ShippingAPI.dll?API=Verify&XML=<AddressValidateRequest USERID=%YOUR USPS ID GOES HERE%22><Address ID=%221%22><Address1></Address1><Address2>%20"
        WebURI = WebURI+alltrim(e.dataSubmitted.mailing_address)+"</Address2><City>"+alltrim(e.dataSubmitted.city)+"</City><State>"+alltrim(e.dataSubmitted.state)+"</State><Zip5></Zip5><Zip4></Zip4></Address></AddressValidateRequest>"
        
        Response = http_post_page2(WebURI,"",.f.,ResponseTimeout)
        *property_from_xml(response,content,.t.)
        
        'debug(1)
        'Get Street Address
        IF eval_valid("content.AddressValidateResponse.Address[1].Address2[1].__A5_elementContent")
        USPS_Address = content.AddressValidateResponse.Address[1].Address2[1].__A5_elementContent
        END IF
        
        'Get City
        IF eval_valid("content.AddressValidateResponse.Address[1].City[1].__A5_elementContent")
        USPS_City = content.AddressValidateResponse.Address[1].City[1].__A5_elementContent
        END IF
        
        'Get State
        IF eval_valid("content.AddressValidateResponse.Address[1].State[1].__A5_elementContent")
        USPS_State = content.AddressValidateResponse.Address[1].State[1].__A5_elementContent
        END IF
        
        'Get Zip
        IF eval_valid("content.AddressValidateResponse.Address[1].Zip5[1].__A5_elementContent")
        vczip = content.AddressValidateResponse.Address[1].Zip5[1].__A5_elementContent
        END IF
        
        'Get Zip Suffix
        IF eval_valid("content.AddressValidateResponse.Address[1].Zip4[1].__A5_elementContent")
        vplus4 = content.AddressValidateResponse.Address[1].Zip4[1].__A5_elementContent
        END IF
        
        USPS_Zipcode_Lookup2 = ""
        
        IF vczip = "" .OR. USPS_Address = "" .OR. USPS_City = "" .OR. USPS_State = ""
           USPS_Zipcode_Lookup2= alltrim(e.dataSubmitted.postal_code)
           success = .F.
        ELSE
        IF vplus4 = ""
          USPS_Zipcode_Lookup2= vczip
        ELSE
          USPS_Zipcode_Lookup2= vczip+"-"+vplus4
        END IF
        
        'Use your field names here
        e._set.mailing_address.value = USPS_Address
        e._set.city.value = USPS_City
        e._set.state.value = USPS_State
        e._set.postal_code.value = USPS_Zipcode_Lookup2
        success = .T.
        END IF
        
        'retstring = "A5.msgBox.buttonAlign = 'center';A5.msgBox.show('USPS Verification','<div style=\"height: 20px; padding: 25pt;\">"+resultmsg+"</div>',[{name: 'ok', html: 'OK', value: 'ok'}],function(button) {if(button == 'ok') {setTimeout(function() {{dialog.Object}.setFocus('SALES_PRICE');},10)};A5.msgBox.buttonAlign = '';});"
        IF success = .F. ' Only show a message if not successful
          PostOffice = "{dialog.object}.runAction('USPSError');"
        ELSE
          PostOffice = "{dialog.object}.runAction('USPSSuccess');"
        END IF
        
        END FUNCTION
        Brad Weaver, President
        ComputerAid International
        Ottawa ON Canada
        Versailles KY USA
        www.compuaid.com

        Comment


          #5
          To follow up, at the end of the function I call one of two Action JavaScript items that displays a nicely formatted message telling the user the outcome.
          Brad Weaver, President
          ComputerAid International
          Ottawa ON Canada
          Versailles KY USA
          www.compuaid.com

          Comment

          Working...
          X