Heckaman Jeremy Final Project Report

download Heckaman Jeremy Final Project Report

of 12

Transcript of Heckaman Jeremy Final Project Report

  • 8/8/2019 Heckaman Jeremy Final Project Report

    1/12

    MBA 614 Final Project Report Jeremy Heckaman

  • 8/8/2019 Heckaman Jeremy Final Project Report

    2/12

    Page | 2

    Executive Summary

    Viking Pest and Plant, LLC is a pest control company that offers additional services, such as plant andtree disease diagnosis and treatment, tree pruning and trimming and landscape consulting. Thecompany is owned and operated by my brother, primarily in the St. George, Utah metropolitan area. Heprincipally operates the business out of an office in his home, where he keeps files and customerinformation, along with any other company documents and information. Customers will sign a contractwhich stipulates the services requested and the frequency of such services. Based on this information,services are scheduled and payment is collected at that time. Given the limited office space, andproximity to small children, my brother experiences some difficulty keeping his records organized andsecured from potential destruction. In addition, scheduling out services cost effectively can be a timeconsuming and error prone process. Currently he needs to sort through a stack of paper contracts andwrite down a paper schedule for all customers. This process needs to be repeated periodicallyconsuming unnecessary labor hours. The manual process is expected to become unmanageable as hiscustomer base grows beyond about 250 records. Automation of these tasks will reduce labor needs andenhance his ability to track his customer activity and service requirements.

    For my project, I designed a data base in Excel, using primarily VBA forms, which will allow my brother toinput customer data, link multiple contracts to a customer record and link multiple service call historiesto those contracts. All of this information is input through user friendly forms, and can be recalled andedited. In addition, the data base has a scheduling function that allows my brother to see upcomingservices for the next week or month. This allows for safe and secure storage of all files in a safe, centrallocation with easier and more accurate record changes to that information. In addition, it reducesscheduling time and difficulties because my brother only needs to plan a few weeks in advance, insteadof planning out many months in advance or periodically reviewing all contracts. This program will alsoallow my brother to accurately record and report regulatory data, e.g., pesticide usage, required byState and Federal agencies, e.g., The EPA. Lastly, it provides a platform for additional functionality that Iplan to program in the future, further increasing its value to my brothers company.

    Implementation

    Phase I Design

    To begin my project, I first had to review my brothers business model and determine what data wouldbe recorded. I also had to determine what functions the program would need to support, not only forthe scope of this project, but for the future as well. Since this project will potentially store all of my

  • 8/8/2019 Heckaman Jeremy Final Project Report

    3/12

    Page | 3

    brothers files in the future, it needs to be robust enough to allow for more features. I had to work withhim to define several features and then prioritize them so that the initial program would be useful andallow addition of new features and reporting over time.

    After determining that the customer information, contract information, and service call informationwere most important, I designed the database, along with all the primary and foreign keys. The database structure is simple, with multiple service calls attached to one contract, and multiple contractsattached to one customer. I linked the tables through a simple key system. Each customer has a uniquenumber. Each contract has a unique number and the associated customer number. Lastly, each servicerecord has a number and the associated contract number. The data base relationships are outlinedbelow in figure 1.

    Next step was designing the forms that would be necessary for data entry and editing, as well asqueries. Programming earlier assignments with one or two forms was simple. Having multiple formsproved difficult, and I quickly found myself bogged down in determining the best way to move throughthe forms and sub-forms. I found programming user friendly alerts and controls to be difficult as well,since you can never quite know the proper balance of information. On one hand, you tell the user toolittle and they do something devastating, on the other, you bombard them with information aboutunlikely scenarios, and they stop reading alerts altogether.

    Upon opening the file, the main menu (figure 2 below) automatically appears, and the first spreadsheetopens as a background. The user can choose to add a new customer (figure 3), or edit a customer record(figure 4). Upon adding a new customer, the user is prompted if they would like to add a contract to thecustomer, which takes them to an add contract form (figure 5). This is different from the add contractform accessible through the main menu (figure 6) because the users information is automaticallyloaded into the top label. In the other form, the user must select the customer record to attach acontract to. There is also a form for editing contracts (figure 7) which requires the user to select acustomer record first, and then select the desired contract associated with that customer. The last form

    Figure 1Relational Data Base

    table diagram

  • 8/8/2019 Heckaman Jeremy Final Project Report

    4/12

    Page | 4

    is the schedule form (figure 8) that allows the user to view the upcoming service dates for the nextweek, or four weeks.

    Figure 2Main Menu

    Figure 3Add New Customer

  • 8/8/2019 Heckaman Jeremy Final Project Report

    5/12

    Page | 5

    Figure 4Edit Customer (Existing Customer)

    Figure 5Add Contract (New Customer)

    *New customers data

    automatically loads here*

  • 8/8/2019 Heckaman Jeremy Final Project Report

    6/12

    Page | 6

    Figure 6Add Contract (Existing Customer)

    Figure 7Edit Contract (Existing Contract)

  • 8/8/2019 Heckaman Jeremy Final Project Report

    7/12

    Page | 7

    Figure 8Appointment Schedule

    The data entered or edited is then written to the tables. The customer table (figure 9) and contract table(figure 10) are shown below.

    Figure 9

    Customer Table

    Figure 10Contract Table

    Phase II Programming

    Next, I started programming the forms. I found writing data from the forms to the data base is fairlyeasy to understand and perform. I struggled, however, with linking the data in one table to another viathe table keys. I show the following example as demonstration of my solution. This code is used in theedit contract form (figure 7 above). The user first selects an existing customer record in the top combo

  • 8/8/2019 Heckaman Jeremy Final Project Report

    8/12

    Page | 8

    box. Then this code runs, filling an array with information regarding the existing contracts associatedwith the selected customer. The array is subsequently loaded into the second combo box.

    Private Sub cmbSelectCust_Change()

    If cmbSelectCust.Value = "" ThenClearFormExit Sub

    End If

    'this selects the customer number from the selection on the combo boxAddCustomerNumber = cmbSelectCust.ListIndex + 1

    If AddCustomerNumber < 1 ThenExit Sub

    End If

    'this loads the contract array based on the customer selectedDim R As IntegerDim X As IntegerDim NN As IntegerDim conInfo()

    'prevents an error in the event that there are no contracts savedIf Sheets("ContractTable").Range("a2").Value = "" Then

    cmbSelectCon = "There are no contracts for any customers listed"Exit Sub

    End If

    (1) 'fills the customers() array with the customer numbers in the ContractTable and the associated row number

    R = Range(Sheets("ContractTable").Range("a2"), Sheets("ContractTable").Range("a2").End(xlDown)).Count

    ReDim Customers(1 To R, 1 To 2)For X = 1 To R

    Customers(X, 1) = Sheets("ContractTable").Range("a" & X + 1).ValueCustomers(X, 2) = X + 1

    Next

    NN = 1N = 0

    (2)'counts the number of customer matches

    For X = 1 To RIf Customers(X, 1) = AddCustomerNumber Then

    N = N + 1End If

    Next

    (3)If N < 1 Then'if there are no contracts under the customer's record

    cmbSelectCon = "No contracts are saved for this customer"cmbSelectCon.Clear

    ElsecmbSelectCon = "Select a contract"

    'loads the contract's row location into the contracts() arrayReDim contraCts(1 To N)For X = 1 To R

    If Customers(X, 1) = AddCustomerNumber ThencontraCts(NN) = Customers(X, 2)NN = NN + 1

    End If Next

  • 8/8/2019 Heckaman Jeremy Final Project Report

    9/12

    Page | 9

    (4)'loads the contract information into an array off of the row information

    ReDim conInfo(1 To N)For X = 1 To N

    conInfo(X) = "Con Type = " & Sheets("ContractTable").Range("i" & contraCts(X)).Value & "; Serv Type = " _& Sheets("ContractTable").Range("j" & contraCts(X)).Value & "; Frequency = " & _

    Sheets("ContractTable").Range("k" & contraCts(X)).Value & "; Price = " & _

    Sheets("ContractTable").Range("l" & contraCts(X)).Value & "; Initial Service = " & _Sheets("ContractTable").Range("m" & contraCts(X)).ValueNext

    (5)'loads the info array into the combo box

    cmbSelectCon.lisT = conInfoEnd If

    End Sub

    The code is redundant in searching for matches, but effective. Basically what happens is it (1) loads thecustomer key for each contract into an array, and then (2) goes through that array counting matcheswith the selected customers key. After determining the number of matches, it redims an array, whichthen (3) loads the row number of each contract with a match. Lastly, it (4) loads an array with all of thedesired contract information, which is then (5) loaded into the second combo box. The user can thenselect a contract from the second combo box to modify.

    I also decided that for some input fields it would be good to ensure that data was uniform andcomplete. I put controls on the phone numbers, the state, and the zip code inputs. The various controlscheck for proper entries (length, numbers or symbols, etc.) and then format the entry into a desiredstandardized format. If an incorrect input is entered, the user is prompted to re-enter the information.This is another area that proved to be difficult. Once you find an error you need to inform the user andthen prevent the tab from progressing so that they user remains in the current text box. This presenteda challenge as well. By using the exit event, you can prevent the curs or from exiting the box if there isincorrect data, but what if the customer just wants to leave the item blank (e.g., the cust omer doesnt

    have a cell phone)? To solve this, I simply inserted an if statement that allowed the user to exit if thefield was blank. Below is the code for the phone number and zip code checks.

    Function CleanPhone(theInput As String) As String'checks phone numbers for validity, and formats them as (###)###-#### regardless of their current format

    Dim oneChar As StringDim X As IntegerDim phoneNumber As String

    For X = 1 To Len(theInput)oneChar = Mid(theInput, X, 1)If IsNumeric(oneChar) Then

    phoneNumber = phoneNumber & oneCharEnd If

    Next

    If Left(phoneNumber, 1) = 1 ThenphoneNumber = Right(phoneNumber, Len(phoneNumber) - 1)

    End If

    If Len(phoneNumber) 10 ThenMsgBox ("This is not a valid phone number. Please enter a 10 digit phone number")CleanPhone = "BAD"

    ElseCleanPhone = "(" & Left(phoneNumber, 3) & ")" & Mid(phoneNumber, 4, 3) & "-" & Right(phoneNumber, 4)

    End If

  • 8/8/2019 Heckaman Jeremy Final Project Report

    10/12

    Page | 10

    End Function

    Function CheckZip(ZiP As String) As Boolean'checks zip codes for characters other than numbers and length only...

    Dim X As IntegerDim oneChar As StringDim N As IntegerN = 0

    If Len(ZiP) = 5 ThenFor X = 1 To 5

    oneChar = Mid(ZiP, X, 1)If IsNumeric(oneChar) Then

    N = N + 1End If

    NextIf N 5 Then

    CheckZip = FalseMsgBox ("That is not a valid zip code. Please enter a five digit zip code.")

    ElseCheckZip = TrueEnd If

    ElseMsgBox ("That is not a valid zip code. Please enter a five digit zip code.")CheckZip = False

    End If

    End Function

    One of the most difficult parts of this project was reporting the service schedule by forecasting futureservice dates based on the initial service date and the service frequency listed on the contract. Contractservice frequency can be quarterly, monthly, annually, etc. To program the Appointment Scheduler, Ifirst needed to make a function that would estimate the next scheduled service date. This function wasfairly difficult to create and had a few bugs to work out. I needed to scan the contracts and project thenext service date using last service date, frequency and the current date. However, in the end, it is

    probably my favorite piece of code that I created (shown below). The date calculation information wasvery helpful in finishing this routine.

    (1)Function NextServ(InitialServe As Date, Frequency As String) As Date'function to find the next scheduled service date

    Dim NewDate As Date

    (2) If Frequency = Sheets("comboarrays").Range("d2").Value Then 'every other week(3) If Date > InitialServe Then(5) NewDate = DateAdd("ww", 2, InitialServe)

    If Date > NewDate Then

    (6) Do Until NewDate > DateNewDate = DateAdd("ww", 2, NewDate)

    LoopEnd If

    (7) NextServ = NewDateElse

    (4) NextServ = InitialServeEnd If

    End If

  • 8/8/2019 Heckaman Jeremy Final Project Report

    11/12

    Page | 11

    I only include the code for the every other week frequency option, since the other options are the exactsame logic with a different time period. This code is (1) sent the initial service date and the frequencyfrom the data base record for a given contract. It then (2) takes the frequency and determines whichvalue it is (e.g., monthly, annually, etc). It (3) next checks to see if the initial service date has alreadypassed. (4) If not, the initial service date is given as the next service date. (5) If the initial service date hasalready passed, however, the function adds the correct time interval to the initial service date. (6) If thisnew date is still older than the current date, it continues to add the given interval until the date is pastthe current date. (7) This date is then given as the next estimated service date.

    This data is subsequently used to identify contracts whose service dates are coming up within theselected time interval. This will help my brother to access upcoming service calls at the touch of abutton, instead of having to thumb through multiple paper contracts and calculate out future services.

    What I Learned

    This project provided many learning opportunities, both expected and unexpected, both enjoyable andnot so enjoyable. I learned that programming becomes increasingly difficult as the number of interrelated sub procedures and functions increase. Changes in one area can have unexpected effects inanother, and are very difficult to track down.

    As previously mentioned, I also learned that programming user friendliness is very difficult to do. Theuser friendliness of a program seems to be inversely related to a programmer s suffering. Features thatare attempted with good intentions seem to wreak havoc on a large program for the reasons mentionedin the previous paragraph. In addition, some very useful items can take up large amounts of programming and testing time, while not providing much obvious benefit in return. A significant portionof the time I put into this project was spent trying to figure out small controls and intricate features that,in the end, appear small and insignificant to the program functionality as a whole, but needed to becompleted.

    This leads into the difficulties of testing a program as it is developed and in the final state. Manyproblems continually came up as the program was completed piece by piece. Many of these problemswent unnoticed as they occurred in forms or sub procedures that I had previously tested and assumedthat they were complete. For this reason, I had to spend a lot of time going back through the databaseand using the various forms in different ways to test where errors and or malfunctions could possiblyoccur. To help expedite this process, I even sent my file to my dad, who is a partner in the business, sothat he could be an extra test user for the forms and program as well. I found that the user interface wasquickly created but very time consuming to test and fix, where some more complex functions, such assearch routines, were tougher to figure out but faster to test and correct.

    Lastly, a technical code item I learned was how to work with dates. There were many issues with thedates being loaded in the proper format. Some functions require that they be processed as a date, andothers can take it as a string. Sometimes I needed to use the dates as different formats, so this made itdifficult when I needed to process the dates as both a date and a string in the same procedures. I alsolearned about the dateadd function (taught to me by Professor Allen), which was critical inprogramming the service Appointment Scheduler function discussed above.

  • 8/8/2019 Heckaman Jeremy Final Project Report

    12/12

    Page | 12

    Conclusion

    In conclusion, this project was a great opportunity for learning. I had wanted to program something formy brother for some time now, hoping to help him stay more organized and access information moreeasily. This project was a perfect opportunity to do so. Through this project I was able to program a data

    base that is capable of storing customer and contract records for my brother, as well as helping himschedule out his work weeks. In addition, the foundation is set for future functionality, such as an ARaging report, automated emailing lists, or revenue projects, among other things.

    I also learned about the difficulties and potential pitfalls that increase exponentially with increasedproject scope. If I were able to do the project over again, I would have spent a lot more time planningout the structure and framework logic that the data base would run on before writing one line of code.As it is, I spent a lot more time reworking and editing the project than a more efficient programmerwould have likely required. However, it was a great learning experience, and will help me to tacklefuture projects more efficiently.