Using RPG As Your ASP Language, Part 2
May 5, 2004 Howard Arner, Jr., and Holley Davis
Last week, we ran the first article in this two-part series, which described our experiences in creating a Web application, using RPG as our ASP language. We discussed the project we were attempting to create, its requirements, setting up the environment, and our first programming steps. In this article, we finish the project by adding interactive grids to the browser application, adding an additional drill-down to allow the viewing of physical file fields, and offer our conclusions about developing with ASNA‘s Visual RPG for Visual Studio .NET.
To catch you up, my partner and I had decided to create a Web application that accepts a library and file name and then allows users to click a “go” button. On clicking the button, we wish to display a grid of related files, by calling a stored procedure that interacts with AS/400 API calls to gather this information. In the last article, we had programmed the call to the stored procedure but had not begun to deal with the returned result set. We pick up at the point of having our result set but no mechanism to display the results.
PUTTING RESULTS IN A GRID
Of course, we don’t want to see just the number of fields in the result set; we want to see the list of files that are related to the input file. To do this, we switched back to the Web page view and dropped a DataGrid control onto the Web page. A DataGrid is a control that can be bound to a DataReader object and used to display the records in the DataReader, in an HTML table. We then used F4 to set the data grids properties. The procedure we are calling returns four columns of information: the dependent file, its library, a description of the file, and the file’s attribute. To set up the display, we pressed F4 and selected the “columns” collection of the data grid control, and we were presented with an editor that allowed us to configure the data grid display. In this editor (Figure 1), we defined five display columns for the grid. The first column is called “dependent file” and is bound to the field DBFFDP in our procedure result set. Binding is how you associate a control with data in a result set or a data reader object. By setting the field name property of a column in the grid to a valid field in the data reader, you are instructing the Web grid to display the results of that field in this column of the grid. Binding is cool because you only need to set the properties of the grid to the fields you want to display; the .NET environment takes care of marshaling the data from the result set into the grid.
Figure 1: Visual Studio makes visual programming easy; here, the editor lets you set the properties of the grid control
Once Holley and I had defined each of the display columns for the four result set columns, we defined a “column called” field and placed a LinkButton in that column. A link button is like a regular button on a form, in that when a user clicks a link button it fires an event. However, a link button also allows you to capture information about the grid row where the event was fired. Pressing “ok” causes all of your changes to be recorded to the Grid object and you are returned to the Web page editor. Now you set the “data grid visible” property to “false,” so that when the page is displayed the grid will not be shown when the user initially loads the page. We then added the following two lines of code to the getFileData subroutine right after the call to the ExecuteReader method of the command object:
The first line causes the DataGrid to be displayed in the user’s browser. The second line sets the data grid DataSource property to the data reader object “r,” causing the grid to render all of the records in “r” to the client browser as an HTML table. That’s it; those two lines of code cause the server to create a grid of the results of the call to the stored procedure. Figure 2 shows an example of calling the procedure for the QADBFDEP file in the QSYS library.
Figure 2: Here is our rendered output in the browser; the “Fields” link button lets us drill down and get field information for the selected file
So far we have a Web page where a user can enter a library and file name and then press a button. Pressing the button causes a trip back to the Web server, where we call a procedure and display a list of related files in a grid. Next, we need to capture the user clicking on the field’s LinkButton, so that we can generate a list of fields and display that to the user. To do this, we need to capture the ItemCommand event from the grid object DataGrid1. First, we placed a second data grid on the Web design interface and set its properties to display nine columns of data. We then set up each column to bind to data that will be generated in the result set of our procedure by placing the correct field names in the Data Field property of the columns collection. Finally, we switched to the code view of the Visual Studio editor and entered the following code to trap the ItemCommand event:
BegSr FieldClick Access(*Private) Event(*this.DataGrid1.ItemCommand) DclSrParm sender Type(*Object) DclSrParm e Type(System.Web.UI.WebControls.DataGridCommandEventArgs) odbcConnection1.Open() dclfld Cmd2 Type(System.Data.Odbc.OdbcCommand) dclfld Rr Type(System.Data.Odbc.OdbcDataReader) Cmd2 = *new system.Data.Odbc.OdbcCommand() Cmd2.CommandType = System.Data.CommandType.StoredProcedure cmd2.CommandText = "CALL SQLBOOK.GETFIELDS(?,?)" Cmd2.Connection = *this.odbcConnection1 Cmd2.Parameters.Add(*new System.Data.Odbc.OdbcParameter("Parameter1", System.Data.Odbc.OdbcType.Char, 10)) Cmd2.Parameters.Add(*new System.Data.Odbc.OdbcParameter("Parameter2", System.Data.Odbc.OdbcType.Char, 10)) Cmd2.Parameters(1).value = e.Item.Cells(1).text cmd2.Parameters(0).value = e.Item.Cells(0).text Rr = cmd2.ExecuteReader() datagrid2.DataSource=Rr datagrid2.Visible()=*on *this.DataBind() datagrid1.Visible()=*off EndSr
The ItemCommand event passes an object “e,” which contains the event arguments. By interrogating the Item property of the “e” object, we can investigate the values of the individual cells in the row of data from where the grid was clicked. Notice that in the subroutine above, we are primarily interested in setting up the properties of the ODBC Command object, so that we can call our next stored procedure, and then setting the parameters of the procedure call to the values from cells 0 and 1 of the row clicked by the user. If you look back at the Web paged displayed in Figure 2, you will note that cell 0 contains the name of the dependent file and cell 1 contains the library where the dependent file lives. In the lines highlighted in red above, we are retrieving the values of the library and file name clicked and putting them into the command object, to send to our stored procedure on the iSeries. Once the ExecuteReader method is called, “Rr” is instantiated with a data reader object, which we can then bind to the DataSource property of the DataGrid2 object. Finally, we turn off the display of data grid 1 and turn on the display of data grid 2. Figure 3 shows the output rendered in the user’s browser.
Figure 3: Upon clicking the “Fields” button, on the previous screen, the RPG program invokes another stored procedure on the iSeries and renders its results in a grid
OUR CONCLUSIONS AND IMPRESSIONS
In an hour and a half, without touching the product documentation, Holley and I were able to create a small Web application that calls stored procedures on our iSeries and displays their results in a Web browser. You have seen the small amount of code we had to write in order to make this function. Most of our time was spent interacting with property windows in the development environment to specify how things should look, not writing code to read data and write it to a browser. Programming in Visual Studio is mostly a visual endeavor, not a code-writing endeavor. You tend to spend most of your time placing things on forms and setting their properties and behaviors, not writing code.
My biggest hurdle was that I do not know RPG, Holley’s biggest hurdle was not knowing Visual Studio .NET. I was able to tell Holley what object we would need in order to communicate with the AS/400 and display the results, but I had no idea how to set the object properties or how to write the code using RPG. Holley was able to do this easily, primarily because of the automatic prompting for methods and properties in the Visual Studio environment, and his knowledge of the RPG language.
As Holley pointed out, this is not RPG; it is ASNA’s version of RPG. However, the syntax is what you expect from RPG; you just have these extensions and new objects to worry about. We think that with minor coaching or a one-day class, most RPG programmers will have a good enough grasp of the fundamentals of the Windows objects to communicate with the iSeries and return results. In addition, playing with the different objects available in the Visual Studio environment will allow an RPG programmer to gain further understanding of the neat tools and controls they can use to create Web- and Windows-based applications. The major difference between “traditional” RPG programming and programming RPG in .NET is that you end up calling and creating a large number of subroutines. That is because of the nature of .NET. This environment is about responding to events like user clicks or menu selections. You trap the events by adding subroutines to handle them.
In this article, we only touched on developing an ASP.NET application using AVR for .NET, but using this tool you could create a Windows application, a Web service, or even a program that runs on Windows CE devices or smart phones. Another thing to bear in mind is that this tool can actually help Holley and I collaborate on Windows projects. I can continue to develop objects and code in Visual Basic, and Holley can write Web services and objects using AVR for .NET. My programs can consume his objects, and his programs can consume and extend my objects. This allows us to both work on the same projects but to keep our preferred languages, which is totally cool and will make us much more productive.
The development environment is what makes this tool shine. And the prompting for parameters and liberal pop-up tool tips that explain what different methods do means there’s less consulting of the documentation. Bottom line, if you are an RPG programming and want a painless, Java-less entry into creating Web applications, this tool deserves a look. You will quickly become productive and can leverage a language skill that you already have and quickly begin developing Windows and Web applications.
Howard F. Arner, Jr., is the author of iSeries and AS/400 SQL at Work and is a consultant at Client Server Development in Jacksonville, Florida. Holley Davis is president of Davis Software and works as a consultant in Jacksonville. Howard and Holley pool their time to create tools for the iSeries, like the Atomic Time Manager 400, SQLThing Enterprise Edition, and Programmer in a Box. You can find out more at www.sqlthing.com or www.fad400.com. E-mail: email@example.com or firstname.lastname@example.org