Visual COBOL and COBOL For .NET Language Introduction en
Visual COBOL and COBOL For .NET Language Introduction en
Visual COBOL and COBOL For .NET Language Introduction en
Micro Focus The Lawn 22-30 Old Bath Road Newbury, Berkshire RG14 1QN UK http://www.microfocus.com
Copyright Micro Focus IP Development Limited . All rights reserved. MICRO FOCUS, the Micro Focus logo and are trademarks or registered trademarks of Micro Focus IP Development Limited or its subsidiaries or affiliated companies in the United States, United Kingdom and other countries. All other marks are the property of their respective owners.
ii
Contents
Visual COBOL and COBOL for .NET Language Introduction ........................4
Introduction .........................................................................................................................4 Visual Studio Overview ............................................................................................4 Starting Visual COBOL ............................................................................................5 Projects and Solutions ..............................................................................................6 A First Console Application .................................................................................................6 Creating a Console Application ................................................................................6 Building and Executing an Application from Visual Studio .......................................7 Building and Executing an Application from a Command Prompt ............................7 A First Graphical Application ...............................................................................................8 Creating a Graphical Application ..............................................................................8 Adding a Label Control .............................................................................................8 Adding a Button Control ...........................................................................................9 Adding a Click Event Handler ...................................................................................9 Adding a Text Box Control .....................................................................................10 Tying it all Together ................................................................................................10 Overview of Visual COBOL Debugging ............................................................................11 Building for Debug ..................................................................................................11 Executing with Debug .............................................................................................12 Breakpoints ............................................................................................................12 Debug Navigation ...................................................................................................13 Migrating to Managed Code ..............................................................................................14 The CblDemo1 Sample Application .......................................................................14 Working with Data Types and Namespaces ..........................................................17 Error Capture ..........................................................................................................22 Working With Classes ............................................................................................23 Further Application Enhancements ...................................................................................26 Appendix ...........................................................................................................................28 Changing the Startup Object ..................................................................................28 Data Type Reference .............................................................................................29 Working with IntelliSense .......................................................................................30
Contents | 3
Managed code is code that executes in a controlled runtime environment. Machines with microprocessor types different from the source code machine cannot execute the code natively without a system to manage code execution. On Windows systems, the controlled environment is the .NET Framework Common Language runtime (CLR).
On windows systems, source code is encoded in the Microsoft Intermediate Language (MSIL). The CLR manages the encoding to MSIL. Any programming language that targets the CLR produces the correct encoding for that language. Before execution, the CLR compiles the MSIL into machine dependent, or native executable code. Because the compiling is done in a managed environment, that managed code can be used by any host machine.
If prompted to set the environment, choose General development environment. The General development environment customizes Visual Studio to work with COBOL projects. Visual COBOL starts within Visual Studio, and the Visual Studio Start page appears with up-to-date Visual Studio information as follows.
|5
Use the File menu to open solutions and projects. The Solution Explorer appears in the right-hand pane. The Solution Explorer displays the structure of the opened solution or project. In the Solution Explorer, double click a file name to display its contents in a separate Code Editor tab. The Output window displays below the Code Editor tab. This is where messages from the Visual Studio Integrated Development Environment (IDE) and compiler appear. The Error List tab in the Output window shows any error messages, warnings and other messages that occur during code development or when compiling a solution or project.
1. Click File > New > Project. The New Project dialog box appears. 2. Click COBOL > Managed in the Installed Templates pane. Available COBOL templates appear in the templates list. 3. Select Console Application from the list. 4. Enter ConsoleHelloWorld as the name of the project in the Name field, and click OK. Visual Studio creates a new solution and a project in the solution named ConsoleHelloWorld, and a new program template named Program1.cbl. Program1.cbl displays in a Code Editor tab. The current code for Program1.cbl is the template code, as shown in the following. program-id. Program1 as "ConsoleHelloWorld.Program1". data division. working-storage section. procedure division. goback. end program Program1. 5. Add a statement to this program to display the text "Hello World" when executed. To do this, place the cursor after the procedure division. line and press Tab to move the cursor to the start of Area B (column 12). Add the display statement into the program between the procedure division and the goback statement so the program looks as follows. program-id. Program1 as "ConsoleHelloWorld.Program1". data division. working-storage section. procedure division. display "Hello World" goback. end program Program1. 6. Click File > Save Program1.cbl to save the code update.
To execute an application from a command prompt instead of with Visual COBOL, open a Visual COBOL command prompt and enter the command to execute the application. 1. Click Start menu > All Programs > Micro Focus Visual COBOL 2010 > Visual COBOL Tools > Visual COBOL Command Prompt (32-bit). This opens a command prompt to your document directory by default. From this directory, navigate to the directory containing the application. This directory is \Visual Studio 2010\Projects \ConsoleHelloWorld\ConsoleHelloWorld\bin\debug by default. Verify that the application is in this directory. 2. To navigate to the directory containing the application, type cd \[default document directory] \Visual Studio 2010\Projects\ConsoleHelloWorld\ConsoleHelloWorld\bin\debug at the command prompt and press Enter. 3. Type ConsoleHelloWorld and press Enter. The application starts, displays the text Hello World and then ends. The text Press any key to continue... does not appear. This text only appears if the application runs in Visual COBOL to allow you to see the console application output after completion.
4. Type Hello World to change the property value and press Enter. The property value for the Label control updates. Use instructions in Building and Executing an Application from Visual Studio to build and execute the application. This opens a form called form1 that displays a label named Hello World. Click on the x in the top-right corner to close the form and stop the application.
|9
This code moves the text Hello World to the Text property of the previously created label1 label. This removes the current label1 value. Tip: Visual COBOL uses IntelliSense to suggest text completions as you type. See Working With IntelliSense for more information. The code should be as follows. working-storage section. method-id NEW. procedure division. invoke self::InitializeComponent goback. end method. method-id button1_Click final private. procedure division using by value sender as object e as type System.EventArgs. set self::label1::Text to "Hello World" end method. end class. 4. Click on the tab labeled Form1.cbl [Design] at the top of the code editor to display the form in the Code Editor tab. 5. Click on the Label control. The control's properties appear in the Properties pane. 6. Clear the Text property value and press Enter. The property value updates. Use instructions in Building and Executing an Application from Visual Studio to build and start the application. When started, the form opens and displays a button with the text Say Hello. Click the button to cause Hello World to display on the form. Click the x in the top-right corner to close the form and stop the application.
10
2. In the Solution Explorer, highlight the Text property value in the Appearance section of the Properties pane. 3. Type First Name to change the property value and press Enter. The property value for the Label control updates. 4. Double-click the Button control. The code for Form1.cbl appears. This code contains the click event handler for the button that was updated in the exercise to add a click event handler, but with an additional method for the new label as shown in the following. working-storage section. method-id NEW. procedure division. invoke self::InitializeComponent goback. end method. method-id button1_Click final private. procedure division using by value sender as object e as type System.EventArgs. set self::label1::Text to "Hello " & self::textBox1::Text end method. method-id label2_Click final private. procedure division using by value sender as object e as type System.EventArgs. end method. end class. 5. Replace the previously added code so it reads as follows: set self::label1::Text to "Hello " & self::textBox1::Text This concatenates the constant text Hello and the contents of the text box textBox1, and places the results into the label1 label when clicking the button. Build and execute the application to display a text box labeled First Name and a button. Type Fred into the text box and click the button. The text Hello Fred appears.
| 11
Breakpoints
A breakpoint is a placeholder placed in the source code. When a breakpoint is encountered during application execution, the application pauses and the line containing the breakpoint highlights. While the application is paused you can retrieve information about current variables, set additional breakpoints or interrogate application behavior. Tip: Pausing the application during debug execution is also known as break mode.
Setting a Breakpoint
Perform the following steps to set a breakpoint: 1. Click the line where you want to pause the application execution. 2. Click Debug > Toggle Breakpoint. A breakpoint is created. A red dot displays in the left margin next to the code line where execution is set to pause.
12
Note: If a breakpoint is set on a non-executing code line, the application pauses at the next executing code line.
Disabling a Breakpoint
While debugging you might want to ignore a set breakpoint, but keep it in place for later use. This cannot be done by using the menu options at the top of the Visual COBOL window, but instead via the context menu as follows: 1. Right-click on the line of code beside the breakpoint to display the context menu. 2. Select Breakpoint > Disable Breakpoint. The selected breakpoint disables as indicated by the red circle in the left margin. To re-enable a breakpoint select Breakpoint > Enable Breakpoint from the context menu.
Removing a Breakpoint
Once you have no further use for a breakpoint, remove it by doing the following. 1. Select the breakpoint by clicking on the corresponding code line. 2. Click Debug > Toggle Breakpoint. The selected breakpoint is removed. Repeating these steps alternatively sets and removes a breakpoint.
Debug Navigation
Dynamically interrogating and monitoring data movement during application execution is a powerful and useful feature within the Visual COBOL environment. The current line of execution displays in the Code Editor tab during application debugging. As the application executes, the display steps into or over the methods as directed, highlighting the next line of code to be executed. The list below shows the navigational options available during debugging. Stepping Over (Debug > Step Over) Executes the current line and progresses to the next line of code in the current code block. Any methods the debugger encounters execute completely. If the end of the code block is reached, control returns to the calling block. Stepping Into (Debug > Step Into) Executes one code command at a time. For a simple numeric operation, the debugger behaves as if Step Over is being used. For more complex code, the debugger passes control to any called method and executes its first code line, steps through the rest of the method before returning to the calling method. The Code Editor tab shows the executing code line. Stepping Out (Debug > Step Out) Completes the current method and stops at the next line of the calling method. Restarting the debugger (Debug > Restart) Restarts debugging at the first line of the application. Stopping the debugger (Debug > Stop Debugging) Terminates the debugger. Setting the next statement. Allows you to set the next statement to be executed. To do this, right-click the line of code to be executed and select Set Next Statement.
| 13
99. 99. 99. 99. 99. 99. 99. 99. 999. X(30). X(60). X(60). X(12). X(10) value "Hello Mr ". X(11) value " you have ". ZZ9. X(40) value " days until next birthday".
PROCEDURE DIVISION. DISPLAY "Enter your full name" ACCEPT full-name DISPLAY "Enter your date of birth in mmdd format" ACCEPT test-date
14
PERFORM validate-test-date MOVE test-date TO dob DISPLAY "Enter the date today in mmdd format" ACCEPT test-date PERFORM validate-test-date MOVE test-date TO today PERFORM add-day-difference PERFORM add-mth-difference UNTIL (max-month = DOB-month) MOVE total-days TO output-days STRING txt1, full-name DELIMITED BY SIZE INTO greeting-output DISPLAY greeting-output STRING full-name, diff-output DELIMITED BY SIZE INTO display-output DISPLAY display-output STOP RUN . validate-test-date SECTION. IF (test-day = 0) STOP "Invalid day field" STOP RUN END-IF. IF ((test-month = 0) OR (test-month > 12)) STOP "Invalid month field" STOP RUN END-IF. MOVE test-month TO max-month. PERFORM set-max-days. IF (test-day > max-days) STOP "Invalid day field" STOP RUN END-IF . add-day-difference SECTION. MOVE today-month TO max-month PERFORM set-max-days IF (DOB-day = today-day) MOVE ZERO TO total-days ELSE IF (DOB-day > today-day) COMPUTE total-days = DOB-day - today-day ELSE COMPUTE total-days = (max-days - today-day) + DOB-day PERFORM increment-test-month END-IF END-IF . add-mth-difference SECTION. PERFORM set-max-days ADD max-days TO total-days PERFORM increment-test-month . increment-test-month SECTION. ADD 1 TO max-month IF (max-month > 12) MOVE 1 TO max-month END-IF . unused SECTION. EXIT SECTION.
| 15
set-max-days SECTION. EVALUATE max-month WHEN 1 MOVE 31 WHEN 2 MOVE 28 WHEN 3 MOVE 31 WHEN 4 MOVE 30 WHEN 5 MOVE 31 WHEN 6 MOVE 30 WHEN 7 MOVE 31 WHEN 8 MOVE 31 WHEN 9 MOVE 30 WHEN 10 MOVE 31 WHEN 11 MOVE 30 WHEN 12 MOVE 31 END-EVALUATE . END PROGRAM CblDemo1.
TO TO TO TO TO TO TO TO TO TO TO TO
max-days max-days max-days max-days max-days max-days max-days max-days max-days max-days max-days max-days
COBOL Margins
Visual COBOL displays the set COBOL margins. A gray margin for the sequence number and the indicator displays when the format is set as Variable. An additional margin displays to the right when the format is set as Fixed. Changing COBOL Margins The following steps show you how to change COBOL margins inVisual COBOL: 1. Right-click on the project in the Solution Explorer and select Properties. The project properties display in the Properties page. 2. In the Properties page, select the COBOL tab. The COBOL tab properties appear. 3. Use the Source Format list box to select the appropriate COBOL margin type. This sets the displayed margins for COBOL code in Visual COBOL.
16
Use the Source Format setting to specifying margin settings instead of the SOURCEFORMAT compiler directive.
In the sample solution, CblDemo2 contains the completed code based on DateTime data type exercises completed in this section. CblDemo3 contains the completed code based on String data type exercises
| 17
completed in this section. See the Changing the Startup Object appendix for information on starting the programs.
Namespaces
A namespace is a grouping containing related data types. A namespace references its available classes and methods. For example, the field dob is defined as being of type DateTime which is grouped into the namespace System: 01 dob type System.DateTime.
The .NET Framework includes a variety of namespaces such as Accessibility, System.Data, System, System.IO, and System.Runtime. All namespaces include related classes and methods. Visual COBOL imports the namespace System by default, so there is no need to prefix classes from this namespace. This means the example above can also be written as: 01 dob type DateTime. Removing Namespace Prefixing Add namespaces directly to your project properties so that you don't need to type the fully qualified namespace when developing code. The System namespace is included by default. To add other namespaces to your project properties: 1. Right-click on the project name in the Solution Explorer and select Properties. The project properties display in the Properties page. 2. In the Properties page, select the References tab. The References tab properties appear. 3. Scroll down to the Imported Namespaces list. This list contains all available namespaces. 4. Select the check box next to each namespace in the list to directly import into the project build. This indicates whether the namespace is directly imported in the project build. Namespaces not selected require the full namespace prefixing in code. Simplify your code by removing namespace prefixes included in the Imported Namespaces list. Use the Imported Namespaces project setting to add namespace to a project, as it supercedes the $SET ILUSING compiler directive.
18
namespace is included in the imported namespaces list by default, the data definition for today and dob can be replaced with simply DateTime. Types derived from System.Object must be declared at level 01. Since DateTime does not have a synonym in COBOL, the type keyword must precede it. In the sample application, the variable today contains the current date. The value is initialized using the built-in DateTime method Today(). The following shows the changed variable definitions: 01 today type DateTime value type DateTime::Today(). 01 dob type DateTime. 01 test-date. 03 test-month PIC 99. 03 test-day PIC 99. 01 max-month PIC 99. 01 max-days PIC 99. 01 total-days PIC 999. 01 full-name PIC X(10). 01 display-output PIC X(60). 01 greeting-output PIC X(60). 01 txt1 PIC X(10) value "Hello Mr ". 01 diff-output. 03 txt2 PIC X(11) value " you have ". 03 output-days PIC ZZ9. 03 txt3 PIC X(40) value " days until next birthday". In this example, a variable derived from System.Object provides the contents of the variable by default. You can use data types of a namespace to replace standard variable data definitions without having to make further updates to existing procedure division code. Since retrieving the current date for input is no longer required, the lines of code in the sample application that previously defined the today and dob fields can be removed. DateTime Object Initialization The dob field is assigned the DateTime object value using validated variables as parts of a constructor. A constructor is a method that is called when it's object is initialized, and is typically used to initialize the object's parameters. In the sample application, the year parameter is provided by the year field from the today object as shown below: set dob to new type DateTime(today::Year, test-month, test-day) Note: Commas separating the parameters are optional. DateTime Object Comparison DateTime objects provide a range of methods allowing for date and time manipulation and comparison. Using the difference between the today and dob fields can be obtained in a much simpler way. To ensure that negative results are not returned, compare dates to ensure that the dob field contains a value that is not less than the value in today. The DateTime object provides a CompareTo() method which returns zero if the dates are identical and +1 or -1 to indicate a difference. The DateTime object provides methods which add and subtract individual elements of a date, automatically adjusting the other elements to ensure that the date remains valid. In the demonstration application the year is incremented by one if the dob date is less than today's date to ensure that it is in the future. The method to be used is AddYears() which accepts an integer as a parameter.
| 19
In the following line, the if statement equates to true if today is greater than dob. If true, the year element of dob increments by one. if today::CompareTo(dob) > 0 set dob to dob::AddYears(1) end-if. Use CompareTo() method as a condition to a perform statement to write a single section to determine the number of days between two DateTime objects, as shown in the following. perform add-to-total until today::CompareTo(dob) = 0 The add-to-total section increments the variable total-days and today. The add statement increments the total-days variable. The AddDays() method increments the day element of the today variable. add-to-total SECTION. add 1 to total-days set today to today::AddDays(1). With the add-to-total section in place, the sections add-day-difference, dd-mth-difference and incrementtest-month are now redundant and can be removed.
20
The sample application copies text captured from the console into the String field display-output to take advantage of available methods. String Functionality Defining the variables as type String does not require amendments to procedure division code as default behavior of a variable derived from System.Object provides the contents of the variable. The sample application copies the text captured from the console into the String field display-output to take advantage of available methods. Displaying The Surname The application displays an informal salutation. This exercise shows how to change this to display a surname. The application displays the contents of the field txt1 followed by the surname and lastly a comma (,). Assuming that the surname is the last part of the full name preceded by a space character, the position of the space just before the surname needs to be found. The String object lets you use a method to retrieve a substring. To set up the code to take advantage of this method, first set up the display-output variable to receive the substring. The Trim() method removes all leading and trailing spaces from the string. Use the statement shown below to populate the greetingoutput variable with the substring. set display-output to full-name set greeting-output to display-output(???:)::Trim() The example still needs to determine the start position of the surname. Use the String object to determine the last occurrence of a provided Unicode character. To do this, use the LastIndexOf() method with the first position of the string set to zero. The method takes two parameters separated by a colon (:). The first parameter is the start position of the substring, with one being the first position in the original string. The second parameter is the length of the string to retrieve. If not provided, the remainder of the string is returned. Use this to populate the temp1 variable so that the final space character position is just before the surname. Increment the temp1 variable value by one to give the surname start position. set display-output to full-name set temp1 to display-output::Trim()::LastIndexOf(' ') set greeting-output to display-output(temp1 + 1:)::Trim() To display the information, use the display keyword followed by the variables in sequence: set display-output to full-name set temp1 to display-output::Trim()::LastIndexOf(' ') set greeting-output to display-output(temp1 + 1:)::Trim() display txt1 greeting-output "," Displaying the First Name Now that the code is updated to display the surname, this exercise shows how to update the code with managed COBOL to display the following in order: The first name The txt2 variable value The number of days until the next birthday The txt3 variable value.
It is assumed that no leading spaces have been entered. The previous exercise uses the substring method to display the surname as part of the salutation. This exercise uses it to retrieve the first name from the beginning of the string. The exercise assumes no leading spaces are entered in the string.
| 21
With the length of the first name string to be determined, the display statement is as follows: display display-output(1:???) txt2 total-days txt3 Use the IndexOf() method to determine the position of the first provided Unicode character, with the first position of the string being zero. Locating the string's first space position gives the length of the first name. The following populates the temp1 variable with the first space in the display-output string: set temp1 to display-output::IndexOf(' ') Putting these two statements together results in displaying the first name with the contents of txt2, totaldays and txt3 as shown below: set temp1 to display-output::IndexOf(' ') display display-output(1:temp1) txt2 total-days txt3 The display statement concatenation accepts numeric and string values.
Error Capture
This section looks at the basic error capturing in the sample application and shows how use the Try statement to enhance error capturing. Deciding what to do once an error is captured typically depends on the application. This exercise displays a message when capturing an error. Note: CblDemo4 contains completed code once for changes discussed in this section. To execute the program see Changing the Startup Object appendix. The validate-test-date section in the sample application validates that the supplied birth day and month are in range. It validates that the birth day is not zero and that the birth month is a number from 1 to 12. The set-max-days then retrieves the maximum days in the birth month and validates that the entered birth day is within range: validate-test-date SECTION. IF (test-day = 0) STOP "Invalid day field" STOP RUN END-IF IF ((test-month = 0) OR (test-month > 12)) STOP "Invalid month field" STOP RUN END-IF MOVE test-month TO max-month. PERFORM set-max-days IF (test-day > max-days) STOP "Invalid day field" STOP RUN END-IF . The section set-max-days is straightforward code. However, it contains no code to manage leap year determination: set-max-days SECTION. EVALUATE max-month WHEN 1 MOVE 31 TO max-days WHEN 2 MOVE 28 TO max-days WHEN 3 MOVE 31 TO max-days WHEN 4 MOVE 30 TO max-days WHEN 5 MOVE 31 TO max-days WHEN 6 MOVE 30 TO max-days WHEN 7 MOVE 31 TO max-days WHEN 8 MOVE 31 TO max-days WHEN 9 MOVE 30 TO max-days WHEN 10 MOVE 31 TO max-days WHEN 11 MOVE 30 TO max-days
22
WHEN 12 MOVE 31 TO max-days END-EVALUATE . This is an acceptable way to handle errors. However, the DateTime data type also validates the entered values as the data type is created, including leap year determination, and throws an exception if they are in error.
Wrapping the constructor in a try statement informs the application to check the validation result. If any exceptions are raised, the first catch statement matching the thrown exception executes. The catch statement below uses the variable result to tell the application what to do when the user supplied data causes an exception. try set dob to new type DateTime(today::Year test-month test-day) catch argException display "I couldn't understand your date entry" display argException::Message stop run end-try The above code replaces the functionality provided by validate-test-date and set-max-days so that code can be removed. The redundant variables max-month and max-days can also be removed.
Creating a Class
A class is a type definition containing fields and methods, usually representing a tangible thing or action. Since the sample application includes code that creates, stores and displays information about an individual, create the Person class for that information. 1. Right-click on the project name in the Solution Explorer window and select Add > New Item.... The Add New Item window appears. 2. Click COBOL Items > Managed in the Installed Templates pane, then select COBOL Class from the list. 3. Type Person.cbl in the Name field. The Name indicates both the name of the file and class to create. This denotes the name of the file and class being created.
| 23
4. Click Add to create a file called Person.cbl containing the empty Person class template. The class template is very similar to the program template and contains an empty method. class-id CblSolution.Person. working-storage section. method-id InstanceMethod. local-storage section. procedure division. goback. end method. end class. 5. Remove CblSolution from the class identifier located on the first line of the class template. The solution name prefixes to the class identifier by default to ensure unique class names across the an application. This is not required for the sample application and can be removed.
24
The Person class that contains the full name and date of birth of a person, which can only be successfully created if both the full name and date of birth are provided.
| 25
set return-value to full-name(temp1 + 1:)::Trim() end method. 3. First name functionality. As with the surname, the sample application extracts entered first name and displays it as part of a phrase. Create a method to return the first name as a StringUse existing code from the sample application as a basis: method-id FirstName. 01 temp1 PIC 99. procedure division returning return-value as type String. set temp1 TO full-name::IndexOf(' ') set return-value to full-name(1:temp1) end method. You can combine the two lines above for efficiency as shown in the following, keep the code as two lines for readability: method-id FirstName. procedure division returning return-value as type String. set return-value to full-name(1:full-name::IndexOf(' ')) end method.
26
By introducing classes to provide standard methods, new applications are easier and quicker to write. You can update your existing applications to use the new class as the opportunity presents itself, steadily moving code towards more efficiency in development. With the updated sample application, the text constants are contained in three variables. These variables could be removed, replacing them with the quoted string directly in the code, or the strings themselves could be provided via a second class. The console application itself could be completely replaced with a Windows application now that the functionality has been moved to a class. The greeting text "Hello Mr " indicates that the application has been written assuming that the user will always be a man; however the application could ask the user to enter their gender. The Person class could then have a new method written to provide the formal greeting, allowing the text to simply read "Hello". You can extend the demonstration application further with the suggestions above, or with additional functionality of your own design. Below is the final console application code: PROGRAM-ID. CblDemo5. 01 person1 type Person. 01 test-date. 03 test-year PIC 9999. 03 test-month PIC 99. 03 test-day PIC 99. 01 full-name PIC X(30). 01 txt1 String value "Hello Mr ". 01 txt2 String value " you have ". 01 txt3 String value " days until next birthday". 01 argException type ArgumentException. PROCEDURE DIVISION. display "Enter your full name" accept full-name display "Enter your date of birth in yyyymmdd format" accept test-date try set person1 to new type Person(full-name new DateTime(test-year test-month test-day)) catch argException display "Invalid arguments provided" display argException::Message stop run end-try display txt1 & person1::familyName() & "," display person1::firstName() & txt2 & person1::daysUntilBirthday() & txt3 stop run . END PROGRAM CblDemo5. Here is the final code for the Person class: class-id Person. 01 full-name 01 dob string public property as "FullName". type DateTime public property as "DateOfBirth".
method-id New public. procedure division using by value fullname as string birthday as type DateTime. set full-name to fullname set dob to birthday goback. end method. method-id NextBirthday. 01 today type DateTime value type DateTime::Today().
| 27
procedure division returning return-value as type DateTime. set return-value to new DateTime(today::Year, dob::Month, dob::Day) end method. method-id DaysUntilBirthday. procedure division returning return-value as binary-long. set return-value to self::NextBirthday()::Subtract(type DateTime::Today())::Days end method. method-id FamilyName. 01 temp1 PIC 99. procedure division returning return-value as type String. set temp1 TO full-name::Trim()::LastIndexOf(' ') set return-value to full-name(temp1 + 1:)::Trim() end method. method-id FirstName. procedure division returning return-value as type String. set return-value to full-name(1:full-name::IndexOf(' ')) end method. end class.
28
| 29
string
System.String
30