Script that will hold the previous attributes of last object - ArcPad

7701
12
Jump to solution
08-21-2014 10:57 PM
timdunlevie
Occasional Contributor

Hi guys,

I have designed a template to capture field data.

I want to enter point data - fill in all the relevant fields on page 1, then fill in more specific data about the object on page 2.

The next point object I enter will have the same attributes on Page 1 but different attributes on page 2.

Is there a script or code I can add to my .apl file that makes my data entry behave like that?

I don't want to re-enter data which won't change in my data collection.

Thanks

1 Solution

Accepted Solutions
MosquitoGIS
Occasional Contributor

There is the Repeat Attributes button on the bottom of forms during the collection process, not the creating a form part, (Icon with a green arrow that points to the right), that if you select and fill out a form, it will keep all that same information and then next time you capture data and it opens the form it has all the previously entered data.  That would do it for all pages though.  So they would have to remove and change/edit everything on that second page. To do it for only one page, I think you are going to have to do the scripting with Global Variables like Rebecca Strauch‌ said above.

There are "event scripts", but anything beyond quick quirps of code, you have to create a separate *.vbs file that compliments and is referred to in your form (*.apl). I, like Rebecca above started out with ArcPad 6 and so don't know much about AB, but will do my best to help you out.  I was once just starting and trying to learn on my own and so hopefully this helps give you a starting position, as it sounds like you are interested in branching out, but have no idea how to get started.  I am going to write this very basic in case that is the situation, if you are more advanced than just ignore the parts that you already know.

So, If you are looking at something as simple as: A person opens up ArcPad and collects their first data for the day and fills out the form and moves to the next.  Upon collecting the next bit of data, the first page is filled out with exactly what was last written, but the second page is blank.  Here is what you will need to do.

Create a .vbs file in the same directory as your .apl that has the same name as the .apl (i.e. If Tracker is hte name of your apl, you would do this: Tracker.apl & Tracker.vbs).  A very simple way to do this is to copy a previous .vbs file there and rename it or create a blank Notepad file and change the name as well as the extension (New Notepad Document.txt to Tracker.vbs).  Either way, once done, use Arcpad Studio to open the .vbs file.  Make sure everything is cleared out and that is blank and then copy and paste the following into it:

Option Explicit

'setting program Variables
Dim OnOff
'On means to now load what was last typed in last.
'Since the first time it loads there is no Variables it is set to off, as soon as the
'first form is filled out, it is then turned on

Sub LayerOpen()
OnOff = 0 'Upon first load of the whole Layer, set OnOff to Off
End Sub

Sub Pressing_Ok()
' get page 1 controls
Dim pControls
Set pControls = ThisEvent.Object.Pages(1).Controls

' store the form data into a Global Variable. 
'Replace the Names "txtStationID" with the ones that match your actual Names on your form.
Application.UserProperties("VarStationID") = pControls("txtStationID").Value
Application.UserProperties("VarProject") = pControls("cboProject").Value
Application.UserProperties("VarStationType") = pControls("txtStationType").Value
Application.UserProperties("VarTenement") = pControls("cboTenement").Value
'DATE:This style doesn't work with Date, so it is not included
Application.UserProperties("VarLogged_by") = pControls("cboLogged_by").Value
Application.UserProperties("VarRock_Code") = pControls("cboRock_Code").Value
Application.UserProperties("VarLith_desc") = pControls("txtLith_desc").Value

' clean up
    Set pControls = Nothing

OnOff = 1
End Sub

Sub FormInit()

  If OnOff = 1 then
   ' get page 1 controls
Dim pControls
Set pControls = ThisEvent.Object.Pages(1).Controls


'Set the form data to what is stored in the Global Variables
'Replace the Names "txtStationID" with the ones that match your actual Names on your form.
pControls("txtStationID").Value = Application.UserProperties("VarStationID")
pControls("cboProject").Value = Application.UserProperties("VarProject")
pControls("txtStationType").Value = Application.UserProperties("VarStationType")
pControls("cboTenement").Value = Application.UserProperties("VarTenement")
'This style doesn't work with Date, so it is not included
pControls("cboLogged_by").Value = Application.UserProperties("VarLogged_by")
pControls("cboRock_Code").Value = Application.UserProperties("VarRock_Code")
pControls("txtLith_desc").Value = Application.UserProperties("VarLith_desc")

  ' clean up
    Set pControls = Nothing
  End if

End Sub

Read through the code and Rem'd notes (Those just after an apostrophe) as there are some places you will need to make some changes to the code to make it work with your program.  I tried to document it fairly well so that you can make changes as needed and get an idea on how it works so that you can have an idea for the next time.

Now back in your .apl, you will have to make a few changes on those event scripts on certain parts of it.  Open the portion for the layer and set the onopen event to "Call LayerOpen()" without the quotes.  What this is doing is saying upon this event, call upon the sub-routine in the .vbs file.  If you look above in the code, you will see there is a "Sub LayerOpen()" and then sometime after that is an "End Sub".  Everything between that is a sub-routine.  So when that sub-routine is called, it runs everything within that routine.  OK, two more.  Now open the form and set onload to "Call FormInit()" without quotes and also set onok to "Call Pressing_ok()".

Ok, so now your apl know it needs to call those sub-routines, but needs to know what file to find those in.  Since I have no idea how to do this except besides code, you will have to do this last part via that way. On your toolbar in ArcPad studio with the apl open, there will be a button that has to arrows pointing away from each other one a top the other.  One is blue and one is red.  The tooltip on it says "Toggle between source and treeview".  Click that button and it will probably ask you to save and of course say yes.  You will now be looking at the code.  Without changing anything, go to the very bottom and right above where it says "</ArcPad>"  type  "<SCRIPT src="Tracker.vbs" language="vbscript"/>"  without the first and last quote.  Make sure to change the actual "Tracker.vbs" to whatever the name of your .vbs file is.  Esentially, it should look something like this at the end:

</LAYER>

<SCRIPT src="Tracker.vbs" language="vbscript"/>

</ArcPad>

Go ahead and hit that toggle between source and treeview button again.  Tell it yes you want to save and then  you should be in business.

As for the date field, since it can't be handed in this same manner, if it is just for today's date you are looking for anyway, set that text fields default value to "Now" without quotes.

Good luck and let me know how it works out.

View solution in original post

12 Replies
RebeccaStrauch__GISP
MVP Emeritus

Hi Tim,

You didn't mention how you are customizing your ArcPad.  If you are using .vbs, I can tell you how I did this.  This may not be the best or only method, since this was written originally for ArcPad 6.1, but it does still work with the latest release.  Please let me know if you need more clarification since it is a bit hard to pick out the main points, but should help you find the keywords in the help.  These are:  Application.UserProperties  Application.GetProfileString Application.WriteProfileString

Brief description of my project: If is an aerial survey of wildlife.  Some values (computer number, last animalID, incremental segment number, etc) carry forward between sessions by reading/writing to the ArcPad.ini file.  Other variables (transect number, species, etc) are set in a subroutine, and the variable are written to global variable (Application.UserProperties).  The values of all can change throughout the session, some by the user and others behind the scene.  Many carry forward between forms, and also show in a formatted status bar at the bottom.

Warning/suggestion:  if it's a variable you do not want to lose if the computer crashes, periodically save it to the ArcPad.ini (don't wait until final closing of the program) 

Save/retrieve values between ArcPad sessions, I use the "Application.GetProfileString" or "Application.GetProfileInt" (for reading) and  "Call Application.WriteProfileString" or "Call Application.WriteProfileInt" (for writing).  These are written and read from the ArcPad.ini file. For example to read and write the string variable "LastTransNo" to the ArcPad.ini,  and to/from a session global variable "strLastTransNo":

Read....

    Application.UserProperties("strLastTransNo") = Application.GetProfileString("SessionVars","LastTransno","none")

Write...

    Call Application.WriteProfileString("SessionVars","LastTransno",strTransno)

Saving variables within an ArcPad session (and to carry forward),  use    Application.UserProperties("myVariable")  to store the variables for example

            Application.UserProperties("strLastTransNo") = Application.GetProfileString("SessionVars","LastTransno","none")

or, for example, to increment a value (on certain event):

    Application.UserProperties("intSegment") = (Application.UserProperties("intSegment") + 1)"

Using the saved variable to populate a field on a form (carry forward)

In my project, in my transectapps.vbs  I have a  "Sub TransSetup()"     which includes...

          ...

        Dim objTheForm  

        Set objTheForm = Applet.Forms("frmTransSetup")

        objTheForm.Show

          ...

This particular form is located in my project.apa file.  inside the form for TransNo field, I show

     <EDIT name="txtTransno" x="45" y="5" width="25" height="12" onvalidate="ThisEvent.Object.Parent.Controls(&quot;txtTransno&quot;).text = ThisEvent.Object.Text

     SetTransno" defaultvalue="Application.UserProperties(&quot;strTransno&quot;)" tooltip="Transect No." group="false" tabstop="true" border="true" readonly="false" sip="auto" uppercase="true"/>

The defaultvalue=  displays the current value of the "strTransno" variable, which stays the same thru many forms until I call my setup trans and allow the user to change it.

I hope this makes sense.   Let me know if you need clarification on the above.

0 Kudos
timdunlevie
Occasional Contributor

Hi Rebecca,

Thanks heaps for the in-depth response!

Much appreciated.

I am completely new to ArcPad so have been playing around with customising an .apl file in Arc Studio.

I found a licence of ArcPad so I thought I might have a look at it.

The guys I support in our office want to go out into the field with a toughpad and pick up structural measurements of rocks/bedding.

They normally do this with a pen & paper!

This is what I am thinking of doing:

“Page1” captures basic information about the project.

“Page2” in the form captures specific details of the rock – dip, dip direction etc..

Page1:

Page 2:

I notice there are “event scripts” which can be entered to customise how the controls behave??

I was hoping there was a way I could set up the form so that some of the information I collect for Point 1 is available when I collect Point 2 in ArcPad ??

So that I don’t have to re-enter the information again ?

So something like “lastStationID”, “lastProject”, “lastTenement”, “lastDate”, “lastLoggedBy” etc…

The user should only edit some info on Page1 and most of the data on Page2.

Hope that make more sense?

I will read up on the help and you points in your email to play around with the coding.

Thanks,

Tim

0 Kudos
RebeccaStrauch__GISP
MVP Emeritus

Hi Tim,

That is very similar to what I do, although I have buttons on a toolbar instead of multiple pages, since I can fit most of my input on one page, and I have multiple feature classes that are related (e.g. transect number and animalID are carried forward, if appropriate...animalID is incremented for new location, etc) and the shapefiles (in the case of this program..reember it was written for ArcPad 6.1) are created as needed in the session.  Most of my development was done before Application Builder was as robust as it is now, so I still edit most of the files direct, so I can't be much help on the AB side of things.  Also, at the time since some of the things I was doing wasn't 100% supported by AB, bringing it is may have corrupted my files.

After you read up on some of the info and read thru my samples a bit more, let me know if you have additional questions.

0 Kudos
MosquitoGIS
Occasional Contributor

There is the Repeat Attributes button on the bottom of forms during the collection process, not the creating a form part, (Icon with a green arrow that points to the right), that if you select and fill out a form, it will keep all that same information and then next time you capture data and it opens the form it has all the previously entered data.  That would do it for all pages though.  So they would have to remove and change/edit everything on that second page. To do it for only one page, I think you are going to have to do the scripting with Global Variables like Rebecca Strauch‌ said above.

There are "event scripts", but anything beyond quick quirps of code, you have to create a separate *.vbs file that compliments and is referred to in your form (*.apl). I, like Rebecca above started out with ArcPad 6 and so don't know much about AB, but will do my best to help you out.  I was once just starting and trying to learn on my own and so hopefully this helps give you a starting position, as it sounds like you are interested in branching out, but have no idea how to get started.  I am going to write this very basic in case that is the situation, if you are more advanced than just ignore the parts that you already know.

So, If you are looking at something as simple as: A person opens up ArcPad and collects their first data for the day and fills out the form and moves to the next.  Upon collecting the next bit of data, the first page is filled out with exactly what was last written, but the second page is blank.  Here is what you will need to do.

Create a .vbs file in the same directory as your .apl that has the same name as the .apl (i.e. If Tracker is hte name of your apl, you would do this: Tracker.apl & Tracker.vbs).  A very simple way to do this is to copy a previous .vbs file there and rename it or create a blank Notepad file and change the name as well as the extension (New Notepad Document.txt to Tracker.vbs).  Either way, once done, use Arcpad Studio to open the .vbs file.  Make sure everything is cleared out and that is blank and then copy and paste the following into it:

Option Explicit

'setting program Variables
Dim OnOff
'On means to now load what was last typed in last.
'Since the first time it loads there is no Variables it is set to off, as soon as the
'first form is filled out, it is then turned on

Sub LayerOpen()
OnOff = 0 'Upon first load of the whole Layer, set OnOff to Off
End Sub

Sub Pressing_Ok()
' get page 1 controls
Dim pControls
Set pControls = ThisEvent.Object.Pages(1).Controls

' store the form data into a Global Variable. 
'Replace the Names "txtStationID" with the ones that match your actual Names on your form.
Application.UserProperties("VarStationID") = pControls("txtStationID").Value
Application.UserProperties("VarProject") = pControls("cboProject").Value
Application.UserProperties("VarStationType") = pControls("txtStationType").Value
Application.UserProperties("VarTenement") = pControls("cboTenement").Value
'DATE:This style doesn't work with Date, so it is not included
Application.UserProperties("VarLogged_by") = pControls("cboLogged_by").Value
Application.UserProperties("VarRock_Code") = pControls("cboRock_Code").Value
Application.UserProperties("VarLith_desc") = pControls("txtLith_desc").Value

' clean up
    Set pControls = Nothing

OnOff = 1
End Sub

Sub FormInit()

  If OnOff = 1 then
   ' get page 1 controls
Dim pControls
Set pControls = ThisEvent.Object.Pages(1).Controls


'Set the form data to what is stored in the Global Variables
'Replace the Names "txtStationID" with the ones that match your actual Names on your form.
pControls("txtStationID").Value = Application.UserProperties("VarStationID")
pControls("cboProject").Value = Application.UserProperties("VarProject")
pControls("txtStationType").Value = Application.UserProperties("VarStationType")
pControls("cboTenement").Value = Application.UserProperties("VarTenement")
'This style doesn't work with Date, so it is not included
pControls("cboLogged_by").Value = Application.UserProperties("VarLogged_by")
pControls("cboRock_Code").Value = Application.UserProperties("VarRock_Code")
pControls("txtLith_desc").Value = Application.UserProperties("VarLith_desc")

  ' clean up
    Set pControls = Nothing
  End if

End Sub

Read through the code and Rem'd notes (Those just after an apostrophe) as there are some places you will need to make some changes to the code to make it work with your program.  I tried to document it fairly well so that you can make changes as needed and get an idea on how it works so that you can have an idea for the next time.

Now back in your .apl, you will have to make a few changes on those event scripts on certain parts of it.  Open the portion for the layer and set the onopen event to "Call LayerOpen()" without the quotes.  What this is doing is saying upon this event, call upon the sub-routine in the .vbs file.  If you look above in the code, you will see there is a "Sub LayerOpen()" and then sometime after that is an "End Sub".  Everything between that is a sub-routine.  So when that sub-routine is called, it runs everything within that routine.  OK, two more.  Now open the form and set onload to "Call FormInit()" without quotes and also set onok to "Call Pressing_ok()".

Ok, so now your apl know it needs to call those sub-routines, but needs to know what file to find those in.  Since I have no idea how to do this except besides code, you will have to do this last part via that way. On your toolbar in ArcPad studio with the apl open, there will be a button that has to arrows pointing away from each other one a top the other.  One is blue and one is red.  The tooltip on it says "Toggle between source and treeview".  Click that button and it will probably ask you to save and of course say yes.  You will now be looking at the code.  Without changing anything, go to the very bottom and right above where it says "</ArcPad>"  type  "<SCRIPT src="Tracker.vbs" language="vbscript"/>"  without the first and last quote.  Make sure to change the actual "Tracker.vbs" to whatever the name of your .vbs file is.  Esentially, it should look something like this at the end:

</LAYER>

<SCRIPT src="Tracker.vbs" language="vbscript"/>

</ArcPad>

Go ahead and hit that toggle between source and treeview button again.  Tell it yes you want to save and then  you should be in business.

As for the date field, since it can't be handed in this same manner, if it is just for today's date you are looking for anyway, set that text fields default value to "Now" without quotes.

Good luck and let me know how it works out.

timdunlevie
Occasional Contributor

Brilliant.

Thanks so much both Devin & Rebecca.

Playing around with the code seems to work well.

Once thing I did find, is if I ticked “limit to list” for my list of values for a combo box, then those values were not remembered after hitting “OK”.

But if I unticked the “limit to list” box, then the sub routines worked a treat!

Weird.

But all good….it’s now given me some more ideas!

Regards,

Tim

0 Kudos
MosquitoGIS
Occasional Contributor

Sorry about that, I was quickly writing that and didn't think about the combo boxes.  It only works with "Limit To List" off because .value essentially means typing that value. You have to have "Limit to List" off to type in a combo box, hence why it worked that way.

Use ".ListIndex" instead of ".value" on those.

Application.UserProperties("VarProject") = pControls("cboProject").ListIndex

pControls("cboProject").ListIndex = Application.UserProperties("VarProject")

Also, here is a link to another post that has some helpful links with developing in ArcPad.  ArcPad Studio

Glad to hear it is working for you and you are thinking of some more ideas for yourself.  Good luck! 

0 Kudos
MosquitoGIS
Occasional Contributor

Hey Tim, were you able to get this working to what you were looking for?  I see it is still marked as unanswered.

0 Kudos
timdunlevie
Occasional Contributor

Hi mate,

Yep – both your reply & help from Rebecca I was able to work it out.

Thanks,

Tim

0 Kudos
BenjaminGrover
New Contributor II

Hi!  Wondering if anyone could help me with this.  I'm wanting to do exactly what the script above has been written to do, but am having problems actually getting my text box in my form to populate with the global variable value.  I've added a message box into the code at both the creation of the variable and in the bit of code that is supposed to populate the text box with the variable value, and the message box is giving me the value, but my text box in the form will not populate!  I'm not getting any errors, its just not working.  I've pasted my script below.  Any input would be a tremendous help!

Option Explicit

'setting program Variables

Dim OnOff

'On means to now load what was last typed in last.

'Since the first time it loads there is no Variables it is set to off, as soon as the

'first form is filled out, it is then turned on

Sub LayerOpen()

  OnOff = 0 'Upon first load of the whole Layer, set OnOff to Off

End Sub

Sub Pressing_ok()

  ' get page 2 controls

  Dim pControls

  Set pControls = ThisEvent.Object.Pages("PAGE2").Controls

  ' store the form data into a Global Variable. 

  'Replace the Names "txtStationID" with the ones that match your actual Names on your form.

  Application.UserProperties("VarHouseNum") = pControls("Edit_Addr_Hou").Value

  ' clean up

    Set pControls = Nothing

  OnOff = 1

  msgbox(Application.UserProperties("VarHouseNum")) &vbNewLine& (pControls("Edit_Addr_Hou").Value)

End Sub

Sub FormInit()

  If OnOff = 1 then

   ' get page 2 controls

  Dim pControls

  Set pControls = ThisEvent.Object.Pages("PAGE2").Controls

  'Set the form data to what is stored in the Global Variables

  'Replace the Names "txtStationID" with the ones that match your actual Names on your form.

  pControls("Edit_Addr_Hou").Value = Application.UserProperties("VarHouseNum")

  ' clean up

  msgbox(Application.UserProperties("VarHouseNum")) &vbNewLine& (pControls("Edit_Addr_Hou").Value)

    Set pControls = Nothing

  End If

End Sub

I'm ultimately wanting to embed this script into an if statement based on the checking of a box in the form, so that if the box is checked stating that this point is at the same addressed as the previous record, the field worker doesnt have to re-enter the same address over, they can just check the box and it will auto populate.  Any help with that would be appreciated as well!

Thanks

0 Kudos