SkillCheck Development Records Database

53
SkillCheck Development Records Database Kate Butler Tufts University May 2004

Transcript of SkillCheck Development Records Database

Page 1: SkillCheck Development Records Database

SkillCheck Development Records Database

Kate Butler Tufts University May 2004

Page 2: SkillCheck Development Records Database
Page 3: SkillCheck Development Records Database

1. Introduction .......................................................................................................................4 2. The Problem Defined.........................................................................................................4 3. Requirements.....................................................................................................................6 4. Architecture and Design....................................................................................................6

4.1 Database Design ..........................................................................................................8 4.2 Database Risk Assessment ........................................................................................10 4.3 Application Design .....................................................................................................10 4.4 Application Risk Assessment..................................................................................... 11

5. Prototype Implementation ..............................................................................................12 6. User Evaluation...............................................................................................................13 7. Conclusions and Future Work.........................................................................................14 8. Acknowledgements ..........................................................................................................15 Sources .................................................................................................................................16 Appendix A: Sketches and Storyboards..............................................................................17 Appendix B: Visual Basic Code ...........................................................................................19

Page 4: SkillCheck Development Records Database

SkillCheck Development Record Database Kate Butler

SkillCheck, a small software company, has been maintaining records of weekly

developer output since mid-2000. These records are currently written in an

internal, informal and inconsistent shorthand. This project will create, using

software engineering and user interface design techniques, an alternative method

by which to record the data and provide an interface which will permit the

company to more easily understand the records that have been taken.

1. Introduction SkillCheck, a software company located in Burlington, MA, specializes in the creation of skill assessment products, focusing mainly on software applications. These tests are made by the test development team, a group that has varied in size over the past four years from 8-20 full time people. As a small company working to gain market share, SkillCheck early on recognized the importance of being able to accurately predict the availability date of upcoming products. To this end, the head of development wished to devise a method for making a reasonable estimate of how long a new product would take to create. And as the team continued to grow in size and the number of products to multiply, she similarly desired a way to keep regular track of individual contributions to the team's output. To solve the latter problem and make steps toward a solution to the former, the team began reporting their accomplishments to her on an (approximately) weekly basis. After some time, with enough data now in hand, it proved possible to begin predicting with some degree of accuracy how long a new project would take. 2. The Problem Defined The record keeping method currently employed by SkillCheck is a relatively simple one: once a week, a development team lead is responsible for collecting from the developers a list of what tasks they have done over the course of the past week. Developers are encouraged to be as detailed as possible so that all of the possible information is captured. Once their reports have been heard, the lead is then responsible for transcribing the data into a spreadsheet and passing it up the chain of command.

Page 5: SkillCheck Development Records Database

Figure 2.1: A fragment of the current development record. (1) Developer's name, (2) End date of period reported, (3) Something completed during the week.

As may be seen in figure 2.1, the data, though taken on a regular basis, is not taken according to a consistent scheme. Some activities may be implied to have taken place and not recorded. Sometimes numerical information for tasks is not supplied. Because the notes, though in an internal shorthand, use natural language as their basis, entries may be ambiguous and depend upon the context. For example, in the above fragment, the word 'fixes' has several different connotations. In cell B2, B3 and B4 the fixes mentioned are problems that were located by the developers on an answer sheet and marked as needing correction. These may have been errors covering a range of problems, from typos to missing information. In cells B6, C2, C5 and C6 the fixes are actually requests from a client for alterations to be made to a test. They may be bug reports, but they may also be requests to alter how a question is phrased. Though most of these variations are easily parsed by an experienced human, and may even be understood by an inexperienced one, they render it difficult to use the data in any sort of calculation. Extensive and tedious work is required to go through and pull out

Page 6: SkillCheck Development Records Database

values of interest to be examined. Because of this, the data is currently not used for much more than to provide an immediate snapshot of recent events. The current method of anticipating a project's time in development was created by looking at the data and making some educated guesses about how many hours a particular task would take, on average. However, it should be possible to use the information directly in making this calculation, as well as to more easily view historical output by the development team. To do this, I will define a scheme for the data that will allow it to be understood by a program. Then, I will create a tool to interact with the data and allow a user to see what has been produced, to see trends in developers' activities over time, and to use past performance as a basis for predicting the time needed to create future products. 3. Requirements With the goal of the tool and the desires of the users in mind, the following requirements were decided upon for the application to be developed: Records should be transformed into a format providing easier access to

quantitative information Records should retain the information they currently hold Application should provide ability to input data similar to current method but

which saves it in new format Application should be easy for target users to understand and begin to use (they

should be able to open it and start using it immediately, without training) Application should provide ability to estimate length of time a new test will take,

given # of questions and # of developers, based on historical data Application should provide ability to see output of group and individuals over

time 4. Architecture and Design After the requirements were settled and before starting the actual design, first it was necessary to sit down and work out a set of assumptions about the potential users of the system. This list (shown in Table 4.1) could then be used as a jumping off point to

Page 7: SkillCheck Development Records Database

determine what need and need not be included in terms of user interface and help.

User Assumptions Familiar with using a computer for work purposes Familiar with Microsoft Office English may not be their native language, but they can read and understand it to a high level Thoroughly familiar with SkillCheck terms and test development process Familiar with other SkillCheck internal applications and databases

Table 4.1: User Assumptions

The design process then began with the most basic of 3-layered shapes [Figure 4.1], which was then expanded to describe an architecture specific to this particular problem. [Figure 4.2]

Figure 4.1: The 3-layered architecture. Arrows represent interaction between layers.

Page 8: SkillCheck Development Records Database

Figure 4.2: Application Architecture. Arrows represent interaction between layers.

Within the application layer, the architecture calls for the user interface and the back end to be separated as much as possible. This should help make the application more consistent for users, as changes can be made to improve function without disrupting the familiar experience. The database is also a separate unit, to be hidden from direct contact with the user by the application. It can then be accessed as necessary by the application, and updated only in a regulated fashion. Once the architecture was decided upon, it was clear that the tool would necessarily consist of two entirely separate parts: the application (consisting of the user interface and the code to perform the tasks) and the database. 4.1 Database Design The current data has no required format. However, a format must be defined if it is to be entered consistently into a database. The first step, then, to defining a reasonable format, was to identify what entities were present in the data. I determined that there were 5 clear objects present: Test, Language, Developer, Period and Action. These five items are then combined, along with a total number of questions, into a task which the

Page 9: SkillCheck Development Records Database

developer has performed. This task, I decided, was the central event of the data, which made the identified entities ideal candidates to be arranged in a typical star schema as shown in Figure 4.3.

Figure 4.3: The database schema. DevEvents becomes the central fact table, while the others form dimension tables.

The central event permitted the development records to be transformed from paragraphs grouped by period and developer to unique records in a database. [Figure 4.4]

Figure 4.4: Transformed data

Page 10: SkillCheck Development Records Database

4.2 Database Risk Assessment Though necessary, the intended data transformation posed some risks to the project. First, because of the inconsistent formatting of the original records, fully automating the transformation process was impossible. This would require much of the cleaning to be done by hand, and with over three years of data extant, this would be a labor-intensive effort. This risk was managed by first, using as much automation as was actually possible before human intervention was required to complete the task. Using Excel macros to shift the data, from horizontal to vertical orientation saved a large amount of time. Once the returns on attempting to automate the effort grew less, assistants were recruited to help with the manual data entry that remained. The task was time intensive, but it was also a one time cost, as data entered need not be entered again, and with all of the backlog taken care of, newer data can be kept up to date on an ongoing, less time consuming basis. The second major risk factor also arose from the non-automated portion of the data transcription. Data entry error is a common phenomenon, and some estimates state that 1-5% of all data in databases may be faulty1. This risk was handled in two ways: first, after transcription and prior to loading into the database, an experienced user examined the data. Many errors were caught and corrected this way. However, since this is still not a 100% guarantee of accuracy, the original entry from which the data was taken was attached to the new record in the form of a note, in case a later sanity check might be needed. 4.3 Application Design Designing the user interface and the code to communicate between the user and the database began with a return to the basic design plan illustrated in Figure 4.2. With this serving as a base from which to build, the purpose of each part and the interactions between them were more clearly defined. 1 Twidale, M.B. & Marty, P.F. (1999). An Investigation of Data Quality and Collaboration. Technical Report ISRN UIUCLIS--1999/9+CSCW. http://www.lis.uiuc.edu/~twidale/pubs/dq.html

Page 11: SkillCheck Development Records Database

Figure 4.5: Design Plan showing transitions and communication.

In Figure 4.5, transitions between states are represented by lines (and can go both directions), while arrows represent information being passed in the indicated direction. The rectangular shape signals that this entity is designed to interact directly with the user. The user should have direct access to no other modules. 4.4 Application Risk Assessment Before continuing with the design process, another risk assessment was necessary, as the database was not the only source of possible pitfalls. The first risk requiring attention was complexity. Using the tool should be easy for the user and require no intervention on the part of anyone else, as stated in the requirements specification. To assist in fulfilling this requirement, the design was updated to include some basic help files, one for each of the user interface screens where there was more to do than click a button.

Page 12: SkillCheck Development Records Database

Figure 4.6: Updated design plan.

The second risk was a general one, and a risk for most projects where use is not likely to be enforced. That is, that the users may not adopt the use of the application. Change is difficult. This problem was borne in mind during the prototype implementation to follow, and efforts were made to echo other familiar interfaces to lessen the feeling of difference. In addition, efforts were made to keep the entry of data feeling as similar as possible to the old way. It will, however, not be identical, as there are now restrictions on what can be entered. 5. Prototype Implementation Once a basic design was determined, a prototype needed to be constructed for the users to examine. At this point it became necessary to determine a platform on which to build. I ultimately decided to create this tool as a Visual Basic application interacting with a Microsoft Access database. There were several reasons behind this decision:

1. All of the potential users have the ability to run this sort of tool on any

Page 13: SkillCheck Development Records Database

machine they may be using. 2. All of the potential users are quite familiar with using a similar tool: all peer

review comments are entered into an Access database via a form. 3. Previous projects that attempted to use new or different platforms as an entry

point have failed to be adopted by the development team on more than one occasion. The failed platforms include both the web and Crystal Reports. There is resistance to changing habits.

Work proceeded to the next stage of the design process after Access had been pinpointed as the target development platform. Prior to beginning the implementation of the user interface, sketches of possible UI layouts were created, to prevent time lost from endlessly playing with layouts in Access itself. After the preliminary sketches were complete, several candidate layouts were selected and used to create storyboards illustrating some simple usage scenarios. Representative sketches and storyboards can be found in Appendix A. Form creation in Access began once the storyboarding was finished. Further refinement of the user interface continued as the prototype was built. Efforts were made to stick as closely as possible to the modular design plan, separating out the functions which would interact with the database from the purely user interactive ones. The goal was to make future expansion and revision easier. 6. User Evaluation When the prototype was complete and the data entered into the database, the tool and its accompanying database were submitted to the users for an initial review. The comments were overall positive, though there were also some serious issues discovered:

The application was well-received: it looks nice The review page did not generate any complaints in this initial round of

review It was noted that the values returned by the estimate algorithm were not the

same as the ones returned by the formula SkillCheck currently uses. There were concerns about the data entry form

Page 14: SkillCheck Development Records Database

seems 'inflexible' - only choices in the combo boxes no way to see previous records for comparison (such as a report of

all last week's events) no way to browse or delete records

7. Conclusions and Future Work After the user comments were received, they needed to be evaluated to determine if they were valid concerns, and if so, if it was possible to improve the situation without compromising some portion of the specified requirements. Observations about the data entry form were deemed correct: it is inflexible, and it does not have the ability to do any of the mentioned functions (browse, delete, report). Unfortunately, at this time there does not appear to be a way to make the entry more flexible without creating a danger of data appearing that is no longer in the specified format. The next, concern, however, was graver; an important function of the previous spreadsheet was the ability to see at a glance what had been completed the week before. In fact, because of the new rules governing the data format, knowledge of previous weeks' work has become even more essential. This arises from the habit of developers to report their progress in terms of the number of questions total they have so far done; from this total the previous week's total must be subtracted to discover how much was actually accomplished in the particular period specified. Some method of providing this information to the user will need to be implemented. The ability to browse through entries further back than that, though a possible future improvement, does not need to be a high priority. Permitting users to delete records from a form may be possible, but will require some study to determine if it is desirable for them to be able to do this. The other major comment involved the difference in estimated values produced by the tool versus those produced by the formula currently in use. The results were not wildly different, but were far enough apart to be noticeable. This difference probably arises from the fact that the tool uses the actual numbers from the database to perform its calculation, while the current production formula uses numbers derived from looking at the data. Currently implemented in the program are two different possible algorithms for predicting the length of time it will take to produce a new product. The quality of the formulas used by these algorithms to calculate the estimate may not be of the best; a statistician or statistics text is required to determine that. Once a best method is found,

Page 15: SkillCheck Development Records Database

and the algorithm implemented in Visual Basic, it will be easily plugged into the tool to replace what is there. In this vein, the ability to painlessly add additional functionality to the tool has been designed in from the start. As much as possible, the user interface is decoupled from the subroutines performing the actual work to permit alteration of the back end without disruption on the front end. The nature of Access also makes it simple to add new forms to the database project; paths to those could be added to the entry point without interfering with any current function. One possible instance of this would be that as the tool matures, it might become necessary to add administrative functions in conjunction with security for the database. At present, security is very loose; users can 'unhide' the database and gain access to the data if they so desire. In terms of the original requirements however, I determine that the tool currently does not manage to satisfy all of them completely, though it does satisfy all at least in part. Due to the lack of reporting the previous week's data, I judge that the requirements of "Records should retain the information they currently hold" and "Application should provide ability to input data similar to current method but which saves it in new format" to be partially compromised. The addition of a mechanism by which to report the recent entries should correct this error and fulfill the original requirements. 8. Acknowledgements The author wishes to thank J. Andrews, R. Goemans, S. Bibeau for their timely assistance with various aspects of the project, including data transcription, Access help and comments.

Page 16: SkillCheck Development Records Database

Sources Hebert, Dan. Comp 150: Data Warehousing class notes (Spring 2003) Jacob, Robert. Comp 171: Human Computer Interaction class notes (Spring 2003) McConnell, Steve. Software Project Survival Guide. Microsoft Press. 1998. Novalis, Susann. Access 2000 VBA Handbook. Sybex. 1999. Twidale, M.B. & Marty, P.F. (1999). An Investigation of Data Quality and Collaboration.

Technical Report ISRN UIUCLIS--1999/9+CSCW. http://www.lis.uiuc.edu/~twidale/pubs/dq.html

Van Vliet, Hans. Software Architecture. Wiley. 2000.

Page 17: SkillCheck Development Records Database

Appendix A: Sketches and Storyboards Appendix A contains a representative sample of the sketches and storyboards that were made in the process of designing the tool's user interface. Sketches of possible layouts for the various user screens:

Storyboard of the usage scenario: Enter the record corresponding to the following task: Ling scripted 11 questions in test EN_W10 on 1/15/2004. This date is already in the database.

Storyboard of the following usage scenario: Estimate how long a test with 45 questions and 2 simultaneous developers will take.

Page 18: SkillCheck Development Records Database

Storyboard of the following usage scenario: Display a graph of the number of questions completed for each language. Do not separate by action type.

Page 19: SkillCheck Development Records Database

Appendix B: Visual Basic Code What follows is the visual basic code supporting the forms in the Access database created for this project. It can also be found by viewing the code from within Access. VERSION 1.0 CLASS

BEGIN

MultiUse = -1 'True

END

Attribute VB_Name = "Form_Welcome"

Attribute VB_GlobalNameSpace = False

Attribute VB_Creatable = True

Attribute VB_PredeclaredId = True

Attribute VB_Exposed = False

'Skillcheck Development Records Database

'Author: Kate Butler

'

'Welcome

'Controls for the welcome screen.

'

'-----------------------------------------------------------------------

Option Compare Database

Option Explicit

Private Sub btnAdd_Click()

'Open the Data Entry form

DoCmd.OpenForm "DataEntry"

Me.Form.Visible = False

End Sub

Private Sub btnExit_Click()

'Quit the application

Page 20: SkillCheck Development Records Database

DoCmd.Quit

End Sub

Private Sub btnReview_Click()

'Open the Review Data form

DoCmd.OpenForm "Review"

Me.Form.Visible = False

End Sub

Private Sub btnEstimate_Click()

'Open the perform estimate form

DoCmd.OpenForm "Estimate"

Me.Form.Visible = False

End Sub

VERSION 1.0 CLASS

BEGIN

MultiUse = -1 'True

END

Attribute VB_Name = "Form_DataEntry"

Attribute VB_GlobalNameSpace = False

Attribute VB_Creatable = True

Attribute VB_PredeclaredId = True

Attribute VB_Exposed = False

'Skillcheck Development Records Database

'Author: Kate Butler

'

'Data Entry

'This code controls the function of the form for data entry. That form

Page 21: SkillCheck Development Records Database

'receives the data the user is typing in. When submit is clicked, the

'data is checked for validity and then added to the database after

'confirmation.

'

'-----------------------------------------------------------------------

Option Compare Database

Option Explicit

Private Sub btnCancel_Click()

'Return to the welcome screen and close this form

DoCmd.Close acForm, Me.Name, acSaveNo

End Sub

Private Sub btnHelp_Click()

'If they click the help button, display the help page

DoCmd.OpenForm "DataEntryHelp"

End Sub

Private Sub btnReset_Click()

'Clear all values and return them to their original state

ClearForm

End Sub

Private Sub btnSubmit_Click()

'Submit the data entered.

Dim vCheck As Variant, intRes As VbMsgBoxResult

Dim intPeriod As Long

Page 22: SkillCheck Development Records Database

'Check the supplied date.

vCheck = DLookup("periodid", "Period", "end_date = #" & txtDate & "#")

'If it's not in the Period table already

If IsNull(vCheck) Then

'then check to see if the date given is after the last date in the

'table.

vCheck = DMin("end_date", "Period", "end_date > #" & txtDate & "#")

'if the date occurs before the last date, it's an error.

If Not IsNull(vCheck) Then

MsgBox "You have entered an invalid date. The nearest valid date is " &

CDate(vCheck) & ". Click OK to continue.", vbCritical, "Error"

Controls("txtDate").SetFocus

GoTo abortsub

Else

'if the date occurs after, it is a new date. Display a warning

intRes = MsgBox("The date you have entered is new. Click OK to confirm,

or Cancel to go back.", vbOKCancel + vbInformation, "Notice")

If intRes = vbCancel Then

'if they select cancel, go back and add nothing

Controls("txtDate").SetFocus

GoTo abortsub

Else

'if they select OK, add a new record and continue

DoCmd.SetWarnings False

DoCmd.RunSQL "INSERT INTO Period (start_date, end_date) values (#" &

DMax("end_date", "Period") & "#, #" & CDate(txtDate) & "#)"

Page 23: SkillCheck Development Records Database

DoCmd.SetWarnings True

vCheck = DLookup("periodid", "Period", "end_date = #" & CDate(txtDate)

& "#")

End If

End If

End If

txtPeriod = vCheck

DoCmd.OpenForm "Confirm", acNormal, , , , acDialog

abortsub:

End Sub

Private Sub Form_Close()

'Display the welcome form again when this form closes

Forms("Welcome").Visible = True

If CurrentProject.AllForms("DataEntryHelp").IsLoaded Then

DoCmd.Close acForm, "DataEntryHelp", acSaveNo

End If

End Sub

Private Sub Form_Load()

'When the form loads, disable the submit button if required fields

'aren't filled in

btnSubmit.Enabled = FormValid()

End Sub

Page 24: SkillCheck Development Records Database

Private Sub txtDate_AfterUpdate()

'Enable/Disable the submit button if all required fields are filled

btnSubmit.Enabled = FormValid()

End Sub

Private Sub cboDeveloper_AfterUpdate()

'Enable/Disable the submit button if all required fields are filled

btnSubmit.Enabled = FormValid()

End Sub

Private Sub cboLanguage_AfterUpdate()

'Enable/Disable the submit button if all required fields are filled

btnSubmit.Enabled = FormValid()

End Sub

Private Sub cboTest_AfterUpdate()

'Enable/Disable the submit button if all required fields are filled

btnSubmit.Enabled = FormValid()

End Sub

Private Sub cboAction_AfterUpdate()

'Enable/Disable the submit button if all required fields are filled

btnSubmit.Enabled = FormValid()

End Sub

Page 25: SkillCheck Development Records Database

Private Sub txtNumberOfQuestions_AfterUpdate()

'Enable/Disable the submit button if all required fields are filled

btnSubmit.Enabled = FormValid()

End Sub

Private Sub txtNotes_AfterUpdate()

'Enable/Disable the submit button if all required fields are filled

btnSubmit.Enabled = FormValid()

End Sub

Function FormValid() As Integer

'Check if the required fields are filled in. Return true/1 if they are.

FormValid = Not IsNull(txtDate) And Not IsNull(cboDeveloper) And Not

IsNull(cboAction)

End Function

Public Sub ClearForm()

'Return all fields on the form to their default values.

Dim ctl As Control

For Each ctl In Me.Form.Controls

If ctl.ControlType = acTextBox Or ctl.ControlType = acComboBox Then

ctl.Value = Null

End If

Next ctl

Controls("txtDate").SetFocus

Page 26: SkillCheck Development Records Database

btnSubmit.Enabled = False

End Sub

VERSION 1.0 CLASS

BEGIN

MultiUse = -1 'True

END

Attribute VB_Name = "Form_Confirm"

Attribute VB_GlobalNameSpace = False

Attribute VB_Creatable = True

Attribute VB_PredeclaredId = True

Attribute VB_Exposed = False

'Skillcheck Development Records Database

'Author: Kate Butler

'

'Confirm

'Here is where the user confirms their desire to submit the data

'into the database as a new record.

'

'-----------------------------------------------------------------------

Option Compare Database

Option Explicit

Private Sub btnBack_Click()

'Close this form and return to the DataEntry form

DoCmd.Close acForm, Me.Name, acSaveNo

End Sub

Private Sub btnConfirm_Click()

'Confirm desire to add record. Insert values into database using InsertRecord

Page 27: SkillCheck Development Records Database

Dim intResult As Integer

With Forms("DataEntry")

intResult = InsertRecord( _

.Controls("txtPeriod").Value, _

.Controls("cboDeveloper").Value, _

.Controls("cboLanguage").Value, _

.Controls("cboTest").Value, _

.Controls("cboAction").Value, _

.Controls("txtNumberOfQuestions").Value, _

.Controls("txtNotes").Value)

End With

If intResult <> 1 Then

'If the InsertRecord failed, give a warning

MsgBox "An error occurred, record not saved. - " & intResult, vbCritical

End If

'Once the insert has occurred, return to the DataEntry form and clear it.

Forms("DataEntry").ClearForm

DoCmd.Close acForm, Me.Name, acSaveNo

End Sub

Private Sub Form_Load()

'When the confirmation screen appears, do these things.

Dim strMsg As String

Dim vDate As Variant, vPeriod As Variant, vDeveloper As Variant, vLanguage As

Variant, _

Page 28: SkillCheck Development Records Database

vTest As Variant, vAction As Variant, vNumberOfQuestions As Variant, vNotes

As Variant

With Forms("DataEntry")

'Display what the record input values are.

vDate = .Controls("txtDate").Value

vPeriod = .Controls("txtPeriod").Value

vDeveloper = DLookup("name", "Developer", "developerid = "

& .Controls("cboDeveloper").Value)

vLanguage = .Controls("cboLanguage").Value

If Not IsNull(vLanguage) Then vLanguage = DLookup("name", "Language",

"languageid = " & vLanguage)

vTest = .Controls("cboTest").Value

If Not IsNull(vTest) Then vTest = DLookup("name", "Test", "testid = " & vTest)

vAction = DLookup("actiontype", "Action", "actionid = "

& .Controls("cboAction").Value)

vNumberOfQuestions = .Controls("txtNumberOfQuestions").Value

vNotes = .Controls("txtNotes").Value

End With

strMsg = "You are about to insert the following data:" & vbCrLf & vbCrLf & _

Format(vDate, "mm/dd/yyyy") & " " & _

vDeveloper

If Not IsNull(vLanguage) Then

If Not IsNull(vTest) Then

strMsg = strMsg & " " & vLanguage & "_" & vTest

Else

strMsg = strMsg & " " & vLanguage

End If

Else

If Not IsNull(vTest) Then

strMsg = strMsg & " " & vTest

End If

Page 29: SkillCheck Development Records Database

End If

strMsg = strMsg & " " & vAction

If Not IsNull(vNumberOfQuestions) Then

strMsg = strMsg & " " & vNumberOfQuestions

End If

If Not IsNull(vNotes) Then

strMsg = strMsg & vbCrLf & vbCrLf & vNotes

End If

txtMsg = strMsg

End Sub

VERSION 1.0 CLASS

BEGIN

MultiUse = -1 'True

END

Attribute VB_Name = "Form_Confirm"

Attribute VB_GlobalNameSpace = False

Attribute VB_Creatable = True

Attribute VB_PredeclaredId = True

Attribute VB_Exposed = False

'Skillcheck Development Records Database

'Author: Kate Butler

'

'Confirm

'Here is where the user confirms their desire to submit the data

'into the database as a new record.

'

'-----------------------------------------------------------------------

Option Compare Database

Page 30: SkillCheck Development Records Database

Option Explicit

Private Sub btnBack_Click()

'Close this form and return to the DataEntry form

DoCmd.Close acForm, Me.Name, acSaveNo

End Sub

Private Sub btnConfirm_Click()

'Confirm desire to add record. Insert values into database using InsertRecord

Dim intResult As Integer

With Forms("DataEntry")

intResult = InsertRecord( _

.Controls("txtPeriod").Value, _

.Controls("cboDeveloper").Value, _

.Controls("cboLanguage").Value, _

.Controls("cboTest").Value, _

.Controls("cboAction").Value, _

.Controls("txtNumberOfQuestions").Value, _

.Controls("txtNotes").Value)

End With

If intResult <> 1 Then

'If the InsertRecord failed, give a warning

MsgBox "An error occurred, record not saved. - " & intResult, vbCritical

End If

'Once the insert has occurred, return to the DataEntry form and clear it.

Forms("DataEntry").ClearForm

Page 31: SkillCheck Development Records Database

DoCmd.Close acForm, Me.Name, acSaveNo

End Sub

Private Sub Form_Load()

'When the confirmation screen appears, do these things.

Dim strMsg As String

Dim vDate As Variant, vPeriod As Variant, vDeveloper As Variant, vLanguage As

Variant, _

vTest As Variant, vAction As Variant, vNumberOfQuestions As Variant, vNotes

As Variant

With Forms("DataEntry")

'Display what the record input values are.

vDate = .Controls("txtDate").Value

vPeriod = .Controls("txtPeriod").Value

vDeveloper = DLookup("name", "Developer", "developerid = "

& .Controls("cboDeveloper").Value)

vLanguage = .Controls("cboLanguage").Value

If Not IsNull(vLanguage) Then vLanguage = DLookup("name", "Language",

"languageid = " & vLanguage)

vTest = .Controls("cboTest").Value

If Not IsNull(vTest) Then vTest = DLookup("name", "Test", "testid = " & vTest)

vAction = DLookup("actiontype", "Action", "actionid = "

& .Controls("cboAction").Value)

vNumberOfQuestions = .Controls("txtNumberOfQuestions").Value

vNotes = .Controls("txtNotes").Value

End With

strMsg = "You are about to insert the following data:" & vbCrLf & vbCrLf & _

Format(vDate, "mm/dd/yyyy") & " " & _

vDeveloper

Page 32: SkillCheck Development Records Database

If Not IsNull(vLanguage) Then

If Not IsNull(vTest) Then

strMsg = strMsg & " " & vLanguage & "_" & vTest

Else

strMsg = strMsg & " " & vLanguage

End If

Else

If Not IsNull(vTest) Then

strMsg = strMsg & " " & vTest

End If

End If

strMsg = strMsg & " " & vAction

If Not IsNull(vNumberOfQuestions) Then

strMsg = strMsg & " " & vNumberOfQuestions

End If

If Not IsNull(vNotes) Then

strMsg = strMsg & vbCrLf & vbCrLf & vNotes

End If

txtMsg = strMsg

End Sub

VERSION 1.0 CLASS

BEGIN

MultiUse = -1 'True

END

Attribute VB_Name = "Form_Estimate"

Attribute VB_GlobalNameSpace = False

Attribute VB_Creatable = True

Attribute VB_PredeclaredId = True

Page 33: SkillCheck Development Records Database

Attribute VB_Exposed = False

'Skillcheck Development Records Database

'Author: Kate Butler

'

'Estimate

'This code controls the function of the form 'Estimate', which takes

'in a number of developers and number of questions from the user and

'returns an estimated time to completion for a test being created with

'those parameters.

'

'-----------------------------------------------------------------------

Option Compare Database

Option Explicit

Private Sub btnCalculate_Click()

'Calculate the estimate based on the values given

RefreshForm

End Sub

Private Sub btnCancel_Click()

'Close this form and return to the welcome screen

DoCmd.Close acForm, Me.Name, acSaveNo

End Sub

Private Sub btnHelp_Click()

'Open the help window when the help button is clicked

DoCmd.OpenForm "EstimateHelp"

End Sub

Page 34: SkillCheck Development Records Database

Private Sub btnReset_Click()

'Clear the fields and reset to null values

ClearForm

End Sub

Private Sub Form_Close()

'Display the welcome form again when this form closes

Forms("Welcome").Visible = True

If CurrentProject.AllForms("EstimateHelp").IsLoaded Then

DoCmd.Close acForm, "EstimateHelp", acSaveNo

End If

End Sub

Private Sub Form_Load()

'As the form loads, clear the fields and reset to null values

ClearForm

End Sub

Private Sub RefreshForm()

'Perform the calculation and update the Estimate label with our result.

Dim dblEstimate As Double, vQ As Variant, vD As Variant

vQ = txtQuestions

vD = txtDevelopers

'First, make sure the data the user entered is valid.

If IsNumeric(vQ) And IsNumeric(vD) Then

'At present, there are two choices for estimating algorithms to use:

Page 35: SkillCheck Development Records Database

'Simple and Divided. It may be desirable in the future to have

'just one available to the user to prevent confusion over differing

'numbers. The user does not see how the calculation is being

'performed, but it may be advantageous to describe how numbers

'are arrived at in the help screen.

'If Simple is selected, do a simple estimate.

If EstMethodGroup.Value = 1 Then

'SimpleEstimate is located in the Common Module

lblEstimate.Caption = Format(SimpleEstimate(CDbl(vD), CDbl(vQ)), "0.00""

weeks""")

Else

'Otherwise do a Divided estimate. DividedEstimate is located

'in the Common Module

lblEstimate.Caption = Format(DividedEstimate(CDbl(vD), CDbl(vQ)),

"0.00"" weeks""")

End If

Else

'If the required fields aren't filled, blank out the estimate field.

lblEstimate.Caption = "-----"

End If

End Sub

Public Sub ClearForm()

'Reset all values to their defaults.

txtQuestions.Value = Null

txtDevelopers.Value = Null

lblEstimate.Caption = "-----"

Controls("txtQuestions").SetFocus

End Sub

Page 36: SkillCheck Development Records Database

VERSION 1.0 CLASS

BEGIN

MultiUse = -1 'True

END

Attribute VB_Name = "Form_Review"

Attribute VB_GlobalNameSpace = False

Attribute VB_Creatable = True

Attribute VB_PredeclaredId = True

Attribute VB_Exposed = False

'Skillcheck Development Records Database

'Author: Kate Butler

'

'Review

'This code controls the function of the review form. It changes the

'view of the Review area where the resultant data is displayed, and also

'calls the functions which construct the queries from the selected items

'

'-----------------------------------------------------------------------

Option Compare Database

Option Explicit

Private Sub btnDisplay_Click()

'Grabs the selected values and updates the appropriate graph and the table to hold the

'current results of the query.

Dim strSQL As String

'Call MakePreviewSQL to create the query string appropriate for the selected items

strSQL = MakePreviewSQL(cboGroup1, cboGroup2, cboFilterGroup1, cboFilter1,

cboFilterGroup2, cboFilter2, frmGroup)

'Update the table subform to hold the contents of the query

subPreview.Form.RecordSource = strSQL

subPreview.Form.Requery

Page 37: SkillCheck Development Records Database

'If there are two groups, update the 3D chart with the results

'If there's just one group, update the 2D chart with the results

'If you previously had a different number of groups and the chart was visible,

'switch to the other chart.

Select Case frmGroup

Case 1

If graphTwoGroups.Visible = True Then

graphOneGroup.Visible = True

graphTwoGroups.Visible = False

End If

graphOneGroup.RowSource = strSQL

graphOneGroup.Requery

Case 2

If graphOneGroup.Visible = True Then

graphOneGroup.Visible = False

graphTwoGroups.Visible = True

End If

'If we now have two groups, for the chart we need a different SQL query string.

strSQL = MakePreviewCrosstabSQL(cboGroup1, cboGroup2, cboFilterGroup1,

cboFilter1, cboFilterGroup2, cboFilter2, frmGroup)

graphTwoGroups.RowSource = strSQL

graphTwoGroups.Requery

End Select

End Sub

Private Sub btnExit_Click()

'Close this form and return to the welcome screen

DoCmd.Close acForm, Me.Name, acSaveNo

End Sub

Private Sub RefreshForm()

Page 38: SkillCheck Development Records Database

'Update the form and all of the cboxes with the correct values depending on what is

'presently selected

cboGroup2.Visible = (frmGroup.Value = 2)

'For the first row of filters

Select Case cboFilterGroup1

'If action is selected, fill the second box with the possible action types

'from the database

Case "Action"

cboFilter1.Visible = True

cboFilter1.RowSource = "SELECT actiontype FROM Action GROUP BY actiontype

ORDER BY actiontype"

cboFilter1.Requery

'If developer is selected, fill the cbox with the developers' names

Case "Developer"

cboFilter1.Visible = True

cboFilter1.RowSource = "SELECT name FROM Developer GROUP BY name ORDER BY

name"

cboFilter1.Requery

'If language is selected, fill the cbox with the language abbreviations

Case "Language"

cboFilter1.Visible = True

cboFilter1.RowSource = "SELECT name FROM Language GROUP BY name ORDER BY

name"

cboFilter1.Requery

'If date is selected, fill the cbox with all of the available period end dates

Case "Date"

cboFilter1.Visible = True

cboFilter1.RowSource = "SELECT end_date FROM Period GROUP BY end_date

ORDER BY end_date DESC"

cboFilter1.Requery

'if test is selected, fill the cbox with the possible tests

Case "Test"

cboFilter1.Visible = True

cboFilter1.RowSource = "SELECT name FROM Test GROUP BY name ORDER BY name"

Page 39: SkillCheck Development Records Database

cboFilter1.Requery

'If it's a language and a test (ex: JP_W10) fill the box with the possible

'combinations

Case "Language/Test"

cboFilter1.Visible = True

cboFilter1.RowSource = "SELECT L.name & ""_"" & T.name FROM Language AS

L, Test AS T GROUP BY L.name & ""_"" & T.name ORDER BY L.name & ""_"" & T.name"

cboFilter1.Requery

Case Else

'If none of these are selected in the first filter box, the accompanying box

'should not be visible

cboFilter1.Visible = False

End Select

'If the first filter is active, show an option for the second filter

If cboFilterGroup1 <> "None" Then

cboFilterGroup2.Visible = True

'Same as above, fill the cbox according to what is selected to be filtered by

Select Case cboFilterGroup2

Case "Action"

cboFilter2.Visible = True

cboFilter2.RowSource = "SELECT actiontype FROM Action GROUP BY

actiontype ORDER BY actiontype"

cboFilter2.Requery

Case "Developer"

cboFilter2.Visible = True

cboFilter2.RowSource = "SELECT name FROM Developer GROUP BY name ORDER

BY name"

cboFilter2.Requery

Case "Language"

cboFilter2.Visible = True

cboFilter2.RowSource = "SELECT name FROM Language GROUP BY name ORDER

BY name"

cboFilter2.Requery

Case "Date"

cboFilter2.Visible = True

cboFilter2.RowSource = "SELECT end_date FROM Period GROUP BY end_date

Page 40: SkillCheck Development Records Database

ORDER BY end_date DESC"

cboFilter2.Requery

Case "Test"

cboFilter2.Visible = True

cboFilter2.RowSource = "SELECT name FROM Test GROUP BY name ORDER BY

name"

cboFilter2.Requery

Case "Language/Test"

cboFilter2.Visible = True

cboFilter2.RowSource = "SELECT L.name & ""_"" & T.name FROM Language

AS L, Test AS T GROUP BY L.name & ""_"" & T.name ORDER BY L.name & ""_"" & T.name"

cboFilter2.Requery

Case Else

cboFilter2.Visible = False

End Select

Else

'if the first filter isn't being used, don't show the second.

cboFilterGroup2.Visible = False

cboFilter2.Visible = False

End If

End Sub

Private Sub btnHelp_Click()

'If they click the help button, display the help page

DoCmd.OpenForm "ReviewHelp"

End Sub

Private Sub btnReset_Click()

'This subroutine resets all cboxes, charts and tables to their default values.

Dim strSQL As String

cboGroup1 = "Action"

Page 41: SkillCheck Development Records Database

cboGroup2 = "Action"

cboFilterGroup1 = "None"

cboFilterGroup2 = "None"

frmGroup.Value = 1

cboGroup1.SetFocus

RefreshForm

strSQL = MakePreviewSQL(cboGroup1, cboGroup2, cboFilterGroup1, cboFilter1,

cboFilterGroup2, cboFilter2, frmGroup)

subPreview.Form.RecordSource = strSQL

subPreview.Form.Requery

subPreview.Visible = True

graphOneGroup.Visible = False

graphTwoGroups.Visible = False

End Sub

Private Sub btnToggle_Click()

'Switch between chart view and table view of the results.

Dim strSQL As String

'If a chart is visible, switch to the table. Make the charts invisible and change

'the button text.

If graphOneGroup.Visible Or graphTwoGroups.Visible Then

graphOneGroup.Visible = False

graphTwoGroups.Visible = False

subPreview.Visible = True

btnToggle.Caption = "Show Graph"

Else

'Otherwise, hide the table and display the correct chart.

Select Case frmGroup

Case 1

graphOneGroup.Visible = True

graphTwoGroups.Visible = False

Case 2

graphOneGroup.Visible = False

Page 42: SkillCheck Development Records Database

graphTwoGroups.Visible = True

End Select

subPreview.Visible = False

btnToggle.Caption = "Show Table"

End If

End Sub

Private Sub cboGroup1_AfterUpdate()

'After changing the value of the cbox, refresh the form.

RefreshForm

End Sub

Private Sub cboGroup2_AfterUpdate()

'After changing the value of the cbox, refresh the form.

RefreshForm

End Sub

Private Sub cboFilterGroup1_AfterUpdate()

'After changing the value of the cbox, refresh the form.

RefreshForm

End Sub

Private Sub cboFilterGroup2_AfterUpdate()

'After changing the value of the cbox, refresh the form.

RefreshForm

End Sub

Page 43: SkillCheck Development Records Database

Private Sub Form_Close()

'When the form is closed, make the welcome form visible again.

Forms("Welcome").Visible = True

If CurrentProject.AllForms("ReviewHelp").IsLoaded Then

DoCmd.Close acForm, "ReviewHelp", acSaveNo

End If

End Sub

Private Sub Form_Load()

'When the form first loads, refresh the form and also update the table.

'This will fill in the table with the default SQL query, which is also

'displayed by the chart (because of the nature of charts)

RefreshForm

btnDisplay_Click

End Sub

Private Sub frmGroup_AfterUpdate()

'After changing the value of the radio button, refresh the form

RefreshForm

End Sub

Attribute VB_Name = "Common"

'Skillcheck Development Records Database

'Author: Kate Butler

'

'Common

'This module holds functions and subroutines which interact directly with the

'database.

'

Page 44: SkillCheck Development Records Database

'-----------------------------------------------------------------------

Option Compare Database

Option Explicit

Function InsertRecord( _

intPeriod As Variant, _

intDeveloper As Variant, _

intLanguage As Variant, _

intTest As Variant, _

intAction As Variant, _

intNumberOfQuestions As Variant, _

strNotes As Variant) As Integer

'Insert a record into the DevEvent Database

Dim rst As New ADODB.Recordset

With rst

rst.Open "DevEvents", CurrentProject.Connection, adOpenDynamic,

adLockOptimistic

rst.AddNew

.Fields("developerid") = intDeveloper

.Fields("languageid") = intLanguage

.Fields("testid") = intTest

.Fields("periodid") = intPeriod

.Fields("actionid") = intAction

.Fields("number_of_questions") = intNumberOfQuestions

.Fields("notes") = strNotes

.Update

End With

Page 45: SkillCheck Development Records Database

InsertRecord = 1

End Function

Function DevEstimate() As Double

'Return the simple estimated value of # of questions a developer can do per

'period. This value rolls AS, AS PR, scr, PR and PR fix all together

'Calculated by:

' * Summing the number of questions done by a developer during a period

' * Summing the number of questions done by all developers during the

' period and summing the total number of developers involved

' * Using those numbers to calculate the average # of questions for that

' period

' * Add all averages together and divide by the total number of periods

DevEstimate = DLookup("Result", "Q_DevEstimate")

End Function

Function DevEstimateAS() As Double

'Return the estimated value of # of AS questions a developer can do per

'period.

'Calculated by:

' * Summing the number of AS questions done by a developer during a period

' * Summing the number of AS questions done by all developers during the

' period and summing the total number of developers involved

' * Using those numbers to calculate the average # of AS questions for that

' period

' * Add all averages together and divide by the total number of periods

DevEstimateAS = DLookup("Result", "Q_DevEstimateAS")

End Function

Function DevEstimateASPR() As Double

'Return the estimated value of # of AS PR questions a developer can do per

'period.

Page 46: SkillCheck Development Records Database

'Calculated by:

' * Summing the number of AS PR questions done by a developer during a period

' * Summing the number of AS PR questions done by all developers during the

' period and summing the total number of developers involved

' * Using those numbers to calculate the average # of AS PR questions for that

' period

' * Add all averages together and divide by the total number of periods

DevEstimateASPR = DLookup("Result", "Q_DevEstimateASPR")

End Function

Function DevEstimateSCR() As Double

'Return the estimated value of # of SCR questions a developer can do per

'period.

'Calculated by:

' * Summing the number of SCR questions done by a developer during a period

' * Summing the number of SCR questions done by all developers during the

' period and summing the total number of developers involved

' * Using those numbers to calculate the average # of SCR questions for that

' period

' * Add all averages together and divide by the total number of periods

DevEstimateSCR = DLookup("Result", "Q_DevEstimateSCR")

End Function

Function DevEstimatePR() As Double

'Return the estimated value of # of PR questions a developer can do per

'period.

'Calculated by:

' * Summing the number of PR questions done by a developer during a period

' * Summing the number of PR questions done by all developers during the

' period and summing the total number of developers involved

' * Using those numbers to calculate the average # of PR questions for that

' period

' * Add all averages together and divide by the total number of periods

Page 47: SkillCheck Development Records Database

DevEstimatePR = DLookup("Result", "Q_DevEstimatePR")

End Function

Function DevEstimatePRFIX() As Double

'Return the estimated value of # of PR Fix questions a developer can do per

'period.

'Calculated by:

' * Summing the number of PR Fix questions done by a developer during a period

' * Summing the number of PR Fix questions done by all developers during the

' period and summing the total number of developers involved

' * Using those numbers to calculate the average # of PR Fix questions for that

' period

' * Add all averages together and divide by the total number of periods

DevEstimatePRFIX = DLookup("Result", "Q_DevEstimatePRFIX")

End Function

Function SimpleEstimate(vDevs As Double, vQs As Double) As Double

'Use the value from DevEstimate to calculate how long it will take for vDevs

'# of devs to complete a test of vQs # of questions.

'This estimate does not differentiate between different types of test creation

'activities. Instead, it uses all activities to calculate the average # of questions

'a developer can complete in a week. Since each test requires a single question

'to pass through 5 stages, the test is 'really' 5 * vQs in length.

SimpleEstimate = (vQs * 5) / (vDevs * DevEstimate)

End Function

Function DividedEstimate(vDevs As Double, vQs As Double) As Double

'Use the values calculated to figure out how long it will take vDevs # of devs

'to complete a test of vQs # of questions.

'This equation divides the test into five parts and estimates different lengths

'of time for each part, then adds them together.

Page 48: SkillCheck Development Records Database

DividedEstimate = vQs / (vDevs * DevEstimateAS) + vQs / (vDevs * DevEstimateASPR)

+ vQs / (vDevs * DevEstimateSCR) + vQs / (vDevs * DevEstimatePR) + vQs / (vDevs *

DevEstimatePRFIX)

End Function

Function MakePreviewSQL(vGroup1, vGroup2, vFilterGroup1, vFilter1, vFilterGroup2,

vFilter2, vGroup) As String

'Make a SQL statement for either a 2D graph or the table

Dim strSelect As String, strGroupBy As String, strWhere As String

'Construct the statement from parts determined by what was selected

Select Case vGroup1

Case "Language/Test"

strSelect = "A.LanguageTest AS Group1"

strGroupBy = "A.LanguageTest"

Case Else

strSelect = "A." & vGroup1 & " AS Group1"

strGroupBy = "A." & vGroup1

End Select

If vGroup = 2 Then

Select Case vGroup2

Case "Language/Test"

strSelect = strSelect & ", A.LanguageTest AS Group2"

strGroupBy = strGroupBy & ", A.LanguageTest"

Case Else

strSelect = strSelect & ", A." & vGroup2 & " AS Group2"

strGroupBy = strGroupBy & ", A." & vGroup2

End Select

Else

'If there was no group 2, use a dummy

strSelect = strSelect & ", ""-----"" AS Group2"

Page 49: SkillCheck Development Records Database

End If

'If there were no filters selected, don't enter anything for the where clause

If vFilterGroup1 = "None" Then

strWhere = ""

Else

Select Case vFilterGroup1

Case "Language/Test"

strWhere = "A.LanguageTest = """ & vFilter1 & """"

Case Else

strWhere = "A." & vFilterGroup1 & " = """ & vFilter1 & """"

End Select

If vFilterGroup2 <> "None" Then

Select Case vFilterGroup2

Case "Language/Test"

strWhere = strWhere & " AND A.LanguageTest = """ & vFilter2 & """"

Case Else

strWhere = strWhere & " AND A." & vFilterGroup2 & " = """ & vFilter2

& """"

End Select

End If

End If

'Once the parts have been chosen, query from the pre-constructed

'query Q_ReviewEvents, which joins all information together as one table

MakePreviewSQL = "SELECT " & strSelect & ", Sum(A.Questions) AS Value1 " & _

"FROM Q_ReviewEvents AS A " & _

IIf(strWhere <> "", "WHERE " & strWhere & " ", "") & _

Page 50: SkillCheck Development Records Database

"GROUP BY " & strGroupBy & " " & _

"ORDER BY " & strGroupBy

End Function

Function MakePreviewCrosstabSQL(vGroup1, vGroup2, vFilterGroup1, vFilter1,

vFilterGroup2, vFilter2, vGroup) As String

'In the event of needing to fill the 3D graph, must use a crosstab query instead

'Crosstab Syntax Reminder

'TRANSFORM Sum(Q_ReviewEvents.Questions) AS SumOfQuestions

'SELECT Q_ReviewEvents.Developer FROM Q_ReviewEvents

'GROUP BY Q_ReviewEvents.Developer PIVOT Q_ReviewEvents.Language;

Dim strSelect As String, strGroupBy As String, strPivot As String, strWhere As

String

'Select which strings the statement should be made up of based on what

'selections were made on the form.

Select Case vGroup1

Case "Language/Test"

strSelect = "A.LanguageTest AS Group1"

strGroupBy = "A.LanguageTest"

Case Else

strSelect = "A." & vGroup1 & " AS Group1"

strGroupBy = "A." & vGroup1

End Select

Select Case vGroup2

Case "Language/Test"

strPivot = "A.LanguageTest"

Case Else

strPivot = "A." & vGroup2

End Select

If vFilterGroup1 = "None" Then

Page 51: SkillCheck Development Records Database

strWhere = ""

Else

Select Case vFilterGroup1

Case "Language/Test"

strWhere = "A.LanguageTest = """ & vFilter1 & """"

Case Else

strWhere = "A." & vFilterGroup1 & " = """ & vFilter1 & """"

End Select

If vFilterGroup2 <> "None" Then

Select Case vFilterGroup2

Case "Language/Test"

strWhere = strWhere & " AND A.LanguageTest = """ & vFilter2 & """"

Case Else

strWhere = strWhere & " AND A." & vFilterGroup2 & " = """ & vFilter2

& """"

End Select

End If

End If

'Put the sql string together now that all of the parts have been selected

MakePreviewCrosstabSQL = "TRANSFORM Sum(A.Questions) AS Value1 " & _

"SELECT " & strSelect & " " & _

"FROM Q_ReviewEvents AS A " & _

IIf(strWhere <> "", "WHERE " & strWhere & " ", "") & _

"GROUP BY " & strGroupBy & " " & _

"PIVOT " & strPivot

End Function

Page 52: SkillCheck Development Records Database

Attribute VB_Name = "Utility"

'Skillcheck Development Records Database

'Author: Kate Butler

'

'Utility

'This module contains some random functions which aren't currently

'used by the project, but are used in macros that helped set up the project

'

'-----------------------------------------------------------------------

Option Compare Database

Option Explicit

Function SetStartDates() As Integer

'Calculate the correct value to put into the start_date field

'The end_date is the value given

Dim rstWrite As New ADODB.Recordset

Dim rstRead As New ADODB.Recordset

On Error GoTo forgetaboutit

rstRead.Open "Period", CurrentProject.Connection

rstWrite.Open "Period", CurrentProject.Connection, adOpenDynamic,

adLockOptimistic

rstRead.MoveFirst

rstWrite.MoveFirst

rstWrite.Fields("start_date") = #1/1/1970#

rstWrite.Update

rstWrite.MoveNext

Page 53: SkillCheck Development Records Database

Do While Not rstWrite.EOF

rstWrite.Fields("start_date") = rstRead.Fields("end_date")

rstWrite.Update

rstWrite.MoveNext

rstRead.MoveNext

Loop

forgetaboutit:

rstRead.Close

rstWrite.Close

SetStartDates = 1

End Function