"Content": "<html><head><TITLE>Developing Applications with the Microsoft Visual Basic 6.0 Data Object Wizard</TITLE><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\r\n<META content=\"MSHTML 5.50.4134.100\" name=GENERATOR></head>\r\n<BODY>\r\n<DIV style=\"DISPLAY: none\"><IMG height=0 hspace=0 \r\nsrc=\"http://c.microsoft.com/trans_pixel.asp?source=msdn&TYPE=PV&p=library_en-us_dnvb600_html&qs=frame=true\" \r\nwidth=0 border=0></DIV></LAYER><SPAN id=StartMenu \r\nstyle=\"DISPLAY: none\"></SPAN><LINK \r\nhref=\"/library/shared/eyebrow/css/default.css\" type=text/css rel=stylesheet>\r\n<xml id=xmlPageContext><eyebrow findmenu=\"false\">\r\n\t<item label=\"MSDN Home\" url=\"/default.asp\"/>\r\n\t<item label=\"MSDN Library\" url=\"/library/default.asp\"/>\r\n\t<item label=\"Visual Tools and Languages\" id=\"msdnlib859\" xmlsrc=\"/library/en-us/toc/msdnlib/msdnlib859.xml\"/><item label=\"Visual Basic\" url=\"/nhp/default.asp?contentid=28000520\" id=\"msdnlib943\" xmlsrc=\"/library/en-us/toc/msdnlib/msdnlib943.xml\"/><item label=\"Visual Basic 6.0\" id=\"msdnlib947\"/><item label=\"Technical Articles\" id=\"msdnlib951\"/><item label=\"Developing Applications with the Microsoft Visual Basic 6.0 Data Object Wizard\" url=\"/library/en-us/dnvb600/html/dowwp.asp\" id=\"dnvb6005\"/></eyebrow></xml>\r\n<TABLE cellSpacing=0 cellPadding=0 width=\"100%\" border=0>\r\n<TBODY>\r\n<TR>\r\n<TD vAlign=top align=left width=\"100%\">\r\n<TABLE height=24 cellSpacing=0 cellPadding=4 width=\"100%\" bgColor=#ffffff \r\nborder=0>\r\n<TBODY>\r\n<TR>\r\n<TD class=eyebrow vAlign=center align=left width=\"100%\"> <A \r\nclass=small href=\"/default.asp\">MSDN Home</A> > <A class=small \r\nhref=\"/library/default.asp\">MSDN Library</A> > <A class=small \r\nhref=\"/nhp/default.asp?contentid=28000520\">Visual Basic</A> > <A \r\nhref=\"\"></A> </TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>\r\n<TABLE cellSpacing=0 cellPadding=0 width=\"100%\" border=0>\r\n<TBODY>\r\n<TR>\r\n<TD style=\"PADDING-RIGHT: 15px\" vAlign=top align=right width=\"100%\">\r\n<SCRIPT>\r\n function fnOpenRating( oAnchor )\r\n {\r\n event.returnValue = \r\n false; varsOpts=\"menubar=no,status=no,toolbar=no,menubar=no\";\r\n fnOpenInCenter( oAnchor , \"RatingWindow\" , sOpts , 150 , 240 );\r\n window.onunload = fnCloseRatingWindow;\r\n return false;\r\n }\r\n function fnOpenInCenter( oAnchor , sWindowName , sOpts , iHeight , iWidth )\r\n {\r\n sOpts = \"height=\" + String( iHeight ) + \",width=\" + String( iWidth ) + \",\" + sOpts;\r\n if( \"object\" == typeof( window.screen ) )\r\n {\r\n var iTop = window.screen.height/2 - 75;\r\n var iLeft = window.screen.width/2 - 120;\r\n sOpts = \"left=\" + String( iLeft ) + \",top=\" + String( iTop ) + \",\" + sOpts;\r\n }\r\n window.oRatingWindow = window.open( oAnchor.href , sWindowName , sOpts );\r\n }\r\n function fnCloseRatingWindow()\r\n {\r\n window.oRatingWindow.close();\r\n }\r\n </SCRIPT>\r\n\r\n<TABLE cellSpacing=0 cellPadding=2 border=0>\r\n<TBODY>\r\n<TR>\r\n<TD align=right><A onclick=\"return fnOpenRating( this );\" target=_new \r\nhref=\"/library/shared/ratings/asp/submitrating.asp?aid=362184\">Rate this page: \r\n</A></TD>\r\n<TD>3 users </TD>\r\n<TD vAlign=bottom>\r\n<TABLE class=clsRating cellSpacing=0 cellPadding=0 border=2>\r\n<TBODY>\r\n<TR height=4>\r\n<TD bgColor=#ff3300><IMG height=4 src=\"./images/FF3300.gif\" \r\nwidth=20></TD>\r\n<TD bgColor=#ff3300><IMG height=4 src=\"./images/FF3300.gif\" \r\nwidth=20></TD>\r\n<TD bgColor=#ff3300><IMG height=4 src=\"./images/FF3300.gif\" \r\nwidth=20></TD>\r\n<TD bgColor=#ff3300><IMG height=4 src=\"./images/FF3300.gif\" \r\nwidth=20></TD>\r\n<TD noWrap bgColor=#ffffff><IMG height=4 \r\nsrc=\"./images/ts.gif\" \r\nwidth=20></TD></TR></TBODY></TABLE></TD>\r\n<TD> <B>4.0</B> out of \r\n5</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>\r\n<TABLE class=clsContainer cellSpacing=0 cellPadding=15 width=\"100%\" border=\"0\" \r\nfloat=\"left\">\r\n<TBODY>\r\n<TR>\r\n<TD vAlign=top align=left><!--TOOLBAR_START--><!--TOOLBAR_EXEMPT--><!--TOOLBAR_END--><!-----------------><!--BEGIN_CONTENT--><!-----------------><!--NONSCROLLING BANNER START-->\r\n<DIV id=nsbanner>\r\n<DIV id=TitleRow>\r\n<H1 class=dtH1><A name=dowwp></A>Developing Applications with the Microsoft \r\nVisual Basic 6.0 Data Object Wizard</H1></DIV></DIV><!--NONSCROLLING BANNER END-->\r\n<H1></H1>\r\n<P>Microsoft Corporation</P>\r\n<P>December 1998</P>\r\n<P>The Visual Basic? Data Object Wizard (DOW) is a Visual Basic Add In Wizard. \r\nThe DOW significantly reduces development time of data components.</P>\r\n<P>You can use the DOW to create data Classes and User Controls that display and \r\nmanipulate data. You can add these components to Visual Basic forms to create a \r\ndata application.</P>\r\n<P>Before you can use the DOW, you must create one or more commands with the \r\nVisual Basic DataEnvironment Designer (DED). One DED command specifies the \r\nsource of data. Other optional DED commands specify lookup and data modification \r\ncommands.</P>\r\n<P>A DOW data Class contains a RecordSet for each DED data source, lookup, and \r\ndata modification command. Data consumers can either bind to the Class or use \r\nmanual techniques to access the data from the Class.</P>\r\n<P>A DOW User Control can be a DataGrid, Single Record, ComboBox, or ListBox. \r\nThese User Controls bind to DOW data Classes.</P>\r\n<P>Several complex design issues are addressed by the DOW, allowing it to create \r\ndata components that are useful in serious enterprise client/server \r\napplications.</P>\r\n<H4 class=dtH1>Contents</H4>\r\n<P><A target=_self href=\"#dowwp_design\">Design Issues</A><BR><A target=_self \r\nhref=\"#dowwp_commands\">DOW Commands</A><BR><A target=_self href=\"#dowwp_ded\">The \r\nDataEnvironment Designer</A><BR><A target=_self \r\nhref=\"#dowwp_createdataclass\">Creating a Data Class</A><BR><A target=_self \r\nhref=\"#dowwp_databoundctrls\">Creating Data-Bound User Controls</A><BR><A \r\ntarget=_self href=\"#dowwp_usingdowobjects\">Using DOW Objects in an \r\nApplication</A><BR><A target=_self href=\"#dowwp_appendix\">Appendix</A></P>\r\n<H2 class=dtH1><A name=dowwp_design></A>Design Issues</H2>\r\n<H3 class=dtH1>Stored Procedures</H3>\r\n<P>A generally accepted standard for client/server development is to have all \r\ndatabase access accomplished through a secure application programming interface \r\n(API). An example of this is the use of Stored Procedures with SQL Server?. Most \r\nserious applications need the security and performance enhancements offered by \r\nthis secure API.</P>\r\n<P>The DOW allows separate DED commands for \"Select\" (main data source), \r\n\"Lookup,\" \"Update,\" \"Insert,\" and \"Delete\" operations.</P>\r\n<H3 class=dtH1>Update Timing</H3>\r\n<P>Few serious client/server applications allow the user instant control over \r\nupdates. Generally, the user is allowed to make local changes, then access a \r\ncontrol (often a \"Save\" button) to update the Data Source.</P>\r\n<P>Many binding mechanisms change the Data Source immediately when the user \r\nleaves a cell or record. (Some binding mechanisms have a \"batch\" update mode \r\nthat allows the developer to control the moment of update.)</P>\r\n<P>DOW components use either \"batch\" or \"immediate\" update mode to allow the \r\napplication user to freely make local changes, then either \"Cancel\" or \"Save\" \r\nthe changes to the Data Source.</P>\r\n<H3 class=dtH1>Lookup (Foreign Key) Relationships</H3>\r\n<P>Most code generators have no provision for displaying meaningful text for \r\nLookup options. Usually, only the (often) cryptic Lookup values are shown.</P>\r\n<P>For example, a PersonID, like \"28282,\" might be typically displayed instead \r\nof an actual name (\"Joe Smith\") for a Person as a Lookup in a table.</P>\r\n<P>These relationships are often defined by multiple fields of different data \r\ntypes (not just one field of integer datatype).</P>\r\n<P>For each Lookup relationship, the DOW replaces multiple fields of multiple \r\ndata types with one field, displaying a validation list of meaningful text \r\ndescriptions (generally in ComboBoxes).</P>\r\n<H3 class=dtH1>Primary Key Generation</H3>\r\n<P>There are so many schemes for generating Primary Keys (identity constraints, \r\nmax(value) +1, manually generated schemes, and so on), that it would be \r\nimpractical to attempt to generate code for them.</P>\r\n<P>The DOW will rely on either (1) the User's \"Insert\" command to automatically \r\ngenerate the Primary Key values(s) or (2) allowing direct user input of primary \r\nkey values.</P>\r\n<P>If the DED \"Insert\" command has Input/Output parameter(s) that feed back \r\nsystem generated Primary Key values to the DED command, the DOW data Class \r\nstores these values, which allows immediate Updates or Deletes of the newly \r\ninserted Record.</P>\r\n<H3 class=dtH1>Null Values</H3>\r\n<P>Many real client/server applications require that Null data be clearly \r\nidentified to users. In many cases, users need to be able to see a difference \r\nbetween values that are Null and values that are blanks (zero length strings), \r\nfor example.</P>\r\n<P>Null values are often displayed as meaningful text, such as \"(None),\" \r\n\"(Null),\" or \"(Nothing),\" and so on.</P>\r\n<P>The DOW displays meaningful text for a null value.</P>\r\n<H3 class=dtH1>Command Parameters</H3>\r\n<P>Supplying command parameter values should not be an afterthought in the \r\ndesign process. Most commands in serious applications have parameters. These \r\nvalues need to be provided to the commands before they can be executed.</P>\r\n<P>The DOW creates a data Class Property for each Parameter of each DOW Select \r\nand Lookup command. These Properties can either be set on the Property Sheet of \r\nthe DOW User Control at design time or manually by code at run time.</P>\r\n<H2 class=dtH1><A name=dowwp_commands></A>DOW Commands</H2>\r\n<P>Before you use the DOW, you need to use the DED to create one Select command, \r\nthe main data source. Then, depending on your application requirements, you will \r\ncreate Lookup commands and Insert, Update, and Delete commands.</P>\r\n<H3 class=dtH1>One Select Command</H3>\r\n<P>You must have one Select command. The Select command returns the basic data \r\nyou want to access. Many applications will require that the Select command have \r\nParameters. The Select command will also need to have one or more fields as its \r\nPrimary Key.</P>\r\n<H3 class=dtH1>Zero or More Lookup Commands</H3>\r\n<P>If your Select command has fields whose values are obtained from a finite set \r\n(domain), then you can create a Lookup command that will retrieve this set. Data \r\nfrom this Lookup command will then be displayed in a DOW User Control's ComboBox \r\nso that the user can only choose valid values.</P>\r\n<BLOCKQUOTE class=dtBlock><B>Note </B>The Lookup command \r\ndisplay field must be of String data type, since it will be displayed as text in \r\nComboBoxes and the Lookup column in a DataGrid.</BLOCKQUOTE>\r\n<P>The DOW maps <B>Lookup Fields</B> in the Select command <B>to Primary Key \r\nfields</B> in the Lookup command(s).</P>\r\n<H3 class=dtH1>Zero or One Insert Command</H3>\r\n<P>If you want to be able to add records to the set defined by the Select \r\ncommand, create an Insert command. The Insert command must have Parameters for \r\neach Not Null field defined by the Select command.</P>\r\n<P>The DOW maps <B>Fields</B> in the Select command to <B>Parameters</B> in the \r\nInsert command.</P>\r\n<P>If the Primary Key value(s) are system-generated by the Insert command and \r\nthe Insert command returns these values through input/output Parameter(s), the \r\ndata Class generated by the DOW will store these values and associate them with \r\nthe newly Inserted record. Updates and Deletes can then be immediately performed \r\nusing these values.</P>\r\n<H3 class=dtH1>Zero or One Update Command</H3>\r\n<P>If you want to be able to Edit records, create an Update command.</P>\r\n<P>The DOW maps <B>Fields</B> in the Select command to <B>Parameters</B> in the \r\nUpdate command.</P>\r\n<P>The DOW allows you to use the same command for Insert and Update if that \r\ncommand provides for both functionalities.</P>\r\n<H3 class=dtH1>Zero or One Delete Command</H3>\r\n<P>If you want to be able to Delete records, create a Delete command.</P>\r\n<P>The DOW maps<B> Primary Key Fields</B> in the Select command to \r\n<B>Parameters</B> in the Delete command.</P>\r\n<H2 class=dtH1><A name=dowwp_ded></A>The DataEnvironment Designer</H2>\r\n<P>Before you can use the DOW, you must have created commands with the \r\nDataEnvironment Designer (DED).</P>\r\n<P>Your VB project can have only one DataEnvironment Designer.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp1.gif\" border=0 ></P>\r\n<P class=label><B>Figure 1. DataEnvironment Designer</B></P>\r\n<H2 class=dtH1><A name=dowwp_createdataclass></A>Creating a Data Class</H2>\r\n<H3 class=dtH1>Select Data Environment Command</H3>\r\n<P>The DOW reads your DED and displays all of its commands.</P>\r\n<P>Choose the DED command that will be your primary source of data. This is the \r\nDOW \"Select\" command.</P>\r\n<P>This command must have Primary Key field(s) included as well as all Not Null \r\nfields if you want to perform Inserts and Updates.</P>\r\n<P class=normal>This command must have Primary Key fields(s) included if you \r\nwant to perform Deletes.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp2.gif\" border=0 ></P>\r\n<P class=label><B>Figure 2. Select Data Environment command</B></P>\r\n<H3 class=dtH1>Define Class Field Information</H3>\r\n<P>Since it is not always possible to get field nullability and Primary Key \r\ninformation from all types of commands, that is, stored procedures, the user \r\nmust supply this information.</P>\r\n<P>If a field is a Primary Key, it is not necessarily a Not Null field from the \r\nDOW's perspective. An example of this is a Select command that provides \r\nsystem-generated Primary Key values through input/output parameter(s). In this \r\ncase, set the \"Nullable?\" column to \"Yes\" so that the DOW will not require a \r\nvalue be entered in this field for Inserts and Updates.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp3.gif\" border=0 ></P>\r\n<P class=label><B>Figure 3. Define class field information</B></P>\r\n<H3 class=dtH1>Define Lookup Table Information</H3>\r\n<P>This step defines Lookup relationships for the Select command.</P>\r\n<P>Each relationship has one or more (Foreign Key) fields in the Select command. \r\nThese fields need to be mapped to the Lookup command's Primary Key fields.</P>\r\n<P>For example, in the <A target=_self href=\"#dowwp_erd\">sample entity \r\nrelationship diagram (ERD)</A> in the <A target=_self \r\nhref=\"#dowwp_appendix\">appendix</A>, there are three Lookup relationships: \r\n<UL type=disc>\r\n<LI>Person CountyID and StateCode map to County CountyID and StateCode, \r\nrespectively. \r\n<LI>Person CompanyCarID maps to CompanyCar CompanyCarID. \r\n<LI>Person ManagerID maps to Person PersonID. </LI></UL>\r\n<P>For each relationship, choose a Source (Select) field, Lookup command, Lookup \r\nfield to display, and the Primary Key fields in the Lookup command that will be \r\nmapped in the next step.</P>\r\n<P>After all information has been entered for the relationship, press the \"Add\" \r\nbutton to include the relationship in the \"Selected lookup commands.\"</P>\r\n<P>The screen below shows the relationship information entered for the first \r\nrelationship:</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp4.gif\" border=0 ></P>\r\n<P class=label><B>Figure 4. Define the first Lookup relationship</B></P>\r\n<P>Information for the second relationship:</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp5.gif\" border=0 ></P>\r\n<P class=label><B>Figure 5. Define the second Lookup relationship</B></P>\r\n<P>Information for the third relationship:</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp6.gif\" border=0 ></P>\r\n<P class=label><B>Figure 6. Define the third Lookup relationship</B></P>\r\n<H3 class=dtH1>Map Lookup Fields</H3>\r\n<P>Since there can be more than one field in each Lookup relationship, there is \r\na \"Map Lookup Fields\" screen for each relationship.</P>\r\n<P>The DOW makes an attempt to match Select command field names with Lookup \r\ncommand field names, displaying these matches in a grid. If the mapping is \r\nincorrect or other mapping rows need to be added, click the appropriate cell and \r\nchoose the correct Select field name from the \"Source Command Fields\" ComboBox \r\nand the correct Lookup field name from the \"Lookup Command Fields\" ComboBox.</P>\r\n<P>If a mapping row exists that should not be there, choose \"(None)\" from the \r\nComboBox for both the Select and Lookup field names.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp7.gif\" border=0 ></P>\r\n<P class=label><B>Figure 7. Map Lookup Fields</B></P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp8.gif\" border=0 ></P>\r\n<P class=label><B>Figure 8. Map Lookup Fields</B></P>\r\n<P>The default mapping for the third relationship is not correct and needs to be \r\nmodified:</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp9.gif\" border=0 ></P>\r\n<P class=label><B>Figure 9. Incorrect Lookup mapping</B></P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp10.gif\" border=0 ></P>\r\n<P class=label><B>Figure 10. Correcting Lookup mapping</B></P>\r\n<H3 class=dtH1>Define and Map Insert Data Command</H3>\r\n<P>If you want to be able to add records to your data source, you will need to \r\nspecify the DED Insert command and mapping between the DOW Select Command \r\n<B>fields</B> and the DED Insert command <B>parameters</B>. The DOW attempts to \r\ndo this for you, mapping fields to parameters with the same names.</P>\r\n<P>This screen is functionally similar to the \"Map Lookup Fields\" screen. If the \r\ndefault mapping is not correct, you can change it by clicking on the incorrect \r\ncell and selecting the correct values from the ComboBoxes.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp11.gif\" border=0 ></P>\r\n<P class=label><B>Figure 11. Define and Map Insert Data Command</B></P>\r\n<H3 class=dtH1>Define and Map Update Data Command</H3>\r\n<P class=normal>This is similar to the \"Map Insert Data Command\" screen, except \r\nthat if you are using the same command, you can just check \"Use Insert command \r\nfor Update.\"</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp12.gif\" border=0 ></P>\r\n<P class=label><B>Figure 12. Define and Map Update Data Command</B></P>\r\n<P class=normal>If you want to be able to delete records from your data source, \r\nyou will need to specify the DED Delete command and mapping between the DOW \r\nSelect Command <B>fields</B> and the DED Delete command <B>parameters</B>. The \r\nDOW attempts to do this for you, mapping fields to parameters with the same \r\nnames.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp13.gif\" border=0 ></P>\r\n<P class=label><B>Figure 13. Define and Map Delete Data Command</B></P>\r\n<P>Complete the process by choosing a name for your DOW data Class. The DOW will \r\nnotify you if the Class already exists, in which case you can choose a new name \r\nor overwrite the existing Class.</P>\r\n<BLOCKQUOTE class=dtBlock><B>Warning </B>You will lose any \r\nunsaved work on an existing Class if you choose to overwrite it. </BLOCKQUOTE>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp14.gif\" border=0 ></P>\r\n<P class=label><B>Figure 14. Naming the data Class</B></P>\r\n<H2 class=dtH1><A name=dowwp_databoundctrls></A>Creating Data-Bound User \r\nControls</H2>\r\n<P>To display and manipulate data in a DOW data Class, you can generate a \r\nDataGrid, Single Record, ComboBox, or ListBox User Control. Select command \r\nlookup fields are replaced with a ComboBox displaying the Lookup \"display\" \r\nfield.</P>\r\n<P>A DOW DataGrid User Control displays several rows of data in grid format.</P>\r\n<P>A Single Record User Control displays one row of data in TextBoxes, \r\nComboBoxes, and CheckBoxes, depending on the data type.</P>\r\n<P>Combo/ListBox User Controls display data in either a ComboBox or ListBox, \r\nrespectively.</P>\r\n<P>A DOW-generated DataGrid User Control:</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp15.gif\" border=0 ></P>\r\n<P class=label><B>Figure 15. DataGrid User Control</B></P>\r\n<P>A DOW-generated Single Record User Control:</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp16.gif\" border=0 ></P>\r\n<P class=label><B>Figure 16. Single Record User Control</B></P>\r\n<P>A DOW-generated ComboBox User Control:</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp17.gif\" border=0 ></P>\r\n<P class=label><B>Figure 17. ComboBox User Control</B></P>\r\n<P>A DOW-generated ListBox User Control:</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp18.gif\" border=0 ></P>\r\n<P class=label><B>Figure 18. ListBox User Control</B></P>\r\n<H3 class=dtH1>DataGrid</H3>\r\n<H4 class=dtH1>Select the data Class to use</H4>\r\n<P>Choose a DOW-created data Class as a source of data for your DataGrid. This \r\nscreen only shows Classes created by the DOW.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp19.gif\" border=0 ></P>\r\n<P class=label><B>Figure 19. Select data Class</B></P>\r\n<H4 class=dtH1>Select User Control type</H4>\r\n<P>Select the type of User control you would like to create, in this case a \r\nDataGrid.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp20.gif\" border=0 ></P>\r\n<P class=label><B>Figure 20. Select User Control type</B></P>\r\n<H4 class=dtH1>Map Class Properties to a Control type</H4>\r\n<P>You can now choose the type of control to display data for each field: \r\n<UL type=disc>\r\n<LI>(None)?aDon't show the field in the User Control. \r\n<LI>ComboBox?aIf the field is a Lookup field in the Select command, you may \r\nchoose to show the \"display\" field of the Lookup command in this field, instead \r\nof the actual Lookup fields. In the example below, even though \"StateCode\" and \r\n\"CountyID\" are listed, they will not be shown in the DataGrid. Instead, they \r\nwill be replaced by \"CountyDescr\" from the GetCounty command, which will be \r\nshown in a ComboBox when the user clicks on a DataGrid cell in that column. \r\n<LI>TextBox?aThis shows the value of the field as it exists in the Select command \r\nfield. </LI></UL>\r\n<P class=normal>If the field is a Primary Key, the DOW defaults to \"(None),\" \r\nassuming that in most applications, Primary Key values are system generated and \r\nnot supplied by the user. If the field is a Lookup field, a ComboBox is shown by \r\ndefault. ComboBoxes are only intended for Lookup fields and are therefore \r\nignored if the field is a non-Lookup field, in which case a TextBox is \r\ndisplayed.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp21.gif\" border=0 ></P>\r\n<P class=label><B>Figure 21. Map Class Properties to a Control type</B></P>\r\n<H4 class=dtH1>Enter User Control name</H4>\r\n<P>Complete the process by choosing a name for your DataGrid User Control. The \r\nDOW will notify you if the User Control already exists, in which case you can \r\nchoose a new name or overwrite the existing User Control.</P>\r\n<BLOCKQUOTE class=dtBlock><B>Warning </B>You will lose any \r\nunsaved work on an existing User Control if you choose to overwrite it. \r\n</BLOCKQUOTE>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp22.gif\" border=0 ></P>\r\n<P class=label><B>Figure 22. Enter User Control Name</B></P>\r\n<H3 class=dtH1>Single Record</H3>\r\n<P>The Single Record User Control generation is the same as the DataGrid User \r\nControl.</P>\r\n<H3 class=dtH1>Combo/ListBox</H3>\r\n<P>The Combo/ListBox User Controls are generated in the same way as the DataGrid \r\nUser Control, except that all Lookup , Insert, Update, and Delete command \r\ninformation in the data Class is ignored, since Lookup and data manipulation \r\noperations do not apply to these two User Controls.</P>\r\n<P>The field displayed in the Combo/ListBox controls is the first field in the \r\nSelect command that is displayed with a TextBox. If you would like to have \r\nanother field displayed in the ComboBox, see the comments in the \"Public \r\nFunction Init?\" in the generated Combo/ListBox code.</P>\r\n<H2 class=dtH1><A name=dowwp_usingdowobjects></A>Using DOW Objects in an \r\nApplication</H2>\r\n<H3 class=dtH1>DataEnvironment Commands</H3>\r\n<P>The Select command must have a Primary Key field if Update and Delete \r\noperations are to be performed with DOW generated objects.</P>\r\n<P>Lookup commands typically consist of one or more Primary Key fields and a \r\nDescription field. The Lookup command can be based on a single table or it might \r\nbe a join of several parent tables, with the Description field being \r\nconcatenated from description fields in the parent tables.</P>\r\n<BLOCKQUOTE class=dtBlock><B>Note </B>The Description field \r\nmust be of String data type.</BLOCKQUOTE>\r\n<P>There must be one Lookup (Foreign Key) field in the Select command for each \r\nPrimary Key field in the Lookup command. These field names do not need to be the \r\nsame, the DOW FK Mapping screens will allow you to map fields that have \r\ndifferent names.</P>\r\n<P>If the system is generating Primary Key values for Inserted records, create \r\nInput/Output command parameters for these Primary Keys. Have the Insert command \r\nset these parameters with the system generated values. The DOW data Class will \r\nretrieve these values so that immediate Updates and Inserts can be performed on \r\nnewly Inserted records.</P>\r\n<H3 class=dtH1>Data Class</H3>\r\n<H4 class=dtH1>Events</H4>\r\n<P>Certain methods raise the ClassError event. The DataGrid and Single Record \r\nUser Controls both sink this event and display the error description from this \r\nevent.</P>\r\n<P>Event rsMoveComplete is useful in a DataGrid/SingleRecord Master/Detail \r\nscenario. When the user changes record focus in the DataGrid, the SingleRecord \r\ncan refresh its data based on that record by sinking this event.</P>\r\n<P>DeleteRecordComplete notifies the User Control that the record has been \r\nsuccessfully completed.</P>\r\n<P>rsUpdateEvent fires when the method rsUpdate is complete.</P>\r\n<H4 class=dtH1>Data binding</H4>\r\n<P>There are two kinds of data binding?asimple bound and complex bound.</P>\r\n<P>Simple binding can be applied to controls that are not \"binding aware.\" \r\nSimple binding requires the BindingCollection object. Simple binding is really a \r\n\"property setter\"?ait sets a property of another control to a value of a field in \r\na RecordSet. For example, you can set the Text Property of a TextBox to the \r\nvalue of a particular field in a RecordSet. The TextBoxes and CheckBoxes of the \r\nDOW SingleRecord User Control use simple binding.</P>\r\n<P>Complex binding refers to data controls that are \"binding aware.\" These \r\ncontrols have functionality similar to the BindingCollection built into the \r\ncontrol. The DOW DataGrid is \"complex\" bound to the Select RecordSet in the data \r\nClass.</P>\r\n<H4 class=dtH1>RecordSets</H4>\r\n<P>Lookup command \"display\" fields do not exist in the Select command. In order \r\nfor them to be shown in a bound DataGrid, these fields must be \"added\" to the \r\nSelect command RecordSet.</P>\r\n<P>Therefore, for any Select command that has Lookup relationships, a new \r\nRecordSet is created that includes a Lookup \"display\" field for each \r\nrelationship. Select commands without Lookup relationships use the DED Select \r\ncommand directly.</P>\r\n<P>The Select RecordSet is disconnected from its data source either because it \r\nis a locally created RecordSet or the DED Select command DataSource is set to \r\nNothing. This allows substituting other DED commands for Update, Insert and \r\nDelete operations.</P>\r\n<H4 class=dtH1>Methods</H4>\r\n<P>The Init? methods return the data Class object and have an optional parameter \r\nwhich is a data Class object. Therefore, the same instance of the data Class can \r\nbe used by more than one User Control. An example of this is a Master Detail \r\nForm, where the Master could be a DataGrid which contains a few fields of a \r\nRecordSet. The Detail could be a SingleRecord User Control which contains all \r\nthe fields of the same RecordSet. In this case the DataGrid User Control would \r\ninstantiate the data Class (returned from the Init? method), then pass it as a \r\nparameter of the SingleRecord Init method).</P>\r\n<H4 class=dtH1>System-generated Primary Key values</H4>\r\n<P>If your Insert command generates Primary Key values from the system and this \r\ncommand has parameters for each of these Primary Keys, then these values are \r\nreturned to the data Class. This allows immediate Updates or Deletes following \r\nan Insert.</P>\r\n<P>In this case, set the \"nullability\" of the Primary Key fields to \"Yes,\" so \r\nthat the DOW generated data class does not require value(s) for Primary Key \r\nfields.</P>\r\n<H3 class=dtH1>User Controls</H3>\r\n<H4 class=dtH1>Auto Initializing</H4>\r\n<P>Auto Initializing allows the generated User Controls to run and be filled \r\nwith data by only (1) placing the User Control on a Form and (2) setting its \r\nSelect command parameter Properties.</P>\r\n<P>By default, the Property ManualInitialize is False. If the Select command \r\nparameter Properties on the Property Sheet (for the User Control on the Form) \r\nhave been specified, the User Control will load with data upon \r\ninitialization.</P>\r\n<P>If the parameter Property values are missing or of the wrong data type, and \r\nso on, the Form will load but the User Control will have no data.</P>\r\n<H4 class=dtH1>Manual Initializing</H4>\r\n<P>ManualInitialize = True is the normal mode of initialization in most \r\napplications.</P>\r\n<P>If ManualInitialize = True, then the values for the parameter Properties are \r\nset in Code, usually in the form that contains the User Control. The Init? \r\nmethod is run (generally from the Form) to Initialize the User Control and load \r\ndata.</P>\r\n<P>If ManualInitialize = False, then parameter Property values are read from the \r\nProperty Sheet for the User Control.</P>\r\n<H2 class=dtH1><A name=dowwp_appendix></A>Appendix</H2>\r\n<H3 class=dtH1>Class</H3>\r\n<H4 class=dtH1>Properties</H4>\r\n<P><B>Select Command Field Properties:</B> For each field in the Select command, \r\nthere are corresponding Property Lets and Gets that allow reading and writing to \r\nthe current Select command record. These properties have the same name as the \r\nfield in the Select command.</P>\r\n<P><B>Select Command Parameter Properties:</B> For each parameter in the Select \r\ncommand, there are corresponding Properties that allow setting the Select \r\ncommand parameter values. These Properties have names that are concatenations of \r\nthe Select command name and the Select parameter name.</P>\r\n<P><B>Lookup Commands Parameter Properties:</B> For each parameter in each \r\nLookup command, there are corresponding Properties that allow setting the Lookup \r\ncommand parameter values. These Properties have names that are concatenations of \r\nthe Lookup command name and the Lookup parameter name.</P>\r\n<P><B>Lookup Commands RecordSet Properties:</B> For each Lookup command, there \r\nis a corresponding Public RecordSet Property. These RecordSets are named with \r\nthe Lookup command name preceded by \"rs.\"</P>\r\n<P><B>AbsolutePosition As Long:</B> Returns the Select \r\nRecordSet.AbsolutePosition.</P>\r\n<P><B>BOF As Boolean:</B> Returns the Select RecordSet.BOF value.</P>\r\n<P><B>EOF As Boolean:</B> Returns the Select RecordSet.EOF value.</P>\r\n<P><B>SaveMode As EnumSaveMode:</B> \r\n<UL type=disc>\r\n<LI><B>AdImmediate</B>?aSets LockType to Optimistic. Automatically saves when \r\nmoving to a new current record in the RecordSet. \r\n<LI><B>AdBatch</B>?aSets LockType to BatchOptimistic. Saves current record \r\nmanually with \"Update\" method. Saves all dirty records manually with \r\n\"UpdateBatch\" method. </LI></UL>\r\n<H4 class=dtH1>Methods</H4>\r\n<P><B>Sub AddRecord():</B> Adds a blank record to the Select RecordSet.</P>\r\n<P><B>Sub Delete():</B> Deletes the current Select RecordSet record and runs the \r\nDED Delete command.</P>\r\n<P><B>Sub Move(lRows As Long):</B> The record lRows from the current Select \r\nrecord becomes the current record.</P>\r\n<P><B>Sub MoveFirst():</B> The first record in the Select RecordSet becomes the \r\ncurrent record.</P>\r\n<P><B>Sub MoveLast():</B> The last record in the Select RecordSet becomes the \r\ncurrent record.</P>\r\n<P><B>Sub MoveNext():</B> The next record in the Select RecordSet becomes the \r\ncurrent record.</P>\r\n<P><B>Sub MovePrevious():</B> The previous record in the Select RecordSet \r\nbecomes the current record.</P>\r\n<P><B>Function MoveToPk(Value1,?,ValueN) As Boolean:</B> Moves to the record in \r\nthe Select RecordSet having the Primary Key values Value1,?,ValueN.</P>\r\n<P><B>Sub rsUpdate(vFieldName):</B> Updates field vFieldName with the correct \r\n\"display\" Lookup command field value for the Select command Lookup fields.</P>\r\n<P><B>Sub Update():</B> Saves the all dirty records (SaveMode = adBatch), \r\nrunning the DED Update command.</P>\r\n<P><B>Sub UpdateBatch():</B> Saves the current record (SaveMode = adBatch), \r\nrunning the DED update command.</P>\r\n<P><B>Function ValidateData() As Boolean:</B> Validates the data values in the \r\ncurrent Record.</P>\r\n<H4 class=dtH1>Events</H4>\r\n<P><B>ClassError(sProcedureName As String, oErr As ErrObject):</B> Occurs for \r\ncertain application errors. Returns the Procedure name, sProcedureName, and the \r\nErr object.</P>\r\n<P><B>DeleteRecordComplete():</B> Occurs after a record has been deleted from \r\nthe Select RecordSet.</P>\r\n<P><B>rsMoveComplete():</B> Occurs after the Select RecordSet has completed a \r\nmove to a new current record.</P>\r\n<P><B>rsUpdateEvent(vFieldName):</B> Occurs after the Lookup display fields have \r\nbeen updated for field vFieldName.</P>\r\n<H3 class=dtH1>User Controls: DataGrid</H3>\r\n<H4 class=dtH1>Properties</H4>\r\n<P><B>Select Command Parameter Properties:</B> For each parameter in the Select \r\ncommand, there are corresponding Properties that allow setting the data Class \r\nSelect command parameter values. These Properties have names that are \r\nconcatenations of the Select command name and the Select parameter name.</P>\r\n<P><B>Lookup Commands Parameter Properties:</B> For each parameter in each \r\nLookup command, there are corresponding Properties that allow setting the data \r\nClass Lookup command parameter values. These Properties have names that are \r\nconcatenations of the Lookup command name and the Lookup parameter name.</P>\r\n<P><B>GridEditable As Boolean:</B> Set to True to enable data modifications to \r\nthe DataGrid and enabling the Lookup command ComboBoxes on the Lookup \"display\" \r\nfields.</P>\r\n<P><B>ManualInitialize As Boolean:</B> Set to False to enable filling the \r\nDataGrid with data when the User Control is initialized. This allows the control \r\nto be fully operational after the DataGrid User Control is (1) generated, (2) \r\nany Command property parameter values are entered on the Property Sheet, and (3) \r\nthe User Control is placed on a Form.</P>\r\n<P>When set to True, parameter values are not read from the PropertySheet. \r\nSelect and Lookup command parameter property values are set from code in the \r\nForm containing the User Control.</P>\r\n<P><B>SaveMode As EnumSaveMode:</B> \r\n<UL type=disc>\r\n<LI><B>AdImmediate</B>?aSets data Class LockType to Optimistic. Automatically \r\nsaves when moving to a new current record in the RecordSet. \r\n<LI><B>AdBatch</B>?aSets data Class LockType to BatchOptimistic. Saves current \r\nrecord manually with \"Update\" method. Saves all dirty records manually with \r\n\"UpdateBatch\" method. </LI></UL>\r\n<H4 class=dtH1>Methods</H4>\r\n<P><B>Function(s) UpdateFK{FKCommand}(nSurrogateKey As Integer):</B> For each \r\nLookup command, sets the Lookup fields for the current {FKCommand} record to the \r\nLookup RecordSet record fields having a Surrogate Key of nSurrogateKey.</P>\r\n<P><B>Function Init({DataClass}) As Object:</B> Initializes the DataGrid by \r\nsetting command parameters, setting the DataSource of the DataGrid to the data \r\nClass, setting data updatability according to GridEditable, hiding Lookup \r\nfields, and so on.</P>\r\n<P>DataClass is an optional parameter. If passed, this instance of the data \r\nClass is used as the DataGrid DataSource. Otherwise, a new instance of the data \r\nClass is created.</P>\r\n<P>The Object returned is the data Class used as the DataGrid DataSource.</P>\r\n<P><B>Update():</B> Runs data Class method, Update, saving the all dirty records \r\n(SaveMode = adBatch), using the DED Update command.</P>\r\n<P><B>UpdateBatch():</B> Runs \r\n the data Class method, UpdateBatch, Saving the current record (SaveMode = \r\n adBatch), using the DED update command.</P>\r\n<H4 class=dtH1>Events</H4>\r\n<P><B>MoveComplete(oDataSource As Object):</B> Sinks the data Class \r\nrsMove_Complete event. Returns the DataSource data Class.</P>\r\n<H3 class=dtH1>User Controls: Single Record</H3>\r\n<H4 class=dtH1>Properties</H4>\r\n<P><B>Select Command Parameter Properties:</B> For each parameter in the Select \r\ncommand, there are corresponding Properties that allow setting the data Class \r\nSelect command parameter values. These Properties have names that are \r\nconcatenations of the Select command name and the Select parameter name.</P>\r\n<P><B>Lookup Commands Parameter Properties:</B> For each parameter in each \r\nLookup command, there are corresponding Properties that allow setting the data \r\nClass Lookup command parameter values. These Properties have names that are \r\nconcatenations of the Lookup command name and the Lookup parameter name.</P>\r\n<P><B>ManualInitialize As Boolean:</B> Set to False to enable filling the \r\nSingleRecord User Control with data when the User Control is initialized. This \r\nallows the control to be fully operational after the SingleRecord User Control \r\nis (1) generated, (2) any Command parameter property values are entered on the \r\nProperty Sheet, and (3) the User Control is placed on a Form.</P>\r\n<P>When set to True, parameter values are not read from the PropertySheet. \r\nSelect and Lookup command parameter property values are set from code in the \r\nForm containing the User Control.</P>\r\n<P><B>SaveMode As EnumSaveMode:</B> \r\n<UL type=disc>\r\n<LI><B>AdImmediate</B>?aSets data Class LockType to Optimistic. Automatically \r\nsaves when moving to a new current record in the RecordSet. \r\n<LI><B>AdBatch</B>?aSets data Class LockType to BatchOptimistic. Saves current \r\nrecord manually with \"Update\" method. Saves all dirty records manually with \r\n\"UpdateBatch\" method. </LI></UL>\r\n<H4 class=dtH1>Methods</H4>\r\n<P><B>AddRecord():</B> Runs the data Class AddRecord method.</P>\r\n<P><B>Delete():</B> Runs the data Class Delete method.</P>\r\n<P><B>Function Init({DataClass}) As Object:</B> Initializes the SingleRecord \r\nUser Control by setting command parameters, setting the DataSource of the User \r\nControl to the data Class, hiding Lookup fields, and so on.</P>\r\n<P>DataClass is an optional parameter. If passed, this instance of the data \r\nClass is used as the User Control's DataSource. Otherwise, a new instance of the \r\ndata Class is created.</P>\r\n<P>The Object returned is the data Class used as the SingleRecord \r\nDataSource.</P>\r\n<P><B>Sub Move(lRows As Long):</B> Runs the data Class Move method?athe record \r\nlRows from the current Select record becomes the current record.</P>\r\n<P><B>Sub MoveFirst():</B> Runs the data Class MoveFirst method?athe first record \r\nin the Select RecordSet becomes the current record.</P>\r\n<P><B>Sub MoveLast():</B> Runs the data Class MoveLast method?athe last record in \r\nthe Select RecordSet becomes the current record.</P>\r\n<P><B>Sub MoveNext():</B> Runs the data Class MoveNext method?athe next record in \r\nthe Select RecordSet becomes the current record.</P>\r\n<P><B>Sub MovePrevious():</B> Runs the data Class MovePrevious method?athe \r\nprevious record in the Select RecordSet becomes the current record.</P>\r\n<P><B>Function MoveToPk(Value1,?,ValueN) As Boolean:</B> Runs the data Class \r\nMoveToPk method?amoves to the record in the Select RecordSet having the Primary \r\nKey values Value1,?,ValueN.</P>\r\n<P><B>Update():</B> Runs data Class method, Update, saving the all dirty records \r\n(SaveMode = adBatch) using the DED Update command.</P>\r\n<P><B>UpdateBatch():</B> Runs \r\n the data Class method, UpdateBatch, saving the current record (SaveMode = \r\n adBatch) using the DED update command.</P>\r\n<H4 class=dtH1>Events</H4>\r\n<P><B>MoveComplete(oDataSource As Object):</B> Sinks the data Class \r\nrsMove_Complete event. Returns the SingleRecord data Class.</P>\r\n<H3 class=dtH1>User Controls: Combo/ListBox</H3>\r\n<H4 class=dtH1>Properties</H4>\r\n<P><B>Select Command Parameter Properties:</B> For each parameter in the Select \r\ncommand, there are corresponding Properties that allow setting the data Class \r\nSelect command parameter values. These Properties have names that are \r\nconcatenations of the Select command name and the Select parameter name.</P>\r\n<P><B>ManualInitialize As Boolean:</B> Set to False to enable filling the \r\nCombo/ListBox User Control with data when the User Control is initialized. This \r\nallows the control to be fully operational after the Combo/ListBox User Control \r\nis (1) generated, (2) any Command parameter property values are entered on the \r\nProperty Sheet, and (3) the User Control is placed on a Form.</P>\r\n<P>When set to True, parameter values are not read from the PropertySheet. \r\nSelect and Lookup command parameter property values are set from code in the \r\nForm containing the User Control.</P>\r\n<P><B>NoneFirst As Boolean:</B> If true, loads \"(None)\" in the first row of the \r\nCombo/ListBox. This is used in relationships that allow nulls in the Foreign Key \r\nside of the relationship.</P>\r\n<H4 class=dtH1>Methods</H4>\r\n<P><B>Function Init({DataClass}) As Object:</B> Initializes the Combo/ListBox \r\nUser Control by setting command parameters, setting the DataSource of the User \r\nControl to the data Class, and so on.</P>\r\n<P>DataClass is an optional parameter. If passed, this instance of the data \r\nClass is used as the User Control's DataSource. Otherwise, a new instance of the \r\ndata Class is created.</P>\r\n<P>The Object returned is the data Class used as the Combo/ListBox \r\nDataSource.</P>\r\n<P><B>Events</B></P>\r\n<P>Combo/ListBoxClick(PKVal1,?,PKValN)</P>\r\n<P>Occurs when a user clicks on a Combo/ListBox row. This event supplies Primary \r\nKey values for the record, PKVal1 through PkValN.</P>\r\n<H3 class=dtH1>clsDow</H3>\r\n<P>When a DOW data Class is generated, if the class clsDow is not in the VB \r\nProject, it is added. clsDow contains the definition for EnumSaveMode.</P>\r\n<H3 class=dtH1>Typical Example</H3>\r\n<H4 class=dtH1><A name=dowwp_erd></A>A Sample Entity Relationship Diagram \r\n(ERD)</H4>\r\n<P>Below is a sample ERD that illustrates building a DOW data Class and User \r\nControls.</P>\r\n<P class=fig><IMG alt=\"\" src=\"./images/dowwp23.gif\" border=0 ></P>\r\n<P class=label><B>Figure 23. Entity Relationship Diagram</B></P>\r\n<H4 class=dtH1>Sample Command Stored Procedures</H4>\r\n<P>GetPerson (Select Command):</P><PRE class=code>create procedure GetPerson5\r\n @PersonID int=0\r\nas\r\nselect p.PersonID,p.FirstName,p.LastName,p.StateCode,p.CountyID,\r\n p.CompanyCarID,\r\n p.HireDate,p.ManagerID,p.Salary,p.LaborClassCode,MailCheck,Comment\r\nfrom Person p\r\nwhere p.PersonID>@PersonID\r\norder by p.LastName,p.FirstName\r\n</PRE>\r\n<P>GetCounty (Lookup Command):</P><PRE class=code>create procedure GetCounty5\r\n @StateCode char(2)=\" \",@CountyID int=0\r\nas\r\n select c.StateCode,c.CountyID,s.Descr+' '+c.Descr CountyDescr\r\n from County c,State s\r\n where c.StateCode=s.StateCode\r\n and c.StateCode>@StateCode\r\n and c.CountyID>@CountyID\r\n order by CountyDescr\r\n</PRE>\r\n<P>GetCompanyCar (Lookup Command):</P><PRE class=code>create procedure GetCompanyCar5\r\n @CompanyCarID int=0\r\nas\r\n select CompanyCarID,Descr CompanyCarDescr\r\n from CompanyCar\r\n where CompanyCarID>@CompanyCarID\r\n order by CompanyCarDescr\r\n</PRE>\r\n<P>GetManager (Lookup Command):</P><PRE class=code>create procedure GetManager5\r\n @ManagerID int=0\r\nas\r\n select PersonID,FirstName+' '+LastName ManagerName\r\n from Person\r\n where PersonID>@ManagerID\r\n order by LastName,FirstName\r\n</PRE>\r\n<P>PutPerson (Insert, Update Command):</P><PRE class=code>create procedure PutPerson5\r\n @PersonID int out,\r\n @FirstName varchar(30),\r\n @LastName varchar(30),\r\n @StateCode char(2),\r\n @CountyID int,\r\n @CompanyCarID int,\r\n @HireDate datetime,\r\n @ManagerID int,\r\n @Salary money,\r\n @LaborClassCode decimal(3,3),\r\n @MailCheck bit=1,\r\n @Comment text\r\nas\r\n\r\nif not exists (select *\r\n from Person\r\n where PersonID=@PersonID)\r\n begin\r\n select @personID=isnull(max(personID),0)+1\r\n from Person\r\n\r\n /* insert Person */\r\n insert Person(PersonID,CompanyCarID,FirstName,LastName,CountyID,StateCode,\r\n HireDate,ManagerID,Salary,LaborClassCode,MailCheck,Comment)\r\n values(@PersonID,@CompanyCarID,@FirstName,@LastName,@CountyID,@StateCode,\r\n @HireDate,@ManagerID,@Salary,@LaborClassCode,@MailCheck,@Comment)\r\n\r\n /* Check if record saved successfully. If not, then return false. */\r\n if (select @@rowcount) <> 1\r\n return (-1)\r\n else\r\n return\r\n end\r\nelse\r\n begin\r\n /* update Person */\r\n update Person set\r\n CompanyCarID=@CompanyCarID,\r\n FirstName=@FirstName,\r\n LastName=@LastName,\r\n CountyID=@CountyID,\r\n StateCode=@StateCode,\r\n HireDate=@HireDate,\r\n ManagerID=@ManagerID,\r\n Salary=@Salary,\r\n LaborClassCode=@LaborClassCode,\r\n MailCheck=@MailCheck,\r\n Comment=@Comment\r\n where PersonID=@PersonID\r\n\r\n /* Check if record saved successfully> If not, then return false. */\r\n if (select @@rowcount) <> 1\r\n return (-1)\r\n else\r\n return\r\n end\r\n</PRE>\r\n<P>DeletePerson (Delete Command):</P><PRE class=code>create procedure DeletePerson5\r\n @PersonID int\r\nas\r\n delete Person\r\n where PersonID=@PersonID\r\n</PRE></TD></TR></TBODY></TABLE></BODY></html>\r\n"
"Content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><html><head><TITLE>Save Your Tips</TITLE><meta http-equiv=\"Content-Type\" content=\"text/html; charset=gb2312\">\r\n<META content=\"MSHTML 5.50.4134.100\" name=GENERATOR></head>\r\n<BODY><FONT face=\"MS Sans Serif\" color=#000000 size=3><B>Save Your Tips</B><FONT \r\nface=\"MS Sans Serif\" color=#000000 size=2> <BR></FONT><FONT face=Arial \r\ncolor=#000000 size=2><BR><B>You can easily save tips to your own database by : \r\n<BR><BR>A . Save the </B><FONT face=Arial color=#ff0000 size=2><B>whole page \r\n(include images)</B></FONT></FONT><FONT face=Arial color=#000000 size=2><B> from \r\nInternet Explorer . <BR></B>Just right click in IE to prompt menu ,then click \r\n\"<FONT face=Arial color=#0000ff size=2><B>Save to Sharp \r\nTips</B></FONT></FONT><FONT face=Arial color=#000000 size=2>\". Then this page \r\nwould be saved to your database, you must <FONT face=Arial color=#0000ff \r\nsize=2><B>refresh</B></FONT></FONT><FONT face=Arial color=#000000 size=2> the \r\nparent node in program Tips.exe so as to and view it. <BR><B><BR><IMG height=547 \r\nalt=savepaged.png src=\"./images/savepaged.png\" width=737 border=0 > <BR><BR>B . Save the \r\n</B><FONT face=Arial color=#ff0000 size=2><B>selection (include \r\nimages)</B></FONT></FONT><FONT face=Arial color=#000000 size=2><B> from Internet \r\nExplorer . <BR></B>Just select what you want in IE, Then right click to prompt \r\nmenu and click <B></B>\"<FONT face=Arial color=#0000ff size=2><B>Save \r\nSelection</B></FONT></FONT><FONT face=Arial color=#000000 size=2>\".<B> Remember \r\nto </B><FONT face=Arial color=#0000ff size=2><B>refresh</B></FONT></FONT><FONT \r\nface=Arial color=#000000 size=2><B> the parent node in tips.exe to view it. \r\n<BR><BR><IMG height=546 alt=saveselt.png src=\"./images/saveselt.png\" width=721 border=0 > \r\n<BR><BR><BR>C . Drag the file(s) upon to the \"Running Label\" from \"File \r\nExplorer\". <BR><IMG height=34 alt=dropwin.png src=\"./images/dropwin.png\" width=37 \r\nborder=0 > -- -- Just this,\"Running Label\" ,Appear in font of the desktop. \r\n<BR><BR></B>\r\n<P align=center><B><IMG height=160 alt=dragfile.png src=\"./images/dragfile.png\" width=421 \r\nborder=0 > <BR></B></P><B>D . Drag the text you selected to the \"Running Label\" . \r\n(Version 1.0) <BR>E . Paste from ClipBoard to the \"Running Label\" . <BR><IMG \r\nheight=200 alt=paste.png src=\"./images/paste.png\" width=560 border=0 > <BR><BR>F . Import \r\nfrom a file you specify in file explorer. <BR><BR><IMG height=253 \r\nalt=importfromfile.png src=\"./images/importfromfile.png\" width=617 border=0 > \r\n<BR><BR><BR></B></FONT></FONT></BODY></html>\r\n"