📄 ch09.htm
字号:
</TR>
</TABLE>
<BR>
<BR>
Here are some of the properties associated with a
<TT>TField</TT> object: <BR>
<BR>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103" ALIGN="LEFT"><TT>AsBoolean</TT></TD>
<TD ALIGN="LEFT">Conversion property, can be used to read or set the value of a field as a Boolean
value.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103" ALIGN="LEFT"><TT>AsDateTime</TT></TD>
<TD ALIGN="LEFT">Conversion property, can be used to read or set the value of a field as a date.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103" ALIGN="LEFT"><TT>AsFloat</TT></TD>
<TD ALIGN="LEFT">Conversion property, can be used to read or set the value of a field as <TT>Float</TT>.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103"
ALIGN="LEFT"><TT>AsString</TT></TD>
<TD ALIGN="LEFT">Conversion property, can be used to read or set the value of a field as a string.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103" ALIGN="LEFT"><TT>AsInteger</TT></TD>
<TD
ALIGN="LEFT">Conversion property, can be used to read or set the value of a field as an <TT>Integer</TT>.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103" ALIGN="LEFT"><TT>Calculated</TT></TD>
<TD ALIGN="LEFT">Read only Boolean property,
tells whether a field is calculated.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103" ALIGN="LEFT"><TT>DataSet</TT></TD>
<TD ALIGN="LEFT">Assign a dataset to a field, or read what dataset is associated with a field.</TD>
</TR>
<TR
ALIGN="LEFT" rowspan="1">
<TD WIDTH="103" ALIGN="LEFT"><TT>EditMask</TT></TD>
<TD ALIGN="LEFT">Define a mask limiting the valid characters used by a field.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103"
ALIGN="LEFT"><TT>Value</TT></TD>
<TD ALIGN="LEFT">The standard means for accessing the value of a field.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103" ALIGN="LEFT"><I>FieldName</I></TD>
<TD ALIGN="LEFT">The name of the underlying
field in the database.</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD WIDTH="103" ALIGN="LEFT"><TT>Visible</TT></TD>
<TD ALIGN="LEFT">Boolean property toggles whether or not a field is visible.</TD>
</TR>
</TABLE>
<BR>
<BR>
Most of the properties
and methods listed previously are discussed in the next few
pages of this book. For now you can just review the functionality previously outlined
in a general way, so that you can get some sense of what the <TT>TField</TT> class
is about. Remember,
the previous list is far from exhaustive. It is meant merely
to introduce some of the key features of the object.</P>
<P>The <TT>TField</TT> object also has a number of useful descendant classes with
names such as <TT>TStringField</TT> and
<TT>TIntegerField</TT>. These child objects
are discussed in Chapter 17, "Printing: QuickReport and Related Technologies."</P>
<P>The <TT>FieldCount</TT> property returns an integer that specifies the number
of fields in the current record
structure. If you wanted a programmatic way to read
the names of these fields, you could use the <TT>Fields</TT> property:</P>
<PRE><FONT COLOR="#0066FF">{
AnsiString S(Table->Fields[0]->FieldName);
}
</FONT></PRE>
<P>If a record had a
first field called <TT>CustNo</TT>, the preceding code would
put the string <TT>"CustNo"</TT> in the variable <TT>S</TT>. If you wanted
to access the name of the second field in the example, you could write this:</P>
<PRE><FONT
COLOR="#0066FF">S = Table->Fields[1]->FieldName;
</FONT></PRE>
<P>In short, the index passed to <TT>Fields</TT> is zero-based, and it specifies
the number of the field you want to access, where the first field is number zero,
the second is
referenced by the number one, and so on.</P>
<P>If you want to find out the current contents of a particular field from a particular
record, you can use the <TT>Fields</TT> or <TT>FieldByName</TT> property, or you
could access the entire table as an
array of fields. To find the value of the first
field of a record, index into the first element of the <TT>Fields</TT> array:</P>
<PRE><FONT COLOR="#0066FF">S = Table->Fields[0]->AsString;
</FONT></PRE>
<P>Assuming that the first field in a
record contains a customer number, the code
shown would return a string such as `<TT>1021</TT>', `<TT>1031</TT>', or `<TT>2058</TT>'.
If you wanted to access this variable as an integer value, you could use <TT>AsInteger</TT>
in place of
<TT>AsString</TT>. Similar properties of <TT>Fields</TT> include <TT>AsBoolean</TT>,
<TT>AsFloat</TT>, and <TT>AsDate</TT>.</P>
<P>If you want, you can use the <TT>FieldByName</TT> function instead of the <TT>Fields</TT>
property:</P>
<PRE><FONT
COLOR="#0066FF">S = Table->FieldByName("CustNo")->AsString;
</FONT></PRE>
<P>As used in the examples shown here, both <TT>FieldByName</TT> and <TT>Fields</TT>
return the same data. The two different syntaxes are used solely to provide
programmers
with a flexible and convenient set of tools for programmatically accessing the contents
of a dataset. When in doubt, use <TT>FieldByName</TT> because it won't be affected
if you change the order of the fields in your table.
<DL>
<DT></DT>
</DL>
<BLOCKQUOTE>
<P>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B>I'll add a note here for Delphi
programmers who may be a bit confused by the tack I am taking on this subject. In
Delphi, you can also treat <TT>TTable</TT>
as a variant array, which will let you
access the fields of a table with the following syntax:
</BLOCKQUOTE>
<PRE></PRE>
<BLOCKQUOTE>
<PRE><FONT COLOR="#0066FF">S := Table1[`CustNo'];</FONT></PRE>
<P>This is obviously a considerable improvement
over the <TT>FieldByName</TT> method.
However, this syntax is not supported in BCB.
<HR>
</BLOCKQUOTE>
<P>It might be helpful to take a few moments to discuss a set of routines from the
FieldObject program found on the disk that accompanies this
book. These routines
illustrate the most common ways to access the value of a field.</P>
<P>The <TT>vValueClick</TT> routine shows the default means for setting or getting
the value of a field:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall
TForm1::bValueClick(TObject *Sender)
{
ShowMessage(tblOrders->FieldByName("TaxRate")->Value);
}
</FONT></PRE>
<P>This is the standard way to get at a field. You use the <TT>AsString</TT> or <TT>AsInteger</TT>
properties for
conversion, but when you just want to get at the type of a field,
you can use the <TT>Value</TT> property. However, the issue of conversion can sometimes
raise its head at strange moments, so it is helpful to note that properties such
as
<TT>AsInteger</TT> and <TT>AsString</TT> exist.</P>
<P>In the <TT>TField</TT> object, the <TT>Value</TT> property is declared as being
of type <TT>Variant</TT>, which means it will handle most type conversions for you
automatically. This is
illustrated in the previous example, where the <TT>TaxRate</TT>
field, which is of type <TT>Float</TT>, is converted for you automatically to a string.
Note, however, that descendants of <TT>TField</TT>, such as <TT>TStringField</TT>,
may explicitly
declare the <TT>Value</TT> field as an <TT>AnsiString</TT>:</P>
<PRE><FONT COLOR="#0066FF">__property System::AnsiString Value;
</FONT></PRE>
<DL>
<DT><FONT COLOR="#0066FF"></FONT></DT>
</DL>
<BLOCKQUOTE>
<P>
<HR>
<FONT
COLOR="#000077"><B>NOTE:</B></FONT><B> </B>Remember that Object Pascal treats
properties and methods with the same name differently than C++. In particular, there
is no function or method overloading in Object Pascal.
<HR>
</BLOCKQUOTE>
<P>Here
are some other illustrations of how to use the <TT>TField</TT> object:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall TForm1::bAsStringClick(TObject *Sender)
{
ShowMessage(tblOrders->FieldByName("TaxRate")->AsString);
}
void
__fastcall TForm1::bAsIntegerClick(TObject *Sender)
{
int i = tblOrders->FieldByName("TaxRate")->AsInteger;
ShowMessage(static_cast<AnsiString>(i));
}
void __fastcall TForm1::bAsFloatClick(TObject *Sender)
{
float f
= tblOrders->FieldByName("TaxRate")->AsFloat;
ShowMessage(static_cast<AnsiString>(f));
}</FONT></PRE>
<P>Three of the four routines shown here from the FieldObject program produce the
same output. The odd man out in this
group is the <TT>bAsIntegerClick</TT> method,
which displays the value as an <TT>Integer</TT>, rather than as a floating-point
number. For instance, if the value of the <TT>TaxRate</TT> field in the current record
was 4.5, three of the methods shown
here would display the string <TT>"4.5"</TT>.
The <TT>bAsIntegerClick</TT> method, however, would display the string as simply
<TT>"4"</TT>. The difference here is simply due to the fact that the <TT>AsInteger</TT>
property
automatically converts a floating point number to an int.
<H3><A NAME="Heading15"></A><FONT COLOR="#000077">More Information on the Fields
Property</FONT></H3>
<P>The Fielder program that ships on this book's CD-ROM demonstrates some simple
ways to
use the <TT>Fields</TT> property of <TT>TDataSet</TT>. If you want to construct
the program dynamically, place a <TT>TTable</TT>, two buttons, and two list boxes
on a form, as shown in Figure 9.4. Hook up the <TT>TTable</TT> object to the
<TT>CUSTOMER</TT>
table that ships with BCB.<BR>
<BR>
<A NAME="Heading16"></A><A HREF="09ebu04.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/09/09ebu04.jpg">FIGURE 9.4.</A><FONT COLOR="#000077">
</FONT><I>The Fielder program shows how to use the <TT>Fields</TT> property.</I></P>
<P>Double-click the
<TT>Fields</TT> button and create a method that looks like this:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall TForm1::bbFieldsClick(TObject *Sender)
{
int i;
ListBox1->Clear();
for (i = 0; i < tblCustomer->FieldCount; i++)
ListBox1->Items->Add(tblCustomer->Fields[i]->FieldName);
}
</FONT></PRE>
<P>This method starts by clearing the current contents of the first list box, and
then it iterates through each of the fields, adding their names one by one to the
list box. Notice that the <TT>for</TT> loop shown here counts from <TT>0</TT> to
one less than <TT>FieldCount</TT>. If you don't remember to stop one short of the
value in <TT>FieldCount</TT>, you will get a "List Index Out of Bounds"
error,
because you will be attempting to read the name of a field that does not exist.</P>
<P>If you enter the code correctly, you will fill the list box with the names of
all the fields in the current record structure. BCB provides other means to get at
the
same information, but this is a simple, programmatic way for you to access these
names at runtime.</P>
<P>In the Fielder example, you can associate the following code with the second button
you placed on the program's form:</P>
<PRE><FONT
COLOR="#0066FF">void __fastcall TForm1::bbCurRecordClick(TObject *Sender)
{
int i;
ListBox2->Clear();
for (i = 0; i < tblCustomer->FieldCount; i++)
ListBox2->Items->Add(tblCustomer->Fields[i]->AsString);
}
</FONT></PRE>
<P>This code adds the contents of each of the fields to the second list box. Notice
that once again, it is necessary to iterate from zero to one less than <TT>FieldCount</TT>.
The key point here is that the indices to <TT>Fields</TT> is
zero-based.
<DL>
<DT></DT>
</DL>
<BLOCKQUOTE>
<P>
<HR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -