Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Libro. Los Tomos de Delphi. Delphi Sin Problemas PDF
Libro. Los Tomos de Delphi. Delphi Sin Problemas PDF
© 2002 Danypress
[www.danypress.com]
Los Tomos de Delphi: Delphi sin problemas
Por Clay Shannon
Copyright versión en castellano © 2002 Danysoft Internacional
Avda. de España 17 - 28100 Alcobendas - Madrid
www.danypress.com
ISBN: 84-923926-81
Depósito Legal: M.
iii
Comentarios sobre:
Los Tomos de Delphi: “Delphi sin problemas”
de Clay Shannon
“He estado utilizando el libro durante el mes pasado y fue muy útil cuando
estaba tratando de resolver el mensaje de error inexplicable de turno. No
utilizará este libro todos los días, pero cuando ocurra un error misterioso
estará muy feliz de tenerlo a su alcance. En él no solamente se identifica la
causa que está provocando el mensaje de error, sino que además se ofrecen
soluciones y ejemplos que permiten resolver el problema muy rápidamente.
Si su tiempo es valioso y desea minimizar su ‘tiempo muerto’, le recomenda-
ría adquirir este libro”.
Barry McClure
President
Grebar Systems, Inc.
iv
Contenido
Cómo este libro se diferencia de los demás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix
Los mensajes de error son sus amigos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix
Cómo encontrar mensajes de error específicos en este libro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxx
Cuando hay muchas causas potenciales para el mismo error . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxi
Cuando necesite más información . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxii
Mensajes de Error
“.” Expected. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
$2109 Cannot initialize the BDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
$DENYPACKAGEUNIT <> cannot be put into a package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
$DESIGNONLY and $RUNONLY both specified . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
$DESIGNONLY and $RUNONLY only allowed in package unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
$WEAKPACKAGEUNIT & $DENYPACKAGEUNIT both specified . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
$WEAKPACKAGEUNIT <> cannot have initialization or finalization code . . . . . . . . . . . . . . . . . . . . . . 4
$WEAKPACKAGEUNIT <> contains global data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
‘;’ not allowed before ‘Else’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
<> already exists. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
<> can’t be added to this package because another file with the same base name (<>) is already in the directory of
the package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
<> clause not allowed in interface type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
<> directive not allowed in interface type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
<> expected but <> found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
<> has no index for fields <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
<> has the descendent <> in the Repository and therefore cannot be removed . . . . . . . . . . . . . . . . . . 10
<> is a read-only file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
<> is a reserved word . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
<> is already in the Repository. Replace it? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
<> is already in use by <>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
<> is an invalid filename . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
<> is an invalid PageIndex value. PageIndex must be between 0 and <> . . . . . . . . . . . . . . . . . . . . . 13
<> is not a type identifier. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
<> is not a unique name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
<> is not a valid component name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
<> is not a valid date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
<> is not a valid date and time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
<> is not a valid floating point value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
<> is not a valid floating point value for field “<>” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
v
<> is not a valid identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
<> is not a valid integer value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
<> is not a valid integer value for field “<>” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
<> is not a valid path. Make sure that the path name is spelled correctly and that you are connected to the server on
which the file resides. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
<> is not a valid time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
<> is not a valid value for field <>. The allowed range is <> to <>. . . . . . . . . . . . . . . . . . . . . . . . 23
<> must be saved before adding to Repository. Save now? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
<> or <> expected but <> found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
<> property out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
{$R *.RES} missing or incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
(<>, <>, <>, <>) is not a valid DateMonthWeek quad . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
(<>, <>, <>) is not a valid DateWeek triplet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
16-Bit segment encountered in object file <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
A class named <> is already installed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
A CoClass must have at least one default interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
A CoClass must implement at least one interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
A component class named <> already exists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
A component named <> already exists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
A component named <> already exists in a descendent form . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
A connection with the server could not be established . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
A device attached to the system is not functioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
A dispinterface type cannot have an ancestor interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
A dispinterface type requires an interface identification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
A field or method named <> already exists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
A module called <> is already installed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
A page must be empty before it can be deleted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
A reference to <> already exists in the Type Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A required .DLL file, <>, was not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
A transaction is already active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
A user transaction is already in progress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
A value must be specified for <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
A Win32 API function failed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Abstract method error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Abstract methods must be virtual or dynamic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Access violation (General Protection Fault) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Access violation at address <>.<> of address <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Ambiguous overloaded call to <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Ancestor component not found. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
An error occurred while attempting to initialize the Borland Database Engine (error <>) . . . . . . . . . . . . . 51
Another file named <> is already on the search path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Another file with the same base name (<>) is already on the search path . . . . . . . . . . . . . . . . . . . . . 51
Application is not licensed to use this feature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Arithmetic Overflow Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
vi
Array type required. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Assertion failed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Assignment to FOR-Loop variable <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Asynchronous socket error <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
At end of table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Bad argument type in variable type array constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Bad global symbol definition: <> in object file <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Bad packaged unit format: <>.<> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Bad unit format: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
BDE Initialization Error $2501 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Before you can deploy, you must complete the Web Deployment page of the Project|Web Deploy Options dialog. . 63
Bitmap image is not valid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Bits index out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
BLOb has been modified . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Break or Continue outside of loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Breakpoint is set on line that may have been removed by the optimizer or contains no debug information. Run anyway?
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Call to Application.CreateForm is missing or incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Call to RegisterClass is missing or incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Can’t change value while socket is active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Can’t compile Complib. Too many files in project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Can’t delete or change record. Since related record exists in table =‘xxx’, referential in tegrity rules would be violated
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Can’t load [complib.dcl, cmplib32.dcl, vcl30.dpl, vcl40.bpl, vcl50.bpl, vcl.bpl] . . . . . . . . . . . . . . . . . . . . 74
Can’t load package <>.<> One of the library files needed to run this package cannot be found . . . . . . . . . . 75
Can’t load package <>. The specified module could not be found. . . . . . . . . . . . . . . . . . . . . . . . . . 76
Can’t write .EXE file. Disk full?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Cannot add a session to the form or data module while session <> has AutoSessionName enabled . . . . . . . . 78
Cannot assign to a read-only property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Cannot break, continue, or exit out of a finally clause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Cannot change the size of an icon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Cannot change Visible in OnShow or OnHide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Cannot complete a class with incomplete methods implementations . . . . . . . . . . . . . . . . . . . . . . . . 82
Cannot connect, <> must contain a valid ServerName or ServerGUID . . . . . . . . . . . . . . . . . . . . . . . 83
Cannot connect to database <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Cannot copy a Repository Project to a directory underneath itself . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Cannot create cursor handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Cannot create file <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Cannot create form. No MDI forms are currently active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Cannot create Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Cannot debug project unless a host application is defined. Use the Run|Parameters. . . dialog box . . . . . . . . . . 88
Cannot enable AutoSessionName property with more than one session on a form or data module . . . . . . . . . . 89
Cannot find <> on the search path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
Cannot find Engine configuration file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
vii
Cannot find implementation of method <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Cannot find server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Cannot focus a disabled or invisible window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Cannot hide an MDI Child Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Cannot inherit from form <>. It contains a component with a blank name property . . . . . . . . . . . . . . . . 95
Cannot initialize local variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Cannot initialize multiple variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Cannot initialize thread local variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
Cannot Load IDAPI Service Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Cannot load IDAPI[32].DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Cannot load language driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Cannot load package <>. It contains unit <> which is also contained in package <> . . . . . . . . . . . . . . 102
Cannot locate IDAPI[01,32].DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Cannot make a visible window modal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Cannot modify a read-only dataset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Cannot modify SessionName while AutoSessionName is enabled . . . . . . . . . . . . . . . . . . . . . . . . . . 106
Cannot open component library <Path>\Complib.dcl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Cannot open file <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Cannot open module because it is a dependent of <>, which is open as text . . . . . . . . . . . . . . . . . . . 108
Cannot optimize. Not an .exe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Cannot override a static method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Cannot perform operation - DB is not open. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Cannot perform this operation on a closed connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Cannot perform this operation on a closed database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Cannot perform this operation on a closed dataset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Cannot perform this operation on an active session. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Cannot perform this operation on an empty dataset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Cannot perform this operation on an open database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Cannot perform this operation on an open dataset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Cannot perform this operation with table open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Cannot perform utility while table is in use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Cannot read a write-only property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Cannot Run a Unit or DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Cannot update, <> is not owned by <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Cannot use array of Field values with Expression Indices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Cannot use reserved unit name <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Cannot write EXE or DLL to disk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Cannot Write to Engine Configura tion File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Capability Not Supported . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Case label outside of range of case expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
Circular datalinks are not allowed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Circular Unit Reference [to <>] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Class <> not found. [Ignore the error and continue?] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Class already has a default property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
viii
Class does not have a default property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Class, interface and object types only allowed in type section . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Class methods not allowed as property getters and setters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Class not registered. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Class or object types only allowed in type section. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Class type required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Clipboard does not support Icons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Close error on <Filename> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
Code Insight features are disabled while debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Code Segment Too Large . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
COINITIALIZE has not been called . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Column not a BLOb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Comma Expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Compilation terminated; too many errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Component already installed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Connection error—no server available . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Connection in use by another statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
Connection name missing. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Constant expression expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Constant expression violates subrange bounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Constant object cannot be passed as var parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Constant or type identifier expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Constant out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
Constants cannot be used as open array arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Constructing Instance of <> containing abstract methods. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
Constructors and Destructors must have register calling convention . . . . . . . . . . . . . . . . . . . . . . . . 150
Constructors and Destructors not allowed in OLE automation section . . . . . . . . . . . . . . . . . . . . . . . 151
CONTAINS clause is incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Control <> has no parent window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Controls cannot be added to a data module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Corrupt table/index header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Could not create out put file <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Could not find IDataBroker in type library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Could not find interface <> in type library. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Could not find interface IDataBroker in type library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Could not find language driver ($220B) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Could not find object. Cannot load an IDAPI service library. File: ODBC32.DLL . . . . . . . . . . . . . . . . . . . 159
Could not initialize IDAPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Could not load <>. The OLE control may possibly require support libraries that are not on the current search path or
are not present on your system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Could not load RLINK32.DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Could not load StdOle version 1.0 type library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Could not load Type Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Could not load unit <> symbol information for <> Do you want to try to find this file yourself? . . . . . . . . . 162
ix
Couldn’t perform the edit because another user changed the record . . . . . . . . . . . . . . . . . . . . . . . . 163
Data Base Error: Database access resulted in error. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Data Segment Too Large . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
Data Structure Corruption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Data Type too large: exceeds 2 GB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Database name missing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
Database not Assigned . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
Dataset is not a query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
Dataset not configured for network access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Dataset [is] not in edit or insert mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
DAX Error: Class not registered. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
DAX Error: Name not unique in this context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
DAX Error: Unexpected failure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
DCOM not installed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Debug process is already running . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Debug session in progress. Terminate? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
Debugger kernel error. Error code: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Decla ration expected but <> found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Decla ration of <> differs from declaration in interface <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Decla ration of <> differs from previous declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
Decla ration of class <> is missing or incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
DEFAULT clause not allowed in OLE automation section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Default parameter ‘<>’ must be by-value or const . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Default property must be an array property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Default value required for <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Default values must be of ordinal, pointer, or small set type . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
Destination must be indexed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Directory Is Busy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Directory is controlled by other .NET file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Disk Error. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Disk full. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Disk read error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Disk write error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Dispid <> already used by <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Dispid clause only allowed in OLE automation section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Dispose not supported (nor necessary) for dynamic arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Division by zero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Duplicate case label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Duplicate database name <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
Duplicate dynamic method index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Duplicate field name <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Duplicate implements clause for interface <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
Duplicate message method index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Duplicate resource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
x
Duplicate session name <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Duplicate Tag Value. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Dynamic method or message handler not allowed here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
Dynamic method or message handlers not allowed in OLE automation sections . . . . . . . . . . . . . . . . . . 201
EAccessViolation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
EBitsError. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
EClassNotFound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
EComponentError. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
EConvertError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
EDatabaseError. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
EDivByZero. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
EFCreateError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
EFilerError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
EGPFault . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
EInOutError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
EIntOverflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
EInvalidCast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
EInvalidGraphic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
EInvalidGraphicOperation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
EInvalidOp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
EInvalidOperation: Cannot create form. No MDI forms are currently active . . . . . . . . . . . . . . . . . . . . 207
EInvalidOperation: Cannot make a visible window modal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
EInvalidPointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Element 0 Inaccessible—use Length or SetLength . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
END expected but <> found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
END expected but implementation found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
END. missing at end of module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
EOLEError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
EOLEException . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
EOleSysClass not Registered . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
EOleSysError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
EOleSysOperation Unavailable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
EOutOfMemory. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
EOutOfResources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
ERangeError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
EReadError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
ERegistryException . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
EResNotFound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Error 0: RLINK32 Error opening file <TypeLibrary>.tlb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Error 2—File not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Error 4—Too many open files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Error 68—Circular Unit Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Error 76—Constant out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Error 94—“.” Expected. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
xi
Error 101—Disk write error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Error 102—File not assigned . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Error 103—File not open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Error 104—File not open for input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Error 105—File not open for output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Error 200—Division by zero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Error 201—Range check error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Error 202—Stack overflow error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Error 203—Heap overflow error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Error 204—Invalid pointer operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Error 207—Invalid floating point operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Error 210—Abstract Method Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Error 215—Arithmetic overflow error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Error 216—Access Violation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Error 219—Invalid Typecast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
Error 220—Invalid Variant Typecast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Error 227—Assertion failed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Error Creating Cursor Handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Error creating form: access violation at. . . vcl[30,40,50,60] . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
Error creating form: Ancestor for “<>” not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
Error Creating Form: Cannot inherit from form <>. Contains a component <> that does not support inheritance 221
Error Creating Form: Cannot inherit from form <>. It contains a component with a blank name property . . . . 221
Error creating form: Cannot open file <>.DFM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Error Creating Form: Duplicate resource [Type:,Name:] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Error Creating Form: Invalid Stream Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Error creating Process. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Error Creating Variant Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Error Creating Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
Error debug setting hook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Error in CREATE INDEX statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Error in mod ule <>: Call to Application.CreateForm is missing or incorrect . . . . . . . . . . . . . . . . . . . . 228
Error in mod ule <>: CONTAINS clause is incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Error in mod ule <>: Declaration of class <> is missing or incorrect . . . . . . . . . . . . . . . . . . . . . . . 228
Error in mod ule <>: END. missing at end of module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Error in mod ule <>: Implementation part USES clause incorrect . . . . . . . . . . . . . . . . . . . . . . . . . 229
Error in mod ule <>: Incorrect field decla ration: class <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Error in mod ule <>: REQUIRES clause is incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Error in mod ule <>: USES clause is missing or incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Error initializing BDE ($2B05) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Error loading type library/dll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Error Opening Component Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
Error reading <>.<>: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Error reading <ComponentName or FormName>.<Propertyname>. Property does not exist. Ignore the error and con-
tinue? NOTE: ignoring the error may cause components to be deleted or property values to be lost. . . . . . . . . 232
xii
Error reading <Database>.SessionName. Duplicate database name <> . . . . . . . . . . . . . . . . . . . . . 233
Error reading <Session>.SessionName. Duplicate session name <> . . . . . . . . . . . . . . . . . . . . . . . 233
Error reading symbol file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
Error saving I(Interface): The parameter is incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
Error setting debug exception hook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
Error starting Program. The <>.DLL file appears to be corrupt. Reinstall the file, and then try again. . . . . . . . 236
EStackOverflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
EStringListError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
EThread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
EVariantError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Except or Finally expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Exception <> in module <> at <>.<>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Expected an identifier but function found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
Expecting a column separator in table [header] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Exports allowed only at global scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Expression expected but <> found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
External error C0000006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
External error C0000012 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
External exception C0000008 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
F004 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Failed to get data for <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Failed to load stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Fatal Error: <>: Required Package <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Field <> cannot be modified. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Field <> cannot be used in a filter expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Field <>.<> does not have a corresponding component. Remove the declaration? . . . . . . . . . . . . . . . . 246
Field <> is not indexed and cannot be modified . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Field <> is not of the expected type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Field <> is of an unknown type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Field <> is of an unsupported type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Field <> must have a value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Field <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Field <> should be of type <> but is declared as <>. Correct the declaration? . . . . . . . . . . . . . . . . . 253
Field declarations not allowed in interface type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Field definition not allowed after methods or properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
Field in group by must be in result set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
Field in order by must be in result set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
Field index out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
Field name already exists. Rename one of the fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Field not found in table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Field or method identifier expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Field out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Field types do not match . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Field value required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
xiii
File <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
File access denied . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
File extension <> is not valid. Expecting <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
File is Locked. Table: <> User: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
File not assigned . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
File not found <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
File not open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
File not open for input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
File not open for output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
File or directory does not exist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
File type not allowed here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
Fixed column count must be less than column count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
Fixed row count must be less than row count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
For Loop control variable must be simple local variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
For Loop control variable must have ordinal type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
For-Loop variable <> cannot be passed as var pa rameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Form <> links to form <> which cannot be found in the current project. Do you wish to remove/re direct the links to
another form?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
Form <> references another form and cannot be saved until <> is loaded . . . . . . . . . . . . . . . . . . . . 277
Format “<>” invalid or incompatible with argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Function needs result type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
General SQL Error—connection does not exist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
General SQL Error—FROM keyword not found where expected . . . . . . . . . . . . . . . . . . . . . . . . . . 279
General SQL Error: Missing Left Pa renthesis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
General SQL Error: SQL Command not properly ended . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
General SQL Error: SQL is too complex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
General SQL error. The [Commit,Rollback] Transaction request has no corresponding begin transaction . . . . . . 281
GOTO <> leads into or out of TRY statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
Grid Index Out of Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
GROUP BY is required when both aggregate and non-aggregate fields are used in result set . . . . . . . . . . . . 283
Heap Overflow Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
High cannot be applied to a long string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
Higher table level required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
I/O Error 102 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
I/O Error 103 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
I/O Error 104 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
I/O Error 105 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
I/O error found for file “<Current directory>\Database.GDB”. Error while trying to open file. The system cannot find
the file specified. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
Identifier expected but <> found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
Identifier expected but array found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Identifier expected but number found. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
Identifier redeclared: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Illegal character in input file: <> (<>) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
xiv
Illegal message method index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
Illegal type in OLE automation section: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Illegal type in Read/Readln statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Illegal type in Write/Writeln statement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
IMPLEMENTATION part is missing or incorrect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
Implementation part USES clause incorrect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
Implements clause only allowed for properties of class or interface type . . . . . . . . . . . . . . . . . . . . . . 295
Implements clause only allowed for readable property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Implements clause only allowed within class types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Implements getter must be register calling convention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Improper GUID syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Incompatible Record Structures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Incompatible Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Incompatible types: <> and <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Incompatible types: Parameter lists differ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Incorrect field declaration: class <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Incorrect method declaration in class <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Incorrect syntax near ':' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
Index already exists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
INDEX clause not allowed in OLE automation section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Index does not exist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
Index is out of date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
Index is out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
Index is read only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
Index not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Index or Primary Key cannot contain a Null value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
INDEX, READ, OR WRITE clause expected but ‘;’ found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
INSERT and UPDATE operations are not supported on autoincrement field type . . . . . . . . . . . . . . . . . . 314
Installation error –113 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Instance variable <> inaccessible here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Insufficient disk space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Insufficient memory for this operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
Insufficient SQL rights for operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Insufficient table rights for operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
Integer constant too large . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
InterBase install DLL ibinstall.dll not found in path. Please install InterBase 6 to use this fun ctionality. . . . . . . 321
Interface <> already implemented by <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Interface <> has no interface identification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
Interface <> not mentioned in interface list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
Interface mismatch. Engine version different . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
Interface type required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
Internal error: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
Internal Error; Near: query shellmgr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
Internal Error 500. Interface not supported . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
xv
Internal Server Error 500 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
Invalid address value. Must be a hexadecimal value in the range 00000000-FFFFFFFF . . . . . . . . . . . . . . . 326
Invalid argument to date encode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Invalid argument to time encode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Invalid Batch Move Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
Invalid Bind Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Invalid BLOb handle [in record buffer] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Invalid BLOb Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Invalid class string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
Invalid class typecast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
Invalid compiler directive: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Invalid directory. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Invalid field name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Invalid field size. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
Invalid field type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Invalid file name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Invalid floating point operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
Invalid function result type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Invalid GUID format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Invalid index descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Invalid index expression. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Invalid index/tag name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Invalid message parameter list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Invalid package file <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Invalid Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Invalid parameter type: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Invalid path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
Invalid pointer operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
Invalid property path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
Invalid property value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
Invalid property value on line <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Invalid resource format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Invalid Stream Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Invalid type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
Invalid Type Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Invalid typecast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Invalid use of keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
Invalid variable reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
Invalid variant type conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
Key Violation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
Label <> is not declared in current procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
Label already defined: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
Label declaration not allowed in interface part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
Label declared and referenced, but not set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
xvi
Label expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
Left side cannot be assigned to . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
Line number must be between 1 and <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Line too long [more than 255 characters] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
List capacity out of bounds (<>) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
List index out of bounds (<>) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
Local class, interface or object types not allowed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
Local class or object types not allowed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
Local procedure/function <> assigned to procedure variable. . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
Lock file [has grown] too large . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Lock time out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
Lock Violation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
Lookup information for field <> is incomplete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
Low bound exceeds High bound. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
Master has detail records. Cannot delete or modify. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
Master has detail records. Cannot empty it. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Master record missing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
Maximum Validity Check Failed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
Memo too large. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
Metafile is not valid. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
Method <> hides virtual method of base class <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
Method <> not found in base class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
Method “<>” not supported by automation object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
Method <> with identical parameters exists already . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
Method identifier expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
Microsoft Transaction Server is not installed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
Minimum Validity Check failed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
Mismatch in datapacket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Missing comma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Missing Connection or Connection String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
Missing Data Provider or Data Packet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
Missing ENDIF directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
Missing operator or semicolon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
Missing or invalid conditional symbol in <$> directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
Missing parameter type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
Missing right quote . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
Missing TableName property . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
Module <>s time/date changed. Reload? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
Module header is missing or incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
Multiple Net Files found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
Multiple Paradox Net files found/in use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
Must apply updates before refreshing data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
Name conflicting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
Name not unique in this context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
xvii
Need to specify at least one dimension for SetLength of dynamic array . . . . . . . . . . . . . . . . . . . . . . . 391
Never-build package <> must be recompiled . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
Never-build package <> requires always-build package <> . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
New not supported for dynamic arrays—use SetLength . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
No address specified . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
No argument for format <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
No code was generated for the current line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
No Databases Are Listed In Transaction Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
No definition for abstract method <> allowed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395
No fields defined—cannot create dataset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 396
No frames in project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
No index currently active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
No MDI forms are currently active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
No MDI Parent Active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
No overloaded method of <> with this parameter list exists . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
No Provider Available . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399
No SQL statement available . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
No user transaction is currently in progress. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
No Web browser could be located . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
NODEFAULT clause not allowed in OLE automation section . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
Not enough actual parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
Not enough file handles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Not exact read/write in <>.mb and <>.mb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
Not in cached update mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
Not initialized for accessing network files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
Number is out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
Number of elements differs from declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
Object Factory for TwebResponse Missing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
Object or class type required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
OLE error 800A03EC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
One or more lines were too long and have been truncated . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Only one of a set of overloaded methods can be published . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Only one TIDAntiFreeze can exist per application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
Only register calling convention allowed in OLE automation section . . . . . . . . . . . . . . . . . . . . . . . . 413
Operation not allowed on a unidirectional dataset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
Operation not allowed on sorted string list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
Operation not applicable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Operation not supported . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
Operator not applicable to this operand type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
ORA-1001 invalid cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
Order of fields in record constant differs from declaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
Ordinal type required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Out of memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
Out of system resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
xviii
Overflow in conversion or arithmetic operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
Overloaded procedure <> must be marked with the overload directive . . . . . . . . . . . . . . . . . . . . . . 424
Overriding automated virtual method <> cannot specify a dispid . . . . . . . . . . . . . . . . . . . . . . . . . 425
Package <> already contains unit <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
Package <> can’t be installed because another package with the same base name is already load ed (<>) . . . 425
Package <> can’t be installed because it is not a design time package . . . . . . . . . . . . . . . . . . . . . . 426
Package <> is recursively required. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Package unit <> cannot appear in contains or uses clauses . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Packages <> and <> both contain unit <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
PACKED not allowed here. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
Page Fault in module <> at <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
Page name cannot be blank. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
Param <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Parameter <> not allowed here due to default value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
Parameter <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
Parameters of this type cannot have default values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
Parent Interface must be Dispatchable for dual interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Passthrough SQL connection must be shared . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Path not found. File <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
Path too long . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
Pointer type required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
Preparation of default expression failed with error “Type mismatch in expression” . . . . . . . . . . . . . . . . . 434
Previous declaration of <> was not marked with the ‘overload’ directive . . . . . . . . . . . . . . . . . . . . . 435
Printing in Progress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
Procedure cannot have a result type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
Procedure FAIL only allowed in constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Procedure, function or property expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Procedure or Function expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Procedure or Function name expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
Program or unit <> recursively uses itself . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
Project <> raised exception class <> with message <>. Process stopped. Use Step or Run to continue. . . . . 440
Property <> does not exist in base class. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Property <> inaccessible here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
Property does not exist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
Property getters and setters cannot be overloaded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
Property overrides not allowed in interface type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Provider name was not recognized by the server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Published field <> not a class nor interface type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
Published property <> cannot be of type <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
Published real[48] property <> must be Single, Double, or Extended . . . . . . . . . . . . . . . . . . . . . . . 446
PutObject to undefined item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Query Is Too Complex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Query makes no sense . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
Query may take a long time to process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
xix
Range check error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Read failure. File: <>.val . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
Read or Write clause expected but identifier <> found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
Record already locked by this session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
Record changed by another user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
Record Key deleted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Record/Key Deleted. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Record Locked by another User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
Record, object or class type required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
Recursive include file <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
Redeclaration of <> hides a member in the base class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
Redeclaration of property not allowed in OLE automation section . . . . . . . . . . . . . . . . . . . . . . . . . 455
Required package <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
REQUIRES clause is incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
Re-raising an exception only allowed in exception handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
Resource <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
Segment/Offset pairs not supported in Borland 32-bit Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
Selection contains a component introduced in an ancestor form which cannot be deleted . . . . . . . . . . . . . 458
Server Execution Failed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
Session name missing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
Sets may have at most 256 elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
Share not loaded. It is required to share local files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
Size mismatch error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
Size of published set <> is greater than [4 bytes, 32 bits] . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
Slice standard function is only allowed as open array argument . . . . . . . . . . . . . . . . . . . . . . . . . . . 464
Socket Error # 10061 – Connection Refused . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
Socket Error # 10065 – No route to host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
Socket Error # 11001 – Host not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
SQL Connection timed out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
SQL Dialect Invalid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
SQL is too complex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
Stack overflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 468
Statement expected, but expression of type <> found. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
Statements not allowed in interface part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
STORED clause not allowed in OLE automation section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470
Stream Read Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470
String constant truncated to fit STRING[ ] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
String [literal]s may have at most 255 elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
Syntax Error in Field Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472
Syntax error in query. Incomplete query clause . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
Syntax error in real number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
System unit out of date or corrupted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
Table cannot be opened for exclusive use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
Table corrupt—other than header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
xx
Table does not exist. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
Table does not support this operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
Table is busy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
Table is full . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
Table is not indexed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
Table is read only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
Table or View does not exist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
TActiveFormX declaration missing or incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
Text after final END . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
The <>.EXE file is linked to missing export <>.DPL:<> . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
The <> method referenced by <>.<> does not exist. Remove the reference? . . . . . . . . . . . . . . . . . . 484
The <> method referenced by <>.<> has an incompatible parameter list. Remove the reference? . . . . . . . 486
The application or DLL <> is not a valid Windows image. Please check this against your instal lation diskette. . . 486
The changes you requested to the table were not successful because they would create duplicate values in the index,
primary key, or relationship. Change the data in the field or fields that contain duplicate data, remove the index, or re-
define the index to permit duplicate entries and try again. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
The Edit Buffer of <> is marked read-only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
The Master Source property of <> must be linked to a DataSource . . . . . . . . . . . . . . . . . . . . . . . . 488
The OLE control may possibly require support libraries that are not on the current search path or are not present on
your system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
The package already contains unit named <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
The package already requires a package named <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
The page cannot be displayed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
The path entered does not exist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
The procedure entry point <> cannot be found in the dynamic link library <>.DLL . . . . . . . . . . . . . . . 491
The project already contains a form or module named <>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491
The Resource DLL Wizard requires a project to be open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
The search string cannot be blank . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
The selected bitmap is larger than 24x24 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
The server returned an invalid response. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
The transaction isolation level must be dirty read for local databases . . . . . . . . . . . . . . . . . . . . . . . 494
The type library has syntax errors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
There is currently no active project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
There is no default printer currently selected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
There is no overloaded version of <> that can be called with these arguments . . . . . . . . . . . . . . . . . . 496
This form of method call only allowed for class methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
This form of method call only allowed in methods of derived types . . . . . . . . . . . . . . . . . . . . . . . . . 499
This package already contains unit named <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
This type cannot be initialized . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
Thread local variables cannot be ABSOLUTE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
Thread local variables cannot be local to a function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
Token not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
Token not found. Token :dbo. line number:1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
Too many actual parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
xxi
Too many connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
Too many files open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
Too many locks on table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
Too many open cursors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
Too many open files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
Too many parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
Transaction Is Active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
Transaction not Assigned . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
Translate error, value out of bounds. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
Tried to search marked block but it is invalid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Type <> has no type info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
Type <> is not yet completely defined . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
Type <> must be a class to have a PUBLISHED section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
Type <> must be a class to have OLE automation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
Type <> needs finalization—not allowed in file type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
Type expected but <> found. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
Type expected but real constant found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
Type mismatch for field <FieldName>, expecting: <Field type>, actual: <Field type> . . . . . . . . . . . . . 514
Type mismatch [in expression] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514
Type not allowed in OLE Automation call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
Type of expression must be BOOLEAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
Type of expression must be INTEGER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
TYPEINFO standard function expects a type identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
TYPEOF can only be applied to object types with a VMT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
Types of actual and formal var parameters must be identical . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Unable to Execute a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Unable to find both a form and a source file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Unable to insert a line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Unable to load GDS[32].DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Unable to load RPTSMITH.EXE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Undeclared Identifier: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
Undeclared Identifier: 'EmptyParam' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Undeclared Identifier: 'Result'. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Undeclared Identifier: 'Unassigned' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Undeclared Identifier: 'VarToStr' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Unexpected end of command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Unit <> was compiled with a different version of <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
Unit File Format Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
Unit name mismatch: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
Unit version mismatch: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
Unknown Column. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
Unknown database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
Unknown directive: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
Unknown directive (already exists) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
xxii
Unknown Identifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
Unknown picture file extension: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
Unknown SQL Error. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
Unknown user name or password . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
Unnamed arguments must precede named arguments in OLE Automation call . . . . . . . . . . . . . . . . . . . 536
Unrecognized database parameter block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
Unsatisfied forward or external declaration: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
Unsupported 16bit resource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Unterminated string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
USES clause is missing or incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539
Validation error for column <Column Name>, value <***Null***> . . . . . . . . . . . . . . . . . . . . . . . 539
Variable <> inaccessible here due to optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
Variable name expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
Variable required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
Variant does not reference an automation object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
Variant does not reference an OLE object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
Variant error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
Variant is not an array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
Vendor initialization failure: ORA[NT]7[1,2,3].DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Windows socket error: <> on API <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
Windows Socket Error: (10060), on API connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Write error on <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
You cannot add a <> to the current project because it is not an ActiveX library. Click OK to start a new ActiveX li-
brary project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
You cannot specify a size for a field of this type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
You must open a project before you can add an Automation Object . . . . . . . . . . . . . . . . . . . . . . . . 547
You must select a VCL class. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
Your application is not enabled for use with this driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
Your username and password are not defined. Ask your database administrator to set up an InterBase login . . . . 549
xxiii
xxiv
Prólogo
Prólogo
Desarrollar software es una tarea difícil. Algunas veces se sentirá como si
estuviera buscando un camino a través de un campo minado. Algunas
minas son letales y explotan en su cara, haciendo que su aplicación deje
de funcionar. Otras podrían simplemente causarle heridas de diversa con-
sideración. Y otras podrían activarse tempranamente, para comenzar a
causar daños sólo al cabo de cierto tiempo.
El problema es, por supuesto, doble: algunas minas son colocadas por Ud.
mismo y otras por poderes “extraños” — podría ser Windows, una actuali-
zación de Windows, una DLL descarriada que ha quedado en memoria, o
alguna aplicación incorrectamente programada que comparte el ordena-
dor con su aplicación.
Por supuesto, la solución verdadera pasa por tener un mapa del campo de
minas. Conociendo donde están las minas, ciertamente será más fácil
encontrar el camino seguro.
Los mensajes de error, por supuesto, sirven para un propósito válido y
pueden ayudar a detectar esas “minas” de programación. Aunque los
desarrolladores generalmente detestan ver mensajes de error, franca-
mente estarían perdidos sin ellos. No obstante, históricamente el proceso
de resolver los problemas de una aplicación que se comporta incorrecta-
mente a partir de los mensajes de error ha tenido generalmente un cierto
componente de “magia negra”. Muchas veces los mensajes de error no son
muy útiles, y en ocasiones pueden ser totalmente engañosos.
Cuando se produce un error, es generalmente responsabilidad del creador
de esa pieza de código particular (aplicación, controlador, componente,
control, etc.) proporcionar una descripción significativa de lo que ha ocu-
rrido. Desafortunadamente, escribir mensajes de error significativos es
una tarea que cae siempre en la parte inferior de la lista de prioridades
del desarrollador. Como resultado, un mensaje de error podría no explicar
con suficiente claridad cuál es el problema. Mi favorito es “General SQL
Error” (”Error general de SQL”). Claramente es un mensaje de error nada
útil — usted sabe que el error tiene relación con SQL, pero nada más. El
problema puede estar en cualquier lugar, haberse producido por cualquier
causa, y eso sería todo lo que podría suponerse para corregir el problema.
Un problema de aún más difícil solución se produce cuando un mensaje de
error no tiene absolutamente nada que ver con el problema real. El
xxv
Prólogo
xxvi
Agradecimientos
Agradecimientos
Ningún libro es una isla. Aunque mucha de la información que se pre-
senta aquí fue adquirida a través de la aproximación directa (¡progra-
mando!), alguna información transmitida en este libro ha sido
indirectamente adaptada de muchas y variadas fuentes. Entre estas otras
fuentes se incluyen otros libros de Delphi, publicaciones periódicas, gru-
pos de noticias y listas de correo, la documentación de ayuda de Delphi, el
código de otras personas y conversaciones con colegas.
Cuando era joven escuché muchas veces la expresión “Construya una
ratonera, y el mundo encontrará el camino hasta ella”. Ahora sé que eso
no es cierto. El mundo debe saber de la existencia de su ratonera, y nor-
malmente habrá que darla a conocer para que la tengan en cuenta, no
importa cuán buena sea. Una gran ayuda para mí en el proceso de hacer
mi “ratonera” conocida ha sido Internet, a través de los grupos de noticias
y el correo electrónico.
Aprecio la ayuda que recibí de Borland, fundamentalmente de Kendyll
Uppstrom, Karen Giles, Christine Ellis, John Kaster, Anneke Leigh,
David Intersimone, Dale Fuller, Bill Widmer y Charlie Calvert.
Un agradecimiento especial a Mark Johnson por ponerme en contacto con
Wordware cuando estaba buscando un editor y ellos estaban buscando
autores de libros sobre Delphi.
Me gustaría agradecer también al autor de Delphi John Ayres y a las
siguientes personas en Wordware: Kellie Henderson, Jim Hill, Beth Koh-
ler, Denise McEvoy, Diane Mueller y Paula Price.
Por último, quiero agradecer a las siguientes personas la contribución de
diversos materiales: Michael Burton, Eric Engler, Ken Hale, Dave Klein,
Walter Novacek, Numega, Atanas Stoyanov, Bob Swart, TurboPower Soft-
ware y Robert Vivrette.
xxvii
Sobre el autor
Sobre el autor
Clay Shannon ha gastado muchos y variados sombreros a lo largo de su
vida. En su juventud, su actividad principal eran los deportes (béisbol,
fútbol y baloncesto), la música (guitarra rítmica y bajo eléctrico) y la foto-
grafía. Como baloncestista, él se describe a sí mismo como un “pequeño,
gordo y viejo Arvydas Sabonis”. En otro tiempo un músico ávido (blues,
rock, country-rock, bluegrass), ahora rara vez encuentra tiempo para
tocar. Como fotógrafo, muchas de sus fotos fueron publicadas en revistas
y materiales publicitarios. Ahora ni siquiera tiene ahora una cámara
“decente”.
A la temprana edad de 35, Clay descubrió la programación, y nada ha
sido lo mismo desde entonces. Como anteriormente ocurrió con la “fiebre
de la guitarra”, hoy se ha convertido en un rehén de la “fiebre de la codifi-
cación”, ya que trabaja en el desarrollo de software día y noche, tanto los
días laborables como los fines de semana.
Shannon ha trabajado intensivamente y extensivamente con Delphi desde
el surgimiento de éste. Nativo de California (nació en Fort Bragg, creció
en Eureka, San José y la región de la fiebre del oro del norte de Califor-
nia), reside actualmente en Coeur d’Alene, Idaho. Ha trabajado como
escritor técnico y desarrollador de Delphi y Access para Information
Anywhere en Jackson, CA, y como desarrollador de Delphi para Marotz
en Sacramento, CA; Softgear en Milwaukee, WI; John Deere en Brook-
field, WI; Source Services (Romac International) en New Berlin, WI; Stra-
tagem en Wauwatosa, WI; y eMake (antes Smart Shop) en Post Falls, ID.
Actualmente es consultor independiente de Delphi, instructor y autor
(“Have Compiler, Will Travel”).
Shannon puede ser contactado en bclayshannon@earthlink.net.
xxviii
Introducción
Introducción
xxix
Introducción
xxx
Introducción
Publicaciones
Impresas
Delphi Developers Journal
Visite su sitio web en http://www.cobb.com/ddj para obtener artículos de
ejemplo, información de suscripción, etc.
The Delphi Informant Magazine
Visite su sitio web en http://www.delphizine.com para obtener artículos de
ejemplo, componentes freeware, información de suscripción, etc.
The Delphi Magazine
Visite su sitio web en http://www.itecuk.com/dmag/ para obtener artículos
de ejemplo, componentes freeware, información de suscripción, etc.
Electrónicas
Boletín informativo Danysoft. Puede sucribirse, y también descargar
artículos, información y recursos desde http://www.danysoft.com
UNDU (Unofficial Newsletter of Delphi Users). Puede suscribirse, y tam-
bién descargar todas las ediciones anteriores de UNDU de su sitio web:
Http://www.undu.com
xxxii
Introducción
http://www.borland.com/delphi/
http://www.danysoft.com/
http://SunSITE.icm.edu.pl/delphi/
http://www.delphi32.com
http://www.delphicorner.f9.co.uk
http://www.chami.com/tips/delphi/
http://www.mindspring.com/~cityzoo/cityzoo.html
http://www.advdelphisys.com
http://www.drbob42.com
http://www.icss.net/~nhodges
http://www.borland.com/codecentral
http://www.borland.com/devsupport
http://www.efg2.com/Lab/Library/Delphi/IO/IOResult.htm
Para obtener una lista de otros sitios dedicados a Delphi, visite:
http://www.borland.com/delphi/
y
www.undu.com (siga el enlace “Delphi links”)
Se puede acceder al sitio web de Borland directamente desde Delphi 3 y
superiores (si tiene un navegador instalado y una cuenta de Internet)
seleccionando Help | Borland Home Page o Help | Delphi Home
Page.
xxxiii
Introducción
borland.public.delphi.multi-tier
borland.public.delphi.winapi
borland.public.delphi.internet
Otros libros
Los Tomos de Delphi: “Algorítmos y estructuras de datos” por Julian
Bucknall.
Programación COM en Delphi por Eric Harmon.
Los Tomos de Delphi: “API gráfico Win 32” por John Ayres y otros.
Los Tomos de Delphi: “Núcleo del API Win 32” por John Ayres y otros.
201 Principles of Software Development por Alan M. Davis.
Code Complete por Scott McConnell.
Delphi Component Design por Danny Thorpe.
Delphi Developer’s Handbook por Marco Cantu, Tim Gooch y John Lam.
Delphi in a Nutshell por Ray Lischner.
Delphi Programming Problem Solver por Neal Rubenking.
Delphi X Developer’s Guide por Steve Teixeira y Xavier Pacheco.
Delphi X Unleashed por Charles Calvert.
Mastering Delphi X por Marco Cantu.
Teach Yourself Delphi in 21 Days por Kent Reisdorph
Otra fuente importante es la documentación de Borland (incluyendo los
FAQs y TIs en el CD de Delphi) y los programas de ejemplo (situados por
defecto en C:\Archivos de programa\Borland\Delphi X\Demos y
C:\Archivos de programa\Delphi X\Help\Examples).
xxxiv
Mensajes de error 1
Mensajes de error
“.” Expected
Posible causa de error
Puede haber asignado un objeto o una clase a una variable. Por ejemplo, si el
nombre de la unidad es BigUnit, lo siguiente generará este error:
Solución rápida
Cambie el nombre de la variable. En el contexto mostrado anteriormente, una
cadena debería ser asignada a la variable, así:
Información adicional
Cuando se intenta asignar un nombre de clase a una variable, el compilador
estará esperando encontrar un punto y una propiedad de la clase de un tipo
adecuado a continuación del nombre de la clase.
Utilice nombres descriptivos para todos los identificadores — formularios, uni-
dades, componentes, variables y constantes.
Solución rápida
Introduzca el camino de IDAPI32.DLL en la siguiente clave del Registro:
HKEY_LOCAL_MACHINE\SOFTWARE\BORLAND\DATABASE
ENGINE\DLLPATH.
El valor usual de esta entrada es: \Borland\Common files\BDE.
Información adicional
Puede que la entrada requerida esté ausente solamente en el Registro de la
máquina en la que se realiza la distribución de una aplicación.
Para acceder a RegEdit (el editor del Registro), seleccione Inicio| Ejecutar,
escriba regedit, y pulse el botón Aceptar.
Solución rápida
Elimine la directiva de compilador {$DENYPACKAGEUNIT ON} de la unidad
o cámbiela a {$DENYPACKAGEUNIT OFF}.
Información adicional
Este mensaje de error es único para Delphi 3 y posteriores, ya que Delphi 1 y 2
no utilizan paquetes.
La directiva de compilador {$DENYPACKAGEUNIT ON} prohibe que la uni-
dad que la contiene pueda ser colocada en un paquete.
{$DENYPACKAGEUNIT OFF} es la configuración por defecto.
Solución rápida
Elimine una o ambas directivas de compilador del archivo fuente donde
aparecen.
Información adicional
Ambas directivas de compilador están desactivadas (off) por defecto. Pueden
ser activadas (on) o desactivadas (off) de la siguiente manera:
{$DESIGNONLY ON} o {$DESIGNONLY OFF}
{$RUNONLY ON} o {$RUNONLY OFF}
Solución rápida
Elimine estas directivas de compilador del archivo fuente donde aparecen.
Información adicional
Estas directivas de compilador afectan la forma en que el entorno integrado de
Delphi trata una DLL que contiene un paquete. Por esa razón, solamente pue-
den estar contenidas en archivos fuente de paquetes (.DPK).
4 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Elimine una o ambas directivas de compilador del archivo fuente donde
aparecen.
Información adicional
Si la directiva de compilador {$WEAKPACKAGEUNIT ON} aparece en un
archivo de unidad, el compilador omite esa unidad de los .DPLs (las bibliotecas
de paquetes de Delphi) si es posible.
No utilice la directiva de compilador {$WEAKPACKAGEUNIT ON} en una uni-
dad que contenga variables globales, secciones Initialization o secciones
Finalization.
Solución rápida
Elimine la directiva de compilador $WEAKPACKAGEUNIT o las secciones
Initialization/Finalization.
Información adicional
La razón para que una unidad que incluye la directiva de compilador
$WEAKPACKAGEUNIT no pueda contener código de inicialización o finaliza-
ción (o datos globales, en realidad) es que potencialmente podrían aparecer
múltiples copias de las mismas unidades débilmente empaquetadas en la
misma aplicación.
Mensajes de error 5
Una unidad puede tener una sección Initialization sin una sección Finaliza-
tion, pero no lo contrario. Si necesita esta última pero no la primera, puede
simplemente declarar una sección Initialization vacía, así:
initialization
// Nada !!!
finalization
{Sacar el gato fuera, cerrar la puerta, apagar las luces,
dar las buenas noches}
Solución rápida
Elimine la directiva de compilador $WEAKPACKAGEUNIT o los datos
globales.
Información adicional
La razón para que una unidad que incluye la directiva de compilador
$WEAKPACKAGEUNIT no pueda contener código de inicialización o finaliza-
ción (o datos globales, en realidad) es que potencialmente podrían aparecer
múltiples copias de las mismas unidades débilmente empaquetadas en la
misma aplicación.
Solución rápida
Elimine el punto y coma.
Información adicional
Un punto y coma significa el final de una sentencia If. Por ejemplo, el siguiente
ejemplo generará el mensaje de error bajo discusión:
6 Los Tomos de Delphi: Delphi sin problemas
if SunIsShining then
PlayBaseball; {causa el error}
else
PlayBasketballIndoors;
if SunIsShining then
PlayBaseball {sin punto y coma, no hay error}
else
PlayBasketballIndoors;
Solución rápida
Elimine la segunda declaración del procedimiento, función o propiedad.
Información adicional
Se debe tener abierto un proyecto para crear un objeto de automatización.
<> can’t be added to this package because another file with the
same base name (<>) is already in the directory of the package
Posible causa de error
Está intentando insertar en un paquete un archivo que ya existe o que tiene el
mismo nombre de un archivo ya incluido en el paquete.
Solución rápida
Si el archivo ya está contenido en el paquete, no intente añadirlo de nuevo. Si
quiere incorporar al paquete una nueva versión del archivo, elimine primero el
archivo original. Si el archivo difiere en funcionalidad pero tiene el mismo
nombre (y los necesita a ambos), renombre el que está intentando añadir e
inténtelo de nuevo.
Mensajes de error 7
Información adicional
Los paquetes aparecieron con Delphi 3. Hay dos tipos de paquetes: de tiempo
de diseño y de tiempo de ejecución. Para más detalles, consulte “packages” en
la ayuda de Delphi.
type
IXMLDOMDelouiseImplementation = interface(IDispatch)
['{2933BF8F-8B36-11D2-B20E-00C04F983E60}']
function hasFeature(const feature: WideString;
const version: WideString): WordBool; safecall;
function JR: Integer;
procedure OrvilleAndWilbur(iChihuahua: Integer);
property ValuesKeepSkyrocketing: Integer read JR
write OrvilleAndWilbur stored False;
end;
Solución rápida
Elimine de la declaración de interfaz la cláusula culpable (en el caso de arriba,
la directiva Stored).
Información adicional
Las interfaces son similares en cierto modo a las clases abstractas; ellas no
implementan sus propios métodos. Se diferencian en que no proveen almacena-
miento para las propiedades. No hay campos de datos en una interfaz. Una
clase concreta debe implementar la interfaz; una clase puede implementar
múltiples interfaces. Para más información, consulte “implements” en la ayuda
de Delphi.
type
IXMLDOMinicSardinaImplementation = interface(IDispatch)
['{2933BF8F-9B36-11D2-B20E-00C04F983E60}']
private
function Troiano(const feature: WideString;
const version: WideString): WordBool; safecall;
function GermanNovel: Integer;
procedure Richard(iChicago: Integer);
property ValuesKeepSkyrocketing: Integer read GermanNovel
write Richard;
end;
Solución rápida
Elimine de la declaración de interfaz la directiva responsable (en el caso de
arriba, la directiva Private).
Información adicional
Las interfaces no soportan ningún identificador de visibilidad. Consulte “imple-
ments” en la ayuda de Delphi para más información sobre la implementación
de interfaces en las clases de Delphi.
Solución rápida
1. Reemplace el elemento encontrado por uno adecuado.
2. Añada el elemento omitido.
Información adicional
1. Si viene a Delphi/Object Pascal de un lenguaje que, como Visual Basic, uti-
liza el símbolo = como operador de comparación (igualdad) y como símbolo
Mensajes de error 9
Solución rápida
1. Cree el índice antes de intentar asignarlo.
2. Borre el valor de la propiedad IndexFieldNames o cámbielo a uno apro-
piado para la tabla actual.
Información adicional
1. El código que provoca este error compilará, debido a que hasta donde el
compilador sabe, usted podrá crear el índice mediante código antes de
activarlo. En otras palabras, el error se detectará solamente en tiempo de
ejecución.
Para crear un índice mediante código (lo contrario de hacerlo durante la
creación de la tabla), utilice el procedimiento AddIndex.
Las propiedades IndexFieldNames e IndexName son mutuamente exclusi-
vas. Cuando se asigna un valor a una, el valor de la otra es borrado.
10 Los Tomos de Delphi: Delphi sin problemas
<> has the descendent <> in the Repository and therefore cannot
be removed
Posible causa de error
Puede haber heredado de un objeto del Almacén de Objetos (Object Reposi-
tory), haber luego añadido el objeto heredado al Almacén (presumiblemente
después de hacerle algunos cambios), y ahora intenta eliminar el objeto origi-
nal del cual ha heredado.
Solución rápida
Si realmente desea eliminar un objeto del Almacén, debe primero eliminar
cualquier otro objeto que herede alguna funcionalidad de él.
Información adicional
Este mensaje de error es causado por lo que se conoce en el mundo de las bases
de datos como integridad referencial. No se puede borrar un registro maestro
del que dependen otros registros. La situación es similar aquí, ya que el objeto
heredado en el Almacén depende del objeto que se pretende eliminar.
Solución rápida
1. Puede cambiar el atributo de sólo lectura del archivo de True a False utili-
zando el Explorador de Windows u otro programa de manipulación de
archivos. En el Explorador, siga estos pasos:
a. Localice el archivo y pulse sobre él con el botón derecho del ratón.
b. Si la casilla de verificación de sólo lectura está activada, pulse sobre
ella para desmarcarla.
2. Marque (check out) el archivo e intente grabarlo de nuevo. Asegúrese de no
haber marcado el archivo en modo de sólo lectura.
Mensajes de error 11
Información adicional
1. Compruebe que realmente quiere modificar el archivo. Puede ser que se
haya definido como de sólo lectura (por usted u otra persona) por una
buena razón.
2. Si ha realizado una modificación que afecta al archivo .DFM (como haber
cambiado una propiedad del formulario o sus hijos), la presencia de un
archivo .DFM también marcado (checked out) será necesaria cuando se
graben los cambios a un archivo .PAS.
Solución rápida
Renombre el identificador. Dé al identificador un nombre significativo (lo que
hará el código más fácil de leer y depurar), comenzando ya sea con una letra o
un guión bajo y continuando después con cualquier combinación de letras,
dígitos y guiones bajos.
Información adicional
Delphi/Object Pascal reserva las siguientes palabras para su propio uso:
Solución rápida
Pulse el botón Cancel.
Información adicional
Los objetos en el Almacén pueden ser compartidos entre desarrolladores y pro-
yectos. Si añade un objeto del Almacén a un proyecto, tiene tres posibilidades:
copiar, heredar o utilizar. Si hace una copia del objeto, obtendrá una copia
independiente, sin conexión con el original que reside en el Almacén. Si hereda
del objeto del Almacén, los cambios futuros que se hagan al objeto del Almacén
se reflejarán en su objeto. Si decide usar directamente el objeto, estará traba-
jando sobre la copia original en el Almacén - los cambios que haga sobre el
objeto se reflejarán en todos los objetos que sean heredados de él.
Para más información, consulte “sharing objects in a team environment” en la
ayuda de Delphi.
Solución rápida
1. Cierre el Database Desktop, si tiene la tabla en cuestión abierta.
2. Cierre la(s) tabla(s), asignando False a la propiedad Active de los compo-
nentes TDataset (TTable, TQuery y TStoredProc en todas las versiones de
Delphi; TClientDataset en las versiones Cliente/Servidor de Delphi 3 en
adelante; TNestedTable a partir de Delphi 4), y False a la propiedad
Connected de los componentes TDatabase.
Mensajes de error 13
Información adicional
Si ha experimentado una terminación anormal de la aplicación (o una caída del
sistema), puede que sea necesario salir y luego reiniciar Delphi antes de poder
acceder a la tabla para uso exclusivo.
Solución rápida
Borre la extensión, de modo que la extensión apropiada sea añadida automáti-
camente, o cambie la extensión por una apropiada.
Información adicional
Un ejemplo de acción que podría causar este error es si está utilizando el Acti-
veX Control Wizard (Asistente de controles ActiveX) y está intentando grabar
el nombre del proyecto con una extensión diferente de .DPR.
Windows y Delphi dependen de las extensiones de los nombres de archivos
para saber qué tipo de información éstos contienen y por tanto cómo deben ser
tratados. Si cambia la extensión de un archivo, la máquina no tiene forma de
saber si es un archivo de texto, un archivo fuente, un archivo objeto, un
archivo de proyecto, un archivo ejecutable, etc. (a menos que especifique la aso-
ciación usted mismo).
Solución rápida
Cambie el índice de página a asignar por uno que exista, o cree una nueva
página en el Editor de Formularios (Form Editor) o en el código antes de hacer
la asignación.
Información adicional
Este error no será detectado en tiempo de compilación, debido a que el compila-
dor supone que la página podrá ser creada en el código antes de ser activada
mediante un código similar al de arriba.
Solución rápida
Asegúrese de que ha escrito el nombre del tipo correctamente.
Información adicional
Un ejemplo de cuándo se podría obtener este mensaje de error es si se está tra-
tando de escribir una versión más corta de un tipo de datos. Por ejemplo,
podría intentar esto:
var
s: Str; {se debe declarar string, no str}
i: Int; {se debe declarar integer, no int}
tidy: Bool; {sin embargo, esto está bien ...}
wooly: Boolean; {...al igual que la forma larga}
Solución rápida
Asigne nombres únicos a todos los alias de bases de datos.
Mensajes de error 15
Información adicional
Todas las cosas deben tener nombres únicos para ser identificadas correcta y
absolutamente. Las personas, por ejemplo, tienen nombres que permiten dis-
tinguir a unos de otros. Si dos nombres coinciden hasta un cierto nivel de deta-
lle (por ejemplo, si tanto el nombre como el primer apellido coinciden), entonces
se debe continuar con otro nivel de detalle, tal como el segundo apellido, la
fecha de nacimiento, etc. para que de una manera única y precisa se pueda
identificar a una persona. Los alias de bases de datos deben identificarse de
manera única, y de hecho el mecanismo es mucho más simple que en el caso de
los seres humanos. Si un nombre de alias tiene una sílaba y es único, eso es
suficiente.
Solución rápida
Asigne al componente un nombre que se adhiera a las siguientes reglas:
Debe comenzar con una letra o un caracter de guión bajo (_).
Los caracteres siguientes deben ser letras, números o el caracter de guión
bajo.
No utilice una palabra reservada de Object Pascal para nombrar un
componente. Las palabras reservadas de Object Pascal son:
and, array, as, asm, begin, case, class, const, constructor, destructor, dis-
pinterface, div, do, downto, else, end, except, exports, file, finalization,
finally, for, function, goto, if, implementation, in, inherited, initialization,
inline, interface, is, label, library, mod, nil, not, object, of, or, out, packed,
procedure, program, property, raise, record, repeat, resourcestring, set, shl,
shr, string, then, threadvar, to, try, type, unit, until, uses, var, while, with,
xor.
Información adicional
Por defecto, Delphi asigna a los objetos nombres secuenciales basados en el
tipo del componente, tales como Button1, Button2, Timer1, etc. Para hacer el
código más legible (y de fácil mantenimiento), cambie esos nombres por otros
más significativos. Por ejemplo, puede utilizar nombres como btnSave,
btnClose, tmrSplash, etc.
Puede utilizar hasta 63 caracteres para un nombre de componente.
16 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Asegúrese de que la fecha introducida sea válida.
Información adicional
Internamente, un valor TDateTime es almacenado como un número real (para
ser más específicos, un Double). La parte entera (la situada a la izquierda del
punto decimal) representa la fecha (donde el valor 0 representa al 31 de
diciembre de 1899, el valor 366 representa el 1º de enero de 1901, etc.); la parte
fraccionaria (a la derecha del punto decimal) representa la hora del día.
Se puede almacenar fechas anteriores al 31 de diciembre de 1899 utilizando
números negativos (–2 representa el 29 de diciembre de 1899, etc.).
Puede atrapar fácilmente este error encerrando un intento de conversión de
tipos a un tipo de datos TDateTime en un bloque Try...Except, de esta manera:
var
Fig: TDateTime;
try
Fig := StrToDate(Edit1.Text);
except
on EConvertError do ...
Mensajes de error 17
Solución rápida
Verifique que el valor TDateTime que intenta convertir es válido.
Si está almacenando directamente un valor en una variable TDateTime, utilice
este formato:
var
TheDay: TDateTime;
begin
TheDay := 30678.001 {28/12/1983 12:01:26}
Información adicional
No es necesario añadir la parte correspondiente a la hora del valor (la parte a
la derecha del punto decimal). Por ejemplo, en los ejemplos de arriba se podría
haber asignado los valores 30678 y 18/11/2001 (sin las partes de hora, .001 y
‘2:11 am’, respectivamente).
Internamente, un valor TDateTime es almacenado como un valor de tipo
Double. La parte entera (la situada a la izquierda del punto decimal) repre-
senta la fecha (donde el valor 0 representa al 31 de diciembre de 1899, el valor
366 representa el 1º de enero de 1901, etc.); la parte fraccionaria (a la derecha
del punto decimal) representa la hora del día.
Se puede almacenar fechas anteriores al 31 de diciembre de 1899 utilizando
números negativos (–2 representa el 29 de diciembre de 1899, etc.).
18 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Verifique que el valor es un valor de punto flotante válido antes de asignarlo a
la variable. Por ejemplo, podría utilizar algo como esto:
var
Trouble: Double;
try
Trouble := StrToFloat(Edit1.Text);
except
on EConvertError do ...
Información adicional
Los tipos de datos Real, Single, Double, Extended, Comp y Currency son todos
tipos de punto flotante.
Si se intenta asignar un valor de un tipo inválido a una variable real (por
ejemplo, asignar el valor True, de tipo Boolean, a la variable Trouble del ejem-
plo), se obtendrá el error “Incompatible types: <> and <>” en tiempo de
compilación.
Mensajes de error 19
Solución rápida
Puede evitar que un usuario introduzca un valor inválido permitiendo sólo un
dígito para el primer carácter y un dígito o el punto decimal para los siguientes
caracteres. Por ejemplo, añadiendo el siguiente código al evento KeyPress:
procedure TfrmGetNosy.dbedtSalaryKeyPress(
Sender: TObject; var Key: Char);
begin
{ solamente permite dígitos y el carácter de retroceso }
if not (key in ['0'..'9','.',#8]) then
begin
MessageBeep(0);
Key := #0
end;
end;
Información adicional
Consulte además la propiedad EditMask de los componentes TField y
TMaskEdit (en caso de que pueda prescindir de un componente con conexión a
datos).
Solución rápida
1. Haga la selección adecuada en el cuadro de diálogo antes de pulsar el botón
OK.
2. Utilice las extensiones por defecto (o ninguna, en cuyo caso la extensión
apropiada será añadida automáticamente) para los archivos que Delphi
debe administrar.
Información adicional
Un ejemplo (de entre muchos similares) donde se obtendría este mensaje de
error, es si está intentando instalar un componente y pulsa OK en el cuadro de
diálogo sin introducir un valor en el control de edición del nombre de archivo
de unidad.
Solución rápida
1. Verifique que el valor es un entero válido antes de asignarlo a la variable.
Por ejemplo, se podría intentar algo parecido a esto:
var
CountOfMonteCarlo: Integer;
try
CountOfMonteCarlo := StrToInt(Edit1.Text);
except
on EConvertError do ...
2. Pulse OK para continuar.
Mensajes de error 21
Información adicional
Sí está intentando asignar un valor de un tipo inadecuado a un entero (por
ejemplo, asignar el valor “Drácula” a la variable entera CountOfMonteCarlo)
obtendrá en tiempo de compilación el error “Incompatible types: <> y <>” (y
no en tiempo de ejecución, como en el ejemplo de arriba).
ShortInt, SmallInt, Integer, Byte, Word y Cardinal son todos tipos enteros.
Solución rápida
Puede impedir que un usuario introduzca valores inválidos permitiéndole
introducir en el campo sólo dígitos y el carácter de retroceso. Por ejemplo, aña-
diendo el siguiente código al evento KeyPress:
procedure TfrmLilBigCity. dbedtWaynesWorld(Sender: Tobject;
var Key: Char);
begin
{ permite solamente dígitos y el carácter de retroceso}
if not (key in ['0'..'9', #8]) then
begin
MessageBeep(0);
Key := #0
end;
end;
Información adicional
Consulte además la propiedad EditMask de los componentes TField y
TMaskEdit (si puede prescindir de un componente con conexión a datos).
22 Los Tomos de Delphi: Delphi sin problemas
<> is not a valid path. Make sure that the path name is spelled
correctly and that you are connected to the server on which the file
resides.
Posible causa de error
Puede estar utilizando un componente TADOConnection cuya propiedad
ConnectionString está apuntando a una base de datos en una localización que
no existe. Puede que haya borrado el directorio en el que la base de datos
reside, cambiado su nombre, o movido el proyecto a una máquina distinta en la
que no existe la misma estructura de directorios.
Solución rápida
Siga estos pasos:
1. Haga doble clic sobre el componente TADOConnection para abrir el editor
de la propiedad ConnectionString.
2. Pulse el botón de radio Use connection string.
3. Pulse el botón Build.
4. Modifique la información del camino de la base de datos de tal forma que
coincida con la realidad.
5. Pulse OK dos veces.
Alternativamente, modifique el archivo de Enlace a Datos (Data Link), si está
utilizando alguno.
Información adicional
Utilice siempre el editor de la propiedad ConnectionString para construir su
cadena de conexión. Hacerlo “a mano” es para masoquistas. De esta forma, se
asegurará también de que está introduciendo un camino válido de la base de
datos (por supuesto, si mueve un proyecto de una máquina a otra, puede que
necesite modificar esta propiedad como se ha descrito arriba).
Solución rápida
Asegúrese de que el valor a convertir sea válido.
Mensajes de error 23
Información adicional
Internamente, un valor TDateTime es almacenado como un número real (para
ser más específicos, un Double). La parte entera (la situada a la izquierda del
punto decimal) representa la fecha (donde el valor 0 representa al 31 de
diciembre de 1899, el valor 366 representa el 1º de enero de 1901, etc.); la parte
fraccionaria (a la derecha del punto decimal) representa la hora del día.
Puede atrapar fácilmente este error encerrando un intento de conversión de
tipos a un tipo de datos TDateTime en un bloque Try...Except, de esta manera:
var
TheTimeOfOurLives: TDateTime;
begin
try
TheTimeOfOurLives := StrToTime(Edit1.Text);
except
on EConvertError do begin
ShowMessage('La hora no es correcta');
ActiveControl := Edit1;
end;
end;
end;
<> is not a valid value for field <>. The allowed range is <> to <>
Posible causa de error
Puede haber intentado asignar a un campo de base de datos un valor que es
menor que la propiedad MinValue o mayor que la propiedad MaxValue del
campo.
24 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Introduzca un valor que pertenezca al rango especificado para el campo, o
amplíe el rango permitido disminuyendo la propiedad MinValue y/o incremen-
tando la propiedad MaxValue.
Información adicional
Todos los descendientes numéricos de TField (que son creados por Delphi
cuando los campos de bases de datos subyacentes son inicializados) tienen las
propiedades MinValue y MaxValue.
Solución rápida
Guarde la unidad, seleccionando File | Save, y luego añádala al Almacén.
Para ello pulse el botón derecho del ratón sobre él y seleccione Add to Reposi-
tory, o bien seleccione Project | Add to Repository.
Información adicional
Si está trabajando en un entorno de programación en equipo, se puede configu-
rar un directorio compartido de la red como Almacén de Objetos de Delphi, al
que todos los desarrolladores puedan acceder. Puede configurar Delphi para
que utilice este directorio seleccionando Tools | Environment Options, e
introduciendo la localización de este directorio compartido en el campo Shared
Repository, en la parte inferior de la pestaña Preferences.
La localización por defecto de la copia local del Almacén de Objetos es
C:\Archivos de programa\Borland\Delphi X\ObjRepos.
Solución rápida
1-6.Sustituya el símbolo existente por el esperado.
7. Coloque las declaraciones de tipos solamente en secciones Type.
8. Sustituya el nombre de la unidad por el nombre de la clase.
Información adicional
Consulte la ayuda de Delphi para más información sobre las sentencias de
declaración de tipos, procedimientos y funciones.
Solución rápida
Introduzca un valor válido para la propiedad. En el caso de las propiedades
TabHeight y TabWidth de los controles TabControl y PageControl, asigne a la
propiedad un valor entre 0 y 32767.
Información adicional
Si asigna un valor mayor que 32767 a las propiedades TabHeight o TabWidth
de un TabControl o PageControl, se generará el mensaje de error “Value must
be between –32768 and 32767”. Sin embargo, realmente el valor debe estar
entre 0 y 32767. Introducir un número negativo produce el mensaje de error
bajo discusión.
Solución rápida
Verifique que el archivo .DPR del proyecto contiene la línea:
{$R *.RES}
entre sus secciones Uses y Begin. . . End. Seleccione View | Project Source y
añada o modifique esta línea si es necesario.
Información adicional
La directiva de compilador {$R *.RES} especifica que el archivo con el mismo
nombre base del proyecto y la extensión .RES debe ser enlazado al proyecto.
Este archivo de recursos normalmente contiene solamente el icono de la aplica-
ción del proyecto.
No edite este archivo de recursos, ya que cualquier cambio que haga se perderá
la próxima vez que recompile. Utilice un archivo de recursos separado para
añadir recursos adicionales.
Solución rápida
Verifique que el año esté entre 1 y 9999, el mes esté entre 1 y 12, la semana
del mes esté entre 1 y 5, y el día de la semana esté entre 1 y 7.
Información adicional
Delphi 6 contiene muchas unidades de utilidades nuevas, tales como DateUtils,
StrUtils, VarUtils, IBUtils, ConvUtils y MaskUtils.
Solución rápida
Verifique que el año esté entre 1 y 9999, la semana del año esté entre 1 y 52, y
el día de la semana esté entre 1 y 7.
Información adicional
Delphi 6 contiene muchas unidades de utilidades nuevas, tales como DateUtils,
StrUtils, VarUtils, IBUtils, ConvUtils, y MaskUtils.
Solución rápida
Utilice un archivo objeto que no contenga definiciones de segmento de 16 bits.
Información adicional
Consulte la documentación del producto que fue utilizado para crear el archivo
objeto, y busque instrucciones sobre la conversión de definiciones de segmento
de 16 bits a definiciones de segmento de 32 bits.
28 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Seleccione Component | Configure Palette
2. Localice la página en la que el componente debería aparecer en el cuadro
de lista Pages y selecciónela. Se puede determinar cuál es la página ade-
cuada inspeccionando la llamada a RegisterComponents en la unidad del
componente o su unidad de registro. Por ejemplo, en este caso, la página es
“Samples”:
RegisterComponents('Samples', [TAISWebLauncher1]);
3. Seleccione el componente en el cuadro de lista Components.
4. Pulse el botón Delete.
5. Solucione el problema del componente e intente instalarlo de nuevo (este
proceso se debe repetir tantas veces como sea necesario).
Información adicional
Este problema ocurre más frecuentemente cuando se intenta instalar compo-
nentes propios. Usted intenta instalarlo, no puede hacerlo debido a un mensaje
de error, soluciona el problema, e intenta instalarlo de nuevo; entonces recibirá
este mensaje de error.
Solución rápida
Siga estos pasos:
Mensajes de error 29
1. Decida cuál de las interfaces de la CoClass (si hay más de una) quiere
designar como la interfaz por defecto.
2. Teniendo la CoClass afectada seleccionada en el panel izquierdo del Editor
de Bibliotecas de Tipos, seleccione la página Members en el panel derecho.
3. Si las interfaces no están en la lista, pulse el botón derecho en la página
Members y seleccione Insert Interface.
4. Seleccione de la lista tantas interfaces como desee (utilice la combinación
May./botón para seleccionar más de una interfaz) y pulse el botón OK.
5. Seleccione la interfaz que quiera designar como interfaz por defecto para el
objeto CoClass.
6. Pulse con el botón derecho sobre la interfaz y active el elemento de menú
Default.
Ahora puede guardar la biblioteca de tipos.
Información adicional
Además de simplemente solucionar el error de sintaxis generado por no tener
una interfaz por defecto o interfaces para el objeto CoClass, seguramente tam-
bién deseará añadir procedimientos, funciones y propiedades a la interfaz (en
caso de que no lo haya hecho todavía). Para información específica sobre cómo
hacer esto, consulte “creating a new type library” en la ayuda de Delphi.
El Editor de Bibliotecas de Tipos (Type Library Editor) puede ser accedido
seleccionando File | New | ActiveX | Type Library. Utilice el Editor de
Bibliotecas de Tipos para crear e inspeccionar la información de tipos de los
controles ActiveX y los objetos COM.
Debe tener abierto un proyecto para poder seleccionar File | New | ActiveX
| Automation Object, ya que los objetos de automatización son específicos
para un proyecto. Este no es el caso para la selección File | New | ActiveX |
Type Library.
Solución rápida
Añada al menos una interfaz al objeto CoClass, o elimine el objeto CoClass.
Para añadir una interfaz a un objeto CoClass, siga estos pasos:
1. En Editor de Bibliotecas de Tipos, pulse el icono que representa las interfa-
ces (parecido a una raqueta de ping-pong roja).
30 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Además de simplemente solucionar el error de sintaxis generado por no tener
ninguna interfaz asociada al objeto CoClass, seguramente también deseará
añadir procedimientos, funciones y propiedades a la interfaz (en caso de que no
lo haya hecho todavía). Para información específica sobre cómo hacer esto, con-
sulte “creating a new type library” en la ayuda de Delphi.
El Editor de Bibliotecas de Tipos (Type Library Editor) puede ser accedido
seleccionando File | New | ActiveX | Type Library. Utilice el Editor de
Bibliotecas de Tipos para crear e inspeccionar la información de tipos de los
controles ActiveX y los objetos COM.
Debe tener abierto un proyecto para poder seleccionar File | New | ActiveX
| Automation Object, ya que los objetos de automatización son específicos
para un proyecto. Este no es el caso para la selección File | New | ActiveX |
Type Library.
Solución rápida
Cambie el nombre en el cuadro de edición Class Name a uno que sea único
para su VCL.
Información adicional
Por defecto, Delphi seleccionará un nombre que no entre en conflicto con los
componentes que están instalados en la VCL del usuario.
Mensajes de error 31
Por ejemplo, si selecciona THeader como el tipo ancestro del componente que
va a crear, Delphi introducirá THeader1 en el cuadro de edición Class Name
(si ya hay una clase THeader1 en la VCL del usuario, será THeader2, etc.).
La frase “la VCL del usuario” es utilizada en lugar de “la VCL”, debido que
cada usuario de Delphi probablemente tenga una colección única de componen-
tes VCL. Seguramente tendrá el núcleo de los componentes de la VCL de Del-
phi que vienen con el producto (que es diferente para las distintas versiones y
ediciones de Delphi), pero podrá también tener instalados en su sistema varia-
dos componentes de terceros (como los ofrecidos por Danysoft), componentes
shareware, componentes freeware, así como también algunos propios. Todos
ellos, en su conjunto, constituyen la VCL del usuario.
Solución rápida
Asigne a cada componente un nombre único, preferiblemente uno que describa
el propósito del componente, tal como mniAbout para un ítem de menú que
despliega una caja About (Acerca de...), btnClose para un botón que cierra un
formulario o cuadro de diálogo, etc.
Información adicional
Delphi asigna automáticamente a cada componente que se coloca sobre un for-
mulario un nombre único basado en el tipo de componente y un número incre-
mental. Por ejemplo, si se colocan tres etiquetas sobre un formulario, Delphi
les dará los nombres Label1, Label2, y Label3. Puede cambiar estos nombres
por otros más descriptivos si lo desea, pero cada nombre de componente debe
ser único.
Solución rápida
Asigne al formulario original (ancestro) y a todos los componentes situados
sobre él nombres únicos al proyecto.
Información adicional
Puede tener (y probablemente tendrá) componentes en formularios descendien-
tes que tengan el mismo nombre que los colocados sobre el formulario ancestro,
pero éstos serán aquellos componentes que fueron colocados inicialmente sobre
el formulario ancestro (y que son heredados por el formulario descendiente -
incluyendo el nombre). En otras palabras, los componentes colocados sobre el
formulario ancestro son heredados por el formulario descendiente e incluso tie-
nen el mismo nombre. Los componentes colocados sobre el formulario descen-
diente redefinen o extienden la declaración del formulario ancestro, y el
ancestro no puede heredar nada del formulario descendiente.
Por ejemplo, cree un formulario descendiente siguiendo estos pasos:
1. Seleccione File | New.
2. Seleccione la pestaña que tiene el mismo nombre que el proyecto.
3. Seleccione el formulario del que desea heredar.
4. Verifique que el botón de radio Inherit esté seleccionado.
Si añade un componente TLabel sobre el formulario ancestro, Delphi asignará
al componente el nombre Label1. El formulario descendiente también tendrá
un Label1 en la misma posición (lo ha heredado de su ancestro). Sin embargo,
si ahora añade un componente TLabel directamente sobre el formulario des-
cendiente (al cual Delphi asignará el nombre Label2), luego añade otro TLabel
sobre el formulario ancestro (al cual Delphi asignará el nombre Label3), y
finalmente intenta asignar a Label3 en el formulario ancestro el nombre
Label2, se producirá el mensaje de error bajo discusión.
Solución rápida
Verifique que la aplicación de servidor esté configurada para escuchar por el
puerto correcto, y que la aplicación cliente esté intentando conectarse a ese
mismo puerto.
Mensajes de error 33
Información adicional
Si está probando una aplicación Site Express, puede utilizar el siguiente tipo
de URL: http://localhost:1024/Svrinfo.exe
Localhost es su máquina (IP # 127.0.0.1), a la que está intentando conectarse
por el puerto 1024 y ejecutar la aplicación Svrinfo.
Site Express hizo su aparición con Delphi 6.
Solución rápida
1. Verifique que todas las DLLs requeridas, incluyendo los paquetes, estén
disponibles en el sistema y ubicadas en el lugar adecuado. Deben estar en
el camino de búsqueda de Delphi (Tools | Environment Options, pes-
taña Library, cuadro Library Path), y los paquetes, específicamente,
deben estar en el directorio \Windows\System.
2. Si usted es el autor del paquete, recompile el paquete con la versión de
Delphi en la que está intentando instalarlo. Si no es el autor, intente con-
tactar con su autor para obtener la versión compilada apropiada.
Información adicional
Este es uno de esos mensajes de error que realmente no aportan muchas indi-
caciones en relación con el problema real.
Antes de obtener este mensaje de error, se puede haber obtenido “The <>.EXE
file is linked to missing export <>.DPL:<>”. Consulte esa entrada en este
libro para más información.
Solución rápida
No declare otra interfaz como ancestro de un tipo disp-interfaz.
Información adicional
Un tipo de interfaz especificado mediante la palabra reservada Dispinterface
no puede especificar una interfaz ancestro, debido a que se trata de interfaces
abstractas.
Consulte “dispatch interfaces”, “creating and accessing interfaces” y “dual
interfaces” en la ayuda de Delphi para más información.
Solución rápida
Suministre un GUID para que el tipo disp-interfaz sea accesible.
Información adicional
Un GUID es un valor binario de 16 bytes cuya unicidad está garantizada
(GUID significa Globally Unique Identifier - Identificador Globalmente Unico).
Solución rápida
Primero elimine del archivo .PAS la referencia al objeto o método que no tiene
una referencia correspondiente en el archivo .DFM de formulario; luego vuelva
a añadir el objeto o método al archivo .DFM.
Mensajes de error 35
Información adicional
Cuando añade un objeto o método al formulario, Delphi intenta asignarle el
próximo nombre disponible para una instancia de su clase (por ejemplo, si
arrastra un botón sobre el formulario, recibirá el nombre Button1 si no hay
más botones en el formulario, Button2 si ya existe uno, etc.). Si hay una refe-
rencia a Button1 en el archivo .PAS (pero no en el archivo .DFM), Delphi
intentará nombrar el botón Button1 (debido a que no hay referencias a botones
en el archivo .DFM), lo que ocasionará el mensaje de error bajo discusión, ya
que no puede haber dos componentes llamados Button1 en el mismo archivo
.PAS.
Solución rápida
Siga estos pasos:
1. Cierre el cuadro de mensaje, pulsando el botón OK.
2. En el cuadro de la lista Installed Units, seleccione la unidad que está
intentando instalar.
3. Pulse el botón Remove.
4. Intente instalar el componente de nuevo
Información adicional
El módulo (unidad de componente) estaba instalado parcialmente, impidién-
dole utilizarlo o intentar reinstalarlo (debido a que la instalación se quedó a
mitad de camino).
Esto no se aplica a Delphi 3 y superiores, en los que los componentes se insta-
lan dentro de paquetes. No existe el cuadro de lista Installed Units en esas
versiones de Delphi. Para ver qué componentes han sido instalados en las pági-
nas de la Paleta de Componentes en Delphi 3 y superiores, seleccione Compo-
nent | Configure Palette. Para ver qué componentes están instalados por
paquete, siga estos pasos:
1. Seleccione Component | Install Packages.
2. En la sección Design Packages del cuadro de dialogo que se despliega,
seleccione el paquete que desea inspeccionar.
3. Pulse el botón Components.
36 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Elimine todos los componentes de una página antes de intentar eliminar la
página. Si desea quedarse con los componentes pero deshacerse de la página,
arrástrelos de la página que desea eliminar a otra página; entonces podrá eli-
minar la página.
Información adicional
Delphi 1 y 2
Para eliminar un componente, siga estos pasos:
1. Seleccione Component | Configure Palette.
2. En el cuadro de lista Pages, del lado izquierdo del cuadro de diálogo que se
despliega, seleccione la página que contiene el componente que desea
eliminar. Los componentes que la integran aparecerán en el cuadro de lista
Components al lado derecho.
3. Seleccione el componente que desea eliminar.
4. Pulse el botón Delete.
5. Pulse el botón OK.
Delphi 3
Para eliminar completamente un componente (a diferencia de moverlo a una
página diferente), tendrá que eliminarlo del paquete en el que reside.
Para borrar un componente de un paquete, siga estos pasos:
1. Seleccione Project | Options, y luego pulse sobre la pestaña Packages.
2. En la sección Design Packages de la página Packages, seleccione el
paquete donde está el componente que quiere eliminar (para ver qué com-
ponentes están contenidos en cada paquete, pulse el botón Components).
3. Pulse el botón Edit (no pulse el botón Remove, a menos que se quiera des-
hacer de todo el paquete).
4. Seleccione Yes en el cuadro de diálogo de confirmación que aparece.
5. Pulse con el botón derecho sobre la unidad que quiere eliminar y seleccione
Remove Unit del menú de contexto.
Mensajes de error 37
Delphi 4 y superiores
Para eliminar un componente, debe eliminar el paquete en el que éste reside.
Para hacerlo, siga estos pasos:
1. Seleccione Project | Options, y luego pulse sobre la pestaña Packages.
2. En la sección Design Packages de la página Packages, seleccione el
paquete donde se encuentra el componente que quiere eliminar (para ver
qué componentes están contenidos en cada paquete, pulse el botón
Components).
3. Pulse el botón Remove.
4. Seleccione Yes en el cuadro de diálogo que aparece para confirmar la elimi-
nación del paquete.
Solución rápida
Cambie el nombre en el cuadro de edición New ActiveX Name a uno que sea
único entre los componentes de su VCL.
Información adicional
Cuando se deriva un control ActiveX de un componente de Delphi utilizando el
Asistente de Controles ActiveX (File | New | ActiveX | ActiveX Control),
el asistente crea un nombre por defecto para el nuevo control ActiveX elimi-
nando la ‘T’ del principio del nombre de la clase del componente y añadiendo
una ‘X’ al final. Por ejemplo, si deriva un control ActiveX de un componente de
su biblioteca llamado TNavPanel, el asistente generará para el nuevo control el
nombre NavPanelX. Usted puede cambiar este nombre si lo desea, y si ya ha
creado un control ActiveX a partir del componente y ha utilizado este nombre
por defecto la vez anterior, tendrá que utilizar un nuevo nombre en las ocasio-
nes subsiguientes o recibirá el mensaje de error bajo discusión.
Solución rápida
Asegúrese de que todos los paquetes requeridos estén instalados en el directo-
rio de sistema de Windows (C:\Windows\System).
Información adicional
En Delphi 3, VCL30.DPL es el archivo de biblioteca de componentes principal.
En Delphi 4, es VCL40.BPL, y en Delphi 5 - VCL50.BPL. En Delphi 6, sin
embargo, las cosas cambian: es simplemente VCL.BPL. Todos los problemas de
versiones se resolverán conservando estos archivos en localizaciones separadas
para cada versión de Delphi que tenga instalada. En otras palabras, Delphi 7
presumiblemente vendrá con un archivo denominado VCL.BPL (como lo hace
Delphi 6), pero éste será instalado en un lugar diferente del disco que el
VCL.BPL que viene con Delphi 6. Estos ficheros (VCL*.BPL) sustituyen par-
cialmente a COMPLIB.DCL (Delphi 1) y CMPLIB32.DCL (Delphi 2). Decimos
“parcialmente” debido a que la biblioteca de código completa de Delphi está
ahora dividida en varios ficheros .BPL diferentes (VCL.BPL, RTL.BPL, etc.).
Cuando esté construyendo aplicaciones para utilizar los paquetes de tiempo de
ejecución, asegúrese de que todos los paquetes requeridos se instalen en la
máquina de destino. Puede hacer esto utilizando InstallShield Express, que es
proporcionado con la mayoría de las versiones de Delphi.
Solución rápida
Debe confirmar o deshacer cualquier transacción antes de iniciar otra.
Información adicional
En DBExpress, las transacciones son numeradas. Por ejemplo:
SQLTransaction1.StartTransaction(1);
Mensajes de error 39
Solución rápida
Debe finalizar una transacción de base de datos confirmándola o deshaciéndola
antes de iniciar otra.
Información adicional
Consulte “StartTransaction” e “InTransaction” en la ayuda de Delphi para más
información.
40 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Asegúrese de asignar siempre un valor a todos los campos obligatorios de las
tablas.
Información adicional
Se pueden utilizar tres niveles diferentes de validación de los datos de una
tabla: a nivel de tabla, a nivel de registro y a nivel de campo. Adicionalmente,
se puede imponer una validación a nivel de caracteres en el momento que el
usuario está introduciendo valores utilizando la propiedad EditMask de TField
o a través de código personalizado añadido a cualquiera de los eventos OnKey-
Down u OnKeyPress.
La validación a nivel de tabla se establece durante el diseño de la tabla para
garantizar que el tipo de datos y el tamaño del campo es apropiado para los
valores con los que el campo será llenado. Por ejemplo, un campo llamado
DateOfBirth (Fecha de Nacimiento) deberá utilizar el tipo de datos Date, un
campo llamado LastName (Apellido) deberá contener un String (conocido como
Alpha en Paradox, Char y VarChar en las bases de datos SQL), etc.
Puede (y se recomienda hacerlo) especificar un campo o columna de una tabla
como su clave primaria. Esto evita que a dos registros se les pueda asignar el
mismo valor para este campo. Un ejemplo de dónde podría utilizar esta carac-
terística es en un campo SSN (Número de Seguridad Social) para una tabla
Employee (Empleados). Los campos de tipo Autoincrement también se utilizan
frecuentemente como claves primarias.
Utilizando el Database Desktop y tablas Paradox, se establece un campo como
clave primaria de la tabla durante su diseño haciendo doble clic sobre la
columna Key (o pulsando cualquier tecla cuando la columna tenga el foco). Si
crea la tabla mediante código, puede utilizar el método AddIndex y el valor
ixPrimary en el parámetro Options para indicar que el campo es clave prima-
ria. Consulte “TTable.AddIndex” en la ayuda de Delphi para más información.
Adicionalmente, puede designar campos como obligatorios (required) para evi-
tar que puedan ser dejados en blanco. Para hacer esto en el Database Desktop
con tablas Paradox, seleccione la casilla de verificación 1. Required Field
mientras el campo que se quiere hacer obligatorio está seleccionado en la sec-
ción Field Roster.
Mensajes de error 41
(al contrario de esperar hasta que los valores de todos los campos del registro
sean introducidos).
Para implementar la validación a nivel de campo, puede utilizar el evento
OnValidate de la clase TField. Utilizando este evento, podrá detectar un error
en la introducción de datos inmediatamente, y no varios campos más adelante.
Por ejemplo, he aquí un gestor de eventos que puede ser asignado a un evento
OnValidate de TField para impedir que un valor inapropiado sea introducido:
const
crlf = #13#10; {retorno/cambio de línea}
...
procedure TForm1.Table1QuantityValidate(Sender: TField);
begin
if Table1Quantity.Value < 1 then begin
raise Exception.Create( Cada ítem solicitado requiere' + crlf +
‘ una cantidad de al menos 1.' + crlf +
‘De lo contrario, iremos a la quiebra' + crlf +
' y se quedará sin trabajo.');
Edit3.Color := clRed;
Edit3.SetFocus;
end;
end;
Solución rápida
1. Debe redefinir e implementar cualquier método virtual abstracto antes de
llamarlo. Para el ejemplo de TCustomGrid, redefina el método DrawCell en
la declaración del componente, de esta forma:
protected
procedure DrawCell(ACol, ARow: Longint; ARect:
TRect; AState: TGridDrawState); override;
. . .
44 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Los métodos virtuales pueden ser redefinidos en las clases descendientes. Los
métodos virtuales abstractos deben ser redefinidos en las clases descendientes.
Tenga en cuenta este tipo de situaciones cuando herede de un componente
TCustomX, así como de la clase TStrings.
Solución rápida
Incluya la directiva Virtual o Dynamic detrás de la signatura del método,
antes de la directiva Abstract.
Información adicional
Para los métodos normales (no abstractos), el tipo de método por defecto es el
estático. Para métodos abstractos, se debe especificar Virtual o Dynamic. Los
métodos Abstract deben ser redefinidos, ya que no están definidos en la clase
donde han sido declarados. Esa es la razón por la cual este tipo de clases se
conoce generalmente como clases base (otras clases heredan de ellas, redefi-
niendo el comportamiento abstracto). Las tres declaraciones siguientes son
todas aceptables:
procedure Radio(Interference: Variant); {método estático}
procedure Reality(Memory: Extended); virtual; {método virtual}
procedure Fluid(Duo: Boolean); dynamic; {virtual y dinámico}
Solución rápida
1. Asegúrese de que los objetos a los que hace referencia ya hayan sido crea-
dos, y que no se haga ninguna referencia a objetos después que hayan sido
destruidos. Por ejemplo, asegúrese de que el formulario (o módulo de datos)
en el que su objeto reside haya sido creado (y no haya sido todavía des-
truido) cuando haga referencia a cualquiera de sus propiedades y métodos.
2. Redefina el método Notification y asigne Nil a la propiedad en caso de que
el componente al que se hace referencia sea eliminado del formulario. Por
ejemplo, he aquí las partes relevantes para la implementación del código
de notificación:
TForTheTillerman = class(TComponent);
private
FReferencedObject: TBird;
. . .
protected
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
. . .
implementation
. . .
procedure TForTheTillerman.Notification(AComponent:
TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FReferencedObject) then
FReferencedObject := nil;
end;
3. Si tiene acceso al archivo fuente del componente (*.PAS), asegúrese de que
éste redefine el constructor de su ancestro de la siguiente forma:
public
. . .
constructor Create(AOwner: TComponent); override;
. . .
constructor TControl.Create(AOwner: TComponent);
begin
{Esto hace accesible a los métodos y propiedades heredados
y reserva memoria para ellos}
inherited Create(AOwner);
. . .
end;
Mensajes de error 47
Información adicional
Para crear dinámicamente un formulario (y posteriormente destruirlo), siga
estos pasos:
a. Seleccione View | Project Manager.
48 Los Tomos de Delphi: Delphi sin problemas
GetMem(ptrBuf, RightSize);
FillChar(ptrBuf, RightSize, 0);
Solución rápida
Utilice el operador de derreferenciación (^), de esta manera:
var
ptrBuf: Pointer; //o cualquier otro tipo puntero, como PChar
begin
GetMem(ptrBuf, RightSize);
FillChar(ptrBuf^, RightSize, 0);
Información adicional
En el contexto del ejemplo anterior, el código compila sin error, ya que es sin-
tácticamente correcto. Sin embargo, dado que el puntero en sí (y no la memoria
a la que apunta) es quien ha sido rellenado con ceros, cuando el programa
eventualmente vuelva a la pila para ver a dónde debe retornar, la dirección
que leerá no será una dirección válida, sino $00000000 (lo que provocará el
mensaje de error).
Solución rápida
Puede llamar al método que utiliza el parámetro por defecto proporcionándole
el segundo parámetro (aún cuando su valor sea el mismo que el valor por
defecto proporcionado en la declaración), de esta manera:
Información adicional
La solución mostrada arriba no es la aproximación recomendada, ya que usted
no sería capaz de llamar al otro método PTBoat. Es mejor evitar la utilización
conjunta de métodos con el mismo nombre (sobrecargados) y parámetros por
defecto, a menos que las signaturas de los métodos difieran lo suficiente como
para no causar confusión (al hombre o a la máquina) cuando se llame a cual-
quiera de los métodos.
a:
TFormMaintainanceScript = class(TForm)
Solución rápida
Si la intención es realmente cambiar a TForm como clase base, simplemente
pulse OK en respuesta a todos los mensajes “Component was deleted, delete
reference?”.
Información adicional
Si quiere colocar los componentes sobre el formulario que ahora desciende de
TForm, seleccione Create component as new on the descendant.
Mensajes de error 51
Solución rápida
Llame a Sessions.OpenSession antes de llamar a la función del BDE.
Información adicional
También es posible que esté ejecutando con insuficiente memoria.
Si el código del error es $2C08, consulte “Not initialized for accessing net-
work files”.
Si el código del error es $2C09, consulte “Share not loaded. It is required
to share local files”.
Si el código del error es $2108, consulte “Cannot locate IDAPI32.DLL”.
Si el código del error es $2109, consulte “Cannot load IDAPI32.DLL”.
Another file with the same base name (<>) is already on the search
path
Posible causa de error
Puede estar intentando instalar en la VCL un componente del que ya hay una
versión instalada (o un componente diferente con el mismo nombre ya está
instalado).
Solución rápida
Si está reemplazando una versión más antigua por una nueva versión, primero
elimine la versión más vieja de la biblioteca de componentes antes de instalar
la nueva versión.
52 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Para eliminar un componente existente de su biblioteca de componentes, siga
estos pasos:
Delphi 1y 2
Para eliminar un componente, siga estos pasos:
1. Seleccione Component | Configure Palette.
2. En el cuadro de lista Pages situado a la izquierda del cuadro de diálogo
que se despliega, seleccione la página que contiene el componente que
desea eliminar. Los componentes que integran esa página aparecerán en el
cuadro de lista Components al lado derecho.
3. Seleccione el componente que desea borrar.
4. Pulse el botón Delete.
5. Pulse el botón OK.
Delphi 3
Para eliminar un componente en Delphi 3 pueden utilizarse dos métodos:
Puede eliminar un componente de una página en particular:
1. Seleccione Component | Configure Palette.
2. Seleccione la página en la que el componente reside en el cuadro de lista
Pages.
3. Pulse sobre el componente en el cuadro de lista Components (no es sufi-
ciente que el componente esté simplemente resaltado — debe pulsar sobre
él para evitar obtener el mensaje de error “A page must be empty
before it can be deleted”).
4. Pulse el botón Delete.
O puede eliminar un componente de un paquete en particular:
1. Seleccione Project | Options, y luego pulse sobre la pestaña Packages.
2. En la sección Design Packages de la página Packages, seleccione el paquete
en el que reside el componente que desea eliminar (para ver qué componen-
tes están contenidos en cada paquete, pulse el botón Components).
3. Pulse el botón Edit (no pulse el botón Remove, a menos que quiera desha-
cerse del paquete entero).
4. Seleccione Yes en el cuadro de diálogo de confirmación que aparece.
5. Pulse con el botón derecho sobre la unidad que desea eliminar y seleccione
la opción Remove Unit del menú de contexto.
Mensajes de error 53
Para localizar el archivo que tiene el mismo nombre del que se está intentando
instalar, seleccione Tools | Environment Options. . . y luego inspeccione el
cuadro Library path de la página Library para determinar el camino de bús-
queda que Delphi está utilizando. Puede luego buscar el archivo en esos direc-
torios utilizando las características del Explorador de Windows.
Delphi 4 y superiores
Puede ocultar un componente de modo que no aparezca en la Paleta de Compo-
nentes, o eliminar el paquete en el que reside.
Para hacer que un componente no aparezca en la Paleta (esconderlo), siga
estos pasos:
1. Seleccione Component | Configure Palette.
2. Seleccione la página de la paleta en la que el componente aparece en el
cuadro de lista Pages.
3. Pulse sobre el componente en el cuadro de lista Components (no basta
con simplemente seleccionar el componente — debe pulsar sobre él para
evitar obtener el mensaje de error “A page must be empty before it can
be deleted” ).
4. Pulse el botón Hide.
Para eliminar un componente de un paquete en particular, siga estos pasos:
1. Seleccione Project | Options, y luego pulse sobre la pestaña Packages.
2. En la sección Design Packages de la página Packages, seleccione el
paquete en el que el componente que desea eliminar reside (para ver qué
componentes están contenidos en cada paquete, pulse el botón
Components).
3. Pulse el botón Remove.
Solución rápida
Si no tiene Delphi Cliente/Server (Enterprise), tendrá que desistir de intentar
ejecutar el programa de demostración o adquirir la edición Cliente/Server
(Enterprise).
Si tiene Delphi Cliente/Server y todavía obtiene este mensaje de error, deberá
desinstalar Delphi y luego volverlo a instalar siguiendo estos pasos:
54 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Como las diferentes ediciones de Delphi difieren en características y componen-
tes, no es posible mezclar y combinar proyectos creados con diferentes edicio-
nes. Esto también es válido entre versiones. Es decir, usted no puede compilar
un proyecto creado con una versión de Delphi de 32 bits en Delphi 1 (sin hacer
algunas modificaciones). Consulte la página principal de Delphi en el sitio web
de Borland (http://www.borland.com) para obtener información específica sobre
las diferencias en cuanto a características y componentes entre las distintas
ediciones de Delphi.
Consulte el mensaje “Your application is not enabled for use with this
driver”.
Solución rápida
Cuando declare variables, verifique que sus tipos son adecuados para contener
todos los posibles valores que podría querer almacenar en ellas. Por ejemplo, si
una variable particular puede manejar valores hasta 100.000, no utilice un tipo
de variable Word; en lugar de ello, utilice un Integer (LongInt en Delphi 1).
Información adicional
La excepción es “Runtime Error 215”. Esta excepción solamente se produce si
ha habilitado la comprobación de desbordamiento en el entorno integrado o en
el código.
Para habilitar la comprobación de desbordamiento en el entorno integrado,
siga estos pasos:
Mensajes de error 55
Delphi 1
Seleccione Options | Project, y sobre la página Compiler, verifique que la
casilla de verificación Overflow checking esté habilitada.
Delphi de 32 bits
Seleccione Project | Options, y sobre la página Compiler, verifique que la
casilla de verificación Overflow checking (Q) esté habilitada.
Para habilitar la comprobación de desbordamiento mediante código, añada la
directiva {$Q+} en la parte superior de la(s) unidad(es) donde desee habilitarla.
Solución rápida
Asegúrese de que solamente aplica índices a variables de tipo array.
Información rápida
El siguiente código producirá el mensaje de error bajo discusión, debido a que
en él se hace un intento de acceder a un elemento de RuggedIndividualist, y
esta variable no es un array y por ello no tiene elementos que puedan ser
indizados:
procedure IndexIntoTheArray(element: integer);
var
RuggedIndividualist: integer;
begin
RuggedIndividualist[1] := element;
end;
Assertion failed
Posible causa de error
Una expresión de tipo Boolean pasada a la función Assert ha producido False.
Solución rápida
Si la aserción debería cumplirse, revise el código para averiguar la causa por la
que está fallando.
56 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Si el valor de la expresión debe ser True para que el programa se ejecute efec-
tivamente o proporcione resultados válidos, interrumpa el programa en caso de
que la aserción falle.
Aquí se muestra un ejemplo de cómo utilizar el procedimiento Assert:
procedure ScrutinizePayCheck(amtpaid, amtexpected: Currency);
begin
try
Assert(amtpaid >= amtexpected, '¿Qué está pasando aquí?');
except
on EAssertionFailed do
Halt;
end;
end;
Solución rápida
Elimine la asignación a la variable de control del bucle For.
Información adicional
La variable de control de un bucle For es la variable (comúnmente una varia-
ble entera como i) a la cual se asigna un valor inicial como valor de partida, y
que se incrementa en 1 al finalizar cada iteración. Este valor frecuentemente
se inicializa a 0. El valor final es generalmente una variable, cuyo valor deter-
mina cuántas veces el bucle For se ejecutará. Por ejemplo, a continuación se
muestra un bucle For con sus elementos anotados en los comentarios:
procedure SimpleLoop(TimesToLoop: integer);
var
i: integer; {i es la variable de control del bucle}
s: string;
begin
s := '';
for i := 0 to TimesToLoop do {valores inicial y final}
s := s + IntToStr(i); {cuerpo del bucle}
end;
Mensajes de error 57
Solución rápida
Asigne a las propiedades Port de ambos componentes el mismo valor; de esta
forma, el componente TClientSocket se conectará al mismo puerto por el cual
el componente TServerSocket está escuchando.
Información adicional
Consulte el archivo Services (en C:\Windows) para determinar los números de
puertos que ya están asociados normalmente para otros usos. Por ejemplo, este
es un extracto del archivo:
58 Los Tomos de Delphi: Delphi sin problemas
ftp 21/tcp
Telnet 23/tcp
smtp 25/tcp
At end of table
Posible causa de error
Puede estar intentando acceder a la propiedad OldValue de un campo al inser-
tar un nuevo registro en modo de actualizaciones en caché (CachedUpdates).
Debido a que no existe una versión anterior de este registro, es imposible acce-
der a su valor anterior.
Solución rápida
Antes de intentar acceder a la propiedad OldValue, primero determine si es
factible efectuar una comprobación para ver si el estado del DataSet es dsEdit,
así:
if Table1.State = dsEdit then
FogieVal := OldValue;
Información adicional
Cuando se utilizan actualizaciones en caché, los registros almacenados en la
caché se conocen como ‘valores antiguos’. Esto le permite cancelar las
modificaciones realizadas, y que los campos vuelvan a sus valores anteriores
(con los valores antiguos recuperando su status como valores actuales).
SlErrMsgs.Add(
Format(SErrorMessage, [E.Message,
RaiseLastWin32Error, DateTimeToStr(Now)]);
2. Puede haber intentado insertar una sentencia en el lugar donde se espe-
raba un array constante, como la sección de argumentos de la función
Format. Por ejemplo, el siguiente código generará este mensaje de error:
VariableFormat := Format('%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s\',
[ SEGMENT_IDENTIFIER, {3}
TaxPayerIdentification, {4}
TAX_TYPE_CODE, {5}
PayrollDate, {6}
if length(Trim(NYStateTaxWithheld)) > 0 then
StateAmountTypeCode := STATE_AMOUNT_TYPE_CODE; {7}
. . .
Solución rápida
1. Elimine el procedimiento, o sustitúyalo por una función o variable del tipo
de datos apropiado. Para reparar la línea de código mostrada arriba, por
ejemplo, podría cambiarla a:
SlErrMsgs.Add(
Format(SErrorMessage, [E.Message,
SysErrorMessage(GetLastError), DateTimeToStr(Now)]);
2. Mueva la sentencia fuera de la sección de argumentos. Por ejemplo, para
reparar el código de arriba, haga esto:
StateAmountTypeCode := '';
. . .
if length(Trim(NYStateTaxWithheld)) > 0 then
StateAmountTypeCode := STATE_AMOUNT_TYPE_CODE;
VariableFormat := Format('%s*%s*%s*%s*%s*%s*%s*%s*%s*%s*%s\',
[ SEGMENT_IDENTIFIER, {3}
TaxPayerIdentification, {4}
TAX_TYPE_CODE, {5}
PayrollDate, {6}
StateAmountTypeCode, {7}
. . .
Información adicional
En todo jardín “se cuelan” algunos insectos.
60 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Ignore el error si la definición especificada en el mensaje de error no es necesa-
ria para sus propósitos, o modifique el archivo .OBJ.
Información adicional
Si recibe este mensaje de error, la definición del archivo objeto (.OBJ) que pro-
voca el error sea ignorado.
Las directivas $L y $LINK son sinónimas, y se utilizan para enlazar procedi-
mientos y funciones escritos en otros lenguajes y declarados en Delphi como
externos.
La sintaxis que se utiliza para ello es:
$L[INK] <Archivo objeto>
Solución rápida
Delphi 3
Mueva o borre el archivo .DCP mencionado en el mensaje de error y recompile
el paquete.
Delphi 4 y superiores
Mueva o borre el archivo .DCP mencionado en el mensaje de error y reinstale
el paquete.
Información adicional
Para recompilar un paquete después de borrar el archivo .DCP, siga estos
pasos:
1. Seleccione Component | Install Packages. . . .
2. Seleccione el paquete apropiado en el cuadro de lista Design Packages.
3. Pulse el botón Edit.
4. Pulse el botón Yes en el cuadro de diálogo de confirmación que aparece.
5. Pulse el icono Compile.
Si continúa recibiendo el mismo mensaje de error después de borrar el archivo
corrupto y recompilar el paquete, contacte con Borland por teléfono o a través
de su sitio web.
Solución rápida
Recompile el archivo fuente de la unidad (.PAS) para producir un nuevo
archivo de unidad compilada (.DCU).
Información adicional
Si el .DCU es un archivo de componente, siga estos pasos para recompilar el
archivo fuente de unidad (.PAS) para producir un nuevo archivo de unidad
compilada (.DCU):
1. Seleccione la siguiente opción, en dependencia de su versión de Delphi:
Delphi 1: Options | Install Components
Delphi 2: Component | Install
Delphi 3-6: Component | Install Component
62 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Cambie los valores de los parámetros SHAREDMEMLOCATION y
SHAREDMEMSIZE con la Utilidad de Configuración del BDE (página System
| nodo Init). Incremente el valor de SHAREDMEMSIZE a $4096 u $8192 (es
$2048 por defecto).
Si está ejecutando Windows 95/98, introduzca un valor para
SHAREDMEMLOCATION entre $9000 y $FFFF; si es Windows NT/2000,
entre $1000 y $7F00. Inténtelo primero con $1000. Después cambiar el valor,
cierre todas las aplicaciones que utilicen el BDE. Puede ser necesario probar
con varios valores antes de encontrar uno que funcione bien.
Información adicional
Este error corresponde a “Insufficient memory for this operation” (memo-
ria insuficiente para esta operación).
Para más información, consulte la ayuda del BDE.
Mensajes de error 63
Before you can deploy, you must complete the Web Deployment
page of the Project|Web Deploy Options dialog
Posible causa de error
Puede haber seleccionado Project | Web Deploy sin haber proporcionado
toda la información necesaria en la pestaña Projects del cuadro de diálogo
Web Deploy Options (no hay una página Web Deployment, a pesar del texto
del mensaje de error).
Solución rápida
Pulse OK para desechar el mensaje de error y volver a la página Projects del
cuadro de diálogo Web Deploy Options (Project | Web Deploy Options).
Debe proporcionar entradas en los cuadros de edición Target Dir, Target
URL y HTML Dir.
Información adicional
Además de las entradas requeridas en la página Projects, hay también otras
opciones que debe especificar también en las páginas Packages, Additional
Files y Code Signing del cuadro de diálogo Web Deploy Options.
Los ítems de menú Web Deploy Options y Web Deploy no están disponibles
si no ha abierto un proyecto o está trabajando con un tipo de proyecto
convencional.
Solución rápida
1. Asegúrese de que cualquier archivo que intente cargar en la propiedad
Picture del componente TImage sea realmente un archivo gráfico válido.
2. Cambie el valor de la propiedad Picture.Bitmap.PixelFormat.
3. Haga lo siguiente en el evento AfterScroll del objeto TDataset:
64 Los Tomos de Delphi: Delphi sin problemas
Información adicional
3. Las bases de datos de Microsoft antes mencionadas almacenan los gráficos
como objetos OLE y no como datos puros.
Solución rápida
No utilice como índice un número negativo o un número mayor que el valor de
la propiedad Size de TBits. Si no se asigna explícitamente un valor a la propie-
dad Size, el array se expandirá automáticamente tanto como sea necesario
cuando se asignen valores a elementos de un array TBits.
Información adicional
Los Bits a los que se refiere el mensaje de error es el objeto TBits, que imple-
menta un array de valores Boolean.
En el ejemplo de arriba, un intento de asignar un valor al elemento 7 del array
también provocaría el mensaje de error, ya que el índice está basado en 0 (y
por ello un tamaño de 7 creará únicamente los elementos 0, 1, 2, 3, 4, 5 y 6).
Solución rápida
1. Reemplace la versión de VREDIR.VXD. La versión original (4.00.950) y la
versión 4.00.1116 no ocasionan el problema. VREDIR.VXD debería estar
66 Los Tomos de Delphi: Delphi sin problemas
Información adicional
1. Todos los usuarios pueden ser afectados si algún usuario tiene la versión
inválida de VREDIR.VXD (incluso aquellos que personalmente tienen una
versión correcta en sus máquinas).
2. A continuación se muestra una tabla de los tipos de datos Paradox y sus
correspondientes clases descendientes de TField de Delphi:
Solución rápida
Solamente llame a Break o Continue dentro de un bucle For, While o Repeat.
Extienda el bucle For o While, si es necesario, añadiendo una sección
Begin. . . End después de la palabra reservada Do (los bucles Repeat ya conside-
ran el bloque entero entre Repeat y Until como una sentencia compuesta, y por
lo tanto éstas no necesitan estar encerradas en un bloque Begin. . . End.)
Información adicional
Lo siguiente producirá el mensaje de error bajo discusión:
procedure SaturdayNightAtTheMovies;
begin
while WatchingMovie do
EatPopcorn;
if TheaterCatchesFire then
Break;
end;
procedure DetermineCourseOfAction;
begin
CheckItOut(Soul);
CashItOut(Retirement);
end;
procedure StopInTheNameOfTheLaw;
begin
if YouNeedToShutDownTheApp then
Application.Terminate;
end;
Solución rápida
Quite el punto de ruptura. Asigne puntos de ruptura solamente sobre líneas
que generan código, tales como líneas que contienen sentencias de asignación.
Información adicional
El optimizador de Delphi puede haber eliminado la línea en cuestión (obvia-
mente, no ignorando las líneas que usted ha escrito, sino sólo en lo que al com-
pilador concierne), debido a que el código nunca es llamado en la aplicación.
Un ejemplo de dónde podría obtener el mensaje de error bajo discusión es si
intenta ejecutar la aplicación hasta un lugar de la sección Interface de una
unidad. Normalmente no debería intentar hacer esto; otros ejemplos (en la sec-
ción Implementation) podrían ser la primera línea de un procedimiento, una
línea de declaración de variables, etc.
En el siguiente procedimiento, las líneas que producen este mensaje de error
(si coloca un punto de ruptura sobre ellas) se indican mediante comentarios
que indican “¡aquí no!”:
Solución rápida
Asegúrese de que el archivo de proyecto (seleccione View | Project Source —
Project | View Source en Delphi 4 y posteriores — para examinar el código
fuente del archivo de proyecto) contiene la siguiente sintaxis para cargar al
menos el formulario principal del programa (puede haber múltiples líneas
similares para crear diversos formularios):
Application.CreateForm(TForm1, Form1);
Información adicional
Todos los demás formularios de la aplicación (exceptuando el formulario princi-
pal) pueden ser cargados dinámicamente cuando sean necesarios. Esto amor-
tiza el coste de tener creados los formularios durante períodos de tiempo más
largos de lo necesario, y de crear algunos formularios (como el cuadro de diá-
logo Acerca de..., si tiene alguno) que podrían no ser necesarios en absoluto.
Para crear dinámicamente un formulario (y posteriormente destruirlo), siga
estos pasos:
1. Seleccione View | Project Manager.
2. Pulse el botón Options.
3. En el cuadro de lista Auto-Create Forms, seleccione el formulario que
desea crear dinámicamente.
4. Pulse el botón de flecha a la derecha para mover el formulario a la lista
Available Forms.
5. Pulse el botón OK.
6. Modifique el código que utilizó para mostrar el formulario por el siguiente:
procedure TForm1.ShowAbout(Sender: TObject);
begin
About := TAbout.Create(nil);
try
About.ShowModal;
finally
About.Free;
end;
end;
Sin embargo, si intenta mostrar el formulario antes de que sea creado, así:
AboutBox.ShowModal:
AboutBox := TAboutBox.Create(Application);
AboutBox.Free;
o si ha obviado completamente la llamada a Create, provocará el mensaje
de error bajo discusión.
Es una buena idea crear dinámicamente los formularios mediante código, espe-
cialmente si no son necesarios durante todo el tiempo de ejecución de la
aplicación. Si no crea dinámicamente sus formularios, todos serán creados
72 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Asegúrese de que el End final está intacto y que no ha sido comentado. Verifi-
que que todo Begin tiene un End correspondiente, y que todos los comentarios
que empiezan con una llave izquierda ({ ) estén emparejados con su correspon-
diente llave derecha ( }).
Información adicional
El procedimiento RegisterClass es diferente de RegisterComponents, que se
utiliza en las unidades de componentes para especificar el nombre del compo-
nente y la página en la que será colocado (o, si la página no existe, la página
que será creada para alojar el componente).
Solución rápida
1, 2. Cambie el valor de la propiedad Active a False, haga los cambios, y luego
asigne nuevamente True a la propiedad Active.
Información adicional
El componente TClientSocket apareció en Delphi 4, como el resto de los compo-
nentes de la página Internet. Las versiones anteriores de Delphi tenían una
Mensajes de error 73
Solución rápida
Fusione algunos de los componentes propios o de terceros dentro de uno o unos
pocos directorios comunes y edite la ruta de búsqueda consecuentemente.
Información adicional
Puede también ser útil utilizar nombres de directorios tan cortos como sea
posible. Aparentemente, es el tamaño conjunto de todas las rutas de archivos
lo que ocasiona el problema.
Solución rápida
1. Si necesita modificar un registro maestro, no cambie los valores de los cam-
pos claves, ya que los registros hijos (de detalle) los utilizan para localizar
a su “padre”. Si necesita borrar un registro maestro, borre primero los
registros hijos asociados e él.
2. Actualícese a Access 97, Paradox, InterBase, o alguna otra base de datos.
Alternativamente, elimine la “funcionalidad” de integridad referencial de la
base de datos Access 95.
74 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Consulte “referential integrity” en la ayuda de Delphi.
Solución rápida
1. Asegúrese de que su archivo de biblioteca de componentes reside en el
lugar apropiado en dependencia de su versión de Delphi. Si encuentra el
archivo en otro lugar, muévalo a la localización apropiada e intentar
recompilar la biblioteca (Delphi 1 y 2) o paquete o reinstalar el paquete
(Delphi 3-6). Si el archivo ya está en el lugar correcto pero sigue recibiendo
este mensaje error, siga estos pasos:
a. Haga un copia de resguardo del archivo (COMPLIB.DCL,
CMPLIB32.DCL, VCL30.DPL, VCL40.BPL, VCL50.BPL, VCL60.BPL)
y almacénela en un lugar seguro.
b. Borre la copia original del archivo que ha copiado.
c. Si anteriormente había hecho cambios al archivo, Delphi habrá creado
antes una copia de resguardo de la versión anterior, reemplazando la
primera letra de la extensión con una tilde (~) y truncando la última
letra de la extensión. En Delphi 1, este archivo se llamará
COMPLIB.~DC; en Delphi 2, CMPLIB32.~DC, etc. Si encuentra el
archivo apropiado para su versión de Delphi, renómbrelo en
correspondencia con su versión de Delphi y restáurelo a su estado
inicial como biblioteca de componentes de Delphi. Si no ha hecho
cambios anteriormente al archivo, o la copia de resguardo no existe,
copie el archivo desde el CD de Delphi al lugar apropiado para su
versión de Delphi.
2. Reconstruya o reinstale la biblioteca de componentes.
3. Siga los pasos a-c de arriba para reinstalar la última copia buena de la
VCL.
Mensajes de error 75
Información adicional
En Delphi 1, el nombre de archivo de la biblioteca de componentes era
COMPLIB.DCL. Su tamaño era de 1.036 KB. En Delphi 2, el archivo de la
biblioteca de componentes fue renombrado a CMPLIB32.DCL. Su tamaño era
de 4.636 KB. En Delphi 3-6, no hay ningún archivo con extensión .DCL. En
lugar de una unidad conteniendo toda la VCL, se proporcionan muchos paque-
tes independientes que contienen grupos de componentes relacionados. El
paquete principal, que contiene los componentes más comunes y las unidades
que necesitará para un proyecto de Delphi típico, está contenido en un archivo
.DPL (Delphi package library). En Delphi 3, VCL30.DPL ocupa 1.257 KB. En
Delphi 4, VCL40.BPL ocupa 1.753 KB. En Delphi 5, VCL50.BPL ocupa 1.976
KB. En Delphi 6, el tamaño de VCL60.BPL es de 2.386 KB. Una instalación
completa de Delphi 3 incluye aproximadamente 25 archivos .DPL. Delphi 4
introduce los archivos .BPL, de los cuales hay 38 en la versión Cliente/Server.
La edición Enterprise de Delphi 5 (equivalente a la antigua edición Client/Ser-
ver) contiene 40 archivos .BPL, y la misma edición de Delphi 6 contiene aproxi-
madamente 55 archivos .BPL.
Can’t load package <>.<> One of the library files needed to run
this package cannot be found
Posible causa de error
1. Puede ser que el paquete al que se hace referencia en el mensaje de error
(o un paquete o .DLL del que éste depende) no esté instalado, o no esté ins-
talado en el lugar adecuado.
2. Puede estar intentando cargar un paquete que depende de otro paquete o
.DLL que, aunque está instalado en el sistema (y en el lugar correcto), no
es de la versión adecuada.
Solución rápida
1. Asegúrese de que todos los paquetes y .DLLs requeridos estén situados en
el directorio actual o en el camino de búsqueda de Windows (preferente-
mente en el directorio \Windows\System).
2. Si hace cambios a un paquete del que otro paquete depende, recompile
ambos paquetes (el requerido primero y el dependiente después).
Información adicional
Los paquetes de Delphi son DLLs especializadas (con extensión .DPL en Del-
phi 3 y extensión .BPL en Delphi 4 y superiores) que aparecieron por primera
76 Los Tomos de Delphi: Delphi sin problemas
Can’t load package <>. The specified module could not be found.
Posible causa de error
Puede haber instalado un paquete en Delphi, y haberlo movido posteriormente
a una localización diferente.
Solución rápida
Puede:
Mover el paquete de nuevo a su localización anterior.
-O-
Mensajes de error 77
Información adicional
Esto puede ocurrirle si instala un paquete desde una localización arbitraria,
como por ejemplo un directorio en el que descarga ficheros de Internet, y poste-
riormente decide mover el código a un lugar más centralizado y/o lógico. La
moreleja de este mensaje de error es: debe determinar de antemano dónde
quiere que residan sus paquetes de tiempo de diseño. Para más información,
consulte “Can’t load package <>.<> One of the library files needed to
run this package cannot be found”.
Solución rápida
Pruebe sucesivamente con estas soluciones cada vez más drásticas hasta que
una de ellas funcione:
1. Salga de Delphi; reinicie Delphi; intente compilar la aplicación de nuevo.
2. Salga de Windows; reinicie Windows (inicio en caliente); reinicie Delphi;
intente compilar la aplicación de nuevo.
3. Salga de Windows; apague el ordenador (inicio en frío); espere un par de
minutos; encienda el ordenador; reinicie Delphi; intente compilar la aplica-
ción de nuevo.
4. Si el espacio en disco duro está en bajo mínimos (menos del 10 por ciento
del tamaño total de la unidad está libre), borre todos los archivos innecesa-
rios. Una vez que haya liberado espacio del disco duro (que podrá utilizarse
como memoria virtual), defragmente el disco duro y luego intente compilar
la aplicación de nuevo.
5. Verifique que la memoria virtual esté configurada correctamente en el sis-
tema (Vea la información adicional).
6. Compre más RAM.
Información adicional
Si le parece que tiene problemas con la configuración de la memoria virtual,
puede hacer que Windows ajuste automáticamente la memoria virtual
siguiendo estos pasos:
78 Los Tomos de Delphi: Delphi sin problemas
Cannot add a session to the form or data module while session <>
has AutoSessionName enabled
Posible causa de error
Puede que ya tenga un componente TSession sobre un formulario o módulo de
datos con la propiedad AutoSessionName asignada a True.
Solución rápida
Si va a añadir múltiples componentes TSession a un formulario o módulo de
datos, asigne False a sus propiedades AutoSessionName.
Información adicional
En una aplicación típica, no necesitará colocar ni siquiera un componente
TSession sobre el formulario o módulo de datos. Un componente TSession es
necesario para la conectividad con bases de datos, pero se crea automática-
mente para usted, de una forma similar a como el objeto Application es creado
automáticamente para cada aplicación Delphi.
Si está creando aplicaciones con múltiples hilos o si está accediendo a tablas
Paradox que residen en varios lugares de una red, sin embargo, puede colocar
componentes TSession adicionales sobre el formulario o módulo de datos para
facilitar el trabajo en esas circunstancias especiales.
El propósito de la propiedad AutoSessionName es garantizar a los desarro-
lladores de aplicaciones con múltiples hilos que las sesiones generadas para
cada hilo son únicas en tiempo de ejecución. Cuando se le asigna True a la pro-
piedad AutoSessionName, automáticamente se generará un nombre único para
cada nueva sesión.
Para más información, consulte “AutoSessionName” en la ayuda de Delphi.
Solución rápida
Añada un especificador Write para la propiedad en cuestión, o absténgase de
asignarle valores si la propiedad debe permanecer como de sólo lectura.
Información adicional
Una propiedad debe tener un especificador Read, un especificador Write, o
ambos. Es una práctica común leer de un campo privado (cuyo nombre, por
convenio, empieza con la letra F), y escribir en él utilizando un procedimiento
cuyo nombre comience con la palabra Set. A continuación se presenta un ejem-
plo de algunas de las posibles maneras de declarar propiedades:
private
FScottFitzgerald: String;
FLeeBailey: Boolean;
FAOSchwarz, FDR: Currency;
FPSantangelo: Extended;
procedure SetFee(i: Integer);
procedure SetPrice(c: Currency);
public
{Esta propiedad es de sólo lectura}
property ScottFitzgerald: String; read FScottFitzgerald;
{Esta propiedad es de sólo escritura}
property LeeBailey: Boolean; write SetFee;
{Esta propiedad es de lectura y escritura}
property AOSchwarz: Currency; read FAOSchwarz; write SetPrice;
Solución rápida
Elimine la llamada que causa el problema de la parte Finally de la sentencia
Try. . . Finally.
80 Los Tomos de Delphi: Delphi sin problemas
Información adicional
El lenguaje garantiza que la parte Finally de una sentencia Try. . . Finally se
ejecutará siempre completamente. Por lo tanto, no se permite utilizar en ellos
procedimientos de control de flujo tales como Break, Continue o Exit, que
impedirían potencialmente que se ejecute algún código situado en la parte
Finally.
Solución rápida
No intente cambiar el tamaño de un archivo de icono (.ICO). Las propiedades
Height y Width de TIcon son de sólo lectura y uniformes para todos los iconos
de Windows (32*32 píxeles para los iconos regulares, y 16*16 píxeles para los
iconos pequeños).
Información adicional
Puede crear iconos (entre otras cosas) con la utilidad ImageEditor de Delphi.
Para activarla, seleccione Tools | Image Editor y luego File | New | Icon.
Puede también crear archivos .DCR para los componentes personalizados que
usted cree. Estos deben ser cuadrados, con 24 píxeles de lado. Para hacerlo,
seleccione Tools | Image Editor, luego File | New | Bitmap, asigne 24 al
ancho y la altura, y seleccione VGA (16 colores), a menos que esté seguro de
que todos los usuarios de su componente utilizan sistemas SuperVGA (256
colores). Las imágenes de 16 colores se muestran correctamente en sistemas
configurados para 256 colores, pero las imágenes de 256 colores pueden lucir
mal al mostrarse en sistemas configurados para 16 colores.
FormStyle := fsStayOnTop;
end;
2. Puede haber intentado asignar un valor a la propiedad Visible de un for-
mulario dentro de los eventos OnActivate, OnShow u OnHide del
formulario. Por ejemplo, lo siguiente producirá el mensaje de error bajo
discusión:
procedure TForm1.FormActivate(Sender: TObject);
begin
Visible := false;
end;
Solución rápida
1. No cambie el valor de la propiedad FormStyle del formulario durante los
eventos OnActivate u OnShow.
2. No cambie el valor de la propiedad Visible del formulario durante los even-
tos OnActivate, OnShow u OnHide.
Información adicional
Si asigna True a la propiedad Visible de un formulario en tiempo de diseño,
éste aparecerá inmediatamente en tiempo de ejecución. Delphi mostrará auto-
máticamente el formulario principal de la aplicación en el arranque, y los
demás formularios se mostrarán cuando sus métodos Show o ShowModal sean
llamados. Si asigna True a la propiedad Visible de todos los formularios de su
aplicación en tiempo de diseño, éstos se mostrarán tan pronto como la aplica-
ción se inicie, lo cual podría provocar que la interfaz de usuario no sea intui-
tiva y provoque confusión al usuario.
Si quiere que un formulario aparezca en respuesta a un evento particular (por
ejemplo, una pulsación sobre un botón) y permanezca en pantalla mientras se
trabaja con otros formularios, puede hacerlo así:
procedure TForm1.Button12Click(Sender: TObject);
begin
Form3.Show;
end;
Solución rápida
Solucione cualquier error de sintaxis que exista (seleccione Alt+P, S para veri-
ficar la sintaxis), y luego inténtelo de nuevo.
Información adicional
Consulte “class completion” en la ayuda de Delphi.
Mensajes de error 83
Solución rápida
Introduzca un GUID válido en la propiedad ServerGUID con este formato:
98ED7140-EE18-11D3-A238-80584EC12700
Información adicional
Si proporciona un valor tanto para ServerName como para ServerGUID, este
mensaje de error no aparecerá, siempre y cuando uno de los dos valores sea
válido.
Solución rápida
Proporcione la contraseña cuando se presente el cuadro de diálogo Database
Login, y luego pulse el botón OK.
Información adicional
Puede evitar tener que introducir continuamente una contraseña mientras está
desarrollando su aplicación, asignando la contraseña mediante código o a tra-
vés de la sección Parameter Overrides del editor del componente TDatabase.
84 Los Tomos de Delphi: Delphi sin problemas
Para asignar la contraseña mediante código, añada una línea como la siguiente
antes de acceder a la base de datos (por ejemplo, en el evento OnCreate del for-
mulario o módulo de datos):
Session.AddPassword('Kennwort');
Solución rápida
Guarde el nuevo proyecto en un directorio diferente.
Información adicional
Un ejemplo de cómo podría ocurrir este error es si se ejecutan los siguientes
pasos:
1. Bajo el directorio Delphi X\Objrepos\Logoapp (en Delphi 3 o 4), crear un
directorio llamado Logjam.
2. Seleccionar File | New.
3. Seleccionar el icono Win 95 Logo Application de la página Projects.
4. Intentar guardar el nuevo proyecto (basado en el proyecto Logoapp del
Almacén) en el directorio creado anteriormente.
Mensajes de error 85
Solución rápida
1. Si la sentencia SQL utilizada en el componente TQuery no devuelve un
conjunto de valores (no es una sentencia SELECT de SQL), utilice el
método ExecSQL de TQuery en lugar de Open.
2. Asigne una sentencia SELECT de SQL válida a la propiedad SQL.
Información adicional
Si está utilizando la propiedad SQL para insertar, actualizar o borrar valores
de una tabla, utilice el método ExecSQL de TQuery. El método Open es sólo
para sentencias SELECT.
Annotate := TStringList.Create;
try
Annotate.LoadFromFile('C:\standing\snapshot.txt');
Annotate.Add('Siendo las ' + DateTimeToStr(Now) +
', los resultados son los siguientes...');
. . .
Annotate.SaveToFile('C:\standing\snapshot.txt');
finally
Annotate.Free;
end;
. . .
Solución rápida
1. Asegúrese de que el directorio en el que intenta grabar un archivo con el
método SaveToFile ya ha sido creado. Puede primero crear el directorio y
luego grabar el archivo en él. Por ejemplo, en el ejemplo de arriba podría
hacer esto:
CreateDir('C:\dotbumps');
Image1.Picture.SaveToFile('C:\dotbumps\road.BMP');
2. Asegúrese de que el archivo en el que intenta escribir no esté protegido
contra escritura (sólo lectura).
Información adicional
Los métodos SaveToFile y LoadFromFile de la clase TPicture pueden ser utili-
zados con archivos gráficos. Los métodos SaveToFile y LoadFromFile de la
clase abstracta TStrings pueden ser aplicados a cualquier variable o propiedad
de tipo TStrings, como por ejemplo la propiedad SQL del componente TQuery,
así como a objetos de clases descendientes de TStrings, tales como TStringList.
Por ejemplo, a continuación se muestran algunas formas en las que el método
SaveToFile puede ser utilizado:
procedure TForm1.Button3Click(Sender: TObject);
var
Liszt: TStrings;
begin
Liszt := TStringList.Create;
try
Liszt.Add('Franz, Hungary');
CreateDir('C:\Composers');
{Llamada a SaveToFile de TStringList}
Liszt.SaveToFile('C:\Composers\FLiszt.txt');
{Llamada a SaveToFile de la propiedad SQL de TQuery}
Query1.SQL.SaveToFile('st8ments.txt');
{Llamada a SaveToFile de TPicture para grabar un bitmap;
se asume que el directorio Pitchers ya ha sido creado}
Image1.Picture.SaveToFile('C:\Pitchers\vase.BMP');
finally
Mensajes de error 87
Liszt.Free;
end;
end;
Solución rápida
1. Asegúrese de que la propiedad FormStyle del formulario padre (el formula-
rio cuya propiedad FormStyle tiene el valor fsMDIForm) sea creado antes
de la creación de los formularios hijos.
2. Si algún formulario de la aplicación ha sido configurado como formulario
hijo MDI (asignando fsMDIChild a su propiedad FormStyle), el valor
correspondiente del formulario principal del proyecto debe ser fsMDIForm.
Información adicional
1. Si crea formularios dinámicamente (en el código, en tiempo de ejecución),
el formulario padre debe ser creado en primer lugar.
MDI significa ‘Interfaz de Múltiples Documentos. El estilo de aplicación alter-
nativo es SDI (’Interfaz de Documento Único). Una aplicación MDI contiene un
formulario cuya propiedad FormStyle tiene el valor fsMDIForm y uno o más
formularios hijos, a cuya propiedad FormStyle se le debe asignar el valor
fsMDIChild. En una aplicación MDI, los formularios hijos están siempre conte-
nidos en dentro de los límites del formulario padre.
Un ejemplo de una aplicación MDI es el Administrador de Archivos de
Windows 3.x. Se podían abrir muchas ventanas dentro del espacio de trabajo
del Administrador, y luego disponerlas en cascada (cascade) o en mosaico (tile),
o moverlas a cualquier posición dentro de los límites de la ventana del Admi-
nistrador, pero no fuera de ella.
Un ejemplo de aplicación SDI es Delphi. Delphi está compuesto de múltiples
formularios que flotan libremente (el Inspector de Objetos, la Paleta de Compo-
nentes, el Editor de Código, etc.) y que no están contenidos o restringidos por
ninguna otra ventana.
88 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Reduzca si es posible el número de controles TEdit y TComboBox que está
utilizando. Si esto no es posible, créelos dinámicamente cuando sean nece-
sarios, y libérelos cuando ya no sean necesarios (como ocurre cuando estos
controles aparecen sobre diferentes páginas de un componente de cuaderno
con pestañas).
2. Reduzca si es posible el número de descendientes de TWinControl (contro-
les visuales capaces de recibir el foco) que esté utilizando. Si esto no es
posible, créelos dinámicamente cuando sean necesarios, y libérelos cuando
ya no sean necesarios (como ocurre cuando estos controles aparecen sobre
diferentes páginas de un componente de cuaderno con pestañas).
3. Reinicie la máquina e inténtelo de nuevo.
Información adicional
Consulte “EOutOfResources” en la ayuda de Delphi.
Solución rápida
1. Siga estos pasos:
Mensajes de error 89
Información adicional
La creación de ActiveForms y controles ActiveX se introdujo a partir de Delphi
3. Los formularios ActiveForm pueden ser distribuidos a través de la World
Wide Web (WWW); los controles ActiveX también pueden ser utilizados en
aplicaciones web, pero no sólo sirven para ese fin. Creando componentes Delphi
y luego convirtiéndolos en controles ActiveX, puede ponerlos a disposición no
sólo de los desarrolladores de Delphi, sino también de aquellos que utilicen
cualquier entorno de desarrollo que soporte los controles ActiveX, como C++
Builder, Visual C++, IntraBuilder, Internet Explorer, Visual Basic y
PowerBuilder.
Solución rápida
Mantenga el valor False en la propiedad AutoSessionName si utiliza más de
un componente TSession sobre un formulario o módulo de datos.
Información adicional
Si utiliza más de un componente TSession en una aplicación, no debe asignar
True a la propiedad AutoSessionName de ninguno de ellos. Delphi puede asig-
nar automáticamente los nombres de sesión (y garantizar que las sesiones
90 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Localice el archivo y colóquelo en el camino de búsqueda de Delphi, o modifi-
que el camino de búsqueda para incluir la localización actual del archivo.
Información adicional
Para localizar un archivo utilizando el Explorador de Windows, siga estos
pasos:
1. En el panel de directorios de la izquierda, seleccione el área donde desea
buscar; para buscar sobre toda la máquina, seleccione el icono que repre-
senta al ordenador (denominado por defecto MiPc).
2. Seleccione Herramientas| Buscar | Archivos o Carpetas....
3. Introduzca el nombre del archivo en el cuadro de combinación Nombre
(por ejemplo, Misplaced.PAS).
4. Pulse el botón Buscar ahora.
Para colocar el archivo en el camino de búsqueda de Delphi, primero podría
desear ver qué directorios constituyen el camino de búsqueda de Delphi. Para
ello, siga estos pasos:
1. Seleccione Tools | Environment Options.
2. Seleccione la página Library.
3. Consulte el contenido del cuadro de combinación Library Path.
4. Mueva el archivo a uno de esos directorios, o añada el directorio en que
reside el archivo al camino de búsqueda.
Mensajes de error 91
Solución rápida
Si está utilizando Delphi 1/Windows 3.x, asegúrese de que la localización del
archivo IDAPI.CFG (por defecto C:\IDAPI) coincide con lo indicado en la sec-
ción [IDAPI] de WIN.INI bajo la entrada CONFIGFILE01.
Si es necesario, mueva el archivo al lugar indicado por la configuración en
WIN.INI, o modifique la entrada en WIN.INI para que esté en concordancia
con la localización actual del archivo.
Si está utilizando Delphi de 32 bits y Windows 95, asegúrese de que la localiza-
ción del archivo IDAPI32.CFG (C:\Archivos de programa\Borland\Common
files\BDE por defecto) coincide con lo indicado en el Registro del sistema.
Si es necesario, mueva el archivo al lugar indicado en el Registro, o modifique
la entrada del Registro para que coincida con la localización actual del archivo.
Información adicional
Las cosas han cambiado con la aparición del Registro en las versiones de Win-
dows de 32 bits. Antes de Windows 95, el archivo de configuración del BDE
(IDAPI.CFG) estaba situado por defecto en el directorio IDAPI de la unidad C:.
WIN.INI apuntaba a la localización de ese archivo; de esta manera, se podía
cambiar de sitio el archivo de configuración siempre que se indicara la nueva
localización en WIN.INI, para que los programas que necesitaban referirse a él
pudieran encontrarlo.
En las versiones de Delphi de 32 bits, la localización del archivo de configura-
ción del BDE se indica en el Registro del sistema. Siga estos pasos:
1. Seleccione Inicio | Ejecutar.
2. Introduzca regedit en el cuadro de combinación Abrir y pulse el botón
Aceptar.
3. Navegue hasta HKEY_LOCAL_MACHINE\Software\Borland\Database
Engine.
4. El valor de la clave CONFIGFILE01 indica el directorio donde el archivo
de configuración debe estar situado.
92 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Borre la referencia al método manejador de eventos en la columna derecha de
la página de eventos del formulario, y borre la declaración del método de la
sección Interface de la unidad.
Información adicional
Si borra tanto el cuerpo del método de la sección Implementation de la unidad
como la declaración del método de la sección de Interface (dejando la referencia
al evento sobre la página de eventos del Inspector de Objetos), y luego intenta
volver a crear el gestor de eventos, no recibirá un mensaje de error, pero Del-
phi no creará el esqueleto del gestor de eventos. Como en el caso de arriba,
debe eliminar la referencia al método gestor de eventos en la columna derecha
de página de eventos del formulario antes de poder volver a codificar el
método.
Solución rápida
Verifique que la aplicación servidora está escuchando por el puerto correcto, y
que la aplicación cliente está intentando conectarse a ese mismo puerto.
Información adicional
Si está probando una aplicación Site Express, puede utilizar el siguiente tipo
de URL: http://localhost:1024/Svrinfo.exe
Mensajes de error 93
Solución rápida
1. Verifique que las propiedades Visible y Enabled del control tienen ambas el
valor True antes de intentar asignarle el foco.
2. Abra el formulario como texto y borre la línea donde se asigna el valor a la
propiedad ActiveControl. Puede hacer esto de dos maneras:
Pulsando el botón derecho del ratón sobre el formulario y seleccionando la
opción View as Text del menú de contexto.
-O-
Seleccionando File | Open, asignando el filtro para mostrar los archivos
.DFM y abriendo el formulario en cuestión.
94 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Este mensaje de error puede provocar confusión, debido a una posible diferen-
cia de concepto entre lo que Ud. puede considerar normalmente como una ven-
tana y de lo que Windows y Delphi consideran como una ventana. En este caso,
cuando se habla de ventana se quiere decir en realidad un control de ventana
(cualquier control al que se asigna un manejador de ventana y que es capaz de
recibir el foco y ser padre de otros controles). En este sentido, un botón es una
ventana, un cuadro de edición es una ventana — y en realidad todos los compo-
nentes que descienden de TWinControl son ventanas.
Solución rápida
No asigne el valor caHide al parámetro Action del evento FormClose, ni llame
al método Hide del formulario o asigne False a la propiedad Visible del formu-
lario para un formulario hijo MDI. Si desea eliminar el formulario, llame a su
método Close.
Esto cerrará el formulario:
procedure TMDIChild.Button1Click(Sender: TObject);
begin
Close;
end;
Mensajes de error 95
Información adicional
El método Hide de TForm asigna False a la propiedad Visible.
Cuando se cierra un formulario hijo MDI, el valor que se asigna por defecto al
parámetro Action es caMinimize. Si no quiere que el formulario hijo sea mini-
mizado, puede asignar el valor caFree al parámetro Action para liberar la
memoria reservada para el formulario.
procedure TMDIChild.FormClose(Sender: Tobject;
var Action: TCloseAction);
begin
Action := caFree;
end;
Solución rápida
No asigne valores a las variables en la sección Var de un procedimiento o
función.
96 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Turbo Pascal y todas las versiones de Delphi soportan una especie de variables
inicializadas que se conocen como constantes con tipo (typed constants). Las
constantes con tipo son realmente un híbrido entre constantes y variables.
Como en el caso de las constantes puras, usted puede asignarles un valor en el
mismo momento en que las declara. Como en el caso de las variables, sus valo-
res pueden cambiar en tiempo de ejecución. Y también como las variables (y a
diferencia de las constantes), su tipo de datos se especifica en el momento que
son declaradas (por eso precisamente se les conoce como constantes con tipo).
A continuación se muestran algunos ejemplos de cómo declarar variables,
constantes típicas y constantes con tipo en la sección Interface de una unidad,
mostrando sus semejanzas y diferencias:
unit Aryan;
interface
var
tf: TextFile;
ThisIsThis: Boolean = True;
{variable inicializada - legal en una sección global}
const
crlf = #13#10; {constante “pura”}
Satz: String[50] = 'All we are is dust in the wind';
{constante con tipo}
implementation
. . .
Mensajes de error 97
Para inicializar a True a ambas constantes con tipo, debe hacerlo así:
interface
const
QueSeraSera: Boolean = True;
WhateverWillBeWillBe: Boolean = True;
. . .
Solución rápida
Inicialice cada constante con tipo en su propia sentencia.
Información adicional
Se puede declarar múltiples variables en una misma sentencia, así:
var
i,j,k,l: integer;
o así:
var
aBeam: array[0..3] of integer;
Pero no es posible inicializarlas en una única sentencia, en caso de que las con-
virtiéramos en constantes con tipo.
Solución rápida
Simplemente declare la variable, así:
threadvar
Threadbare: Byte;
Información adicional
Las variables locales de hilo se declaran como si fueran variables globales (es
decir, no puede declararlas en un método de un objeto TThread), pero los obje-
tos TThread pueden hacer referencia a ellas como si hubiesen sido declaradas
localmente. Alternativamente, puede declarar un campo o un par campo/pro-
piedad en la declaración de una clase derivada de TThread, así:
type
ThreadBear = class(TThread)
private
FTroop: WideString;
protected
procedure Execute; override;
property Troop: WideString read FTroop
write FTroop;
end;
Solución rápida
1. Añada la entrada al Registro del sistema, siguiendo estos pasos:
a. Seleccione Inicio | Ejecutar... desde el escritorio de Windows.
Mensajes de error 99
Información adicional
1. Delphi 4 y posteriores ofrecen soporte nativo para Access 97.
6. Si no puede determinar la causa de este mensaje, puede recurrir a la
medida drástica de reinstalar el BDE (seleccione Full Install) desde el CD
de Delphi y/o reinstalar cualquiera de los controladores de base de datos y
herramientas de cliente de la base de datos a la cual se esté conectando.
Para más información, consulte “Class not registered”.
100 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Instale el BDE en todos los ordenadores que ejecutarán programas de base
de datos creados con Delphi (a menos que esté utilizando una alternativa
de terceros para el BDE, en cuyo caso no debería obtener este mensaje de
error).
Consulte DEPLOY.TXT para la información específica sobre cómo distri-
buir las aplicaciones para su versión particular de Delphi. Este archivo
está ubicado por defecto en el directorio \Delphi.
2. Asegúrese de que el lugar indicado por el valor de la entrada ConfigFile01
en WIN.INI o en el Registro del sistema apunte a la localización de su
archivo de configuración (IDAPI[32].CFG).
Aquí están los detalles específicos:
Delphi 1
Localice el parámetro DLLPATH en la sección [IDAPI] de
C:\Windows\WIN.INI y compruebe que su valor sea correcto. Por defecto, es:
[IDAPI]
DLLPATH = C:\IDAPI
Delphi de 32 bits
Localice la clave del Registro que indica la localización de las .DLLs del BDE:
HKEY_LOCAL_MACHINE\Software\Borland\Database Engine\DLLPath.
Si el camino configurado en el Registro del sistema corresponde al valor por
defecto C:\Archivos de programa\Borland\Common files\BDE, pero
Mensajes de error 101
Información adicional
Para editar el Registro del sistema, siga estos pasos:
1. Seleccione Ejecutar del menú Inicio.
2. Introduzca regedit en el cuadro de edición y pulse el botón Aceptar.
3. Navegue hasta HKEY_LOCAL_MACHINE\Software\Borland\Database
Engine\DLLPath.
4. Pulse el botón derecho sobre DLL Path en el panel de la derecha.
5. Seleccione Modificar del menú de contexto.
6. Edite el camino en el cuadro de edición que aparece.
Una instalación parcial coloca una versión ‘recortada’ del BDE en el direc-
torio del programa que utiliza el BDE.
Solución rápida
Para verificar la configuración, siga estos pasos:
1. Seleccione Inicio | Ejecutar.
2. Introduzca regedit y pulse Aceptar.
3. Navegue hasta \HKEY_LOCAL_MACHINE\Software\Borland\Database
Engine\Settings\System\INIT\LANGDRIVER.
El valor de la entrada depende de su localización física (EE.UU., Europa,
Japón, etc.), o más específicamente, de la localización para la que ha sido confi-
gurada el ordenador. Por ejemplo, si está usted en los Estados Unidos, el valor
de la entrada LANGDRIVER debería ser DBWINUS0.
Verifique que la entrada del Registro sea correcta. Si es necesario, modifíquela.
Si la entrada es incorrecta, verifique que el controlador de lenguaje apropiado
exista en el sistema (en \Archivos de programa\Borland\Common files\BDE).
Por ejemplo, el archivo correspondiente a la entrada DBWINUS0 es USA.BLL.
102 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Solución rápida
1. Si el paquete no contiene unidades adicionales que usted necesite, simple-
mente absténgase de cargar el paquete redundante.
2. Seleccione Aceptar para cerrar el cuadro de mensaje de error, y luego
pulse No cuando se le pregunte si desea guardar los cambios. Puede perder
el paquete en el cual instaló el componente. En ese caso, simplemente
reinstale el paquete (esta vez sin el componente adicional).
Información adicional
1. Si ambos paquetes contienen componentes que usted necesita, puede crear
un nuevo paquete que incluya las partes que necesita de ambos paquetes.
Delphi 1
Puede ser que el archivo IDAPI01.DLL nunca haya sido instalado, haya sido
movido o borrado, o la sección [IDAPI] de WIN.INI esté ausente o sea
incorrecta.
Mensajes de error 103
Delphi de 32 bits
Puede ser que el archivo IDAPI32.DLL nunca haya sido instalado, haya sido
movido o borrado, la configuración necesaria en el Registro esté ausente o sea
incorrecta.
Solución rápida
Asegúrese de que el BDE esté instalado y configurado correctamente. Si no
está instalado, instálelo. Consulte DEPLOY.TXT para obtener información
sobre la instalación del BDE para su versión particular de Delphi. El archivo
DEPLOY.TXT está ubicado por defecto en el directorio \Delphi. Si el BDE está
instalado, puede no estar configurado correctamente. Consulte la parte relacio-
nada con su versión de Delphi de la siguiente sección.
Delphi 1
Verifique que la localización de IDAPI.DLL a la que apunta el archivo
WIN.INI esté en concordancia con la localización actual de IDAPI01.DLL. Bus-
que la sección [IDAPI]. Las entradas CONFIGFILE01 y DLLPATH se refieren
a C:\IDAPI por defecto.
Delphi de 32 bits
Verifique que la ubicación a la que apunta el Registro del sistema para
IDAPI.DLL esté en concordancia con la localización actual de IDAPI32.DLL.
Para comprobarlo, ejecute Regedit y navegue hasta
HKEY_LOCAL_MACHINE\Software\Borland\Database Engine.
La ubicación por defecto indicada por las entradas CONFIGFILE01 y
DLLPATH es C:\Archivos de programa\Borland\Common
files\BDE\IDAPI32.CFG.
Información adicional
Delphi 1
Para consultar y posiblemente editar el archivo WIN.INI, navegue hasta él en
el directorio de Windows, ábralo y busque la sección [IDAPI], que debería pare-
cerse un poco a esto:
[IDAPI]
DLLPATH=C:\IDAPI
CONFIGFILE01=C:\IDAPI\IDAPI.CFG
Si parece que las entradas son correctas, mueva los archivos a la localización
indicada por las entradas, o modifique las entradas en concordancia con la ubi-
cación de los archivos.
Delphi de 32 bits
Para consultar y posiblemente editar el Registro del sistema, siga estos pasos:
1. Seleccione Ejecutar del menú Inicio.
2. Introduzca regedit en el cuadro de edición y pulse el botón Aceptar.
3. Navegue hasta HKEY_LOCAL_MACHINE\Software\Borland\Database
Engine\DLLpath.
4. Pulse el botón derecho sobre DLL Path en el panel de la derecha.
5. Seleccione Modificar en el menú de contexto.
6. Edite el camino en el cuadro de edición que aparece.
Solución rápida
No llame al método ShowModal de un formulario al menos que esté creándolo
dinámicamente.
Información adicional
Cuando un formulario es creado automáticamente por Delphi (como ocurre por
defecto con todos los formularios, y siempre con el formulario principal de la
aplicación), Delphi cambia el valor de la propiedad Visible del formulario de
False a True.
La única situación en la que puede (y debe) llamar a uno de los métodos Show
o ShowModal del formulario es cuando cree el formulario dinámicamente. Es
recomendable crear dinámicamente aquellos formularios que no estarán abier-
tos durante todo el tiempo de ejecución de la aplicación (como un cuadro de
diálogo ‘Acerca de...’).
Para crear un formulario dinámicamente, siga estos pasos:
1. Seleccione View | Project Manager.
2. Pulse el botón Options.
3. Seleccione el formulario que desea crear dinámicamente en el cuadro de
lista Auto-Create Forms.
4. Muévalo al cuadro de lista Available Forms pulsando el botón de flecha
derecha.
5. Pulse el botón OK.
6. Añada el siguiente código al evento en el que desee mostrar el formulario
(sustituya AboutBox por el nombre de variable de la instancia del formula-
rio y TAboutBox por el nombre de la clase del formulario):
procedure TForm1.AboutBoxClick(Sender: TObject);
begin
AboutBox := TAboutBox.Create(nil);
try
AboutBox.ShowModal;
finally
AboutBox.Free;
end;
end;
106 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Asegúrese de que la propiedad ReadOnly del objeto TTable tenga el valor False
antes de intentar editar la tabla.
Información adicional
No es posible cambiar la propiedad ReadOnly de un TTable mientras la tabla
esté abierta (su propiedad Active tenga el valor True), por lo que deberá pri-
mero cerrar la tabla, cambiar el valor de la propiedad ReadOnly, y luego hacer
la actualización, inserción o borrado.
with TableTennis do begin
Active := False;
ReadOnly := False;
Active := True;
Insert;
InsertRecord(['Gump', 'Forrest', 'PingPong', 1]);
end;
Solución rápida
Absténgase de editar el nombre generado automáticamente para un compo-
nente TSession, o asigne primero False a la propiedad AutoSessionName antes
de modificar la propiedad SessionName.
Información adicional
El componente TSession es similar a TApplication, ya que normalmente no es
necesario preocuparse por crear uno, ya que Delphi lo hace automáticamente
cuando sea necesario. Pero si está desarrollando aplicaciones multi-hilo o si
desea acceder a tablas Paradox situadas en diferentes lugares de una red,
usted puede añadir componentes TSession adicionales al formulario o módulo
Mensajes de error 107
de datos para facilitar las operaciones bajo esas circunstancias especiales. Para
más información, Consulte “AutoSessionName” y “managing multiple sessions”
en la ayuda de Delphi.
Solución rápida
Copie una versión de copia de seguridad de su biblioteca de componentes
(COMPLIB.DCL) a \Delphi\bin (Delphi 1).
Resuelva el problema con la .DLL antes de instalar el componente de nuevo.
Información adicional
Siempre que sea posible, utilice el enlace dinámico a .DLLs (mediante las fun-
ciones LoadLibrary y GetProcAddress) en lugar del enlace estático. Para más
información, consulte “external reserved word | external declarations” y
“GetProcAddress function” en la ayuda de Delphi.
Solución rápida
1. Verifique que el archivo que está intentando abrir es realmente del tipo de
archivo que espera.
2. Asegúrese de que el archivo esté ubicado en el directorio que ha indicado, y
de que ha escrito correctamente el directorio y el nombre del archivo.
108 Los Tomos de Delphi: Delphi sin problemas
Información adicional
1. Puede ser que la extensión del archivo haya sido cambiada, de tal forma
que no se corresponde con el tipo de archivo. Por ejemplo, se puede haber
modificado la extensión del archivo ShapesOfThingsToCome.TXT de .TXT
a .BMP. Intentar cargar este archivo en la propiedad Picture de un compo-
nente TImage ocasionará este error. Un archivo de texto con cualquier otra
extensión sigue siendo un archivo de texto (y viceversa — un archivo BLOb
con una extensión de archivo de texto sigue siendo un archivo BLOb).
2. El método LoadFromFile puede ser aplicado a objetos TPicture y TStrings
y sus descendientes (como TStringList).
Si está utilizando un objeto TClientDataSet y archivos locales (el modelo de
una capa o de maletín), deberá insertar en él al menos un registro antes de que
sea grabado y pueda ser posteriormente cargado.
Solución rápida
Cambie la vista del archivo a la vista de formulario y compile de nuevo.
Información adicional
Para cambiar la vista de un formulario (archivo .DFM) que está mostrando su
representación textual a su representación visual (Form View), siga estos
pasos:
1. Pulse el botón derecho dentro de la ventana de código del archivo .DFM.
2. Seleccione View As Form del menú de contexto.
Solución rápida
Libere espacio del disco duro, cierre algunos programas que no esté utilizando,
y/o instale más memoria RAM. Desactivar las optimizaciones puede ayudar.
Para desactivar las optimizaciones:
Delphi 1
Seleccione Options | Project | Linker | EXE and DLL Options. Desmar-
que la casilla Optimize for size and load time.
Delphi de 32 bits
Seleccione Project | Options | Compiler | Code Generation, y desmarque
la casilla Optimization.
Información adicional
Puede también recibir el mensaje “Unable to rename <path>.<project>.$$$’
to ‘<path>.<projectname>.dpr’”. Podrá necesitar cambiar la extensión del
archivo de proyecto (.DPR) en el Explorador de Windows de .$$$ a .DPR.
Solución rápida
Elimine la directiva Override en la clase descendiente, o añada una directiva
Virtual o Dynamic en la clase ancestro.
Información adicional
Es posible redefinir (override) los métodos de los objetos ancestros que han sido
declarados utilizando las directivas Virtual, Dynamic, o las directivas Virtual o
Dynamic y Abstract.
Por ejemplo, si la declaración del objeto ancestro es la siguiente:
type
A = class
procedure WorkHard; virtual;
procedure PlayHard; dynamic;
procedure StudyHard; virtual; abstract;
procedure RunHard; dynamic; abstract;
procedure Leotard;
110 Los Tomos de Delphi: Delphi sin problemas
end;
Solución rápida
Asigne True a la propiedad Active del componente TIBDatabase, o llame a su
método Open antes de intentar activar el componente TIBTransaction o llamar
a cualquiera de sus métodos.
Información adicional
TIBTransaction y TIBDatabase son componentes de InterBase Express.
Solución rápida
Llame al método Open del objeto TSQLConnection antes de abrir un conjunto
de datos que dependa de él.
Información adicional
Esto podría haberle ocurrido si tiene un conjunto de datos abierto en tiempo de
diseño en su formulario principal, y el componente TSQLConnection está
situado en otro formulario, como por ejemplo un módulo de datos. El formula-
rio principal se crea primero, y puesto que el objeto TSQLConnection no ha
sido creado todavía, no está abierto. En este caso, será necesario posponer la
apertura del conjunto de datos hasta el tiempo de ejecución.
Los componentes DBExpress aparecieron con Delphi 6.
Solución rápida
Asigne True a la propiedad Connected en tiempo de diseño o en el código, o
llame al método Open del componente TDatabase, antes de llamar a Start-
Transaction. Por ejemplo, para solucionar el problema mostrado arriba, puede
hacer esto:
with Database1 do begin
Connected := True;
StartTransaction;
try
try
Table1.FieldByName('Mister').Value := 'T';
. . .
finally
Commit;
end;
except
Rollback
end;
-O-
112 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Si asignó True a la propiedad Connected del componente TDatabase (en tiempo
de diseño o en tiempo de ejecución, antes de hacer la referencia a la base de
datos) y también asignó True a su propiedad KeepConnection, evitará recibir
este mensaje de error, ya que la conexión a la base de datos siempre estará
abierta.
Solución rápida
1,2. Abra todos los conjuntos de datos necesarios antes de ejecutar cualquiera
de las acciones indicadas arriba.
3. Asigne un TDataSetProvider al componente TClientDataSet.
4. Asigne la propiedad FileName del objeto TClientDataSet, o llame al
método LoadFromFile antes de trabajar con los datos. En Delphi 6 y supe-
riores, puede grabar los datos en dos posibles formatos: el binario o
“clásico”, con extensión .CDS, y el formato XML (¡maravilla!), con extensión
.XML. Por ejemplo, podría guardar y luego volver a abrir de esta manera:
with dm.cdsStudents do begin
MergeChangeLog;
SaveToFile('Students.cds'); //, dfBinary);
SaveToFile('Students.xml'); //, dfXML);
end;
Información adicional
TTable, TQuery, TStoredProc y TClientDataSet son todos descendientes de la
clase TDataSet, y por lo tanto son conjuntos de datos.
2. Si está utilizando un campo calculado en una tabla, éste puede estar
haciendo referencia en el evento OnCalcFields a otra tabla que no ha sido
creada todavía. Todas las tablas deben existir antes de que puedan ser
referenciadas. El orden de creación de los componentes no visuales está
determinado en primer lugar por el orden en que se colocan los componen-
tes sobre el formulario. Si el objeto TTable al que se hace referencia fue
colocado sobre el formulario después del TTable que hace la referencia,
puede alterar el orden de creación seleccionando Edit | Creation Order,
y utilizando los botones de flechas mover el TTable al que se hace referen-
cia para que quede encima del TTable que hace referencia a él.
3,4. En Delphi 6 y superiores, la tecnología MIDAS y la clase TClientDataSet
están por todos lados. Ya que la capa de acceso a datos DBExpress no per-
mite la navegación hacia atrás en un conjunto de resultados, es
recomendable utilizar un TDataSetProvider como intermediario entre
DBExpress y un TClientDataSet, especialmente si va a mostrar los datos
en una rejilla. Si no es incluido como parte integral de Delphi 6, busque el
componente TClientDataSetGrid, creado por John Kaster y Anders
Ohlsson, en Code Central de Borland (community.borland.com/codecentral).
Este ofrece una ordenación de columnas “estilo explorador”, así como un
114 Los Tomos de Delphi: Delphi sin problemas
indicador visual que indica que los datos están ordenados por una columna
y en qué dirección.
Solución rápida
Asigne primero False a la propiedad Active antes de intentar cambiar la pro-
piedad AutoSessionName del objeto TSession a True o modificar su propiedad
SessionName.
Información adicional
Para más información sobre las sesiones, consulte los temas “managing data-
base sessions”, “managing multiple sessions”, “naming a session”, “working
with a session component”, “using the default session” y “using a session com-
ponent in data modules” en la ayuda de Delphi.
Solución rápida
Antes de llamar al método Delete, verifique que la tabla no esté vacía. Por
ejemplo, podría hacer esto:
if Table1.IsEmpty then
Exit
else
Table1.Delete;
-O-
if not Table2.IsEmpty then
Table2.Delete;
Mensajes de error 115
Información adicional
El método Delete de TDataSet borra solamente el registro actual.
Para borrar todos los registros de una tabla, utilice el método EmptyTable.
Para borrar no solamente todos los registros, sino también la tabla en sí (la
información de estructura), utilice el método DeleteTable. La tabla debe estar
cerrada antes de la llamada a DeleteTable (llame al método Close de TTable o
asigne False a su propiedad Active).
Para borrar los registros que cumplan un cierto criterio, utilice un componente
TQuery y asigne a su propiedad SQL una cadena del tipo:
DELETE FROM BogusData
{para borrar todos los registros}
DELETE FROM Airwaves
WHERE ContentType = SoapOpera
{para borrar todos los registros con el valor
‘SoapOpera’ en el campo ContentType}
Solución rápida
1-4.Asegúrese de que el componente TTable o TDatabase no estén activos
antes de intentar tales operaciones. Puede hacer esto haciendo llamadas a
uno de los siguientes métodos:
Table1.Close; {para un componente TTable}
Database1.Close; {para un componente TDataBase}
o mediante asignaciones a propiedades:
Table1.Active := False; {para un componente TTable}
Database1.Connected := False; {para un componente TDataBase}
116 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Si el valor de la propiedad Exclusive de un objeto TTable es True y se intenta
asignar a la propiedad Active el valor True, se generará el mensaje de error
“Table is busy”.
Solución rápida
1. Cierre el TTable antes de modificar cualquiera de las propiedades mencio-
nadas arriba.
2. Cierre el TQuery antes de llamar a Unprepare.
3. Asigne primero False a la propiedad Active del conjunto de datos, o llame a
su método Close, y luego haga las modificaciones al texto de la consulta
antes de abrirla (activarla) de nuevo.
Información adicional
Puede cerrar un TDataSet (del que descienden tanto TTable como TQuery)
asignando False a la propiedad Active:
Table1.Active := False;
-O-
Query1.Active := False;
-O-
Query1.Close;
Solución rápida
Cierre la tabla antes de borrarla.
Información adicional
Puede ejecutar muchas operaciones sobre bases de datos locales o de escritorio,
tales como Paradox, dBASE, MS Access, etc., utilizando la utilidad Database
Desktop. Consulte “Database Desktop” en la ayuda de Delphi.
Solución rápida
Cierre la tabla, asignando False a la propiedad Active del TTable y a la propie-
dad Connected de los componentes TDatabase, y luego vuelva a intentar la
operación.
Información adicional
La tabla puede estar abierta por una aplicación en ejecución o dentro del
entorno integrado de Delphi, si la propiedad Active del TTable o la propiedad
Connected de un componente TDatabase tienen asignado el valor True.
Solución rápida
Solamente intente leer el valor de las propiedades que no son de sólo escritura.
Del mismo modo, solamente intente modificar las propiedades en las que se
puede escribir, o sea, aquellas que no son de sólo lectura. Por ejemplo, puede
leer el valor de la propiedad CanModify así:
if Table1.CanModify = True then
{Realizar el procesamiento condicional}
Información adicional
Si una propiedad es de sólo lectura, es declarada así:
property Required: Boolean read FRequired;
Es común para una propiedad acceder a un campo privado, desde el que se lee
un valor interno, y a un método privado que escribe el valor. A continuación se
presenta un ejemplo extraído de la unidad Dbtables.PAS, donde se declara el
componente TTable, y se muestra la propiedad DatabaseName y su campo y
procedimiento privados asociados:
TTable = class(TDBDataSet)
private
...
FDatabaseName: string;
...
procedure SetDatabaseName(const Value: string);
...
protected
...
public
...
published
property DatabaseName: string read FDatabaseName
write SetDatabaseName;
end;
begin
CheckInactive;
ValidateName(Value);
FDatabaseName := Value;
end;
end;
Solución rápida
1. Abra el archivo fuente del proyecto (archivo .DPR) del cual es parte la uni-
dad antes de intentar ejecutar la aplicación.
2. Aunque las .DLLs son ejecutables, no pueden ser ejecutadas directamente.
Llame a la .DLL desde un .EXE para ejecutarla.
Información adicional
Puede ejecutar una aplicación sin que todas las unidades que la constituyen
estén abiertas en el entorno integrado (siempre que el archivo .DPR esté
abierto), pero no lo contrario. Dicho de otra manera, si abre un archivo de pro-
yecto y lo ejecuta, éste cargará los archivos de unidad (.PAS) que componen el
proyecto. Lo opuesto no es cierto— una unidad no carga el .DPR del cual es
parte constituyente. Una misma unidad puede pertenecer a múltiples proyec-
tos, y por lo tanto podría no ser evidente qué proyecto cargar.
Si quiere compilar una unidad (crear un archivo .DCU a partir de un archivo
.PAS), puede hacerlo utilizando el compilador de línea de comandos dcc32.EXE,
localizado en el directorio \bin de Delphi.
120 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Verifique que todos los objetos TDataSet pasados a ApplyUpdates hagan refe-
rencia al mismo componente TDatabase.
Información adicional
Los descendientes de TDataSet incluyen a TTable, TQuery, TStoredProc y
TClientDataSet.
Solución rápida
Utilice paréntesis en lugar de corchetes:
Table1.AddIndex(<NombreIndice>, <NombreCampo>, [ixExpression]);
Información adicional
Asigne True a la propiedad Exclusive del TTable antes de añadir un índice.
Mensajes de error 121
Solución rápida
No utilice System o SysInit como nombres de unidad. En realidad, no utilice el
nombre de ninguna unidad que ya esté en uso por su aplicación.
Información adicional
Delphi añade implícitamente de forma automática las unidades System y
SysInit a la cláusula Uses de la interfaz de sus unidades.
Solución rápida
Cierre la instancia del programa antes de intentar recompilarlo. Si es necesa-
rio, reinicie Windows para “echar” al ejecutable o la .DLL de la memoria.
Información adicional
Esto también puede ocurrir después de una caída del programa al ser ejecu-
tado desde el entorno integrado. Cierre Delphi y reinícielo, y luego intente com-
pilar el proyecto/programa de nuevo.
Solución rápida
Delphi 1/Windows 3.x
Asegúrese de que la localización real de IDAPI.CFG (C:\IDAPI por defecto)
coincide con el valor que aparece en la entrada CONFIGFILE01 de la sección
[IDAPI] de WIN.INI.
Si es necesario, mueva el archivo al lugar indicado en WIN.INI, o modifique la
entrada en WIN.INI para que coincida con la ubicación del archivo.
Información adicional
Este es el error $8453 del BDE.
Solución rápida
1. Compruebe que la sintaxis de las sentencias SQL sean soportadas por la
base de datos que esté utilizando. Para más detalles, consulte la documen-
tación de la base de datos.
2. Si no necesita un conjunto de resultados actualizable, cambie el valor de la
propiedad RequestLive del componente TQuery a False.
Si necesita un conjunto de resultados actualizable, la consulta no puede
contener lo siguiente:
funciones agregadas (SUM, COUNT, AVG, MIN, MAX, etc.)
Operaciones JOIN, UNION, INTERSECT o MINUS
Una cláusula ORDER BY
3. No intente modificar la propiedad StoredProcName mientras la propiedad
DatabaseName del componente TStoredProc hace referencia a una base de
datos local o de escritorio.
4. Incluya el nombre de la tabla en la sentencia SELECT, y encierre los nom-
bres de columnas entre comillas. Por ejemplo:
SELECT Sees."Chocolate"
FROM Sees
WHERE Sees."Chocolate" = ‘DarkRaspberry’
5. Absténgase de utilizar actualizaciones en caché en combinación con campos
BLOb.
Información adicional
1. Aunque SQL es la “lingua franca” tanto para las bases de datos cliente/ser-
vidor como para las de escritorio, los dialectos y vocabularios difieren entre
las distintas implementaciones. Por ejemplo, Oracle utiliza PL/SQL, MS
SQL Server utiliza Transact SQL, etc.
3. Si está utilizando una base de datos local o de escritorio (como Paradox,
dBASE, MS Access, etc.), no puede utilizar procedimientos almacenados.
Estos son únicamente una característica de las bases de datos de servi-
dores SQL (como InterBase, Oracle, MS SQL Server, Sybase, Informix,
etc.).
Si todo lo demás falla, intente utilizar una variable de cadena en la cláu-
sula WHERE. Por ejemplo,
var
WhereVar: String;
. . .
WhereVar:= 'Morgan Tell Mackenzie Shannon';
. . .
Query1.SQL.Add('SELECT * from "RUNTHE"');
Query1.SQL.ADD('WHERE Whatever = ' + WhereVar);
124 Los Tomos de Delphi: Delphi sin problemas
var
BlackAndBlueDivision : NFCCentralDivision;
. . .
begin
case BlackAndBlueDivision of
MinnesotaVikings:
Writeln('A rolling moss gathers no stone’);
DallasCowboys:
Writeln('Achy Breaky Aikman');
TampaBayBucanneers:
Writeln('A statue of the coach would be a dungy idol');
else
; // Lo que haga falta
end;
end.
Solución rápida
Utilice una variable del tipo SomeFootballTeams (en lugar de una del tipo
NFCCentralDivision), o extienda la declaración de NFCCentralDivision para
que incluya todos los valores que quiera evaluar.
Información adicional
Las sentencias Case son más rápidas que las sentencias If anidadas. Donde
sea posible, utilice sentencias Case. Por ejemplo:
case iNumberOfTickets of
0: ScalpTheScalper;
1: GoAlone;
Mensajes de error 125
2: TakeAFriend;
3: ThreesCompany;
else
;
end;
es preferible a esto:
if iNumberOfTickets = 0 then
ScalpTheScalper
else if iNumberOfTickets = 1 then
GoAlone
else if iNumberOfTickets = 2 then
TakeAFriend
else if iNumberOfTickers = 3 then
ThreesCompany;
var
QBRating: Integer;
este código:
case QBRating of
Favre: s := ‘Lock him up (to a long-term contract)’;
Culpepper: s := ‘Give him a raise’;
Batch: s := ‘Bake him some cookies’;
King: s := ‘Give him a crown’;
McNown: s := ‘He might get better’;
end;
Solución rápida
Asigne a la propiedad MasterSource una fuente de datos (de la lista desplega-
ble que aparece en la propiedad MasterSource) que esté asociada a otro compo-
nente TTable.
Información adicional
Delphi no muestra en la lista desplegable de posibles valores de la propiedad
MasterSource aquellos componentes TDataSource que hacen referencia al pro-
pio componente TTable. Se trata de una medida preventiva para evitar este
mensaje de error. No obstante, se puede teclear lo que se quiera, y si introduce
un TDataSource asociado a la propia tabla en la propiedad MasterSource del
TTable, generará este mensaje de error.
Para más información sobre la utilización de tablas de búsqueda y la propiedad
MasterSource, consulte “TTable.MasterSource” en la ayuda de Delphi.
Solución rápida
Mueva al menos una de las referencias de la cláusula Uses de la interfaz de la
unidad a la cláusula Uses de la sección Implementation (directamente debajo
de la palabra reservada Implementation). Por ejemplo, si el mensaje de error
es ocasionado por la referencia mutua de Unit1 y Unit2 en cada una de las sec-
ciones Uses de sus interfaces, de tal forma que Unit1 actualmente aparece así:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, Unit2;
type
Mensajes de error 127
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
implementation
uses Unit2; {añadida la referencia a Unit2 aquí}
Información adicional
Puede también mover ambas referencias a la parte Implementation de las uni-
dades (debe mover al menos una; o puede mover ambas).
Las únicas unidades que necesitan ser incluidas en la cláusula Uses de la sec-
ción Interface son aquellas clases a las que se hace referencia en la propia
interfaz. Todas las demás pueden (y deben) ser colocadas en la cláusula Uses
de la sección Implementation.
La cláusula Uses de la sección Interface es añadida automáticamente por Del-
phi. Tendrá que añadir manualmente la cláusula Uses de la parte
Implementation.
128 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Consulte el texto del archivo .DFM del formulario pulsando con el botón
derecho sobre el formulario y seleccionando View As Text en el menú de
contexto. Verifique que las definiciones de objetos ahí coincidan con lo que
está actualmente sobre el formulario.
2. Si todavía quiere utilizar la clase perdida, tendrá que reintroducirla en
Delphi ahora o más adelante. Si quiere esperar hasta más tarde (o si no
necesita la clase en absoluto), simplemente ignore el error. Para incorporar
de nuevo la clase a Delphi, siga el curso de acción apropiado en dependen-
cia de lo que ocasionó el problema:
Si ha movido el archivo que el proyecto necesita, devuélvalo al
directorio que aparece en el camino de búsqueda de Delphi o añada el
directorio donde actualmente reside al camino de búsqueda de Delphi
(seleccione Tools | Environment Options. . . , luego la página
Library y el cuadro de combinación Library Path).
Si la clase es un componente que ha desinstalado, reinstálelo.
Si el archivo ha sido borrado, vea si puede conseguir otra copia de
donde obtuvo el original (el CD de Delphi, un CD de un libro de
terceros, un sitio web, etc.).
Si ha eliminado del camino de búsqueda de Delphi el directorio que
contiene la unidad que necesita, añada de nuevo el directorio o mueva
la unidad a una ubicación a la que se haga referencia en el camino de
búsqueda de Delphi.
3. Puede ignorar el error, y las partes del proyecto que no son específicas a la
versión posterior de Delphi se abrirán. Si el proyecto ha sido creado por
usted mismo, probablemente aún tendrá acceso a la versión más nueva de
Mensajes de error 129
Información adicional
Si elige ignorar el error y continuar, Delphi eliminará la referencia a la clase
no encontrada del archivo .DFM. De todos modos, su declaración aún existirá
en el archivo .PAS. Cuando intente compilar el proyecto, que ahora contiene
una discrepancia entre la descripción proporcionada por el archivo .PAS y la
descripción proporcionada por su correspondiente archivo .DFM, obtendrá este
mensaje de error “Field <> does not have a corresponding component.
Remove the declaration?” Si selecciona Yes, la declaración también será eli-
minada del archivo .PAS.
1. Normalmente, editar el objeto en el archivo .DFM también ocasionará que
éste cambie sobre el formulario. Esto es lo que quieren decir cuando se
refieren a Delphi como una herramienta bi-direccional.
Después de cambiar un componente de un tipo a otro en el archivo .DFM,
cuando intente compilar el proyecto puede obtener el mensaje “Field <>
should be of type <> but is declared as <>. Correct the declara-
tion?”. Pulse Yes para permitir que Delphi reconcilie la diferencia.
3. Un ejemplo de este suceso sería si crea un proyecto en Delphi 3 ó 4 que uti-
lice un componente TChart, y luego intenta cargar el proyecto en Delphi 2
(o Delphi 1).
4. Para más información, consulte el mensaje “Field <> does not have a
corresponding component. Remove the declaration?”.
Solución rápida
Elimine una de las declaraciones de propiedad por defecto. Una clase puede
tener solamente una propiedad por defecto.
Información adicional
Cuando se declara una propiedad de tipo array, se la puede definir como la
propiedad por defecto de la clase, así:
130 Los Tomos de Delphi: Delphi sin problemas
type
TCircus = class
. . .
property Clowns[Index: Integer]: String read Fbozo
write SetBozo; default;
. . .
end;
var
Circus: TCircus;
La ventaja de hacer esto consiste en que luego se puede acceder o asignar valo-
res a la propiedad de tipo array en el código sin tener que especificar el nombre
de la propiedad. Por ejemplo, con la propiedad declarada arriba, se podría asig-
nar un valor así:
Circus[i] := Bozo;
-O-
BeatlesParaphernalia := TCollection;
pero la clase TCollection no tiene una propiedad por defecto (aunque sí tiene
una propiedad de tipo array llamada Items).
Mensajes de error 131
Solución rápida
Especifique explícitamente todas las propiedades que no sean la propiedad por
defecto en cualquier sentencia que haga referencia a ellas.
Información adicional
Las propiedades por defecto son propiedades de tipo array cuyo nombre puede
ser omitido en la sentencias de asignación. Para más información, consulte la
entrada anterior “Class already has a default property”.
Solución rápida
Declare los tipos de clase únicamente dentro de las secciones de declaración de
tipos, por ejemplo así:
type
TForm1 = class(TForm)
Información adicional
Si intenta declarar un tipo de clase en una sección Var, así:
var
TForm1 = class(TForm)
Solución rápida
Borre la palabra “class” para hacer que el método se convierta en un método
corriente, en lugar de un método de clase.
Información adicional
Los procedimientos de clase se utilizan a menudo para implementar “construc-
tores” para formularios modales. Eliminando la variable que Delphi añade
automáticamente a la sección Interface de la unidad, usted puede forzar que
cualquier construcción del formulario se realice a través del procedimiento de
clase. Por ejemplo:
type
TfrmTMSExpressMaterial = class(TForm)
StatusBar1: TStatusBar;
private
{ declaraciones privadas}
public
class procedure Cre8Thyself;
end;
implementation
{$R *.DFM}
with Self.Create(nil) do
try
ShowModal;
finally
Free;
end;
end;
Solución rápida
1. Asegúrese de que ha instalado y registrado todos los controles ActiveX
antes de hacer referencia a ellos.
2. Asegúrese de que ha instalado y registrado todos los servidores antes de
hacer una referencia a ellos.
Información adicional
1. Aunque los controles ActiveX (.OCX) son un tipo de .DLL, no es suficiente
que se encuentren en el lugar adecuado, como ocurre en el caso de las
.DLLs. Los controles ActiveX se identifican mediante su GUID (identifica-
dor global único), no por su nombre de archivo, y este GUID debe haber
sido registrado previamente ante Windows (en el Registro del sistema)
para que el control ActiveX pueda ser utilizado.
Para registrar manualmente un control ActiveX (una .DLL con extensión
.OCX), cópielo primero al directorio \Windows\System y luego siga estos
pasos:
a. Abra una ventana DOS.
b. Vaya al directorio \Windows\System.
c. Introduzca el siguiente comando y pulse la tecla Intro:
Regsvr32 <biblioteca>.
Por ejemplo, si la biblioteca de tipos a registrar es IDataBroker, deberá teclear
lo siguiente (ya que está definida en STDVCL32.DLL): Regsvr32 STDVCL32.
134 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Declare los tipos en una sección Type, así:
type
TStudentCommand = (scAdd, scEdit, scActivate, scInactivate,
scRemove);
TMaterialCommand = (mcAdd, mcEdit, mcDelete, mcImport);
TScheduleCommand = (scSchedule, scPrint);
Información adicional
Los tipos de datos definidos por el usuario son una de las buenas característi-
cas de Object Pascal. Al utilizarlos, podrá escribir código como el siguiente:
procedure TfrmTMSXpressMain.lstbxStudentsDblClick
(Sender: TObject);
var
StudentCommands: TStudentCommand;
begin
StudentCommands := TStudentCommand(lstbxStudents.ItemIndex);
with dm do begin
case StudentCommands of
scAdd: AddStudents;
scEdit: EditStudentsInfo;
scActivate: ActivateStudents;
scInactivate: InactivateStudents;
scRemove: RemoveStudents;
Mensajes de error 135
else
MessageDlg(SErrorInStudentsDblClick,
mtInformation, [mbOK], 0);
end;
end;
end;
Solución rápida
1. Cuando utilice la construcción Try. . . Except On. . . <ObjetoExcepción> Do,
utilice una clase de excepción predefinida. Esta puede ser una clase de
excepción de Object Pascal o una definida por el usuario.
2. En la declaración de una clase ActiveForm, debe utilizar un tipo de clase
seguido de un tipo de interfaz, así:
TActiveFormX = class(TActiveForm, IActiveFormX)
Información adicional
1. Este es un ejemplo de utilización de una excepción predefinida de Object
Pascal (EDivByZero):
function DivideThePie(Pieces, Recipients: Integer): Integer;
begin
try
136 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
No intente colocar iconos (archivos con extensión .ICO) en el portapapeles.
Información adicional
Puede colocar mapas de bits (archivos con extensión .BMP) y metaarchivos de
Windows (archivos con extensión .WMF) en el portapapeles.
En otras palabras, el mismo código podría en un caso producir este mensaje de
error (si un icono está asignado a la propiedad Picture) y en otro funcionar
correctamente (si un mapa de bits o metaarchivo está asignado a la propiedad
Picture).
Solución rápida
Verifique que tiene al menos 50 MB o el 10% del disco duro vacío. Si este no es
el caso, podrá sufrir todo tipo de problemas indignantes (archivos dañados, caí-
das aquí y allá, etc.). Si tiene suficiente espacio libre en el disco duro, verifique
que éste no se ha dañado.
Información adicional
Si no dispone de herramientas de terceros (como Norton Utilities), puede utili-
zar la herramienta de defragmentación provista con Windows para verificar los
errores del disco duro. Para localizarla, vaya a Inicio | Programas | Acce-
sorios | Herramientas del Sistema | Defragmentador de Disco. Algunas
versiones de Windows también ofrecen la utilidad Scandisk, que provee dos
niveles de prueba (examen de la superficie y completo).
Solución rápida
Utilice las características Code Insight solamente en tiempo de diseño, sin que
el programa esté ejecutándose.
Información adicional
Code Insight no está disponible en Delphi 1 y 2. Para más información, con-
sulte “Code Insight” en la ayuda de Delphi.
Solución rápida
Mueva algo de código a otra unidad, y añada directamente después de la pala-
bra reservada Implementation una sección Uses que haga referencia a la
138 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Este es generalmente un problema de Delphi 1, ya que el segmento de código
en Windows 3.x está limitado a 64 KB.
Solución rápida
Llame siempre a CoInitialize en todo hilo de una aplicación COM.
Información adicional
También deberá llamar a CoUninitialize cuando la ejecución de cada hilo
finalice.
Comma Expected
Posible causa de error
Puede no estar suministrando los parámetros suficientes a un procedimiento o
función.
Solución rápida
Si el procedimiento o función donde se produce este mensaje de error es un
método de Object Pascal, búsquelo en la ayuda de Delphi para determinar la
cantidad y tipos de los parámetros que el método espera. Si la declaración del
procedimiento o función está contenida en las unidades del proyecto (es un
Mensajes de error 139
Información adicional
En realidad, Delphi probablemente no sólo está esperando una coma, sino tam-
bién como mínimo el parámetro que sigue a la coma. Como la coma es lo pri-
mero que no aparece, se indica como el problema.
Solución rápida
Para reducir el número de errores “vivos”, coloque entre comentarios un gran
bloque de código y solucione los errores uno a uno, hasta que pueda quitar los
comentarios (y entonces corregir los errores contenidos allí).
Información adicional
Puede estar tratando de hacer muchas cosas a la vez, o haber esperado mucho
tiempo antes de compilar. Cuando desarrolle programas, verifique periódica-
mente la validez del código seleccionando Project | Syntax Check, y
resuelva los errores que vaya encontrando, en lugar de esperar hasta el final
para depurar.
Solución rápida
Seleccione Revert en el cuadro de diálogo Install.
Información adicional
Si obtiene este mensaje de error, y posteriormente se queda sin VCL (la biblio-
teca podría no cargarse debido a que ha quedado dañada), deberá reinstalarla
desde del CD de Delphi.
140 Los Tomos de Delphi: Delphi sin problemas
Delphi 1
Reinstale COMPLIB.DCL en C:\Borland\Delphi\BIN.
Delphi 2
Reinstale CMPLIB32.DCL en C:\Archivos de programa\Borland\Delphi
2\BIN.
Delphi 3 y 4
Reinstale VCL30.DPL (Delphi 3) ó VCL40.DPL (Delphi 4) en \Win-
dows\System y VCL30.DCP (Delphi 3) o VCL40.DCP (Delphi 4) en \Archivos
de programa\Borland\Delphi X\Lib.
Puede que sea necesario instalar Delphi. En ese caso, desinstale primero el
Delphi que tenga en el sistema.
Delphi 5 y 6
Reinstale VCL50.DCP (Delphi 5) o VCL60.DCP (Delphi 6) en \Archivos de pro-
grama\Borland\Delphi [5,6]\Lib.
Solución rápida
Proporcione un componente TReport y un componente TTable o TQuery,
asignando el valor True a la propiedad Active de la tabla o consulta.
Información adicional
Debe tener el ReportSmith instalado y un componente TReport de Delphi para
incorporar informes ReportSmith en las aplicaciones de Delphi. ReportSmith
se suministraba con Delphi 1 y Delphi 2. El CD de Delphi 3 contiene Delphi 1,
así que puede instalar ReportSmith desde ahí si lo desea (no confundir con el
componente TReport — ReportSmith es una herramienta de generación de
informes, mientras que TReport es la encapsulación en Delphi de la interfaz de
esa herramienta). Aunque el componente TReport no viene instalado por
defecto con Delphi 3, está disponible. Siga estos pasos para instalarlo en la
Paleta de Componentes:
1. Seleccione Component | Configure Palette. . . .
2. Seleccione Data Access de la lista Pages.
Mensajes de error 141
Solución rápida
1. Asegúrese de que ha finalizado el procesamiento de la consulta anterior
antes de ejecutar una nueva consulta. Para ello, llame al método Last de
TQuery. Luego puede llamar al método First para moverse al inicio del
conjunto resultado si lo desea. Por ejemplo:
with Query1 do
begin
Open;
Last;
First;
end;
Alternativamente, puede llamar al método FetchAll:
with Query1 do
begin
Open;
FetchAll;
end;
2. Llame al método Unprepare de TStoredProc justo después de la ejecución
del primer procedimiento almacenado y antes de la ejecución del segundo,
así:
with StoredProc1 do begin
Prepare;
try
ExecProc;
finally
Close;
Unprepare;
142 Los Tomos de Delphi: Delphi sin problemas
end;
end;
Información adicional
3. Llamando a TQuery.Unprepare se liberan los recursos que el componente
TQuery ha reservado. Delphi llama implícitamen a Prepare y Unprepare
si no son llamados explícitamente. Llame a Prepare cada vez que cambie la
parte Select de una sentencia SQL. Si la parte Select nunca cambia, llame
a Prepare una vez antes de que la consulta se ejecute por primera vez.
Cada llamada a Prepare debe tener una correspondiente llamada a
Unprepare.
Solución rápida
Especifique el componente TConnection que utilizará, arrastrándolo hasta el
módulo de datos (método preferido) o formulario (otra posibilidad) y luego asig-
nándolo mediante el editor de propiedades a la propiedad Connection del
SQLDataSet.
Mensajes de error 143
Información adicional
TConnection en DBExpress es análogo a TDatabase en las aplicaciones basa-
das en el BDE, TIBDatabase en las aplicaciones InterBase Express, y
ADOConnection en las aplicaciones ADO Express.
DBExpress apareció con Delphi 6.
Solución rápida
Para asignar la dirección de una variable a una constante de tipo puntero, la
variable debe ser global:
{ sección Interface }
var
Form1: TForm1;
s: string = 'It''s Howdy Doody Time!';
. . .
procedure TForm1.Button1Click(Sender: TObject);
var
const ptr: Pointer = @s;
Información adicional
Para más información, consulte “pointers” en la ayuda de Delphi.
type
Rays = array[0..6] of string;
end;
...
procedure Radiation;
var
FamousRays: Rays;
begin
FamousRays[0] := 'Ray Bolger';
FamousRays[1] := 'Ray Deaton';
FamousRays[2] := 'Ray Konopka';
FamousRays[3] := 'Ray Krok';
FamousRays[4] := 'Ray Lischner';
FamousRays[5] := 'Ray Pierce';
FamousRays[6] := 'Ray Rogers';
FamousRays[7] := 'Ray [O-Hope, O-Light, O-Vac] West';
{Esta línea provoca el error, pues no hay elemento 7}
end;
2. Puede haber asignado a una variable un valor muy pequeño o muy grande
para su tipo de datos. Por ejemplo, puede estar asignando un número nega-
tivo a una variable de tipo Byte, que solamente acepta enteros de 0 a 255.
Solución rápida
1. Asegúrese de no intentar asignar valor a un elemento de un array que está
fuera de los límites declarados para el array.
2. Asegúrese de que los valores que asigne sean compatibles con el tipo de
datos de las variables a las que realiza las asignaciones.
Información adicional
Para más información, consulte “subrange types” en la ayuda de Delphi.
Solución rápida
1. Si quiere modificar el valor del parámetro, elimine la palabra reservada
Const de la declaración del parámetro en el procedimiento en el que se
hace la llamada. Si no quiere que se modifique el valor, elimine la palabra
reservada Var de la declaración del parámetro en el procedimiento
llamado.
2. Asigne el valor de la propiedad a una variable y pase la variable al procedi-
miento o función. Por ejemplo, para resolver el problema creado en el
código de arriba, podría hacer esto:
procedure TForm1.HealAll(Sender: TObject);
var
s: String;
Sage: TTime;
begin
Sage := TTime.Create;
Wound := 'Bury My Heart at Wounded Knee';
146 Los Tomos de Delphi: Delphi sin problemas
s := Sage.Wound;
delete(s, 1, Length(s));
Sage.Wound := s;
Información adicional
1. Sea consistente en la forma de declarar los parámetros. Estos pueden ser
declarados como constantes (Const), variables (Var), o por valor (por
defecto), pero una vez son declarados de un tipo no pueden ser cambiados a
otro. Para más información sobre los tipos de parámetros, vea “passing
parameters” en la ayuda de Delphi.
2. Busque el procedimiento o función en la ayuda de Delphi para averiguar
los tipos y el orden de los argumentos que espera. Si es un procedimiento o
función de algún tercero, consulte la documentación o el código fuente. Si
es un procedimiento o método propio, consulte su código fuente. Desde
luego, alternativamente podría decidir alterar la declaración del procedi-
miento o función.
Solución rápida
Asegúrese de que los tipos que utilice para las variables sean tipos predefini-
dos de Object Pascal o tipos definidos por el usuario a los que el módulo actual
tenga acceso, debido a que han sido declarados en la unidad actual o en una
unidad mencionada en la sección Uses.
Información adicional
Lo siguiente produce el mensaje de error “Undeclared Identifier: Tex”:
f: Tex;
Solución rápida
1,2. Asegúrese de respetar los límites de los tipos de Object Pascal y los tipos
subrango definidos por el usuario en todas las asignaciones que haga.
Información adicional
En lugar de tratar de resolver el problema después de que se produzca (por
reacción), puede tratarlo proactivamente preparando las condiciones para evi-
tar que ocurra. He aquí una forma de cómo puede hacerlo:
const
Under, Over: Byte;
begin
if StrToInt(Edit1.Text) in [0..255] then
Under := StrToInt(Edit1.Text);
const
Under, Over: Byte;
begin
try
Under := StrToInt(Edit1.Text);
except
on Exception do {atrapar y manejar el error};
end;
end;
Solución rápida
Coloque el array de valores entre corchetes:
Table1.InsertRecord(['Jenny Lind', 'Calaveras',
'California', 50, 1200]);
Información adicional
Además del ejemplo mostrado anteriormente, el procedimiento personalizado
SendAryOfInts produce este mensaje de error:
procedure busywork(aoi: array of integer);
var
li: longint;
i: integer;
begin
for i := low(aoi) to high(aoi) do
ext := ext + aoi[i];
end;
procedure TForm1.SendAryOfInts(Sender: TObject);
begin
Busywork(12, 24, 36, 48); {aquí se produce el error}
end;
Solución rápida
1. Es mejor evitar crear instancias de clases abstractas, ya que es muy fácil
llamar accidentalmente a algún método abstracto (los cuales, por defini-
ción, no tienen implementación).
2. Si no va a redefinir el método en las clases descendientes, haga el método
solamente virtual (y no virtual y abstracto) en el ancestro. Si desea que el
método sea virtual y abstracto, asegúrese de implementarlo en todas las
clases descendientes.
Información adicional
1. Puede desear declarar una variable de tipo TStrings, pero instanciarla
como un descendiente concreto de TStrings (TStringList, por ejemplo), así:
var
CoffeeStrings: TStrings;
. . .
CoffeeStrings := TStringList.Create;
2. Los métodos virtuales no tienen que ser redefinidos en los descendientes.
Si los redeclara y utiliza la directiva Override, puede acceder a la funciona-
lidad en el ancestro llamando a:
inherited <método>;
en el cuerpo de la definición del método en la clase descendiente. Puede
luego extender (añadir funcionalidad) el método con código específico para
la clase descendiente.
Si redeclara el nombre del método sin la directiva Override, estará sustitu-
yendo u ocultando el método del ancestro (consulte “Method <> hides
virtual method of base class <>”).
Si declara un método como virtual, debe también definirlo en la misma uni-
dad, aunque puede definir un cuerpo de método vacío, así:
150 Los Tomos de Delphi: Delphi sin problemas
public
procedure OverrideMe; virtual;
. . .
implementation
. . .
procedure TForm1.OverrideMe;
begin
end;
Si declara un método virtual y abstracto, las clases descendientes deben
redefinirlo e implementarlo (en caso contrario, obtendrán este mensaje de
advertencia).
No defina un método declarado como virtual y abstracto en la unidad en la
que es introducido (esto deberá hacerse en las clases descendientes).
Solución rápida
Elimine la directiva Pascal, Stdcall, Safecall o Cdecl.
Información adicional
Register es el convenio de llamada por defecto para los métodos, y es el único
permitido para los constructores y destructores. No es necesario añadir explíci-
tamente la palabra reservada Register.
Para más información sobre este tema, consulte “calling conventions”, “cons-
tructors and destructors” y “method calling conventions” en la ayuda de
Delphi.
Mensajes de error 151
Solución rápida
Saque el constructor y/o destructor fuera de la sección Automated.
Información adicional
Los constructores y destructores se declaran normalmente en la sección Public.
La sección Automated fue introducida en Delphi 2, dando a Delphi cinco espe-
cificadores de visibilidad: Private, Protected, Public, Published y Automated.
La sección Automated se conserva en Delphi 3 y superiores para compatibili-
dad hacia atrás con Delphi 2.
Para más información, consulte “automated components” en la ayuda de
Delphi.
Solución rápida
1. Asegúrese de que todas las unidades que añada sean válidas. Para ser váli-
das, deben existir, estar correctamente escritas, y estar en la ruta de
búsqueda de Delphi. Para verificar la ruta de búsqueda de Delphi, selec-
cione Tools | Environment Options. . . | Library | Library Path.
2. Borre cualquier extensión de nombre de archivo que pueda haber añadido
a los nombres de las unidades.
3. Asegúrese de que la cláusula Contains finaliza con un punto y coma.
152 Los Tomos de Delphi: Delphi sin problemas
Información adicional
La página Contains del Editor de Paquetes (Package Editor) muestra las uni-
dades que aparecen en la cláusula Contains en el archivo fuente del paquete
(.DPK). Un ejemplo de archivo .DPK se muestra a continuación:
package W8snM;
{$R *.RES}
{$R 'W8snMsrs.DCR'}
{$ALIGN ON}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION ON}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES OFF}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST ON}
{$MINENUMSIZE 1}
{$IMAGEBASE $00400000}
{$DESCRIPTION 'GeekO Weights & Measures Component Suite'}
{$DESIGNONLY}
{$IMPLICITBUILD ON}
requires
vcl30;
contains
AreaM,
CubicM,
DryM,
LinearM,
LiquidM,
W8snMsrs,
W8s;
end.
Mensajes de error 153
Solución rápida
1. Asigne un padre al control antes de intentar mostrarlo o ejecutar cualquier
otra acción sobre él. Por ejemplo, asignar el formulario (el cual es referido
como Self, puesto que la asignación tiene lugar en un método del formula-
rio) como el padre (parent) evita el error:
procedure TForm1.ChildBitBtn(Sender: TObject);
var
Junior: TBitBtn;
begin
Junior:= TBitBtn.Create(Self);
Junior.Parent := Self; {asignar Form1 como padre}
Junior.SetFocus; {esto funciona estupendamente}
end;
2. Asegúrese de que un control tiene su manejador de ventana asignado antes
de hacer una referencia a él. Puede que sea necesario redefinir el método
CreateWnd para ejecutar operaciones sobre un control que requiere un
manejador de ventana válido (que puede no haber sido completamente
creado en el constructor del objeto). Puede mover la sentencia que causa el
error a este método redefinido CreateWnd de esta forma:
procedure TWhatever.CreateWnd;
begin
inherited;
{Aquí se añade el código que no es adecuado
para el constructor del objeto}
end;
154 Los Tomos de Delphi: Delphi sin problemas
Información adicional
1. No confunda el parent (padre) y el owner (propietario) de un control. Es
posible (pero no imprescindible) que un control tenga al mismo control
como propietario y como padre.
Un propietario (owner) se encarga de la creación y destrucción de los com-
ponentes de los que es propietario, y por lo tanto tiene que realizar la
asignación y liberación de memoria.
Un padre (parent), por otra parte, es un control de ventana que visual-
mente contiene otros controles. El padre, por lo tanto, tiene que ver con la
superficie sobre la cual el control hijo es mostrado.
Un control puede tener un mismo propietario y padre. Por ejemplo, un
TBitBtn podría tener un TPanel como padre, y tanto el TBitBtn como el
TPanel tendrían un TForm como propietario.
Como ya se ha mencionado, el padre de un control puede también ser su
propietario. Esto no es imprescindible, sin embargo. El formulario podría
ser el propietario del TBitBtn, pero un TPanel podría ser su padre. He aquí
un ejemplo de esto:
procedure TForm1.ParentNotSameAsOwner(Sender: TObject);
var
Junior: TBitBtn;
begin
Junior:= TBitBtn.Create(Self);
Junior.Parent := Panel1; {se asigna a Panel1 como padre}
Junior.SetFocus; {esto funciona perfectamente}
end;
2. Para más información, consulte “creation order” en la ayuda de Delphi.
Solución rápida
Solamente añada componentes no visuales a los módulos de datos.
Información adicional
Aunque los módulos de datos tienen como objetivo central contener componen-
tes de acceso a datos, no tienen únicamente que contener éstos. Es posible
situar cualquier componente no visual sobre ellos; por ejemplo, componentes
TTimer y componentes de diálogos (como TOpenDialog, TSaveDialog, etc.).
Mensajes de error 155
Solución rápida
1-4.Elimine y luego vuelva a crear el archivo de índice.
Información adicional
Si recibe este mensaje de error en el Database Desktop, puede estar precedido
por “Unable to open table”.
Si la tabla del problema es un tabla Paradox, el archivo de índice que está
dañado probablemente tiene una extensión .PX. A continuación se muestra
una lista de los archivos auxiliares que pueden ser creados (indirectamente)
con Paradox y para qué se utilizan:
<NombreTabla>.PX
Este archivo contiene la información de clave primaria de la tabla, y es proba-
blemente el que se ha dañado. Si designa un campo o grupo de campos como la
clave primaria de la tabla, este archivo es creado.
<NombreTabla>.Xnn
Los archivos con la extensión .Xnn (donde nn es un número hexadecimal) con-
tienen información de índices secundarios.
<NombreTabla>.Ynn
Los archivos con la extensión .Ynn (donde nn es un número hexadecimal) con-
tienen información de índices secundarios.
<NombreTabla>.VAL
Los archivos con la extensión .VAL contienen información que se ha proporcio-
nado a través del Database Desktop con respecto a los chequeos de validación,
como por ejemplo si una columna debe tener obligatoriamente un valor (no se
156 Los Tomos de Delphi: Delphi sin problemas
permite que sea nula), los valores máximos y mínimos permitidos para una
columna, los valores por defecto para una columna y los patrones de
validación.
Seleccione Validity Checks en el cuadro de combinación de propiedades de la
tabla en el Database Desktop para acceder a estas características.
<NombreTabla>.MB
Los archivos con la extensión .MB contienen los datos de las columnas de tipos
Memo y Graphic (TMemoField y TGraphicField).
Solución rápida
1. Asegúrese de que existe el directorio en el que el archivo de salida supues-
tamente será creado.
2. Quite el atributo de sólo lectura del directorio. Para hacerlo utilizando el
Explorador de Windows, pulse con el botón derecho del ratón sobre el direc-
torio, seleccione Propiedades del menú de contexto, y desmarque la
casilla de verificación Sólo Lectura.
3. Si ha experimentado un Error de Protección General y no ha reiniciado,
hágalo.
4. Elimine el control ActiveForm de la Paleta de Componentes de Delphi, y
luego proceda.
Información adicional
4. Cuando un .OCX está siendo utilizado por Delphi, no puede ser sobrescrito.
Por defecto, Delphi almacenará los archivos de salida en el mismo directo-
rio del archivo de proyecto (.DPR). Ejemplos de archivos de salida son los
Mensajes de error 157
Solución rápida
Copie STDVCL[32,40].DLL desde el CD de Delphi a \Windows\System y
regístrelo utilizando TRegSvr (de Borland) o RegSvr32 (de Microsoft).
Para registrar la .DLL (después de copiarla al directorio \Windows\System),
siga estos pasos:
1. Abra una ventana DOS.
2. Vaya al directorio \Windows\System.
3. Introduzca Regsvr32 <biblioteca> y luego pulse la tecla Intro.
Por ejemplo, si la biblioteca de tipos del problema es IDataBroker, podría intro-
ducir lo siguiente (ya que está definido en STDVCL32.DLL): Regsvr32
STDVCL32. En Delphi 4, el archivo correspondiente es STDVCL40.DLL; por lo
tanto, deberá teclear Regsvr32 STDVCL40.
Información adicional
STDVCL[32,40].DLL tiene una biblioteca de tipos correspondiente,
STDVCL.TLB,que está ubicada por defecto en C:\Archivos de programa\Bor-
land\Delphi X\BIN. Stdvcl32 es específica de Delphi 3 y Stdvcl40 para Delphi
4.
TRegSvr.EXE está ubicado en \Delphi\bin en Delphi 4 y superiores. RegSvr32
está ubicado en \Windows\System.
158 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Registre la biblioteca de tipos a la que se hace referencia en el mensaje de
error siguiendo estos pasos:
1. Abra un ventana DOS.
2. Vaya al directorio C:\Windows\System.
3. Introduzca Regsvr32 <biblioteca> y pulse la tecla Intro.
Por ejemplo, si la biblioteca de tipos del problema es IDataBroker, se debe
introducir lo siguiente (ya que está definida en STDVCL32.DLL): Regsvr32
STDVCL32. En Delphi 4, el archivo correspondiente es STDVCL40.DLL; por lo
tanto, deberá teclear: Regsvr32 STDVCL40.)
Información adicional
La ubicación por defecto de STDVCL[32,40].DLL es: C:\Archivos de pro-
grama\Borland\Delphi X\BIN.
STDVCL[32,40].DLL contiene las declaraciones de interfaz para la VCL están-
dar de Borland.
Solución rápida
Registre STDVCL[32,40].DLL utilizando REGSVR32.EXE ó TREGSVR.
Información adicional
IDataBroker está definido en la biblioteca VCL estándar de Borland, ubicada
por defecto en C:\Archivos de programa\Borland\Delphi X\bin.
Mensajes de error 159
Solución rápida
Delphi 1
Asegúrese de que la ruta indicada en WIN.INI corresponde a la ubicación
actual de los controladores de lenguaje que están en el sistema. Una entrada
típica es:
[Borland Language Drivers]
LDPATH=C:\IDAPI\LANGDRV
Delphi de 32 bits
Asegúrese de que el Registro contiene la configuración correspondiente. Eje-
cute RegEdit y navegue hasta la clave HKEY_LOCAL_MACHINE | Software
| Borland | Database Engine | Settings | Drivers.
Información adicional
Este es el código de error $220B.
Could not find object. Cannot load an IDAPI service library. File:
ODBC32.DLL
Posible causa de error
Puede estar intentando cargar los parámetros por defecto en el editor del com-
ponente TDatabase, con un alias no reconocido introducido en el cuadro de
combinación Alias Name.
Solución rápida
Seleccione un alias en el cuadro de combinación Alias Name. Si es necesario,
cree un nuevo alias del BDE antes de configurar los parámetros por defecto.
Información adicional
Para crear un alias del BDE, siga estos pasos:
1. Seleccione Database | Explore.
160 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1,2. Compruebe que las .DLLs del BDE existen y están en la localización espe-
cificada por el archivo WIN.INI (Delphi 1) o el Registro de Windows
(Delphi 32 bits). Si no están en la ubicación especificada pero están en
cualquier otro lugar del sistema, muévalas al lugar esperado o edite
WIN.INI o el Registro y configure su ubicación actual. Si no están en el sis-
tema, cópielas desde el CD Delphi.
Información adicional
Cada PC que utilice el BDE necesita las .DLLs del BDE y un archivo de confi-
guración. En Delphi 1, el archivo de configuración IDAPI se llamaba
IDAPI.CFG. En Delphi de 32 bits, es IDAPI32.CFG. En Delphi 1, la ubicación
de IDAPI.CFG se encuentra en la sección [IDAPI] del archivo WIN.INI. Por
defecto, la configuración es:
DLLPATH=C:\IDAPI
CONFIGFILE01=C:\IDAPI\IDAPI.CFG
Could not load <>. The OLE control may possibly require support
libraries that are not on the current search path or are not present
on your system
Consulte “The OLE control may possibly require support libraries that
are not on the current search path or are not present on your system”.
Solución rápida
Localice RLINK32.DLL. Su ubicación por defecto es C:\Archivos de pro-
grama\Borland\Delphi X\BIN.
Si no está en el lugar por defecto, pero está en algún otro lugar del sistema,
asegúrese de que esté en la ruta de búsqueda de Delphi. Seleccione Tools |
Environment Options, luego la página Library y el cuadro de combinación
Library Path para verificar o modificar la ruta de búsqueda de Delphi.
Si no está en el sistema, cópielo desde el CD de Delphi.
Información adicional
Siempre que sea posible, es mejor mantener los archivos en los lugares por
defecto. No cambie de lugar arbitrariamente los archivos. No borre archivos si
no conoce su propósito — el archivo puede ser vital para la operación del sis-
tema, para Delphi, y/o para su propio bienestar.
Consulte “Error 0: RLINK32 Error opening file <>.tlb”.
Solución rápida
Localice el archivo y muévalo al directorio \Windows\System.
Si el archivo no está en su sistema, cópielo a \Windows\Syste desde el CD de
Delphi hasta \Windows\System.
Información adicional
Delphi 1 utiliza STDOLE.TLB. Delphi de 32 bits utiliza STDOLE2.TLB.
Solución rápida
Si borra un archivo de biblioteca de tipos, pero no ha vaciado la Papelera de
Reciclaje de Windows, siga estos pasos:
1. Pulse con el botón derecho sobre la Papelera de Reciclaje.
2. Seleccione Abrir desde el menú de contexto.
3. Pulse con el botón derecho sobre el archivo que quiera restaurar (un
archivo de biblioteca de tipos en este caso).
4. Seleccione Restaurar desde el menú de contexto.
Si el archivo no se encuentra en el sistema (ni está en la Papelera de Reci-
claje), trate de reinstalarlo desde la fuente original (El CD de Delphi, si es de
donde lo obtuvo).
Información adicional
El archivo más importante de biblioteca de tipos que viene con Delphi 3 es
STDVCL32.TLB, el cual es una interfaz para los controles VCL estándar. El
correspondiente archivo en Delphi 4 es STDVCL40.DLL. No ha habido actuali-
zaciones para Delphi 5 o 6; es decir, no hay un STDVCL50.DLL o
STDVCL60.DLL.
Could not load unit <> symbol information for <> Do you want to
try to find this file yourself?
Posible causa de error
Puede obtener este mensaje de error mientras trabaja con el Asistente para la
creación de controles ActiveX (ActiveX Control Wizard), después de seleccionar
Mensajes de error 163
un componente VCL del cual heredar. Puede ser que el archivo esté en el lugar
correcto (a pesar del mensaje de error), pero hay un error en el archivo.
Solución rápida
Si hay un error en el componente del que intenta derivar, solucione el error
antes de intentar derivar un control ActiveX de este componente.
Información adicional
Si el archivo no puede ser cargado debido a un error, puede que le haya hecho
cambios después de haberlo instalado en la VCL. La ventana de mensajes del
compilador mostrará cualquier error que encuentre. Pulse el botón derecho del
ratón sobre el mensaje de error y seleccione Edit Source. Esto lo llevará direc-
tamente a la línea de código que ocasiona el error en el archivo. Solucione el
error, grabe y cierre el archivo .PAS, y luego intente de nuevo crear el control
ActiveX.
Couldn’t perform the edit because another user changed the record
Posible causa de error
Además de lo obvio (otro usuario accedió al registro y lo modificó), puede ser
que tenga configurados disparadores (triggers) que estén generando automáti-
camente los valores de ciertos campos.
Solución rápida
Compruebe los disparadores para ver qué es lo que están cambiando y cuándo.
Información adicional
Si es realmente posible que otro usuario cambie el registro que está editando,
puede que desee utilizar cualquier mecanismo de bloqueo que soporte su base
de datos. Para más información buscar “locks”, “UpdateMode”, y “TransIsola-
tion” en la ayuda de Delphi.
Solución rápida
Proporcione una contraseña válida en el cuadro de edición Password e intén-
telo de nuevo.
Información adicional
El Query Builder solamente está disponible en la versión Cliente/Servidor
(Enterprise) de Delphi.
Solución rápida
1. Mueva algunas o todas las variables a la sección Private de un objeto en su
unidad.
2. Si el problema se debe a utilizar muchas cadenas en Delphi 1 (en Delphi de
32 bits, simplemente utilice cadenas largas, que son en el fondo punteros
de 4 bytes), puede disminuir la cantidad de espacio que éstas consumen
declarando explícitamente su tamaño, como:
TRecording = record
Number: Integer;
Hits: Integer;
Title: String[24];
Artist: String[16];
end;
Mensajes de error 165
-O-
Puede utilizar recursos de cadenas de caracteres para las constantes que el
programa utilizará. Esto es particularmente fácil a partir de Delphi 3, que
introdujo la palabra reservada Resourcestring. Las constantes de cadena
son almacenadas automáticamente en un archivo de recursos y cargadas
dinámicamente cuando se hace referencia a ellas. Podría utilizar algo así:
resourcestring
KnockKnock = '%s who?';
Excuse = 'The reason %s doesn''t %s is %s';
WeatherDialog = '%s enough for ya?';
ElvinBishop = 'There ain''t no %s like %s %s';
Para las variables de cadena, puede reducir el tamaño de memoria asig-
nada declarando el tamaño máximo que se quiere permitir para una
variable de cadena particular. En otras palabras, si declara una cadena
que contendrá el apellido de la persona, no es necesario reservar la canti-
dad por defecto de 256 bytes para ella. En ese caso podría hacer lo
siguiente:
var
Surname: String[20];
Esto reserva 21 bytes en lugar de 256, un ahorro significativo de memoria.
Si el problema se debe a que tiene demasiadas estructuras de datos gran-
des (que no son cadenas), puede convertirlas en punteros, que solamente
consumen cuatro bytes cada uno, así:
TptrRecording = ^TRecording;
TRecording = record
Number: Integer;
Hits: Integer;
Title: String;
Artist: String;
end;
. . .
var
ptrPlatter, ptrAlbum, ptrDisc, ptrCD,
ptrMusic, ptrTunes, ptrToons: TptrRecording;
Si utiliza punteros, deberá reservar y liberar explícitamente la memoria
que utilizará. En Delphi 1, puede utilizar para ello una sección Initializa-
tion y un procedimiento de salida. En Delphi de 32 bits, puede utilizar las
secciones Initialization y Finalization. A continuación se muestra un ejem-
plo para Delphi 1 (utilizando un procedimiento de salida):
procedure SanitaryEngineer; far;
begin
Dispose(ptrPlatter);
Dispose(ptrAlbum);
. . .
end;
166 Los Tomos de Delphi: Delphi sin problemas
initialization
New(ptrPlatter);
New(ptrAlbum);
. . .
AddExitProc(SanitaryEngineer);
end.
En lo adelante, puede acceder a la memoria apuntada por el puntero derre-
ferenciándolo. Por ejemplo, para almacenar un valor en el campo Artist,
podría hacerlo de esta forma:
ptrPlatter^.Artist := 'Hootie and the Blowfish';
3. Utilice variables inicializadas en lugar de constantes con tipo. Por ejemplo,
en lugar de las siguientes constantes con tipo:
const
StringCheeseString: String = 'Wisconsin Wonder';
TypedTypeTypTip: Integer = 17;
Utilice las siguientes variables inicializadas:
const
StringCheeseString = 'Wisconsin Wonder';
TypedTypeTypTip = 17;
Información adicional
Esto es principalmente un problema de Delphi 1; más específicamente, un pro-
blema de Windows 3.x, donde el segmento de datos está limitado a 64 KB.
1. Trate de evitar utilizar variables globales en la medida de lo posible. Uti-
lice variables locales siempre que sea posible. Si necesita compartir
variables globales entre múltiples unidades, utilice una unidad global espe-
cíficamente para esto.
2. Puede incluir tantas tablas de cadenas de caracteres como quiera, y los
números utilizados en ellas para designar las cadenas no tienen que ser
consecutivos.
3. Las constantes con tipo se añaden al segmento de datos del programa. Las
variables inicializadas, por otra parte, no. Si no va a reasignar el valor de
una constante con tipo, utilice una constante sin tipo, o una variable inicia-
lizada. Sustituya las constantes con tipo por variables inicializadas para
compatibilidad con versiones futuras de Delphi.
Solución rápida
1. Limite la cantidad de cambios en una única transacción a no más de 255.
2. Descargue la versión más reciente del BDE desde el sitio
www.borland.com/devsupport/bde/bdeupdate.html
Información adicional
Los límites de Paradox se indican más abajo. Para información general relacio-
nada con las limitaciones del BDE y dBASE, consulte en la Web de Borland
http://www.borland.com.
Solución rápida
Debe disminuir el tamaño del tipo. Por ejemplo, lo siguiente compilará:
TTexasSizedArray = array[0..100000000] of variant;
Información adicional
200.000.000 enteros y 100.000.000 de variantes deberían ser suficientes en la
mayoría de los casos. Si es necesario, declare dos tipos separados, así:
TAlaska = array[0..200000000] of integer;
TAlaskaAnnex = array[0..200000000] of integer;
Solución rápida
Asigne un valor a la propiedad DatabaseName del componente TDatabase
antes de intentar asignar el valor True a su propiedad Connected.
Mensajes de error 169
Información adicional
El componente TDatabase es similar al componente TSession, en el sentido de
que se crea implícitamente una instancia de ellos con sus propiedades asigna-
das a valores por defecto cuando es necesario.
En muchas ocasiones resulta ventajoso crear explícitamente un componente
TDatabase, especialmente cuando se desea conectar con servidores de bases de
datos SQL (como InterBase, Oracle, MS SQL Server, Informix, etc.).
Puede mejorar el rendimiento en tales casos asignando el valor True a la pro-
piedad KeepConnected del componente TDatabase, evitando muchas inicializa-
ciones de conexión que consumen tiempo durante la ejecución del programa.
Un componente TDatabase permite también utilizar procesamiento de transac-
ciones llamando al método StartTransaction de TDatabase, seguido por una
llamada a Commit o Rollback, en dependencia del éxito o fallo de la
transacción.
He aquí un ejemplo de cómo utilizar las transacciones de bases de datos:
begin
with Database1 do
begin
StartTransaction;
try
Query1.Active := True;
Commit;
except
Rollback;
end; {bloque except}
end; {bloque with}
end;
Result := Fields[0].AsString;
end;
finally
IBQry.Free;
end;
Solución rápida
Asigne una base de datos al componente de consulta antes de ejecutar la con-
sulta, así:
. . .
Database := dm.IBDB;
. . .
Open;
Información adicional
En el código de arriba, dm es un módulo de datos en el que reside un objeto de
tipo TIBDatabase llamado IBDB. Los componentes IBX aparecen en la página
InterBase de la Paleta de Componentes para ser utilizados en las aplicaciones
que utilicen bases de datos InterBase (sin necesidad del BDE). A partir de la
versión 6 de Delphi, también se tiene la opción de utilizar los componentes
DBExpress para acceder a InterBase sin el BDE.
Solución rápida
Proporcione un componente TQuery como valor de la propiedad Dataset del
componente TProvider.
Información adicional
Solución rápida
El parámetro NetDir debe apuntar a un directorio compartido de red al que
todos los usuarios que accederán a las tablas deberán tener derechos de acceso
de lectura, escritura y creación.
Información adicional
Dos propiedades de TSession, NetFileDir y PrivateDir, son específicas para
aplicaciones que trabajan con tablas Paradox. NetFileDir especifica el directo-
rio que contiene el archivo de control de red de Paradox, PDOXUSRS.NET.
Este archivo gestiona la compartición de las tablas Paradox sobre la red. Todas
las aplicaciones que necesiten compartir tablas Paradox deben especificar el
mismo directorio de archivo de control de red (normalmente un directorio sobre
el servidor de archivos de la red).
Solución rápida
Coloque el conjunto de datos en modo de edición o inserción antes de hacer
modificaciones o adiciones a él. Por ejemplo, si quiere editar el registro actual
del campo MonthlySpecial de la tabla Pizza, podría hacer lo siguiente:
with Pizza do
begin
Edit;
PizzaMonthlySpecial.AsString := 'Italian Garlic';
Post;
end;
Información adicional
Para que la sintaxis de arriba funcione (PizzaMonthlySpecial.AsString), el
campo debe haber sido creado en tiempo de diseño utilizando el editor de cam-
pos (Fields Editor). De otro modo, necesitará asignar un valor al campo utili-
zando las propiedades Fields, FieldValues o FieldByName de TDataset.
Los estados o modos posibles de un TDataset son: dsBrowse, dsCalcFields,
dsCurValue, dsEdit, dsFilter, dsInactive, dsInsert, dsNewValue, dsOldValue y
dsSetKey.
Solución rápida
Instale y registre el archivo sobre la máquina cliente.
Información adicional
Para registrar el archivo (después de copiarlo al directorio \Windows\System),
siga estos pasos:
1. Abra una ventana DOS.
2. Vaya al directorio \Windows\System.
3. Introduzca Regsvr32 <archivo> y luego pulse la tecla Enter.
Por ejemplo, si el archivo del problema es DBCLIENT.DLL, sería
Regsvr32 DBCLIENT.DLL.
Consulte “Class not registered”.
Mensajes de error 173
Solución rápida
Añada un gestor de excepciones a su servidor de aplicaciones.
Información adicional
Atrapando los errores en el servidor de aplicaciones podrá determinar la natu-
raleza específica del problema que está experimentando.
Solución rápida
Si es necesario, descargue e instale DCOM del sitio Web de Microsoft.
Información adicional
Windows NT 4, Windows 98, Internet Explorer 4, y sus versiones posteriores
incluyen DCOM.
Solución rápida
1. Espere hasta que la ventana de visualización se haya actualizado antes de
continuar la traza de la ejecución.
2. Después de una excepción en tiempo de ejecución, seleccione Run | Pro-
gram Reset.
Información adicional
2. Al seleccionar Run | Program Reset después de experimentar excepcio-
nes, hará que Delphi libere los recursos asignados por llamadas a la VCL e
inicialice las variables del programa.
Sin embargo, reiniciar un programa desde el entorno integrado de Delphi
de esta manera no necesariamente libera todos los recursos de Windows
asignados por el programa.
Si continúa experimentando inestabilidad sin razón aparente, seleccione
File | Close All, luego File | Exit, y finalmente reinicie Delphi e intente
compilar el proyecto de nuevo.
Solución rápida
Seleccione Cancel cuando reciba este mensaje de error y luego seleccione Run
| Program Reset.
Información adicional
Si está experimentando excepciones o mensajes de error inusuales, seleccione
File | Close All, luego File | Exit y reinicie Delphi. Si continúa teniendo pro-
blemas, cierre todo y reinicie Windows.
Mensajes de error 175
Solución rápida
1. Asegúrese de que cualquier DLL requerida esté accesible. Por convenio, los
archivos DLL (incluyendo los DPLs, o paquetes) se instalan en el directorio
\Windows\System. En el mundo de los ordenadores, normalmente es útil
seguir un convenio, a menos que se tenga una excelente razón para no
hacerlo.
2. Verifique que cualquier procedimiento o función que esté llamando en las
DLLs correspondan en nombre y argumentos. En Windows de 32 bits, los
nombres de los procedimientos exportados son sensibles a las diferencias
mayúsculas/minúsculas.
3. Verifique que está pasando a los procedimientos o funciones que llama la
cantidad y tipos de parámetros adecuados, y en el orden correcto.
4. Permita que todos los valores de la ventana de visualización se actualicen
antes de continuar trazando el código, o elimine algunas variables de la
lista.
5. Verifique que la ruta y el nombre del servidor remoto que esté utilizando
sean válidos.
Información adicional
Intente ejecutar el programa desde el Explorador de Windows. Puede que
obtenga un mensaje de error más descriptivo, que indique qué archivo .DLL es
el que falta.
176 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Utilice un nombre válido de Object Pascal para la declaración. Estas decla-
raciones están bien:
stringy: string;
a1string: string;
_1string: string;
2. Añada de nuevo la declaración necesaria.
3. Añada una sección Initialization antes de la sección Finalization.
Información adicional
3. Si utiliza una sección Finalization, debe también utilizar una sección Ini-
tialization. Puede inicializar variables, asignar memoria, etc., en la sección
Initialization. La sección Finalization es un buen lugar para liberar memo-
ria y otros recursos.
Mensajes de error 177
Solución rápida
Cambie las signaturas en la clase o interfaz para que coincidan.
Información adicional
Cuando las clases implementan interfaces, deben implementar todos los méto-
dos que la interfaz declara. Todas las clases que implementen interfaces deben
implementar los tres métodos de IUnknown (QueryInterface, AddRef y
Release); si deriva su clase de TInterfacedObject (como se muestra arriba), esto
se hace automáticamente. Se hereda la implementación predefinida de esos
métodos heredando de TInterfacedObject.
Solución rápida
1. Consulte la declaración original del procedimiento o función y utilice la
misma signatura en su implementación.
2. Cuando se redefine un método virtual, se debe utilizar la misma lista de
parámetros (cantidad, tipos, nombres y orden de los parámetros).
3. Utilice el mismo convenio de llamada que se utiliza en el método a
redefinir.
Información adicional
3. Para más información, consulte “calling conventions” en la ayuda de
Delphi.
a:
TPanel1 = class(TForm)
provocará este mensaje de error.
2. Puede haber eliminado la referencia al ancestro del tipo de la declaración
Type, así:
TForm1 = class { (TForm) se ha borrado }
Solución rápida
1,2. Vuelva a la declaración que ha generado automáticamente Delphi, es decir:
TForm1 = class(TForm)
o cambie el nombre de la clase (formulario) a través del Inspector de Obje-
tos (Object Inspector).
Información adicional
Puede declarar un nuevo tipo sin especificar un ancestro, así:
TBill = class
Mensajes de error 179
Solución rápida
La cláusula Default no está permitida en las secciones Automated de OLE. Eli-
mine la cláusula.
Información adicional
Delphi 2 y posteriores ofrecen cinco especificadores de visibilidad: Private, Pro-
tected, Public, Published y Automated. Una propiedad de una clase puede
especificar características de almacenamiento mediante las palabras reserva-
das Stored, Default o Nodefault. Estos especificadores de almacenamiento, sin
embargo, no están permitidos en las secciones Automated.
El especificador Index, que permite que múltiples propiedades compartan los
mismos métodos de acceso, tampoco está permitido en la sección Automated.
Solución rápida
Debe elegir una de tres posibles soluciones:
1. Cambie el parámetro a un parámetro constante:
procedure ThatAintWorkin(const iYiYi: Integer = 86);
2. Cambie el parámetro a un parámetro pasado por valor:
procedure ThatAintWorkin(iYiYi: Integer = 86);
Información adicional
En Pascal, hay tres formas de pasar parámetros: por referencia (Var), cons-
tante (Const) o por valor (como es el mecanismo por defecto, no es necesario
especificar nada). La forma por defecto (por valor) es la forma “más segura”,
pero es también la menos eficiente. Cuando un parámetro es pasado por valor,
una copia es creada y enviada (por lo que hay dos instancias del parámetro).
Cuando se pasa por referencia (Var), se envía un puntero al parámetro con
capacidad de escritura. Cuando se pasa una constante, se pasa un puntero de
sólo lectura al parámetro. Por lo tanto, si va a cambiar el valor (y desea que el
cambio se refleje también en el contexto de la llamada), páselo por referencia
(anteponiendo Var al nombre del parámetro). Si el valor no va a cambiar,
páselo como una constante (anteponiendo Const al parámetro). Solamente uti-
lice la forma por defecto (por valor) en caso de que el valor puede cambiar, y no
desea que esos cambios se reflejen en el contexto desde el que se hace la
llamada.
Solución rápida
Borre la directiva Default de la declaración de la propiedad. Solamente es posi-
ble designar una propiedad de tipo array como la propiedad por defecto de la
clase. Por ejemplo, lo siguiente es aceptable:
type
TComputer = class
. . .
property Clones[Index: Integer]: String
read FNetPC write SetNetPC; default;
Información adicional
La ventaja de especificar una propiedad de tipo array como propiedad por
defecto es que luego puede acceder a esa propiedad en el código sin tener que
Mensajes de error 181
Solución rápida
Si proporciona un valor por defecto para un parámetro, deberá también
proporcionar valores por defecto para todos los parámetros que le siguen, así:
procedure BiDefault(i: Integer = 76; s: String = 'trombones');
Información adicional
Algunas funciones, como StrToIntDef, también permiten especificar un valor
de retorno por defecto. Puede, por supuesto, escribir sus propias funciones de
forma que sigan este patrón.
Solución rápida
Elimine la directiva de almacenamiento Default y el correspondiente valor por
defecto. No declare valores por defecto para propiedades de tipo cadena
(string), de punto flotante o arrays.
Información adicional
Como indica el texto de este mensaje de error, los valores de las propiedades
por defecto deben ser ordinales, punteros, o tipos de conjunto pequeños. En tér-
minos prácticos, esto significa tipos enteros, Boolean y enumerados. Como
ejemplo de lo que es aceptado y comúnmente utilizado, he aquí un extracto de
la unidad Buttons de Delphi:
{Tipo enumerado utilizado después como tipo de propiedad}
type
TButtonLayout = (blGlyphLeft, blGlyphRight, blGlyphTop,
blGlyphBottom);
. . .
TSpeedButton = class(TGraphicControl)
{Propiedad de tipo Boolean con directiva de
almacenamiento Default asociada}
property AllowAllUp: Boolean read FAllowAllUp
write SetAllowAllUp default False;
{Propiedad de tipo entero con directiva de
almacenamiento Default asociada}
property GroupIndex: Integer read FGroupIndex
write SetGroupIndex default 0;
. . .
{Propiedad de tipo enumerado con directiva de
almacenamiento Default asociada}
property Layout: TButtonLayout read FLayout
write SetLayout default blGlyphLeft;
. . .
property Cancel stored IsCustom;
property Caption stored IsCustomCaption;
. . .
function TBitBtn.IsCustom: Boolean;
begin
Result := Kind = bkCustom;
end;
. . .
function TBitBtn.IsCustomCaption: Boolean;
begin
Result := CompareStr(Caption,
LoadResString(BitBtnCaptions[FKind])) <> 0;
end;
Solución rápida
Asegúrese de que la tabla a la que hace referencia la propiedad Destination del
componente TBatchMove tiene un índice correspondiente a otro de la tabla a la
que hace referencia la propiedad Source.
Información adicional
Para actualizar o borrar registros específicos de una tabla, Delphi deberá ser
capaz de “emparejar” los registros en la tabla Destination con los registros en
la tabla Source. Si las tablas Destination y Source no tienen índices correspon-
dientes, esto es imposible y por ello obtendrá este mensaje de error.
Para ejecutar la operación de BatchMove en tiempo de diseño, siga estos pasos:
1. Asigne a la propiedad Source del componente TBatchMove un componente
TDataset.
2. Asigne a la propiedad Destination del componente TBatchMove un compo-
nente TTable.
184 Los Tomos de Delphi: Delphi sin problemas
Directory Is Busy
Posible causa de error
Múltiples aplicaciones (o múltiples instancias de una misma aplicación) pue-
den estar intentando utilizar el mismo directorio como directorio privado.
Solución rápida
Distribuya cada aplicación de manera que se ejecute en su propio directorio
separado, o asigne la propiedad PrivateDir del componente TSession durante el
arranque de la aplicación (antes de que se acceda a ninguna tabla). El directo-
rio privado de cada usuario debe ser inaccesible a los demás usuarios; puede
estar situado en el disco duro local del usuario, o sobre la red si el espacio de
almacenamiento local es limitado. Por ejemplo, para hacer que el programa
cree un directorio en el disco duro local del usuario, podría hacer esto antes de
que las tablas sean accedidas:
var
Extension, ExecName, MineAllMine : String;
ExtensionPos: Integer;
. . .
ExecName := ExtractFileName(Application.ExeName);
Extension := ExtractFileExt(Application.ExeName);
ExtensionPos := Pos(Extension, ExecName);
Delete(ExecName, ExtensionPos, 4);
MineAllMine := 'C:\Temp\' + ExecName;
if not DirectoryExists(MineAllMine) then
CreateDir(MineAllMine);
if DirectoryExists(MineAllMine) then
Session.PrivateDir := MineAllMine
else
raise Exception.Create('Por alguna razón, el directorio privado'
+ MineAllMine + ' no fue creado.');
end;
Información adicional
Esto no es un problema si cada usuario está ejecutando su propia copia local
del ejecutable, ya que el Directorio Privado es implícitamente asignado al
directorio actual. A menos que lo haya cambiado, éste será el directorio en el
que el ejecutable reside.
Mensajes de error 185
Si múltiples usuarios acceden al mismo programa sobre una red (todos ejecu-
tan un mismo ejecutable situado en una unidad de red compartida), para cada
uno de ellos se deberá asignar explícitamente un directorio privado distinto del
de los demás. De otra manera, todos los archivos temporales tratarán de utili-
zar el mismo directorio (el directorio en el que reside el ejecutable compartido),
y se producirán conflictos (específicamente, se obtendrá este mensaje de error).
Solución rápida
1. Configure cada máquina de usuario de manera que tengan el mismo valor
de configuración del parámetro NetDir (que indica el directorio de la red en
el que reside el archivo PDOXUSRS.NET). Puede hacerlo siguiendo los
pasos adecuados para su versión de Delphi:
Delphi 1
Si cada usuario tiene su propia copia del BDE en su máquina, puede utilizar la
utilidad de configuración del BDE para asignarles el directorio de red. Para
ello, siga estos pasos:
a. Abra la utilidad de configuración del BDE (BDE Configuration).
b. Con la entrada ‘Paradox’ seleccionada en el cuadro de lista Driver
Name, introduzca la ruta completa del directorio de red compartido
donde se almacena el archivo de control de red (PDOXUSRS.NET) en
el parámetro NetDir.
c. Seleccione File | Exit y grabe los cambios.
Si algún usuario no tiene una copia de la utilidad de configuración del BDE,
asegúrese de que la ubicación actual de su archivo IDAPI.CFG (por defecto
C:\IDAPI) coincida con lo indicado en la entrada CONFIGFILE01 de la sección
[IDAPI] del archivo WIN.INI.
186 Los Tomos de Delphi: Delphi sin problemas
Delphi 2
Si cada usuario tiene su propia copia del BDE, puede utilizar la utilidad de
configuración del BDE para asignarles el directorio del archivo de control de
red de Paradox. Para ello, siga estos pasos:
a. Abra la utilidad de configuración del BDE (BDECFG32.EXE)
seleccionando Inicio | Programas | Delphi | BDE Configuration.
b. Con la entrada ‘Paradox’ seleccionada en el cuadro de lista Driver
Name, introduzca la ruta completa del directorio de red compartido
donde se almacena el archivo de control de red (PDOXUSRS.NET) en
el parámetro NetDir.
c. Seleccione File | Exit y grabe los cambios.
Vea Delphi de 32 bits más adelante.
Delphi 3 y 4
Si cada usuario tiene su propia copia de BDE, puede utilizar la utilidad de
administración del BDE para asignarles el directorio de red de Paradox. Para
ello, siga estos pasos:
a. Abra la utilidad BDE Administration (Inicio | Programas | Delphi
X | BDE Administrator).
b. Seleccione Object | Open Configuration. . . .
c. Abra IDAPI32.CFG.
d. Navegue hasta Configuration | Drivers | Native | Paradox | Net
Dir.
e. Introduzca la ruta completa del directorio en donde reside el archivo de
control de red. Seleccione un directorio de red compartido sobre el que
todos los usuarios de las tablas Paradox tengan derechos de lectura,
escritura y borrado.
f. Seleccione Object | Exit y luego Yes para grabar los cambios
realizados.
Delphi de 32 bits
Si algún usuario no tiene una copia de la utilidad BDE Configuration/Adminis-
tration, puede consultar el Registro del sistema para asegurarse de que la ubi-
cación de IDAPI32.CFG (por defecto C:\Archivos de programa\Borland\
Common files\BDE) coincide con lo que se indica en el Registro del sistema. La
clave del Registro DLLPATH está ubicada en HKEY_LOCAL_MACHINE\
Software\Borland\Database Engine.
Mensajes de error 187
Si es necesario, mueva el archivo para que coincida con la entrada del Registro
o cambie la entrada en el Registro del sistema para que coincida con la ubica-
ción del archivo.
2. Haga que todos los usuarios de los programas que acceden a las tablas en
cuestión salgan de los programas. Busque y borre el archivo
PDOXUSRS.NET y los archivos *.LCK inválidos.
3. Asigne el valor True al parámetro Local Share mediante la utilidad de con-
figuración del BDE.
Información adicional
El directorio en el que reside el archivo de control de red (PDOXUSRS.NET)
debe ser un directorio de red compartido sobre el que todos los usuarios que
accedan a las tablas deben tener derechos de lectura, escritura y creación.
Puede pensar en el archivo de control de red como en un policía de tráfico. Los
conflictos potenciales pueden ser evitados si todos los usuarios/controladores
miran al mismo policía de tráfico/archivo de control de red para orientarse. Si
los usuarios se guían por diferentes policías, el resultado no será agradable.
Si múltiples usuarios compartieran la misma copia de un archivo .EXE (por
ejemplo, uno que resida en una unidad de red compartida) que accede a tablas
de Paradox, ellos deberán asignar al parámetro PrivateDir de Paradox una
ubicación a la que solamente ellos puedan acceder. Por ejemplo, pueden esta-
blecer como su directorio privado un directorio de su propio disco duro, asig-
nándolo a la propiedad PrivateDir del componente TSession. Un ejemplo de
cómo se podría hacer esto es el siguiente:
var
Extension, ExecName, GomerPyle : String;
ExtensionPos: Integer;
. . .
ExecName := ExtractFileName(Application.ExeName);
Extension := ExtractFileExt(Application.ExeName);
ExtensionPos := Pos(Extension, ExecName);
Delete(ExecName,ExtensionPos,4);
GomerPyle := Format( 'C:\Temp\%s',[ExecName]);
if not DirectoryExists(GomerPyle) then
CreateDir(GomerPyle);
if DirectoryExists(GomerPyle) then
Session.PrivateDir := GomerPyle
else
raise Exception.CreateFmt(
’El directorio privado %s no fue creado.',
[GomerPyle]);
end;
188 Los Tomos de Delphi: Delphi sin problemas
Disk Error
Posible causa de error
Puede haber realizado cambios a un archivo, y luego haber intentado grabarlo
a través de un sistema de control de versiones, como PVCS, sin primero haber
marcado (check out) el archivo en modo de escritura.
Solución rápida
Si quiere que los cambios realizados a un archivo se apliquen, debe primero
prepararlo para escritura.
Información adicional
PVCS no se incluye de serie en Delphi, pero Delphi Cliente/Servidor ofrece
soporte nativo para él. Para más información, consulte “PVCS” en la ayuda de
Delphi.
Disk full
Posible causa de error
Puede estar intentando instalar un componente cuyo archivo de recursos aso-
ciado (.DCR) está dañado.
Solución rápida
Borre el archivo .DCR (tiene el mismo nombre del componente, pero su exten-
sión es .DCR en lugar de .PAS o .DCU).
Información adicional
Los archivos .DCR contienen mapas de bits de paleta para el componente
correspondiente. Son una característica útil, que permite distinguir visual-
mente los componentes en la Paleta, así como en los formularios y módulos. Si
no se proporciona un archivo .DCR, o si se ha proporcionado alguno pero no se
utiliza, el componente utilizará el mapa de bits de su ancestro.
Aún cuando dos componentes compartan el mismo mapa de bits, hay formas de
diferenciarlos. En la Paleta de Componentes, posicione el cursor sobre el mapa
de bits hasta que aparezca la indicación (hint) que muestra el nombre del com-
ponente. Si el componente está situado sobre un formulario o módulo de datos,
su tipo se mostrará sobre el Inspector de Objetos (Object Inspector). Por ejem-
plo, si crea un descendiente de TBatchMove y lo denomina TSoftBatchMove, el
cuadro de lista desplegable situado en la parte superior del Inspector de
Mensajes de error 189
Solución rápida
Verifique que el bucle no intente leer más allá del tamaño del archivo. En el
código anterior, reemplace 232 por 50. O mejor todavía, cree una constante y
utilícela así:
const
NUMBER_OF_STATES = 50;
. . .
while I < NUMBER_OF_STATES do . . .
Información adicional
Este es el error 100 de Entrada/Salida.
Flush
Write
Writeln
Solución rápida
Mantenga siempre libre al menos el 10 por ciento del disco duro. Elimine los
archivos innecesarios. Haga copia de seguridad en medios removibles de los
archivos que se utilizan en contadas ocasiones o nunca y luego bórrelos.
Información adicional
Este es el error número 101 de Entrada/Salida.
No tener espacio suficiente en disco duro puede indirectamente ocasionar
muchos errores no relacionados. Una de las causas es que el sistema utiliza ese
espacio para memoria virtual. Si hay más espacio en disco libre, más memoria
virtual habrá disponible. Si comienza a recibir mensajes de error que no parez-
can tener sentido, verifique el espacio disponible en disco.
Solución rápida
Utilice un identificador (dispid) único para cada método. Por ejemplo, en el
código mostrado arriba, simplemente reemplace una de las cláusulas “dispid 1”
por un número distinto de 1, como “dispid 2”.
Información adicional
Las declaraciones de métodos y propiedades en una sección Automated pueden
opcionalmente ir acompañadas de una directiva Dispid. Si se utiliza una direc-
tiva Dispid, ésta debe ir seguida por una constante entera. Si no se especifica
explícitamente una directiva Dispid con su correspondiente número, el compi-
lador generará automáticamente un identificador único.
Para más información, consulte “automated components” en la ayuda de
Delphi.
Mensajes de error 191
Solución rápida
Añada la directiva Dispid únicamente a las propiedades y métodos situados en
la sección Automated de la clase.
Información adicional
Las directivas Dispid pueden ser utilizadas sólo en secciones Automated. Para
más información, consulte “automated components” en la ayuda de Delphi.
Solución rápida
Elimine la llamada a Dispose.
Información adicional
Debido a que los arrays dinámicos mantienen un contador de referencias, se
liberan automáticamente cuando no quedan referencias a ellos.
192 Los Tomos de Delphi: Delphi sin problemas
Division by zero
Posible causa de error
Puede haber intentado dividir un número por cero. Por ejemplo, si la variable
Divisor es igual a 0, lo siguiente generará este mensaje de error:
var
Dividend, Divisor, Quotient: integer;
begin
. . .
Dividend := StrToInt(Edit1.Text);
Divisor := StrToInt(Edit2.Text);
Quotient := Dividend div Divisor;
Solución rápida
Asegúrese de que el divisor no sea 0 antes de dividir, o encierre la operación de
división en un bloque Try. . . Except. Por ejemplo, para prevenir que la opera-
ción de división tenga lugar si el divisor es 0, puede hacer algo así:
. . .
Dividend := StrToInt(Edit1.Text);
if StrToInt(Edit2.Text) > 0 then
begin
Divisor := StrToInt(Edit2.Text);
Quotient := Dividend div Divisor;
end;
else
begin
ShowMessage('Enter a number greater than 0 '
+#13#10+ ' in the Divisor edit box’);
Edit2.SetFocus;
end;
Para encerrar la operación en un bloque Try. . . Except, puede hacer algo así:
. . .
Dividend := StrToInt(Edit1.Text);
Divisor := StrToInt(Edit2.Text);
try
Quotient := Dividend div Divisor;
except
on EDivByZero do
ShowMessage('Enter a number greater than 0 '
+#13#10+ ' in the Divisor edit box’);
Edit2.SetFocus;
end;
end;
Mensajes de error 193
Información adicional
Si está dividiendo números de punto flotante, debe utilizar el operador / en
lugar del operador div, que se utiliza sólo para dividir enteros.
Solución rápida
Asegúrese de que haya solamente una ocurrencia de cada valor en una senten-
cia Case.
Información adicional
Especificar que más de una acción tendrá lugar para un valor particular no
puede ser entendido por el compilador, ya que es ambiguo. El siguiente ejem-
plo, donde el valor ‘walton’ se encuentra dos veces, ocasiona este mensaje de
error:
function GetFirstName(shagger: outfielders): string;
var
FirstName: string;
begin
case shagger of
anderson: FirstName := 'Brady';
belle: FirstName := 'Joey'; //Albert
carter: FirstName := 'Joe';
davis: FirstName := 'Eric';
hammonds,walton: FirstName := 'Jeffrey';
kingsale: FirstName := 'Eugene';
matos: FirstName := 'Luis';
surhoff: FirstName := 'B.J.';
tarasco: FirstName := 'Tony';
walton: FirstName := 'Jerome';
end;
Result := FirstName;
end;
begin
case shagger of
anderson,surhoff: FirstInitial := 'B';
davis: FirstInitial := 'E';
carter,hammonds,walton: FirstInitial := 'J';
tarasco: FirstInitial := 'T';
end;
Result := FirstInitial;
end;
....
function StartersEvaluation(innings: integer): string;
var
outing: string;
begin
case InningsPitched of
1..3: outing := 'Bombed';
4 : outing := 'Poor';
5,6 : outing := 'Decent';
7,8 : outing := 'Good';
9 : outing := 'Excellent';
end;
Result := outing;
end;
Solución rápida
Asigne nombres únicos a todos los componentes TDatabase.
Información adicional
Para mayor claridad y facilidad de mantenimiento del código, es una buena
práctica utilizar nombres descriptivos para los componentes y sus propiedades,
como por ejemplo la propiedad DatabaseName del componente TDatabase. Del-
phi no evita que proporcione el nombre “DB” o “BigIron” o “q” a la propiedad
DatabaseName, pero es mejor evitarlos en lo que respecta a la claridad y man-
tenimiento del código.
Mensajes de error 195
Solución rápida
Cambie las constantes numéricas de los mensajes para que tengan valores
únicos:
const
GOTTA_GETTA_MESSAGE_TO_YOU = WM_User + 160;
MESSAGE_IN_A_BOTTLE = WM_User + 161;
Información adicional
La aplicaciones escritas en Delphi normalmente responden a eventos que son
disparados por los mensajes de Windows. Como se muestra arriba, usted puede
crear sus propias constantes y gestores de mensajes, y luego poner un mensaje
en la cola de mensajes de Windows para hacer que el gestor de mensaje corres-
pondiente se dispare. Para más información, consulte “PostMessage” y “Send-
Message” en la ayuda del SDK de Windows, o busque el libro LosTomos de
Delphi: Núcleo del API Win32, editado en español por Danypress, para más
información sobre cómo utilizar llamadas a la API de Windows. Este excelente
libro contiene multitud de ejemplos en Delphi de llamadas a la API de Win-
dows. Para más información, consulte “message dispatching” en la ayuda de
Delphi. Para información similar, consulte “duplicate message method index”.
Alternativamente, puede estar creando los campos varias veces. Por ejemplo, lo
siguiente funcionará bien la primera vez:
with Table1 do begin
. . .
with FieldDefs do begin
Clear;
Add('Baseball', ftBoolean, 0, True);
Add('Force', ftString, 30, False);
end;
Pero fallará en una ejecución posterior, ya que los campos Baseball y Force ya
existen.
Solución rápida
Sustituya el nombre de campo duplicado por otro único. En el primer ejemplo
dado arriba, por ejemplo, podría renombrar el segundo campo como
SafeSliding.
Información adicional
Para más información sobre creación de tablas en tiempo de ejecución, consulte
“CreateTable” en la ayuda de Delphi.
Solución rápida
Elimine una de las propiedades de interfaz delegadas (o cambie el nombre de
una de las interfaces a otra interfaz disponible).
Mensajes de error 197
Información adicional
Para más información sobre lo que no está permitido cuando se delegan propie-
dades para implementar interfaces, consulte “Implements getter must be
register calling convention” y “Read or Write clause expected, but
identifier <> found”.
Solución rápida
Cambie el valor de una de las constantes de índice de mensaje. En el caso de
arriba, debe cambiar indudablemente la segunda constante, WM_CHAR por
WM_KEYDOWN.
Información adicional
Para más información, consulte la unidad de Messages de Delphi. También
consulte “Duplicate dynamic method index”.
Duplicate resource
Posible causa de error
1. Puede tener una unidad o una clase en una unidad que tiene el mismo
nombre de una unidad o clase ya existente en el ámbito visible del pro-
grama. Podría ser una unidad de Delphi o una unidad propia que tenga
duplicada.
2. Puede que esté utilizando componentes que tengan los mismos nombres de
recursos en sus archivos .DCR.
198 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Localice la unidad o nombre de clase duplicado y renómbrelo. Para hacer
esto en el caso de una unidad, siga estos pasos:
a. Con la unidad seleccionada, seleccione File | Save As. . . .
b. Proporcione un nombre único a la unidad.
c. Modifique las referencias a la unidad para reflejar el nuevo nombre. Si
es un nombre de clase el culpable, simplemente edítelo directamente en
la ventana de código.
2. Si los componentes son suyos o si dispone de su código fuente, revise los
archivos .DCR para determinar qué elementos tienen el mismo nombre.
Renombre uno de los recursos e inténtelo de nuevo. Para renombrar uno de
los recursos utilizando el Editor de Imágenes de Delphi (Image Editor),
siga estos pasos:
a. Seleccione Tools | Image Editor.
b. Seleccione File | Open.
c. Navegue hasta el archivo de recursos (.DCR) y ábralo.
d. En la vista de árbol, navegue hasta el elemento que desea renombrar.
e. Con el elemento seleccionado, pulse con el botón derecho del ratón
sobre él y seleccione la opción Rename del menú de contexto.
f. Introduzca un nuevo nombre.
g. Seleccione File | Exit, y luego Yes para grabar los cambios realizados.
3. Si quiere añadir recursos adicionales, utilice un archivo de recursos
separado, dándole un nombre que no entre en conflicto con el nombre del
proyecto o cualquiera de los nombres de unidades. Añada su archivo de
recursos personalizado a Delphi. Por ejemplo, para añadir un archivo de
recursos que haya creado con el nombre Whatever.RES, introduzca una
línea como:
{$R Whatever.Res}
Información adicional
1. Reduzca el tamaño de las cláusulas Uses, eliminando de ellas cualquier
unidad que no sea necesaria.
3. El archivo de recursos del proyecto, que es creado automáticamente por
Delphi, no se debe modificar. Consulte “EResNotFound”.
Si todo lo anterior falla, intente borrar todos los archivos *.DSM, *.DOF y
*.DSK.
Consulte “Error Creating Form: Duplicate resource [Type:,Name:]”.
Mensajes de error 199
Solución rápida
Asigne un nombre de sesión único a cada componente TSession. Delphi puede
encargarse de esto automáticamente si asigna el valor True a la propiedad
AutoSessionName.
Información adicional
Normalmente no es necesario añadir un componente TSession a las aplicacio-
nes de base de datos. Un componente TSession es creado automáticamente por
defecto (de forma similar al componente TDatabase). Pero si crea aplicaciones
multi-hilo o si está utilizando tablas Paradox que residen en varios lugares de
una red, puede arrastrar componentes TSession adicionales sobre el formulario
o módulo de datos para facilitar el trabajo en tales circunstancias.
Solución rápida
Cambie la segunda aparición de True por False.
Información adicional
No confunda los registros variantes con el tipo de datos Variant.
200 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Sustituya el método de acceso a la propiedad por un campo privado o un
método corriente. No utilice métodos de gestión de mensajes o métodos dinámi-
cos como métodos de acceso para propiedades. Por ejemplo, podría reemplazar
el código de arriba por algo así:
private
FDynamite: Integer;
procedure SetProper(NewProper: Integer);
. . .
published
property propwash: integer read FDynamite;
property proper: integer write SetProper;
-O-
Elimine la directiva Dynamic o Message.
Información adicional
Para más información, consulte “creating properties” y “dynamic methods” en
la ayuda de Delphi.
Mensajes de error 201
Solución rápida
No utilice métodos dinámicos ni métodos de gestión de mensajes en secciones
Automated.
Información adicional
Tratar de declarar un método de gestión de mensajes como éstos aparecen nor-
malmente (con un parámetro de tipo TMessage, en lugar de Integer, como en el
ejemplo de arriba) provoca el mensaje de error “Illegal type in OLE automa-
tion section: TMessage being generated”.
EAccessViolation
Consulte “Access Violation”.
EBitsError
Consulte “Bits Index out of Range”.
EClassNotFound
Posible causa de error
Puede haber modificado directamente un archivo .DFM de formulario, y ahora
Delphi no puede hacer compatible el contenido del archivo .DFM con el
archivo .PAS.
202 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Examine el archivo .DFM pulsando con el botón derecho del ratón sobre el for-
mulario y seleccionando View As Text del menú de contexto. Verifique que las
definiciones de objetos en la clase del formulario coinciden con lo que está
realmente en el formulario.
Información adicional
Muchos estudiantes novatos han experimentado errores de este tipo tratando
de encontrar el camino en el campus de la Universidad.
EComponentError
Posible causa de error
1. Puede haberle dado a un componente un nombre que no es único.
2. Puede haberle dado a un componente un nombre que no es válido.
3. Puede estar intentando llamar al método RegisterComponents fuera del
procedimiento Register en una unidad de componente.
Solución rápida
1. Siempre utilice nombres únicos dentro de un espacio de nombres. Si la uni-
dad abc y la unidad xyz contienen ambas un componente llamado
AlphabetSoup, tendrán una convivencia muy difícil.
2. En Object Pascal, los identificadores (como los nombres de componentes)
deben empezar con una letra o un guión bajo y cada carácter subsiguiente
debe ser una letra, un guión bajo o un dígito.
3. Llame solamente a RegisterComponents dentro del procedimiento Register
de una unidad de componente.
Información adicional
3. El procedimiento Register y su llamada a RegisterComponents son creadas
automáticamente cuando se utiliza el Asistente para la creación de Compo-
nentes (Component Wizard).
EConvertError
Posible causa de error
Puede estar intentando convertir un valor de un tipo de datos a otro, pero la
conversión no es posible tal como se ha intentado.
Mensajes de error 203
Solución rápida
Convierta solamente tipos cuando el valor en cuestión pueda ser traducido o
convertido al otro tipo. Esto requiere que los tipos que están siendo convertidos
tengan una función de conversión correspondiente, y que el valor que va a ser
convertido pueda ser representado en el tipo de datos de destino. Por ejemplo,
intentar convertir un String a Boolean no resultaría, ni tampoco el intento de
traducir un Float a un BLOb. Además, algunas veces el tipo de conversión es
aceptable, pero el valor en sí no lo es. Por ejemplo, intentar convertir el valor
de tipo String ‘Parsley, Sage, Rosemary and Thyme’ a un valor de tipo TTime
no funcionará en ningún caso; en realidad, generará este mensaje de error. Sin
embargo, convertir el valor de tipo String ‘10:09’ al tipo TTime utilizando la
función de conversión StrToTime funcionará bien.
Información adicional
Este es un tipo de error genérico, que es disparado cuando se produce un pro-
blema durante el intento de convertir de un tipo de datos a otro.
Puede utilizar la clase de excepción EConvertError como herramienta de vali-
dación de datos. Por ejemplo, para verificar que una fecha introducida por el
usuario es válida antes de almacenarla, podría hacer algo así:
try
DayTripDay := StrToDate(Edit1.Text);
except
on EConvertError do
MessageDlg('El valor introducido no es una fecha válida’,
mtError, mbOK, 0);
end;
EDatabaseError
Posible causa de error
1. Puede haber intentado ejecutar una aplicación que necesita el BDE sobre
una máquina que no tiene el BDE instalado.
2. Puede haber asignado el valor True a la propiedad Required de un campo
autoincremental.
Solución rápida
1. Es necesario distribuir el BDE con las aplicaciones de Delphi que lo necesi-
ten. Puede consultar los detalles en C:\Archivos de programa\
Borland\Delphi X\deploy.txt.
2. El valor de un campo Autoincrement es asignado por el motor de base de
datos durante la grabación (post) del registro. A los campos obligatorios se
les debe asignar valor antes de intentar su grabación.
204 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Puede haber una segunda parte para este mensaje de error, como “An error
occurred while attempting to initialize the Borland Database Engine”.
En tales casos, busque el mensaje de error específico en este libro.
EDivByZero
Consulte “Division by zero”.
EFCreateError
Posible causa de error
Puede haber dado a un archivo un nombre inválido.
Solución rápida
Utilice nombres de Object Pascal válidos para todos los identificadores. Los
nombres deben comenzar con una letra o un guión bajo, y a continuación tener
sólo letras, guiones bajos y dígitos.
Información adicional
Esta excepción es descendiente de EStreamError, la clase base de todas las
excepciones relacionadas con flujos.
EFilerError
Posible causa de error
Puede haber intentado registrar una clase ante el sistema de flujos (streaming)
utilizando el procedimiento RegisterClass cuando ya había una clase diferente
registrada con el mismo nombre.
Solución rápida
Asegúrese de que todas las clases que cree sean únicas, no solamente en fun-
cionalidad, declaración e implementación, sino también en el nombre.
Información adicional
Intentar registrar la misma clase más de una vez a través de una llamada a
RegisterClass no ocasiona problemas; el segundo intento es simplemente igno-
rado. Diferentes clases con un mismo nombre, sin embargo, provocan error.
Mensajes de error 205
EGPFault
Consulte “Access Violation”.
EInOutError
Posible causa de error
Puede haber intentado añadir datos a un archivo que no existe.
Solución rápida
Evite este error comprobando si el archivo existe, y creándolo en caso de que
no exista, así:
var
tF: TextFile; {o sT: System.Text}
begin
AssignFile(tF,'TrueFun.txt');
if FileExists('TrueFun.txt') then
Append(tF)
else
Rewrite(tF);
. . .
-O-
var
sT: System.Text; {o tF: TextFile}
begin
AssignFile(sT,'SoTrue.txt');
try
System.Append(sT)
except
on EInOutError do
Rewrite(sT);
end;
. . .
CloseFile(globalLog);
except
on EInOutError do
if MessageDlg(
'Problema al grabar el archivo. Salir de todas formas?',
mtError, [mbYes,mbNo], 0) = mrNo then
Exit; {sale del procedimiento, no del programa}
end;
end;
. . .
Información adicional
Para que EInOutError esté disponible, debe tener activada la directiva de com-
pilación de verificación de entrada/salida (I/O), ya sea en el entorno integrado
de Delphi o en el código fuente. Para activarla desde el entorno integrado de
Delphi, siga estos pasos:
1. Seleccione Project | Options. . . .
2. Seleccione la pestaña Compiler.
3. Marque la casilla I/O checking en la sección Runtime Errors.
4. Pulse el botón OK.
Para habilitar la verificación de Entrada/Salida en el código, añada la directiva
{$I+} o {$IOCHECKS ON} en la parte superior de la unidad en la que desea
activar la verificación de Entrada/Salida. Esto no es necesario hacerlo a menos
que haya deshabilitado la opción anteriormente, ya que por defecto está
habilitada.
EIntOverflow
Consulte “Arithmetic Overflow Error”.
EInvalidCast
Consulte “Invalid typecast”.
EInvalidGraphic
Posible causa de error
Puede haber intentado cargar un archivo que no es un .BMP, .ICO o .WMF en
un objeto que espera un gráfico válido de Delphi. Por ejemplo, las dos líneas
siguientes generarían este error, ya que .JPG y .GIF no son formatos gráficos
nativos de Delphi:
Mensajes de error 207
Image1.Picture.LoadFromFile('Kangaroo.jpg');
Image1.Picture.LoadFromFile('ChoosyMothersChooseSkippyNot.gif');
Solución rápida
Cargue únicamente mapas de bits (.BMP), iconos (.ICO) y metaarchivos (.EMF
y .WMF) en objetos TPicture.
Información adicional
Para más información, consulte “TImage”, “TPicture”, “TGraphic”, “TBitmap”,
“TIcon”, y “TMetafile” en la ayuda de Delphi.
EInvalidGraphicOperation
Posible causa de error
Puede haber intentado ejecutar una operación inválida sobre un objeto gráfico.
Por ejemplo, intentar redimensionar un icono generaría este error:
Image1.Picture.Icon.Height := 36;
Solución rápida
No intente modificar el tamaño por defecto de un icono, que es de 32 x 32
píxeles para iconos convencionales y 16 x 16 píxeles para iconos pequeños.
Información adicional
Para más información, consulte el mensaje de error “Cannot change the size
of an icon”.
EInvalidOp
Consulte “Invalid floating point operation”.
EInvalidPointer
Consulte “Invalid pointer operation”.
Solución rápida
Utilice la función Length y el procedimiento SetLength para llevar a cabo la
misma tarea en Delphi de 32 bits. Para almacenar la longitud de una variable
de cadena en una variable entera, haga esto:
procedure FindStringLength;
var
s : String;
StrLength : Integer;
begin
s := 'HowMuchIsThatPCInTheWindow';
StrLength := Length(s);
end;
Información adicional
El tipo de cadena nativo en Delphi de 32 bits no almacena la longitud de la
cadena en el elemento 0, como es el caso en Turbo Pascal y Delphi 1. Esta es la
razón por la cual intentar obtener o asignar la longitud de la cadena a través
del elemento 0 no funciona y no está permitido.
Sí puede asignar cualquier elemento válido de una cadena (con índice distinto
de 0) a otra cadena, por ejemplo:
var
s,t: string;
begin
s := 'Are you just stringing me along?';
t := s[1];
end;
Solución rápida
Elimine el elemento que causa el problema.
Información adicional
Podría usted preguntarse por qué el mensaje de Delphi no es “; expected but
<> found”. Delante de la palabra reservada End, el punto y coma es innecesa-
rio (aunque inofensivo); por lo tanto, el compilador no lo espera.
Solución rápida
Termine la declaración de tipo con la palabra reservada End.
Información adicional
Una declaración de tipo debe tener la siguiente estructura:
type
WhateverYouWant = class
FWhateverYouWant: Boolean;
procedure WhateverYouSay(widget: Integer);
end; {¡no olvide este End al final!}
Solución rápida
1. Asegúrese de que cada Begin tiene su End correspondiente.
2. Añada End a cada sentencia Case y bloque Try. . . Finally y Try. . . Except.
3. Si tiene una llave izquierda ({ ) sin pareja, elimínela si no desea comentar
nada, o añada una llave derecha ( }) al final de la sección que desea
comentar.
Información adicional
Puede también comentar código en Delphi de 32 bits con los dos barras al
estilo de C++. Por ejemplo:
//Este es un comentario. Explique el código aquí.
Aconstúmbrese a añadir un End tan pronto como codifique un Begin, una sen-
tencia Case, un bloque Try. . . Finally o un bloque Try. . . Except. Luego vuelva
atrás y rellene el contenido de la sentencia. También, indente el código de tal
manera que los bloques Begin. . . End se puedan diferenciar visualmente y sea
fácil determinar qué Begin corresponde a un End determinado.
Mensajes de error 211
EOLEError
Consulte “Class not registered”.
EOLEException
Consulte “OLE error 800A03EC”.
EOleSysError
Consulte “Error loading type library/dll”.
212 Los Tomos de Delphi: Delphi sin problemas
EOleSysOperation Unavailable
Posible causa de error
Puede estar llamando a un método de un servidor de automatización OLE que
no está ejecutándose. Por ejemplo, lo siguiente generará este error si Word no
está ejecutándose en el momento de la llamada:
procedure TForm1.StartThatHog(Sender: TObject);
var
Ovari: OleVariant;
begin
Ovari := GetActiveOleObject('Word.Basic');
Ovari.FileNew;
Ovari.Insert('OLE! Muere la tarde’);
end;
Solución rápida
Asegúrese de que el servidor de automatización está ejecutándose antes de
intentar acceder a sus métodos. Puede hacerlo mediante el método
CreateOLEObject:
procedure TForm1.StartThatHog(Sender: TObject);
var
Ovari: OleVariant;
begin
Ovari := CreateOLEObject('Word.Basic');
Ovari.FileOpen('SunNumTu');
Ovari.Insert('Kelvin Caleb Mordecai Shannon');
end;
Información adicional
Si va a utilizar un servidor de automatización más de una vez en la aplicación,
puede evitar múltiples cargas y descargas del servidor declarando a nivel glo-
bal una variable de tipo OleVariant e instanciándola en el evento OnCreate del
formulario.
EOutOfMemory
Posible causa de error
Puede haber intentado reservar más memoria de la que está disponible.
Mensajes de error 213
Solución rápida
Si es posible, equipe su ordenador con al menos 32 MB de RAM. Mantenga
libre al menos el 10 por ciento del disco duro vacío, de manera que pueda ser
utilizado para memoria virtual.
Información adicional
Para más información, consulte “out of memory” en la ayuda de Delphi.
EOutOfResources
Posible causa de error
1. Puede estar (directamente o indirectamente) intentando crear un maneja-
dor (handle) de ventana, pero la cantidad máxima de manejadores ya está
siendo utilizada.
2. Una función de la API de Windows que ha llamado directa o indirecta-
mente puede haber fallado.
3. A pesar del mensaje, puede haber un error en el controlador de pantalla
que está utilizando, específicamente si está operando en modo avanzado
(32 KB ó 64 KB colores).
Solución rápida
1. Mantenga el número de controles de ventana (clases descendientes de
TWinControl) en un mínimo. Utilice controles gráficos donde sea posible
(ya que no requieren un manejador de Windows). Cree los formularios
dinámicamente siempre que sea posible.
2. Consulte la ayuda de la API Win32 (Win32.HLP) que viene con Delphi
para obtener más información sobre la llamada particular. Si no le aclara
suficientemente, podría considerar comprar Los Tomos de Delphi: Núcleo
del API Win32 (editado por Danysoft Internacional,que puede encontrar en
www.danypress.com).
3. Cambie al controlador VGA estándar de Windows, o a un modo menos
potente de su controlador. Si no sabe cómo hacerlo, consulte la documenta-
ción de Windows.
Información adicional
2. Un ejemplo de esto es una llamada a GetDeviceContext de TWinControl,
que a su vez llama a la función GetDC de la API de Windows.
214 Los Tomos de Delphi: Delphi sin problemas
ERangeError
Consulte “Range check error”.
EReadError
Posible causa de error
Los archivos .PAS y .DFM no están sincronizados. Específicamente, el archivo
.DFM puede contener una referencia a algo que no existe en el archivo .PAS.
Solución rápida
Borre las referencias a los métodos o propiedades que haya borrado del archivo
de unidad (.PAS) que existan en el archivo de formulario (.DFM).
Información adicional
Si borra un gestor de eventos existente, Delphi le preguntará cuando compile
“The <> method referenced by <>.<> does not exist. Remove the refe-
rence?” Si selecciona No, obtendrá este error. Al seleccionar Yes, el método
Button1Click (o cualquier método o propiedad que haya borrado) será elimi-
nado también del archivo de formulario (.DFM).
Consulte “Invalid property value” o “Error reading <>.<>: <>”
(dependiendo del mensaje de error específico que acompañe al mensaje de error
genérico EReadError).
ERegistryException
Posible causa de error
Puede haber llamado a ReadBinaryData y asignado un tamaño muy pequeño
al argumento Buffer.
Mensajes de error 215
Solución rápida
Incremente el tamaño del argumento Buffer.
Información adicional
Encierre la operación en una sentencia Try. . . Finally para liberar el objeto
TRegistry en caso de una excepción.
Consulte “Failed to get data for <>”.
EResNotFound
Posible causa de error
1. Puede haber borrado o modificado la directiva de recursos {$R *.DFM} del
archivo del formulario.
2. Puede haber cambiado el nombre del formulario principal en el código.
3. Puede estar intentando cargar recursos propios, pero ha olvidado añadir
{$R <NombreArchivo>.RES} en el archivo de proyecto.
Solución rápida
1. Restaure la directiva {$R *.DFM} en el archivo de unidad del formulario
(.PAS). Si no tiene una cláusula Uses en la sección Implementation, debe
ubicar la directiva detrás de la palabra reservada Implementation, así:
implementation
{$R *.DFM}
Si tiene una cláusula Uses en la sección Implementation, la directiva {$R}
debe aparecer después de la cláusula Uses, así:
implementation
Uses
ItsNoggin, TimeWisely, HardlyAnyOil;
{$R *.DFM}
2. Aunque puede hacerlo, es mejor evitar cambiar los nombres de los objetos
directamente en el código.
3. Añada {$R <NombreArchivo>.RES} en el archivo de proyecto (.DPR).
Información adicional
La directiva {$R *.DFM} enlaza el archivo de formulario (.DFM) con el archivo
de unidad (.PAS). Es una parte necesaria en toda unidad de formulario. Una
unidad “pura” (creada con New | Unit en lugar de New | Form) no contiene
ninguna directiva {$R *.DFM}, y su contenido inicial es mínimo:
unit Unit2;
216 Los Tomos de Delphi: Delphi sin problemas
interface
{Una “unidad pura“:
1) No contiene ninguna sección Uses con muchas unidades añadidas
automáticamente, como en el caso de una unidad de formulario.
2) No contiene ninguna declaración de tipo añadida
automáticamente, como en el caso de una unidad de formulario.
3) No contiene ninguna instancia de variable añadida
automáticamente, como en el caso de una unidad de formulario}
implementation
{4) No contiene ninguna directiva {$R *.DFM} añadida
automáticamente, como en el caso de una unidad de formulario}
end.
Solución rápida
Instale el Internet Explorer desde el CD de Delphi, o copie las DLLs directa-
mente desde \RunImage\Delphi X\Windows\System32.
Información adicional
Consulte “Could not load RLINK32.DLL”.
Solución rápida
1. Si está utilizando un componente TQuery y la sentencia SQL no es una
sentencia SELECT, utilice el método ExecSQL en lugar del método Open.
Por ejemplo, si el componente TQuery se llama Query1, utilice:
Query1.ExecSQL;
en lugar de:
Query1.Open;
2. Asigne un valor a la propiedad StoredProcName antes de intentar asignar
True a la propiedad Active o llamar a su método Open. La propiedad Data-
BaseName debe estar asignada a un alias que describa una base de datos
de servidor SQL, como InterBase, Oracle, MS SQL Server, Sybase, Infor-
mix, etc. Los procedimientos almacenados no son una característica de las
bases de datos de escritorio como Paradox, dBASE, MS Access, etc.
Información adicional
2. Los procedimientos almacenados son sentencias SQL compiladas que se
ejecutan en el servidor. Son mucho más rápidas que una sentencia SQL
220 Los Tomos de Delphi: Delphi sin problemas
local, y son una de las ventajas principales de las bases de datos SQL sobre
las bases de datos locales (de escritorio).
Solución rápida
No cambie el nombre del formulario principal en tiempo de ejecución. Si quiere
cambiar el nombre del formulario, hágalo en tiempo de diseño.
Información adicional
¿Cómo se sentiría si un miembro de su familia fuera por ahí cambiándose el
nombre en ocasiones supuestamente aleatorias?
Solución rápida
Añada los formularios ancestros al proyecto utilizando Project | Add to
Project.
Información adicional
Otra solución consiste en abrir los formularios ancestros en el editor antes de
abrir los formularios descendientes.
Mensajes de error 221
Solución rápida
Sustituya el TTabbedNotebook por un TPageControl.
Información adicional
Solamente obtendrá este error en Delphi de 32 bits (Delphi 1 no soporta la
herencia visual de formularios). Delphi de 32 bits proporciona el componente
TPageControl, que puede ser utilizado en lugar del componente
TTabbedNotebook.
Solución rápida
Asegúrese de que todos los componentes tienen nombre. Delphi sólo permite
tener un componente sin nombre hasta que se intente hacer referencia a él, ya
sea directa o indirectamente.
Información adicional
Delphi 2 introdujo la herencia visual de formularios. Incluso en Delphi 1, un
formulario podía heredarse de un ancestro, pero esto tenía que hacerse
mediante código. En Delphi de 32 bits, se puede heredar visualmente de
formularios.
Siga estos pasos para crear un formulario ancestro:
1. Cree un formulario que incorpore todos los elementos comunes que desee
incluir en los formularios descendientes.
222 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Localice el archivo .DFM especificado en el mensaje de error y muévalo al
directorio donde reside el resto del proyecto.
Si el archivo ya estaba en el mismo directorio que el resto del proyecto, abra el
archivo .DFM con un editor de texto (como el Bloc de Notas) y compruebe los
errores.
Información adicional
El archivo de formulario (.DFM) es una representación textual del formulario.
Contiene las definiciones de los objetos que están sobre el formulario, dónde
están situados esos objetos (sobre el formulario) y los valores de sus
propiedades.
Esta información es almacenada para que el formulario puede ser “recreado”
cuando usted lo abra. Si el formulario contiene errores, se ha dañado o ha sido
movido, Delphi no podrá abrir el formulario para crearlo, ya que no sabrá cómo
ensamblarlo. El proceso mediante el cual se realiza la grabación y carga del
formulario se conoce como “streaming”.
Después de mostrar este mensaje de error, el proyecto, junto con el archivo
.PAS correspondiente (el código asociado al formulario), será abierto. Sin
embargo, cualquier intento de ver la representación visual del formulario
fallará, ya que para ello es necesaria la información contenida en el archivo
.DFM.
Solución rápida
Pulse el botón OK, y luego Build All. Para construir todo en Delphi 1 y 2,
seleccione Compile | Build All. En Delphi 3, seleccione Project | Build All.
224 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Los recursos de 16 bits y de 32 bits son como el agua y el aceite — no se mez-
clan. Es decir, no puede utilizar recursos de 16 bits en Delphi de 32 bits, ni
puede utilizar recursos de 32 bits en Delphi de 16 bits (Delphi 1).
Consulte “Duplicate resource”.
Solución rápida
Utilice la utilidad de conversión de Delphi para convertir los archivos de for-
mulario (.DFM) en el proyecto desde texto a la versión .DFM esperada. Puede
hacerlo siguiendo estos pasos:
1. Abra el proyecto con la versión de Delphi con la que creó el proyecto. Si no
lo ha hecho antes, guarde los archivos de formulario en formato binario
(pulsando con el botón derecho sobre el formulario y desmarcando la opción
Text DFM si está seleccionada).
2. Compile el proyecto.
3. Ejecute la versión de convert.exe de la versión anterior de Delphi a la
cual quiere “portar hacía atrás” su aplicación. Por ejemplo, si quiere compi-
lar un proyecto creado en Delphi 5 en Delphi 3, ejecute la utilidad convert
que está por defecto instalada en C:\Archivos de programa\Borland\
Delphi3\bin.
4. Abra una ventana DOS y vaya al directorio que contiene la utilidad convert
de Delphi 3. Por ejemplo, para convertir los archivos .DFM que residen en
un directorio denominado ConvertMe a texto, introduzca el comando
convert C:\ConvertMe\*.dfm.
Ahora tendrá versiones .TXT de esos archivos de formulario.
5. Abra los archivos de texto (con el Bloc de Notas, WordPad u otro editor
cualquiera) y haga los cambios necesarios. Por ejemplo, si el archivo de for-
mulario contiene referencias a propiedades que no existen en la versión
anterior de Delphi, elimínelas.
Mensajes de error 225
Información adicional
Desde Delphi 5, los archivos de formularios pueden ser almacenados como
archivos de texto o binarios (antes de Delphi 5, eran binarios solamente).
Si un formulario ha sido guardado como archivo binario en Delphi 5 o superior,
el problema es básicamente el mismo, pero el mensaje de error es “Error rea-
ding <>. Property does not exist”. Si el formulario ha sido grabado como
texto (como se ha mencionado, una opción disponible desde Delphi 5), obtendrá
este mensaje de error.
Consulte “Error reading <>. Property does not exist”.
Solución rápida
En Windows NT, haga la referencia sin la extensión .DLL. Por ejemplo, la
siguiente es la sintaxis apropiada para Windows NT:
procedure HawaiianPunch; external ‘pineappl';
Información adicional
Si ésta no es la causa del problema, intente ejecutar el programa fuera del
entorno integrado de Delphi. Windows puede darle un mensaje más detallado,
como el nombre de la .DLL que necesita.
226 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Utilice el tipo de datos varOLEStr para crear un array variante de cadenas,
así:
procedure TForm1.Button1Click(Sender: TObject);
var
Roster: Variant;
begin
Roster := VarArrayCreate([0,3], varOLEStr);
. . .
Información adicional
Para más información, consulte “VarArrayCreate” y “VarArrrayOf” en la ayuda
de Delphi.
Solución rápida
No hay realmente una solución rápida para esto. Elimine cualquier control
extraño que pueda tener. Vea en la sección de Información Adicional más abajo
algunos trucos para recuperar algunos de los manejadores de ventana que esté
utilizando.
Información adicional
Este error es causado generalmente porque la aplicación está utilizando todos
los manejadores de ventanas disponibles. Cada control de ventana (controles
Mensajes de error 227
Solución rápida
Construya la aplicación (utilizando Project | Build en lugar de Project |
Compile o Run | Run (F9)).
Si esto no ayuda, borre todos los archivos, exceptuando los de extensión .DPR,
.PAS, .DFM y .RES.
Información adicional
Después de caídas particularmente graves, es muy útil algunas veces cerrar
Delphi y luego reiniciarlo.
Solución rápida
Utilice la sintaxis apropiada. En el ejemplo de arriba, sería:
with TADOQuery.Create(nil) do
try
Connection := ADOConnection1;
SQL.Add('CREATE INDEX ORD_SEQ ON SCRIPTURES(ORDER_SEQUENCE)');
ExecSQL;
finally
Free;
end;
Información adicional
Utilice la referencia del lenguaje SQL de la base de datos que esté utilizando
para determinar la sintaxis correcta. La sintaxis es usualmente la misma para
las distintas bases de datos, pero hay variaciones. Si no tiene o no puede
encontrar la documentación del SQL de la base de datos, puede intentar buscar
un ejemplo en su disco duro, o también podría encontrar un ejemplo buscando
en Internet (como www.tamaracka.com o www.google.com). Por ejemplo, en el
caso de arriba busque “CREATE INDEX”.
Solución rápida
Instale el BDE. Consulte el fichero “deploy.txt” en C:\Archivos de programa\
Borland\Delphi X.
Información adicional
Cuando se instala Delphi, el BDE también se instala. Puede fácilmente crear
una aplicación de base de datos con Delphi, y luego copiar el archivo .EXE e
incluso los archivos de base de datos a otra máquina, esperando que todo fun-
cionará bien en la máquina donde la ha instalado. Sin embargo, como la Solu-
ción Rápida indica, esto no es suficiente.
Solución rápida
Verifique que STDVCL[32,40].DLL esté en \Windows\System y haya sido
registrado.
Información adicional
Para registrar servidores en su sistema, puede utilizar la utilidad ‘Turbo
Register Server’ (TRegSvr), que es un programa de demostración de Delphi
ubicado por defecto en C:\Archivos de programa\Borland\Delphi X\
Demos\ActiveX\TRegSvr.
Para hacerlo, siga estos pasos:
1. Abra el archivo TRegSvr.DPR.
2. Construya el proyecto.
3. Active una sesión de DOS o abra una ventana de DOS.
4. Navegue hasta el directorio en el que está ubicado TRegSvr.
5. Introduzca el siguiente comando: TRegSvr STDVCL.DLL
(STDVCL40.DLL para Delphi 4, 5, 6 o superior).
6. Pulse la tecla Intro.
Turbo Register Server acepta tres opciones:
-u Para eliminar del Registro un servidor o biblioteca de tipos.
-q Para operar en modo silencioso.
-t Para registrar una biblioteca de tipos (esta es la acción por defecto; si
esto es lo que desea hacer, simplemente teclee el nombre del programa seguido
por el nombre del servidor, como se muestra en el ejemplo de arriba)
Solución rápida
Desinstale el componente que causa el problema.
Si usted mismo ha creado el componente, reemplace las directivas External
(carga estática de .DLLs) por llamadas a las funciones LoadLibrary y
GetProcAddress (carga dinámica de .DLLs).
Mensajes de error 231
Información adicional
Lo más adecuado parece ser cargar las .DLLs dinámicamente, y no
estáticamente.
Solución rápida
1. Seleccione OK, y luego reinstale los componentes a los que el archivo de
formulario se refiere.
2. Seleccione OK. La referencia a la propiedad no existente será eliminada
del archivo .DFM.
3. Seleccione OK, y luego siga estos pasos:
a. Pulse con el botón derecho del ratón sobre el formulario que contiene la
propiedad no existente y seleccione View As Text.
b. Edite el archivo .DFM que aparece para devolverlo a su estado original.
c. Pulse con el botón derecho del ratón sobre el arhivo de formulario
.DFM y seleccione View As Form.
d. Seleccione File | Close All, y guarde los cambios.
e. Vuelva a abrir el proyecto.
4. Asegúrese de que la ubicación de IDAPI32.CFG coincide con la indicada en
el Registro del sistema. Por defecto, la ubicación de este archivo es
C:\Archivos de programa\Borland\Common files\BDE.
El Registro de Windows mantiene la información sobre dónde se encuentra
IDAPI32.CFG. Para ver en qué lugar éste se encuentra en su máquina,
siga estos pasos:
232 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Consulte “Stream Read Error”.
Solución rápida
1. Solamente cambie los componentes por componentes compatibles. Puede
cambiar, por ejemplo, un componente TEdit por un TDBEdit.
2. Abrir los proyectos de Delphi con versiones anteriores de Delphi no es reco-
mendado. Sin embargo, puede seleccionar Yes para ignorar el error, y las
Mensajes de error 233
Información adicional
GExperts (disponible en www.gexperts.org) proporciona un Asistente llamado
ReplaceComponents que permite fácilmente sustituir componentes de un tipo
por otro. La sustitución puede hacerse para todo un proyecto, para un formula-
rio específico o solamente para los controles que seleccione en el editor de for-
mularios de Delphi.
Consulte “Error Creating Form: Invalid Stream Format”.
Solución rápida
Asigne True a la propiedad HandleShared del componente TDatabase.
Información adicional
Para más información, consulte “HandleShared” en la ayuda de Delphi.
Solución rápida
Asigne True a la propiedad AutoSessionName del componente TSession.
234 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Para más información, consulte “AutoSessionName” en la ayuda de Delphi.
Solución rápida
1. Pulse el botón OK para desechar el mensaje de error y luego seleccione
Project | Build <Proyecto>.
2. Pulse el botón OK para desechar el mensaje de error y luego seleccione
Project | Build <Proyecto>.
3. Borre los archivos .DSM y .DSK del proyecto, o simplemente ignore el men-
saje (seleccione OK para desechar el mensaje).
4. Abra el archivo .DSK del proyecto y vaya a la sección Symbols. Haga las
modificaciones necesarias para hacer referencia a los directorios correctos.
Información adicional
Para evitar que aparezca este mensaje de error, puede borrar el archivo .DSM
antes o después de mover el proyecto.
Para cada proyecto de Delphi, se crearán algunos archivos que no deben ser
borrados, en particular los archivos .PAS, .DFM y .DPR. Otras archivos, sin
embargo, serán regenerados automáticamente cada vez que compile, así que
pueden ser borrados sin ningún problema. Entre estos se encuentran, en
dependencia de la versión de Delphi, los archivos de extensión .OPT, .DSK,
.DSM, .RES y .DOF. Adicionalmente, la versión anterior a la última guardada
de los archivos de formulario (.DFM), de proyecto (.DPR), Pascal (.PAS), y, en
Delphi 3 y 4 (cuando sea apropiado), de bibliotecas de tipos (.TLB) se guardan
con una extensión que comienza con una tilde (~) seguida por las dos primeras
letras de la extensión normal. Por ejemplo, los archivos de resguardo de los
archivos .PAS tienen la extensión .~PA. De esta manera, siempre se puede vol-
ver a la versión anterior de uno de esos archivos, si es necesario, cambiando la
extensión de ésta a su formato habitual.
Mensajes de error 235
Solución rápida
Instale Internet Explorer desde el CD de Delphi (no está disponible en todas
las copias de Delphi) o copie directamente las .DLLs de OLE desde el directorio
\RunImage\DelphiX\Windows\System32.
Información adicional
Consulte “Could not load RLINK32.DLL” y “Error 0: RLINK32 Error ope-
ning file <TypeLibrary>.tlb”.
Solución rápida
1. Seleccione OK, pulse Ctrl+F2 o Alt+R+E, y luego seleccione Project |
Build All.
2. Si tiene los archivos fuente correspondientes (.PAS), borre los archivos de
unidad compilados (.DCU) y reconstrúyalos. Las unidades compiladas
serán regeneradas automáticamente a partir de los archivos fuentes.
Información adicional
Nunca borre un archivo de proyecto .DPR, .PAS (fuente Pascal) o .DFM (de for-
mulario). La mayoría de los demás archivos serán regenerados automática-
mente por Delphi sin intervención o interacción alguna del programador. Por
supuesto, si borra los archivos que contienen las opciones de compilación que
ha especificado para la aplicación, deberá especificar esas opciones de nuevo.
Un ejemplo de este tipo de archivo es el archivo de recursos del proyecto, que
tiene el mismo nombre base que el proyecto y la extensión .RES. Este archivo
almacena el nombre que aparecerá debajo del icono de la aplicación, el propio
icono y el archivo de ayuda del proyecto. Borrar tales archivos es algunas veces
necesario (consulte “Error reading symbol file”) y solamente una molestia
(pero nunca un desastre) reconstruirlos.
236 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Trate de obtener una .DLL de 32 bits que sustituya a la de 16 bits.
Información adicional
Cuando porte su aplicación de 16 a 32 bits, deberá tener en cuenta todos los
archivos complementarios y componentes que su aplicación necesita.
EStackOverflow
Consulte “Stack overflow”.
EStringListError
Consulte “List index out of bounds”.
EThread
Posible causa de error
1. Puede tener un hilo principal que ha llamado al método WaitFor, y
posteriormente otro hilo ha llamado al método Synchronize.
2. Puede tener un hilo que ha llamado al método Synchronize, y luego el hilo
principal ha llamado al método WaitFor.
Solución rápida
Elimine en el hilo principal la llamada a WaitFor y/o la llamada al método
Synchronize del otro hilo.
Información adicional
No se puede desarrollar aplicaciones multi-hilo en Delphi 1. Para más
información sobre una manera alternativa de ejecutar procesamiento en
segundo plano, consulte “OnIdle” en la ayuda de Delphi.
Mensajes de error 237
EVariantError
Posible causa de error
Puede haber intentado hacer una referencia a un valor Null de un conjunto
resultado. Por ejemplo, lo siguiente generará este mensaje de error si el valor
del campo ExpendableIncome para el registro actual es Null:
var
i: Integer;
begin
i := Query1['ExpendableIncome'];
Solución rápida
Puede comprobar el resultado para ver si es Null, y solamente asignarlo a la
variable si no lo es, así:
if not VarIsNull(Query1['ExpendableIncome']) then
i := Query1['ExpendableIncome']
else
i := 0;
Información adicional
La propiedad FieldValue de TDataset retorna un valor de tipo Variant, como
se puede deducir del código de arriba. Es menos conveniente pero más rápido
hacer la referencia a los campos de un conjunto resultado en su formato nativo,
por ejemplo:
bs := Query1['ExpendableIncome'].AsString;
TwoThumbsUp: String;
begin
try
TwoThumbsUp := 'Waylon and Willie meet Godzilla';
end; {con o sin este 'end' el mensaje de error es el mismo}
end;
2. Puede tener un paréntesis inválido en el código. Por ejemplo, lo siguiente
generará este mensaje de error:
sl[BillToNamePos] := PadL(sl[BillToNamePos],50));
Solución rápida
1. Si utiliza la palabra reservada Try, deberá utilizar la palabra reservada
Finally o la palabra reservada Except.
2. Elimine uno de los paréntesis al final de la línea, de tal manera que el
código se lea:
sl[BillToNamePos] := PadL(sl[BillToNamePos],50);
Información adicional
Las sentencias Try. . . Finally se utilizan generalmente para asegurar que los
recursos asignados sean siempre liberados (porque la parte Finally siempre es
ejecutada). Esta es la razón por la que los bloques Try. . . Finally son conocidos
como bloques de protección de recursos. Un bloque Try. . . Finally típico podría
ser :
var
Feed: TStrings;
begin
Feed := TStringList.Create;
try
Feed.Add('PurinaHyenaChow');
Feed.Add('PurinaPteradactylChow');
Feed.Add('PurinaChowChow');
Feed.Add('CiaoBaby');
finally
Feed.Free;
end;
end;
Solución rápida
Como este es un mensaje de error muy genérico, tendrá que ir estrechando el
cerco para determinar dónde se está produciendo la excepción. Asegúrese de
que tiene activada la opción Break on Exceptions (vea la ayuda de Delphi
para detalles concretos, ya que es una opción específica a cada versión).
Información adicional
TApplication.HandleException llama a ShowException, que a su vez llama a
ExceptionErrorMessage, que muestra este mensaje.
Solución rápida
Añada el paréntesis faltante:
procedure CalculateDueDate(AAgencyID, AEmployerID: Integer;
APayrollDate: TDate);
Información adicional
Al parecer, hay infinitas formas de equivocarse en la sintaxis.
240 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Sustituya la tabla que causa el problema por su última copia de seguridad.
Información adicional
Puede que sea necesario simultáneamente reemplazar los archivos de Paradox
complementarios, como los archivos de índice (.PX).
Solución rápida
Mueva la cláusula Exports a una sección global. Por convenio, está situada
inmediatamente antes de la sección Initialization de la unidad (si existe una);
en caso contrario, sitúela antes del End final.
Información adicional
La cláusula Exports es utilizada en las .DLLs, para que los procedimientos y
funciones estén disponibles a los módulos externos. Entonces se podrá acceder
a esos procedimientos y funciones utilizando LoadLibrary (o LoadLibraryEx) y
GetProcAddress.
un número al punto decimal. Debe incluir algún dígito (aunque sea el cero),
para que el compilador acepte esta asignación. Por ejemplo, la siguiente
asignación genera este mensaje de error:
MediocreBattingAvg := .246;
3. Puede haber intentado declarar una clase en una sección Const, así:
const
TForm1 = class(TForm)
En este caso, el mensaje de error específico sería “Expression expected
but CLASS found”.
Solución rápida
1. Proporcione una expresión en el lugar donde el compilador generó el men-
saje de error. En este ejemplo, borre el signo más (+) o añada otra
constante o variable. IntToStr(1) o IntToStr(1+2) están bien.
2. Añada un dígito (como 0) antes del punto decimal de esta manera:
MediocreBattingAvg := 0.246;
3. No declare tipos en secciones Const.
Información adicional
3. Los tipos deben ser declarados en secciones Type, y las instancias de tipos
en secciones Var, como lo hace Delphi automáticamente cuando crea un
formulario:
type
TForm1 = class(TForm)
. . .
var
Form1: TForm1;
Solución rápida
Desinstale los componentes añadidos recientemente hasta que el problema
desaparezca. Para desinstalar un componente del entorno integrado de Delphi
en tiempo de diseño, siga estos pasos:
1. Seleccione Component | Install Packages.
2. Desmarque la casilla de verificación correspondiente al paquete que desea
eliminar, o selecciónelo y pulse el botón Remove.
242 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Siempre podrá añadir de nuevo aquellos paquetes que haya eliminado invir-
tiendo el proceso:
1. Seleccione Component | Install Packages.
2. Pulse el botón Add.
3. Abra el archivo .BPL apropiado.
Solución rápida
No estoy seguro de por qué, pero en una ocasión resolví este problema cam-
biando el valor de la propiedad OldCreateOrder de un formulario de False a
True.
Información adicional
Si obtiene “Internal error”, es ciertamente un fallo de Delphi.
Solución rápida
Tiene muchas opciones para remediar este problema; utilice cualquiera de las
siguientes soluciones. La primera es la recomendada por el soporte de Oracle.
a. En Regedit, navegue hasta
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\ OTRACE73 y
renombre esta entrada o elimínela.
b. Elimine Oracle Trace Collection Services 7.3.3.x.x utilizando el
Instalador de Oracle.
c. En Delphi, seleccione Tools | Options | Preferences | Debugging,
y desmarque la casilla Integrated Debugging.
d. Utilice una versión del cliente Oracle SQL Net anterior a la 2.3.3.
Mensajes de error 243
Información adicional
NT 4 informa de todas las excepciones que se disparan durante la depuración
(incluso las excepciones que normalmente se ignorarían).
F004
Posible causa de error
Puede estar intentando instalar Delphi/400 y está utilizando el protocolo SNA
y se cumple una de las siguientes condiciones:
El servidor SNA no está ejecutándose.
Ha sobrepasado la cantidad de licencias de puestos SNA.
Solución rápida
Dependiendo de la causa del problema, arranque el servidor SNA, eche a un
usuario del sistema o aumente la cantidad de licencias de puestos de trabajo.
Información adicional
Delphi/400 es una versión especializada de Delphi para interactuar con servi-
dores AS/400. Para más información, visite www.danysoft.com.
Solución rápida
Verifique que el valor que está leyendo del Registro es del mismo tipo que la
variable o propiedad en la cual lo almacenará o asignará. Puede encerrar la
asignación en un bloque Try. . . Except para atrapar este error, así:
function GoSeeCal: string;
var
ReggiesTree: TRegistry;
begin
ReggiesTree := TRegistry.Create;
try
ReggiesTree.RootKey := HKEY_CURRENT_USER;
try
ReggiesTree.OpenKey('\drmtmale\Baltimore Orioles', False);
Result := ReggiesTree.ReadString('ThirdBase');
except
on ERegistryException do
Result := '';
{manejo de excepciones adicional, si lo desea}
end;
finally
ReggiesTree.Free;
end;
end;
Información adicional
Este mensaje de error es descendiente de ERegistryException.
El Registro del sistema es mucho más flexible que los archivos .INI que se uti-
lizaban antes de Windows de 32 bits (y aún disponibles en Windows de 32
bits). Mientras que solamente se pueden almacenar tres tipos de datos en los
archivos .INI (Bool[ean], Integer y String), el Registro soporta nueve tipos:
Binary, Bool[ean], Currency, Date, DateTime, Float, Integer, String y Time.
Solución rápida
1. Borre el contenido de Params, llamando a CDS.Params.Clear.
2. Asigne a la propiedad IndexName del conjunto de datos el índice con el que
quiere trabajar.
Información adicional
Consulte “IndexName” en la ayuda de Delphi para ver ejemplos de cómo modi-
ficar esta propiedad en tiempo de ejecución utilizando el componente
TClientDataSet.
Solución rápida
1,2. Utilice solamente campos de datos estáticos cuyos valores puedan ser cuan-
tificados a través de expresiones de filtro tipo SQL.
Información adicional
1. En la tabla Country de Paradox que viene con Delphi, lo siguiente es per-
mitido en una expresión de filtro:
Name = 'Bolivia' OR 'Brazil' OR 'Paraguay'
debido a que Name es uno de los campos de datos de la tabla.
Sin embargo, si crea un campo calculado (por ejemplo, Density, basado en
los campos Population y Area), las siguientes expresiones de filtro no serán
permitidas en la propiedad Filter del TDataSet, y generarán este mensaje
de error:
246 Los Tomos de Delphi: Delphi sin problemas
Density > 6
Solución rápida
1. Seleccione Yes para borrar la declaración.
Mensajes de error 247
Información adicional
5. Es más común añadir tipos de clase en la sección Type de una unidad de
componente que en una unidad de formulario. Así es como se crean los
componentes compuestos.
Para más información sobre otras situaciones y mensajes de error relacionados
consulte “Class <> not found. Ignore the error and continue?” y “Error
reading <>”.
Solución rápida
Cuando acceda a tablas locales (Paradox o dBASE), asegúrese de que los cam-
pos sobre los que va a realizar búsquedas estén indizados y que la propiedad
IndexName del componente TTable apunte a ese campo.
Si quiere buscar por una clave primaria (simple o compuesta), asigne el nom-
bre del campo a la propiedad IndexFieldNames. Si es una clave primaria com-
puesta, separe los nombres de campos mediante punto y coma. Puede realizar
esta asignación en el entorno integrado o en el código, así:
IndexFieldNames := 'Apellidos;Nombre';
Información adicional
Si está utilizando una base de datos de servidor SQL (InterBase, Oracle, MS
SQL Server, etc.), puede establecer un rango o hacer una búsqueda sobre cual-
quier campo, esté indizado o no. En tales casos, asigne el nombre del campo
sobre el que desea establecer el rango o buscar a la propiedad IndexField-
Names del objeto TTable.
Solución rápida
Borre las definiciones obsoletas de los campos de la tabla y sustitúyalas por
otras actualizadas. Puede hacer esto siguiendo estos pasos:
1. Pulse el botón derecho del ratón sobre el componente TTable que contiene
el campo que ha sido borrado o modificado.
2. Pulse el botón derecho del ratón sobre la lista de campos y seleccione
Delete del menú de contexto.
3. Pulse el botón derecho del ratón sobre la ventana ahora vacía y seleccione
Add Fields para crear las instancias para las nuevas definiciones.
Mensajes de error 249
Información adicional
Algunas veces podrá tener referencias extraviadas a componentes o sus propie-
dades en el archivo de formulario (.DFM). Siempre puede comprobar el archivo
de formulario pulsando el botón derecho del ratón sobre el formulario y selec-
cionando View as Text del menú de contexto. Busque cualquier componente o
propiedad que no pertenezca o cuya configuración no corresponda con lo que
debería ser. Por ejemplo, un objeto correspondiente a un campo de base de
datos es representado así:
object Table1RptFileName: TStringField
FieldName = 'RptFileName'
Required = True
Size = 6
end
Solución rápida
1. El parámetro no es reconocido por el editor SQL. Para propósitos de
prueba, sustituya el parámetro por un valor cualquiera. Por ejemplo:
select
SCRIPT_ID,
SCRIPT_DESC,
250 Los Tomos de Delphi: Delphi sin problemas
BUILD_NO,
SCRIPT_TYPE
from
SCRIPTMAIN
where
SCRIPT_TYPE = 2
2. Asigne False a la propiedad RequestLive.
3. No anteponga el prefijo OLD_ a los nombres de campo. Delphi lo hace
“internamente” con los registros que están siendo actualizados, de forma
que pueda comparar el valor antiguo con el valor nuevo. Si tiene un campo
llamado OLD_GEEZER, Delphi pensará que se trata del antiguo valor de
un campo llamado GEEZER. Si no existe un campo llamado GEEZER, se
producirá un error.
Información adicional
2. Microsoft Access desafía la convención habitual de SQL y utiliza el signo
almohadilla (#) en lugar de las comillas para encerrar los valores de tipo
Date y TimeStamp (¿Qué? ¡Microsoft establece sus propios estándares!
¡Inconcebible!). Esto provoca el problema.
Solución rápida
Mantenga actualizado todo su software — las herramientas de conectividad,
clientes de base de datos, DLLs, actualizaciones de componentes de terceros y
el propio Delphi.
Información adicional
Consulte el artículo de Dan Miser “The Upgrade Game” disponible en
http://www.delphizine.com/opinion/1998/04/di199804ft_o/di199804ft_o.asp, que
da argumentos firmes sobre las ventajas de mantenerse actualizado.
Mensajes de error 251
Solución rápida
Proporcione valores para todos los campos obligatorios (o NOT NULL) antes de
intentar grabar el registro.
Información adicional
El campo mencionado en el mensaje de error fue diseñado como un campo obli-
gatorio cuando se creó la tabla local (Paradox, dBASE, etc.) utilizando el Data-
base Desktop, o cuando la tabla fue creada mediante código de Object Pascal.
Alternativamente, si está utilizando una base de datos de servidor (InterBase,
Oracle, MS SQL Server, etc.), el campo fue diseñado como obligatorio al defi-
nirlo como NOT NULL.
Si quiere verificar y manejar este incidente usted mismo (en lugar de permitir
que Delphi lo maneje, proporcionándole el mensaje de error bajo discusión),
puede hacer una validación a nivel de registro utilizando el evento BeforePost
del componente TTable, una validación a nivel de campo utilizando el evento
OnValidate de TField, o una validación a nivel de carácter utilizando la propie-
dad EditMask del TField. Si cualquiera de estas validaciones falla, puede
hacer que el cursor aparezca sobre el campo que provoca el problema. Para
más información sobre cómo ejecutar estas verificaciones de validación, con-
sulte “A value must be specified for <>”.
Puede designar como obligatorio un campo TField que haya sido creado en
tiempo de diseño a través de su propiedad Required. Puede también proporcio-
nar un valor por defecto para los descendientes de TField a través de la propie-
dad DefaultExpression. Si hace esto, el campo tendrá un valor por defecto, de
tal forma que no tendrá que preocuparse por este mensaje de error a menos
que el valor por defecto sea borrado.
Si crea una tabla mediante código, puede indicar que un campo es obligatorio
asignando el valor True al cuarto parámetro del método FieldDefs.Add. Los
parámetros son el nombre del campo (String), su tipo de datos (TFieldType), su
tamaño (Word), y si es o no obligatorio (Boolean). Por ejemplo, podría añadir el
campo así:
FieldDefs.Add('MrsLeppard',ftString,20,True);
Solución rápida
1. Asegúrese que cualquier campo al que haga referencia esté correctamente
escrito y sea parte del conjunto de datos en cuestión.
2. Borre el valor situado en la propiedad Filter o asigne un filtro apropiado a
la tabla actual.
3. Después de crear los campos en tiempo de diseño a través del Editor de
Campos, bórrelos antes de cambiar la propiedad TableName del compo-
nente TTable.
4. Verifique que el campo sobre el cual está intentando crear un índice exista
en la tabla. Puede que sea necesario corregir el nombre, cambiar la propie-
dad Table del componente TTable o modificar la tabla.
5. Borre las declaraciones de descendientes de TField en el archivo de formu-
lario (.DFM). Obtendrá el mensaje “Field <> does not have a
corresponding component. Remove the declaration?” Seleccione Yes
siempre.
Información adicional
1. No se puede hacer referencia a un campo calculado o de búsqueda en la
propiedad Filter de un TDataset. Por ejemplo, si KnightsOfTheRound es
una tabla que tiene un campo llamado Address que hace referencia a un
Mensajes de error 253
3. Para borrar los campos que haya creado utilizando el Editor de Campos
(Fields Editor), siga estos pasos:
a. Haga doble clic sobre el componente TTable para activar el Editor de
Campos.
b. Pulse con el botón derecho del ratón en el Editor de Campos y
seleccione Select All.
c. Con todos los campos resaltados, pulse con el botón derecho del ratón
en el Editor de Campos y seleccione Delete.
4. Para información sobre cómo crear campos mediante código, consulte
“AddFieldDefs” en la ayuda de Delphi.
5. Para ver el archivo de formulario (.DFM), pulse con el botón derecho del
ratón sobre el formulario y seleccione View As Text del menú de contexto.
La información de TField que encontrará ahí será parecida a:
object Table1CustNo: TFloatField
FieldName = 'CustNo'
end
object Table1Company: TStringField
FieldName = 'Company'
Size = 30
end
Para volver a la vista normal después de editar el archivo de formulario,
pulse con el botón derecho del ratón en el editor y seleccione View As
Form del menú de contexto.
Field <> should be of type <> but is declared as <>. Correct the
declaration?
Posible causa de error
1. Puede haber cambiado manualmente un archivo de formulario (.DFM). Por
ejemplo, puede haber cambiado un TEdit a TDBEdit después de pulsar con
el botón derecho del ratón sobre el formulario y seleccionar View As Text,
y luego haber obtenido el mensaje de error “Error reading <Component-
Name>.<PropertyName>: Property does not exist. Ignore the error
and continue? NOTE: ignoring the error may cause components to
be deleted or property values to be lost” al seleccionar View As
Form. Posteriormente recibió este mensaje de error tratando de compilar.
2. Puede haber reemplazado la declaración de un componente de forma tal
que el tipo de componente actualmente declarado es distinto. Por ejemplo,
si colocó un TEdit en un formulario, este habrá sido declarado como:
254 Los Tomos de Delphi: Delphi sin problemas
type
TForm1 = class(TForm)
Edit1: TEdit;
Si cambió luego el TEdit a algo distinto de TEdit, como lo siguiente:
type
TForm1 = class(TForm)
Edit1: CoffeeEdit;
Habrá obtenido este mensaje de error.
Solución rápida
1. Seleccione Yes para corregir la declaración del componente en el archivo
.PAS, para que el archivo .PAS y .DFM estén coordinados.
2. No modifique el código que Delphi genera automáticamente.
Información adicional
1. En el contexto particular mencionado arriba, el mensaje de error literal
sería “Error reading Edit1.Text: Property does not exist. Ignore the
error and continue? NOTE: ignoring the error may cause compo-
nents to be deleted or property values to be lost”. Por supuesto, Edit1
es solamente Edit1 si es el primer componente que ha sido arrastrado
sobre el formulario, y usted no ha cambiado su nombre posteriormente.
Normalmente, los cambios que haga en el archivo .PAS (por ejemplo,
borrar un componente situado en el formulario) afectan al .DFM. En este
caso, es el .DFM el que ha sido modificado, y luego debe ser sincronizado
con el .PAS.
Vea en este libro la entrada “Error reading <ComponentName or
FormName>.<Propertyname>. Property does not exist. Ignore the
error and continue? NOTE: ignoring the error may cause compo-
nents to be deleted or property values to be lost”.
2. Consulte “Class <> not found”.
Solución rápida
Elimine el campo de la declaración de interfaz. Las interfaces no almacenan
valores, y por lo tanto no pueden contener campos.
Información adicional
En lo que a mí respecta, IUnknown es un nombre un poco ridículo para la
interfaz base. Lo siguiente, extraído del archivo SYSTEM.PAS de Delphi, es
mucho más significativo:
IInterface = IUnknown;
Solución rápida
1. Las definiciones de campo deben ser situadas antes de las declaraciones de
métodos y propiedades.
2. No utilice estas directivas en una sección Automated.
Información adicional
Este es un ejemplo del orden correcto para declarar un campo y un método:
private
FAppraisedValue: Currency;
. . . {Campos adicionales}
procedure ShowListing;
. . . {Métodos adicionales}
256 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Si utiliza una cláusula GROUP BY en una sentencia SQL, incluya todos los
campos de la parte SELECT en la parte GROUP BY (excluyendo las columnas
calculadas, como las creadas con las funciones de agregación COUNT, SUM,
MIN, MAX y AVG). Por ejemplo, la sentencia de arriba necesita ser modificada
de la siguiente forma:
SELECT Title, Protagonist, Rating, Count(*)
FROM Movies
WHERE Protagonist = 'DeNiro'
OR Protagonist = 'Sinise'
GROUP BY Title, Protagonist, Rating
Información adicional
La sintaxis de SQL exacta requerida o permitida depende del tipo de base de
datos al que esté accediendo y la versión del BDE que esté utilizando. Para
detalles más específicos, consulte la documentación del servidor (si utiliza una
base de datos de servidor SQL) o el archivo de ayuda del SQL Local que viene
con Delphi (si utiliza Paradox o dBASE).
Solución rápida
Verifique que el campo por el que está intentando ordenar (utilizando la cláu-
sula ORDER BY) esté en alguna de las tablas especificadas en la cláusula
FROM de la sentencias SQL, que el campo esté incluido en la cláusula
Mensajes de error 257
Información adicional
Para ordenar por un campo particular, el campo debe de estar incluido en el
conjunto resultado que es producido por la sentencia SQL. Por ejemplo, las
siguientes sentencias SQL producirán este mensaje de error:
SELECT Peaches, Strawberries
FROM Fruitstand
ORDER BY Bananas
Para añadir implícitamente el campo Bananas (así como los demás campos de
la tabla) a la cláusula SELECT de la sentencia SQL, haga esto:
SELECT *
FROM Fruitstand
ORDER BY Bananas
with Table1 do
for i := 1 to IndexFieldCount do
. . .
2. Puede estar utilizando los métodos FindKey o FindNearest de TTable con
tablas dBASE e índices de expresión.
3. Puede estar intentando indizar una tabla por un campo calculado cuya pro-
piedad FieldKind tiene el valor fkCalculated.
4. Puede estar intentando establecer una relación Maestro/Detalle entre dos
tablas sin haber asignado a la propiedad IndexName de la tabla de detalle
un índice que sea compatible con la tabla maestra.
Solución rápida
1. Recuerde que en la VCL los elementos indizados se basan normalmente en
cero. El ejemplo de arriba debe ser modificado, restando 1 a la propiedad
IndexFieldCount si la variable de control del bucle For empieza con 0:
with Table1 do
for i := 0 to IndexFieldCount-1 do
. . .
2. Utilice el método GoToNearest del componente TTable si está tratando con
tablas dBASE e índices de expresiones.
3. Si quiere ordenar por un campo calculado, cambie el valor de la propiedad
FieldKind del campo de fkCalculated a fkInternalCalc.
4. Asigne a la propiedad IndexName de la tabla de detalle la clave foránea
que concuerda con la clave primaria de la tabla maestra.
Información adicional
1. Recuerde que los índices, como todas las propiedades de tipo array, se indi-
zan a partir de cero.
3. Los campos calculados no se almacenan realmente en la base de datos, a
menos que se asigne fkInternalCalc a la propiedad FieldKind.
Solución rápida
Cambie el nombre de uno de los campos duplicados. En el ejemplo de arriba,
cambie el nombre del segundo campo de Address a Address2 (o cambie el pri-
mero a Address1 y el segundo a Address2).
Mensajes de error 259
Información adicional
Los atributos Type, Size y Key de los campos no tienen que coincidir para que
se produzca este mensaje de error — siempre que los dos nombres sean igua-
les, este mensaje de error se generará.
Solución rápida
1. Verifique que el campo que especificó existe en la tabla.
2. Añada la constante ixExpression de tipo TIndexOption en el tercer pará-
metro (Options) del método AddIndex de TTable, así:
with Table1
AddIndex('CityState', 'city+state', [ixExpression]);
Información adicional
El primer parámetro que se pasa al método Addindex de TTable es el nombre
del índice, el segundo es el nombre de los campos que componen el índice, y el
tercero es un conjunto de valores TIndexOptions. Los valores válidos dependen
del tipo de tabla que esté indizando. Para más información, consulte
“AddIndex” en la ayuda de Delphi.
Solución rápida
1. Utilice un campo o método que haya sido previamente declarado como
parte de la clase. Por ejemplo, esto funcionará:
...
private
FRates;
public
...
published
property Rates: string read FRates write FRates;
2. Declare el método en la clase antes de hacer una referencia a él a través de
la propiedad:
private
function GetStartDate: TDateTime;
. . .
public
property StartDate: TDateTime read GetStartDate;
. . .
Información adicional
1. Por convenio, los campos utilizados en las propiedades empiezan con la
letra ‘F’, y los métodos utilizados en las propiedades comienzan por ‘Get’
para los métodos de lectura y ‘Set’ para los de escritura.
Es común utilizar un campo en el especificador de acceso de lectura y un
método en el especificador de acceso de escritura. Sin embargo, puede espe-
cificar un campo o un método en ambas partes de una declaración de
propiedad. Por ejemplo, una propiedad típica puede ser declarada así:
property RealEstate: Currency read FRealEstate
write SetRealEstate;
aunque es permitido utilizar el mismo campo para ambas cláusulas de lec-
tura y escritura, así:
property RealEstate: Currency read FRealEstate
write FRealEstate;
o utilizar métodos (diferentes) para el acceso de lectura y el de escritura,
así:
Mensajes de error 261
Solución rápida
Para ordenar por un campo calculado, asigne fkInternalCalc a la propiedad
FieldKind del correspondiente TField.
Información adicional
Si asigna fkInternalCalc a la propiedad FieldKind del objeto TField, el valor
del campo es almacenado en la base de datos. Para detalles más específicos
sobre los tipos de campos disponibles y sus posibilidades, consulte “FieldKind”
en la ayuda de Delphi. Vea el artículo “Client Dataset: MIDAS on the Cheap”
en la edición de abril de 1998 de The Delphi Informant para más información
sobre el uso de campos calculados en el componente TClientDataSet.
Solución rápida
Para poder enlazar dos tablas con capacidad de búsqueda (lookup), debe selec-
cionar dos campos (uno de cada tabla) que sean idénticos en cuanto a tipo de
datos y tamaño (si es aplicable).
Información adicional
Los nombres de los dos campos no importan, siempre que sean compatibles
desde la perspectiva del Database Desktop (el mismo tipo de datos, y el mismo
tamaño, si éste es aplicable al tipo de datos). Por ejemplo, puede enlazar cual-
quier campo de tipo Number de la tabla A con cualquier campo de tipo Number
de la tabla B, no importa cuáles sean los nombres de los campos. Si quiere
262 Los Tomos de Delphi: Delphi sin problemas
enlazar dos tablas mediante campos Alpha, no obstante, los campos no sola-
mente deben ser campos Alpha sino que deben tener asignado el mismo
tamaño. Por ejemplo, dos campos Alpha con una longitud de 12 caracteres pue-
den ser utilizados para enlazar dos tablas para la búsqueda. Sin embargo,
intentar utilizar para este propósito dos campos Alpha, uno de longitud 12 y
otro con una longitud de 15, produciría este mensaje de error.
Solución rápida
Asegúrese de asignar valores a todos los campos obligatorios.
Información adicional
Consulte en la descripción del mensaje “Field <> must have a value” las téc-
nicas para asegurarse de que toda la información necesaria sea proporcionada.
Solución rápida
Introduzca el nombre de un archivo que exista y sea apropiado para cualquier
tipo de acción que vaya a realizar con él o sobre él.
Información adicional
Un ejemplo de los muchos que podrían provocar este mensaje de error es si
intenta instalar un componente, y luego introduce el nombre de una unidad no
existente en el cuadro de edición Unit File Name.
Mensajes de error 263
Solución rápida
1. Compruebe que esté autorizado para acceder al archivo. Cambie el atributo
de sólo lectura del archivo de True a False en el Explorador de Windows
siguiendo estos pasos:
a. Localice el archivo y luego pulse con el botón derecho del ratón sobre él.
b. Seleccione Propiedades del menú de contexto.
c. Si la casilla Sólo Lectura está seleccionada, desmárquela.
2. Cambie el valor de FileMode a 2 antes de acceder al archivo, si es necesa-
rio, así:
var tF: TextFile;
begin
FileMode := 2;
AssignFile(tF, 'AchtDrei.txt');
. . .
Información adicional
Para más información, consulte “FileMode” en la ayuda de Delphi.
Solución rápida
Seleccione solamente archivos del tipo apropiado para cada tipo de operación.
Por ejemplo, seleccione únicamente archivos con extensión .DPK cuando cree
un nuevo paquete.
Información adicional
La extensión del archivo indica al mundo qué tipo de archivo es, y por tanto
qué se puede hacer con él. Por ejemplo, un archivo .DPK no puede producir
sonidos, y una extensión .WAV no puede ser utilizada para un archivo de
paquete.
Solución rápida
Puede verificar el estado de la tabla antes de acceder a ella, así:
if not Table1.Exclusive then
. . .
Información adicional
Es necesario colocar una tabla en modo exclusivo antes de se que puedan eje-
cutar ciertas operaciones, como crear índices. Asegúrese siempre de quitar el
modo exclusivo cuando haya terminado, para no impedir innecesariamente que
otros usuarios puedan acceder a la tabla.
Si trata de abrir la tabla en modo exclusivo, y alguien tiene ya la tabla abierta,
recibirá el mensaje de error “Table is busy”. Consulte dicha entrada para más
información sobre cómo tratar ese incidente.
Para más información, consulte “exclusive lock” en la ayuda de Delphi.
Solución rápida
Tenga presente llamar siempre a AssignFile antes de intentar utilizar Rewrite,
Reset, Append, Rename o Erase sobre un archivo:
var tex: TextFile;
begin
AssignFile(tex, 'McMurtry.txt');
try
Rewrite(tex);
Writeln(tex, 'Lonesome Dove');
. . .
finally
CloseFile(tex);
end;
end;
Información adicional
Este es el error de Entrada/Salida número 102.
Solución rápida
1. Verifique que ha escrito correctamente el nombre de la unidad, si lo
introdujo manualmente. Si no está utilizando la unidad, bórrela de la lista
de la cláusula Uses. De lo contrario, verifique que el directorio en el que
reside el archivo .DCU correspondiente a la unidad está en la ruta de bús-
queda de Delphi (vea la Solución rápida #2 más abajo).
2. Añada el camino donde reside el archivo a la ruta de búsqueda de Delphi
(que puede ser consultada en Tools | Environment Options, seleccio-
nando la pestaña Library), o mueva el archivo a un directorio de la ruta
de búsqueda.
3. En una instalación por defecto de Delphi 2, el archivo Report.DCU queda
situado en las siguientes localizaciones:
C:\Archivos de programa\Borland\Delphi X\LIB\DELPHI2
C:\Archivos de programa\Borland\Delphi X\Slib
El componente TReport no se instala por defecto. Está incluido todavía en
Delphi 3 (pero no en Delphi 4 y superiores), y puede instalarlo siguiendo
estos pasos:
a. Seleccione Component | Configure Palette. . . .
b. Seleccione Data Access de la lista Pages.
c. Navegue hasta localizar el componente TReport.
d. Seleccione el componente TReport.
e. Pulse el botón Add. El componente TReport será añadido a la página
Data Access de la Paleta de Componentes.
4. Localice los recursos y muévalos al directorio del proyecto.
5. No utilice el procedimiento Reset sobre archivos que no existan en el
momento de la llamada.
6. La utilización de un archivo .DCU para instalar un componente normal-
mente funciona bien, pero si el archivo .DCU fue compilado utilizando una
versión anterior de Delphi, usted necesitará instalarlo utilizando el archivo
.PAS.
7. Si ha incluido el nombre de una unidad de paquete (.DPK) en la sección
Contains de otro archivo de paquete, elimínelo.
8. Importe el archivo en Delphi seleccionando Project | Import Type
Library.
Mensajes de error 267
Información adicional
1. En este caso, Delphi buscará un archivo con el nombre que aparece en la
sección Uses con una extensión .DCU.
Si desea abrir un archivo para escritura utilizando el procedimiento
Append, es recomendable prepararse para la no existencia del archivo en el
momento de la llamada mediante programación defensiva. Por ejemplo,
podría utilizar un código similar al siguiente para evitar errores ocasiona-
dos por archivos inexistentes:
procedure TForm1.btnWriteToTextFileClick(Sender: TObject);
var
tF: TextFile;
begin
AssignFile(tF, 'sexyexe.txt');
if FileExists(ChangeFileExt(Paramstr(0),'.txt')) then
Append(tF)
else
Rewrite(tF);
WriteLn(tF, DateTimeToStr(Now));
CloseFile(tF);
end;
8. Los archivos de bibliotecas de tipos pueden tener las siguientes extensio-
nes: OLB, TLB, OCX, DLL y EXE.
var
JSBach: TextFile;
begin
AssignFile(JSBach,'Meisterstuecke.txt');
try
Reset(JSBach);
Writeln(JSBach, 'Wachet auf, ruft uns die Stimme');
Writeln(JSBach, 'Jesu, Joy of Man''s Desiring');
. . .
finally
CloseFile(JSBach);
end;
end;
Printer.Canvas.Font.Size := 16;
Printer.Canvas.Font.Style := [fsBold];
Writeln(PrintText,'Don’‘t leave me, oh my darling');
Writeln; // Esto genera el error
Solución rápida
1. Debe llamar a Rewrite, Reset o Append antes de poder escribir en el
archivo, de la siguiente forma:
var
Textilefile: TextFile;
begin
AssignFile(Textilefile, 'corduroy.txt');
try
if FileExists('corduroy.txt') then
Append(Textilefile)
else
Rewrite(Textilefile);
Writeln(Textilefile, 'The hippies of the sixties');
finally
CloseFile(Textilefile);
end;
end;
2. Verifique que el archivo existe antes de intentar escribir en él, y utilice
Append o Rewrite en lugar de Reset, de ésta forma:
var
JSBach: Textfile;
begin
AssignFile(JSBach,'Meisterstueck.txt');
try
if FileExists('Meisterstueck.txt') then
Append(JSBach)
else
Rewrite(JSBach);
Writeln(JSBach, 'Air on a G string');
Writeln(JSBach, 'Jesu, Joy of Man''s Desiring');
finally
CloseFile(JSBach);
end;
end;
3. No intente escribir en un archivo dentro de un evento que ocurra antes de
que el archivo de texto haya sido creado. Si desea tener un archivo de texto
disponible (digamos, por ejemplo, como un archivo de registro o errores
durante la depuración), debe asignarlo y abrirlo en el evento OnCreate del
formulario principal, y cerrarlo en el evento OnDestroy del formulario
principal.
4. Añada el nombre del archivo de texto del sistema como parámetro de la
sentencia Writeln, así:
270 Los Tomos de Delphi: Delphi sin problemas
procedure TGoodIdea.SetTheStage;
begin
Screen.Cursor := crHourglass;
AssignPrn(PrintText);
Rewrite(PrintText);
Printer.Canvas.Font.Name := 'Arial';
Printer.Canvas.Font.Size := 16;
Printer.Canvas.Font.Style := [fsBold];
Writeln(PrintText,'For I know I must be brave’);
Writeln(PrintText);
Información adicional
1. Utilice el procedimiento Append para añadir datos a un archivo. Utilice el
procedimiento Rewrite para sobrescribir y reemplazar un archivo existente.
Utilice Reset para abrir un archivo para lectura.
4. Cuando escriba en un archivo de texto que no haya sido asignado a la
impresora, no necesita añadir el parámetro; un simple Writeln será sufi-
ciente para añadir una línea en blanco.
Readln(s);
Solución rápida
1. Antes de intentar leer desde un archivo, llame al procedimiento Reset.
Para arreglar el ejemplo de arriba, añada la llamada antes del bucle While,
así:
. . .
AssignFile(cookie,'history.txt');
try
Reset(cookie);
while not eof(cookie) do
. . .
2. Añada el nombre de la variable del archivo de texto, así:
Readln(SomeTextFile, s);
Información adicional
1. Utilice el procedimiento Append para añadir datos a un archivo. Utilice el
procedimiento Rewrite para sobrescribir y reemplazar un archivo existente.
Utilice Reset para abrir un archivo para lectura.
2. Los programas de Windows requieren la variable de archivo, así como la
variable de cadena en la que se leerá la línea.
Solución rápida
1. Añada WinCRT a la cláusula Uses de la unidad.
2. Abra los archivos para escritura con Append o Rewrite, no con Reset. No se
puede abrir un archivo que no existe, por lo que debe utilizar la siguiente
lógica para escribir en un archivo la primera vez o para prepararse ante la
eventualidad de que el archivo no exista:
. . .
AssignFile(SingSing,'nail.txt');
if FileExists('nail.txt') then
Append(SingSing)
else
272 Los Tomos de Delphi: Delphi sin problemas
Rewrite(SingSing);
Información adicional
2. Utilice el procedimiento Append para añadir datos a un archivo. Utilice el
procedimiento Rewrite para sobrescribir y reemplazar un archivo existente.
Utilice Reset para abrir un archivo para lectura.
Este es el error de Entrada/Salida número 105.
Solución rápida
Asegúrese que la tabla especificada realmente existe en la ubicación que ha
especificado. Puede ser un simple problema de ortografía, que puede ser solu-
cionado en este caso con:
SELECT *
FROM ANIMALS
Información adicional
Si está trabajando con alias locales (estándar) y no ha especificado el tipo de
tabla a la que está intentando acceder, Delphi primero buscará una tabla Para-
dox, luego dBASE y por último un archivo ASCII (texto).
Solución rápida
1. No intente declarar variables de esos tipos.
2. No pase tipos de archivos como parámetros por valor. Hágalo así:
procedure LegoMania(VAR Technik: file);
Información adicional
Puede pasar un tipo de archivo como parámetro Var o Const. Para más infor-
mación, consulte “parameters” en la ayuda de Delphi. Por defecto, los paráme-
tros son pasados por valor.
Solución rápida
No asigne a la propiedad FixedCols un valor mayor o igual que la cantidad de
columnas que la rejilla contiene. Si permite que el usuario asigne el número de
columnas, asegúrese que éste no sobrepase el máximo valor válido. Por ejem-
plo, podría hacer algo así:
procedure TForm1.Button14Click(Sender: TObject);
const
crlf = #13#10; {o hágalo una constante global}
//
procedure Whatchemacolumn(ColNum: Integer);
begin
if ColNum < StringGrid1.ColCount then
StringGrid1.FixedCols := ColNum
else
MessageDlg('El número de columnas fijas debe ser menor’ +
crlf + ‘que la cantidad total de columnas’,
mtInformation, [mbOK], 0);
end;
begin
Whatchemacolumn(StrToInt(Edit1.Text));
end;
Información adicional
Debe tener al menos una columna que no sea fija.
274 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
No asigne a la propiedad FixedRows un valor mayor o igual que la cantidad de
de filas que contiene la rejilla. Si permite que el usuario asigne el número de
filas, asegúrese de que éste no sobrepase el máximo valor válido. Por ejemplo,
podría hacer algo así:
procedure TForm1.Button14Click(Sender: TObject);
const
crlf = #13#10; {o hágalo una constante global}
//
procedure PrettyMaidsAllInARow(RowNum: Integer);
begin
if RowNum < StringGrid1.RowCount then
StringGrid1.FixedRows := RowNum
else
MessageDlg('El número de filas fijas debe ser menor’ +
crlf + ‘que la cantidad total de filas',
mtInformation, [mbOK], 0);
end;
begin
PrettyMaidsAllInARow(StrToInt(Edit1.Text));
end;
Información adicional
Debe tener al menos una fila que no sea fija.
var
Date: TDateRec;
begin
for Date.Year := 1984 to 2001 do
Orwellian(Superman);
Solución rápida
Utilice una “variable local simple” para los bucles, como la apreciada i:
var
i: Integer;
begin
for i := 0 to Pred(AmountOfWoodThatAWoodchuckCanChuck) do
...
Información adicional
Es legal utilizar una variable global como variable de control de un bucle For
(por compatibilidad hacía atrás), pero el uso de una variable local produce un
código más eficiente.
Solución rápida
Utilice un tipo ordinal como variable de control de los bucles For. Es habitual
utilizar un entero declarado como i. Para ejecutar el bucle For intentado
arriba, podría hacer esto:
var
i: integer;
s: string;
begin
s:='';
for i := Ord('a') to Ord('z') do
s := s+Chr(i);
276 Los Tomos de Delphi: Delphi sin problemas
Información adicional
La función Chr realmente recibe un valor de tipo Byte en lugar de un Integer,
pero siempre que se le pase un valor positivo menor que 256, un valor Integer
funcionará. Para asegurar que no se asigna un valor erróneo, puede primero
utilizar la función Ord, como se muestra arriba. Lo mismo podría llevarse a
cabo con:
for i := 97 to 122 do
Pero esto hace que el código sea menos legible y la posibilidad de equivocación
mayor. Para más información, consulte “Ord” y “Chr” en la ayuda de Delphi.
Solución rápida
Modifique el procedimiento llamado de tal forma que el parámetro no se pase
por referencia (parámetro Var):
procedure ColoredMarshmallows(LuckyStars: Integer);
Información adicional
Esto es realmente una advertencia, no un error. El compilador está intentando
decirle, no obstante, que ese tipo de construcción es peligrosa (lógicamente). La
variable de control del bucle For podría teóricamente ser cambiada a cualquier
valor, incluyendo uno que esté fuera de los límites del bucle.
Form <> links to form <> which cannot be found in the current
project. Do you wish to remove/redirect the links to another form?
Posible causa de error
1. Puede haber añadido un formulario existente que depende de otro formula-
rio que no está incluido en el proyecto. Si el primer formulario mencionado
en el mensaje de error (el que pertenece al proyecto) contiene controles
conectados a datos, el segundo formulario mencionado en el mensaje de
error (el que no forma parte del proyecto) puede ser un módulo de datos
que contiene los componentes de datos no visibles correspondientes al pri-
mer formulario (TDatabase, TTable, TQuery, TStoredProc, TDataSource,
etc.).
2. Puede haber intentado guardar un formulario que está enlazado a un for-
mulario que no está cargado.
Solución rápida
1,2. Si no necesita mantener el enlace entre los dos formularios, seleccione Yes
y luego seleccione Remove Link. Si necesita mantener el enlace, cargue el
segundo formulario mencionado en el mensaje.
Información adicional
Consulte “Form <> references another form and cannot be saved until
<> is loaded”. Para más informacion, consulte también “data modules” en la
ayuda de Delphi.
Form <> references another form and cannot be saved until <> is
loaded
Posible causa de error
Puede haber obtenido el mensaje de error “Form <> links to form <> which
cannot be found in the current project. Do you wish to remove/redi-
rect the links to another form?” y respondió No o Cancel (no eliminó ni
redirigió el enlace).
278 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Cargue el segundo formulario mencionado en el mensaje de error dentro del
proyecto actual.
Información adicional
Consulte “Form <> links to form <> which cannot be found in the
current project. Do you wish to remove/redirect the links to another
form?”
Solución rápida
Cambie el especificador de formato por uno apropiado para el argumento. En el
ejemplo de arriba, cambie la “c” por una “s”:
Add(Format('ThouSeparator = %s', [SysUtils.ThousandSeparator]));
Información adicional
Para más información, consulte “Format” en la ayuda de Delphi.
También esto:
function Calc(x,y: integer); integer;
Mensajes de error 279
Solución rápida
Añada el tipo del resultado a la declaración de la función. Por ejemplo, si la
función devuelve un resultado Boolean, declárela así:
function junction(s: string): boolean;
Información adicional
Los procedimientos ejecutan una acción (o acciones). Las funciones normal-
mente hacen lo mismo, pero ellas también devuelven un resultado. Si enseña a
su perro a hacer un giro y a traerle cosas, podría comparar la acción de girar
con un procedimiento y la acción de traerle cosas con una función (el perro le
trae sus zapatillas o el periódico).
Solución rápida
Asigne un componente TSession a cada hilo que acceda a componentes de base
de datos.
Información adicional
Consulte “Session name missing” y “Cannot enable AutoSessionName
property with more than one session on a form or data module”.
Solución rápida
Añada una coma después de todos los campos excepto el último en la lista.
280 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Consulte “<> expected but <> found”.
Solución rápida
Inserte un par de paréntesis alrededor del grupo de valores, así:
SQL.Add('INSERT INTO ISO_CLASS');
SQL.Add('(QAP_ID,PROD_XREF,COVERAGE_REV,ISO_CLASS_XREF,');
SQL.Add('EFF_DATE, EXP_DATE,SCHEDULED_UNIT_SRLNUM)');
SQL.Add('VALUES');
. . .
Información adicional
Por supuesto, también obtendría este error si el grupo de valores no incluyera
el par de paréntesis (que aparecerían directamente después de los fragmentos
de código mostrados arriba).
Solución rápida
Añada una llamada al método Clear, de tal manera que el texto SQL no se
vaya acumulando:
SQL.Clear;
SQL.Add('Select * from FortKnox');
Información adicional
Para ver qué es lo que exactamente está siendo enviado como sentencia SQL,
seleccione Evaluate/Modify del menú, introduzca <NombreQuery>.SQL.Text,
y pulse el botón Evaluate.
Solución rápida
1. Inicie cada transacción con una llamada a StartTransaction, y finalícela
con una llamada a Rollback (para retrocederla si hay algún problema) o
Commit (para confirmarla). Por ejemplo, podría hacerlo de esta manera:
282 Los Tomos de Delphi: Delphi sin problemas
begin
with Database1 do
begin
Connected := True;
StartTransaction;
try
Query1.Active := True;
Commit;
except
Rollback;
end;
end;
end;
2. Después de desechar el mensaje de error, inténtelo de nuevo y grabe sus
cambios.
Información adicional
2. MS SQL Server retrocede las transacciones que experimenten
interbloqueos.
Solución rápida
Elimine la sentencia GoTo del bloque protegido o no salte dentro de un bloque
de código protegido.
Información adicional
Las sentencias GoTo son consideradas una mala práctica de programación. No
utilice sentencias GoTo, a menos que no pueda encontrar otro recurso.
2. Puede estar intentando acceder a una columna que no existe en una rejilla
de cadenas (TStringGrid). Por ejemplo, si está trabajando con una rejilla de
cadenas con tres columnas, lo siguiente generará este mensaje de error:
ColWidths[3] := 100;
Solución rápida
1. Llame al método DisableControls del objeto TDataset mientras esté ite-
rando a través del conjunto de datos, así:
with RegretTable do
begin
DisableControls;
try
First;
while not EOF do
begin
. . .
Next;
end;
finally
EnableControls;
end;
2. Si está trabajando con una rejilla de cadenas con tres columnas, por ejem-
plo, haga referencia al tercer elemento así:
ColWidths[2] := 100;
Información adicional
1. Si llamar a DisableControls no funciona en su situación, añada el siguiente
código en el evento OnCreate del formulario, si la tabla está abierta en el
entorno integrado de Delphi, o inmediatamente después de abrir la tabla
cuyo contenido está mostrando en el DBGrid:
DBGrid1.HandleNeeded;
2. Las rejillas de cadenas utilizan índices basados en cero. La primera
columna es el elemento 0, y así sucesivamente.
FROM CHINESEFOOD
Solución rápida
Si utiliza una función de agregación de SQL, como SUM, AVG, MIN, MAX o
COUNT, debe agrupar por todos los demás campos (no agregados). Por ejem-
plo, la sentencia SQL de arriba sería :
SELECT DIM, SUM(TSINGTAO)
FROM CHINESEFOOD
GROUP BY DIM
Información adicional
La sintaxis y características de SQL difieren de un sistema a otro. Consulte la
documentación de su base de datos para obtener la información pertinente de
la base de datos que esté utilizando. Si está utilizando tablas locales, consulte
LOCALSQL.HLP, que viene con Delphi (se instala por defecto en C:\Archivos
de programa\Borland\Common files\BDE).
Solución rápida
Libere espacio del disco duro y/o incremente el tamaño de la memoria virtual, o
reduzca el tamaño del bloque de memoria que está tratando de reservar.
Información adicional
Este es el error 203.
s := 'esszet';
i := High(s);
Solución rápida
No se puede aplicar la función High a cadenas largas. Sí se puede, sin
embargo, utilizarla con cadenas cortas, que están todavía disponibles en Delphi
de 32 bits. Puede crear una cadena corta en Delphi de 32 bits asignando una
longitud (hasta 255) en la declaración de la cadena o utilizando el tipo
ShortString. El ejemplo de arriba funcionará simplemente añadiendo la longi-
tud que se quiere utilizar en la declaración de la cadena o declarando la cadena
como un tipo ShortString. En otras palabras, cualquiera de los dos ejemplos
siguientes funcionará:
s: string[24]; { o cualquier otro entero positivo hasta 255 }
s: shortString;
Información adicional
Para más información, consulte “open string parameters” y “High function” en
la ayuda de Delphi.
Solución rápida
1, 2Para las dos primeras posibles causas, una opción es añadir el índice en el
Database Desktop en lugar de hacerlo en el código (cuando modifique la
estructura de la tabla, Database Desktop automáticamente elevará el nivel
al nivel más bajo necesario para satisfacer los requisitos). Si no desea rees-
tructurar la tabla, asigne el nivel de la tabla por defecto al nivel más alto
disponible en la utilidad de Configuración o Administración del BDE. Para
ello, siga estos pasos:
Delphi 1 o 2
a. Seleccione Tools | BDE Config.
b. Seleccione Paradox en el cuadro de lista Driver Name.
c. Cambie el valor del parámetro LEVEL al deseado (por ejemplo, de 4 ó 5
hasta 7).
d. Seleccione File | Exit.
e. Seleccione Yes para grabar los cambios.
Delphi 3 y 4
a. Seleccione Inicio | Programas | Borland Delphi X | BDE
[Configuration, Administration].
b. Seleccione la pestaña Configuration en la sección Drivers/System.
c. Expanda el nodo Drivers en vista de árbol.
d. Expanda el nodo Native en la vista de árbol.
e. Seleccione Paradox o dBASE, según sea apropiado.
f. Seleccione el nivel más alto de la lista desplegable LEVEL en la sección
Definition.
g. Seleccione Object | Exit.
h. Seleccione Yes para grabar los cambios.
Todas las tablas siguientes serán creadas con el nivel que haya escogido.
3. Vuelva atrás al convenio 8.3 para los nombres de archivos y los nombres de
directorios cortos sin espacios, o incremente el nivel de la tabla Paradox a
7. Siga los pasos de arriba para incrementar el nivel de la tabla.
4. Deberá asignar el nivel de la tabla Paradox a 7. Para llevar a cabo esto,
siga los pasos descritos arriba.
Mensajes de error 287
Información adicional
Una manera rápida de elevar el nivel de una tabla Paradox al nivel 7 desde el
Database Desktop es añadir un índice descendente. Ya que los índices descen-
dentes no estaban soportados en Paradox hasta la versión 7, al grabar la base
de datos después de añadir el índice descendente ésta se guardará como una
base de datos de Paradox 7.
Sin embargo, a menos que el índice necesite ser añadido en el código (es decir,
no se sabe cuál es el campo para el que se creará el índice en tiempo de
diseño), no tiene sentido añadir un índice que no será necesario con Database
Desktop para luego poder crear uno que sí se necesitará mediante código.
Por consiguiente, hay dos escenarios en los que encontrará necesario añadir un
índice a una tabla con el Database Desktop:
1. Quiere añadir un índice, pero está utilizando una tabla Paradox 3.5, 4, ó 5
(no se puede añadir un índice en el código con estas tablas).
2. Necesita añadir un índice en el código, pero su tabla es de una versión
anterior a la 7 y por lo tanto necesitar promoverla al nivel 7 añadiendo un
índice descendiente.
Para añadir un índice en el Database Desktop, siga estos pasos:
a. Seleccione Tools | Database Desktop.
b. Seleccione File | Open | Table. . . .
c. Navegue hasta la tabla a la que quiere añadir el índice y ábrala.
d. Seleccione Tools | Utilities | Restructure. . . (o pulse sobre el icono
correspondiente).
e. Seleccione Secondary Indexes del cuadro de combinación Table
Properties.
f. Pulse el botón Define.
g. Seleccione el campo que quiere añadir al índice en el cuadro de lista
Fields.
h. Pulse la flecha que apunta a la derecha entre las cajas de lista Fields e
Indexed Fields.
i. Marque las casillas de verificación de la sección Index Options que
desee aplicar al índice. Estas opciones de índice son Unique (Unico),
Case Sensitive (Distingue entre mayúsculas y minúsculas), Descending
(Descendente) y Maintained (Mantenido automáticamente). Maintained
está seleccionado por defecto (aquí es donde podría seleccionar
Descending para forzar que una tabla de Paradox 4 ó 5 sea promovida
a una tabla de Paradox 7).
j. Pulse el botón OK.
k. Proporcione un nombre para el índice en el cuadro de diálogo Save
Index As. A partir de ese momento podrá asignarle ese índice a la
propiedad IndexName de la tabla en el código.
288 Los Tomos de Delphi: Delphi sin problemas
Por supuesto, si desea crear los índices en el código, puede esperar hasta el
tiempo de ejecución para especificar el campo a indizar y posiblemente también
el nombre del índice:
Table1.Exclusive := True;
Table1.AddIndex(Edit1.Text,Edit2.Text,[]);
Solución rápida
Asigne el nombre de la base de datos a la que se desea conectar en la propie-
dad Params.Database de TSQLConnection.
Información adicional
DBExpress apareció por primera vez en Delphi 6.
Solución rápida
1. Elimine la sección vacía o añada una o más declaraciones válidas en ella.
2. No utilice palabras reservadas para ningún otro propósito que no sea aquel
para el que éstas están diseñadas.
3. Elimine el operador de ámbito de la sentencia.
Información adicional
Los identificadores son los nombres que se asignan a los tipos, variables, cons-
tantes, procedimientos, funciones, unidades, programas y campos de registros.
Consulte “Identifier expected but array found” e “Identifier expected
but number found”. Para más información, consulte también “identifiers” en
la ayuda de Delphi.
290 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Declare un tipo para el array que desea utilizar, y luego utilice el nuevo tipo de
array como tipo de retorno de la función. Por ejemplo, para resolver el pro-
blema de arriba, haga lo siguiente:
type
ThreeForOne = array[0..3] of char;
. . .
function Three41(i: integer): ThreeForOne;
Información adicional
Para más información, consulte “arrays” en la ayuda de Delphi.
Solución rápida
Evite iniciar una declaración de un subrango con un paréntesis. El compilador
pensará que usted intenta declarar un tipo enumerado. En lugar de ello,
hágalo de esta manera:
type
TSoberSubrange = 32..255;
Información adicional
Puede utilizar expresiones en la declaración de tipos subrango, siempre que
evite iniciar la declaración con un paréntesis. Por ejemplo, lo siguiente es acep-
table para el compilador:
Mensajes de error 291
type
TSeriousSubrange = 32..255;
type
TSuaveSubrange = 32..((32 * 8) -1);
Solución rápida
1. Elimine o renombre el elemento declarado dos veces.
2. Elimine la referencia a System de la cláusula Uses, ya que es ésta es
importada implícitamente por todas las unidades.
Información adicional
1. No se puede tener dos variables globales con el mismo nombre. Tampoco se
puede tener dos variable locales (en un mismo ámbito) con el mismo
nombre.
Puede tener una variable global y tantas locales como necesite (siempre
que cada una sea única dentro de su ámbito) con el mismo nombre. Por
ejemplo, podría tener una variable global nombrada ExpendableIncome y
simultáneamente declarar una variable con el mismo nombre dentro de un
procedimiento o función (en cuyo caso, la variable global sería ocultada
dentro del procedimiento por la variable local).
2. Puede haber añadido algo a la sección {$R *.RES} en el archivo fuente del
proyecto (.DPR).
3. Puede haberse dejado una llave ( } ) al final de una línea.
Solución rápida
1. Asigne a la variable, tipo, etc. un nombre válido de Object Pascal (que
comience con un guión bajo o caracter alfabético, y a continuación contenga
solamente guiones bajos, caracteres alfabéticos y dígitos).
2. Verifique que la sentencia {$R *.RES} del archivo fuente del proyecto no ha
sido alterada.
3. Elimine cualquier llave ( } ) que pueda tener al final de una línea.
Información adicional
Este mensaje de error se encuentra principalmente en conexión con las cons-
tantes de cadena y los comentarios.
Solución rápida
No utilice un número negativo (ni cero) como índice de un método de mensaje.
Si está capturando un mensaje de Windows, utilice su constante correspon-
diente, tal como está declarada en la unidad Messages.PAS. Por ejemplo, la
declaración de arriba sería:
procedure WMChar(var Message: TWMChar); message WM_CHAR;
Información adicional
Puede también referirse al mensaje WM_CHAR por su valor hexadecimal:
procedure WMChar(var Message: TWMChar); message $0102;
Solución rápida
Utilice solamente tipos válidos para la sección Automated. Consulte “automa-
table types” en la ayuda de Delphi para más información.
Información adicional
En este ejemplo particular, el mensaje de error se produce porque el tipo
TMessage es ilegal.
La sección Automated está obsoleta y se mantiene por compatibilidad.
Solución rápida
Utilice solamente los tipos estándar de Pascal con Readln.
Información adicional
Si quiere leer una lista de cadenas de un archivo, puede hacer esto:
294 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Writeln acepta solamente variables de los tipos estándar de Pascal.
Información adicional
Si quiere escribir el contenido de una lista de cadenas en un archivo, utilice el
método SaveToFile.
Solución rápida
Asegúrese que la palabra reservada Implementation exista entre la sección
Interface y la parte de implementación de la unidad.
Mensajes de error 295
Información adicional
Para más información, consulte “implementation reserved word | positioning a
procedure or function in your code” y “implementation reserved word | the
structure of a unit” en la ayuda de Delphi.
Solución rápida
Verifique que hay una coma entre todas las unidades a las que se hace referen-
cia en la cláusula Uses y un punto y coma al final.
Información adicional
Puede tener una o dos cláusulas Uses en una unidad. Tendrá una en la sección
Interface de la unidad, como aquí:
unit EdStates;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
. . .
type
TMyClass = class(TInterfacedObject)
. . .
property TryToImplementAnInt: Integer read FInteger
implements Integer;
end;
Solución rápida
Elimine la cláusula Implements <tipo_erróneo>, o sustituya el <tipo_erróneo>
(en este caso, Integer) por un tipo de clase o interfaz, así:
type
TMyClass = class(TinterfacedObject, IOfTheStorm)
. . .
property TryToImplementAnInt: Integer read FInteger
implements IOfTheStorm;
end;
Información adicional
Para más información, consulte “implementing interfaces by delegation” en la
ayuda de Delphi.
Solución rápida
Añada la directiva de lectura a la declaración de la propiedad, así:
TItalianStallion = class(TInterfacedObject, IOfTheTiger)
FRockyRead: IOfTheTiger;
property MyInterface: IOfTheTiger read FRockyRead
implements IOfTheTiger;
end;
Información adicional
Para más información, consulte “implementing interfaces by delegation” en la
ayuda de Delphi.
Mensajes de error 297
Solución rápida
Elimine la cláusula Implements. Las clases pueden implementar interfaces.
Las interfaces no pueden implementar interfaces, ya que ellas no tienen imple-
mentación. Son similares a las clases abstractas en Delphi (aunque las clases
abstractas frecuentemente implementan algunos de sus métodos y solamente
dejan un subconjunto de sus métodos abstractos, mientras que las interfaces
son completamente “abstractas”).
Información adicional
Para más información, consulte “implementing interfaces by delegation” en la
ayuda de Delphi.
Solución rápida
Elimine el convenio de llamada Stdcall (o el que fuera) que haya especificado
para el método de acceso.
Información adicional
Para más información, consulte “implementing interfaces by delegation” en la
ayuda de Delphi.
Solución rápida
Cambie nuevamente el GUID a su estado original.
Información adicional
Un GUID debe tener el formato: 00000000-0000-0000-0000-000000000000. Los
ceros representan caracteres alfanuméricos (pueden ser reemplazados por dígi-
tos o caracteres).
Solución rápida
Compruebe que el conjunto de datos fuente y la tabla de destino tengan estruc-
turas compatibles.
Información adicional
Los conjuntos fuente y destino no tienen que coincidir exactamente. Por ejem-
plo, los nombres de las columnas pueden diferir, siempre que sean del mismo
tipo de datos y tamaño.
Mensajes de error 299
Incompatible Types
Posible causa de error
Puede haber indicado un método como “sobrecargado”, y luego haber llamado a
Inherited en su implementación.
Solución rápida
Cambie la directiva Overload por Override, o elimine la llamada a Inherited.
Información adicional
Los métodos declarados como virtuales pueden ser redefinidos en las clases
descendientes. Esto se hace añadiendo la directiva Override a la declaración
del método. Normalmente, en la implementación del método redefinido se lla-
maría a Inherited, así:
procedure DoPopup(Sender: TObject); override;
. . .
procedure TForTheTillermanPopupMenu.DoPopup(Sender:TObject);
begin
inherited;
. . .
published
property EmUpJoe: Boolean read FEmUpJoe write SetEmUpJoe;
end;
8. Puede haber utilizado el procedimiento TextOut sin anteponer Canvas a él.
Por ejemplo, esto generará el mensaje de error bajo discusión:
procedure TForm1.FormMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
TextOut(X, Y, IntToStr(X)+' '+IntToStr(Y));
end;
9. Puede estar intentando asignar un procedimiento o función regular (uno
que no es miembro de una clase, sino un procedimiento o función global o
local) a un puntero a método. Por ejemplo, lo siguiente generará este men-
saje de error:
procedure TForm1.Button2Click(Sender: TObject);
procedure RegularGuy(Sender: TObject);
begin
Label1.Caption := ‘¡Ha pulsado el botón 1!';
end;
begin
Button1.OnClick := RegularGuy;
end;
10. Puede haber intentado asignar un valor de tipo enumerado a un tipo con-
junto así:
type
TFrozenCustardFlavors = (fcfHeath, fcfPistachio, fcfAbsinthe);
TFrozenCustardFlavors = set of TFrozenCustardFlavor;
. . .
case radgrpFrozenCustard.ItemIndex of
0: FrozenCustardObj.Flavors := fcfHeath;
Solución rápida
1. Asigne el valor a una variable del mismo tipo de datos o convierta el valor
a ser almacenado antes de hacer la asignación.
2. Hay dos maneras para asignar el valor de un descendiente de TField a una
variable. Puede añadir la propiedad Value al nombre del campo del que
está obteniendo el valor; alternativamente, puede convertir el valor al tipo
de datos adecuado utilizando una de las propiedades AsX. He aquí algunos
ejemplos de sentencias de asignación válidas:
{Esto funciona}
StringGrid1.Cells[1,1] := Table1Capital.Value;
{Esto también}
StringGrid1.Cells[0,0] := Table1Capital.AsString;
Algunas veces, la propiedad de conversión AsX no funciona, en dependen-
cia de la variable a la que esté asignando el valor y al descendiente de
302 Los Tomos de Delphi: Delphi sin problemas
TField cuyo valor está tratando de obtener. Por ejemplo, la siguiente asig-
nación produce el mensaje de error bajo discusión:
{"Incompatible types: String and Double"}
StringGrid1.Cells[1,1] := Table1Area.AsFloat;
En cualquier caso, utilizar la propiedad de conversión AsVariant (sobre
cualquier descendiente de TField) funcionará adecuadamente:
StringGrid1.Cells[1,1] := Table1Capital.AsVariant;
3. Asegúrese de que el tipo de datos de la variable que pasa a un procedi-
miento o función está acorde con la declaración de ese procedimiento o
función.
4. Asegúrese de que el resultado que devuelve la función coincida con el tipo
de resultado declarado por la función.
5. Utilice Div para producir un resultado entero, y / para producir un resul-
tado real (de punto flotante).
6. No intente hacer control activo del formulario a un control gráfico.
7. Asegúrese de que los tipos de las propiedades y sus campos o métodos de
escritura o lectura sean iguales. En el ejemplo mostrado arriba, cambie el
tipo del campo privado o propiedad de Boolean a String, o cambie el tipo
del parámetro del método de escritura de String a Boolean.
8. Anteponga Canvas a la llamada a TextOut, así:
procedure TForm1.FormMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
Canvas.TextOut(X, Y, IntToStr(X)+' '+IntToStr(Y));
end;
9. Solamente asigne métodos (un procedimiento o función que es miembro de
una clase) a punteros a métodos. Podría llevar a cabo esto reorganizando el
código de esta manera:
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
. . .
public
procedure HandCodedMethod(Sender: TObject);
end;
. . .
procedure TForm1.HandCodedMethod(Sender: TObject);
begin
Label1.Caption := '¡Ha pulsado el botón 1!';
end;
Mensajes de error 303
Información adicional
1. Delphi/Object Pascal ofrece muchas funciones predefinidas que permiten la
conversión entre tipos de datos, como de Integer a String y viceversa, etc.
Por ejemplo, puede asignar una variable de cadena a una entera utilizando
la función de conversión StrToInt, así:
SomeIntegerVariable := StrToInt(Edit1.Text);
Pero el intento de asignar la cadena contenida en un cuadro de edición
directamente a una variable entera, así:
SomeIntegerVariable := Edit1.Text;
causaría el mensaje de error de arriba. Para más información sobre otras
conversiones, consulte “conversions” en la ayuda de Delphi.
2. Cuando la tabla de Paradox Country incluida en Delphi fue creada, al
campo Capital le fue asignado el tipo de datos Alpha, y al campo Area le
fue asignado el tipo de datos Number. Si en Delphi se instancian esos cam-
pos utilizando el Editor de Campos (consulte “Fields Editor” en la ayuda de
Delphi), estos campos serán convertidos de sus tipos de datos nativos de
Paradox a los tipos de datos TStringField y TFloatField de Object Pascal,
respectivamente.
A continuación se ofrece una tabla de los tipos de datos Paradox y sus
correspondiente descendientes de TField de Delphi:
procedure LowerCase;
Solución rápida
1. Para asignar una función o procedimiento a un tipo función o procedi-
miento, sus signaturas (cantidad, tipos de datos y secuencia de los
parámetros) deben ser idénticas (aunque los nombres de los parámetros
pueden diferir). Por ejemplo, lo siguiente funcionaría bien:
function Kool(a,b,c: integer): integer;
type
TAndTheMGs = function(x,y,z: integer): integer;
const
Stylistics: TAndTheMGs = Kool;
2. Modifique el método personalizado para que tenga la misma signatura que
el gestor de eventos que está implementando. Utilizando el ejemplo de
arriba, la declaración de LowerCase debería ser:
procedure LowerCase(Sender: TObject; var Key: Char);
que está en correspondencia con la declaración del gestor de eventos
OnKeyPress.
Información adicional
Para más información, consulte “procedural values” en la ayuda de Delphi.
Solución rápida
Generalmente, no es una buena idea modificar el código que Delphi genera
automáticamente.
306 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Si modifica la declaración de la clase, pero utiliza un identificador válido,
obtendrá el mensaje de error “Field <> should be of type <> but is decla-
red as <>. Correct the declaration?” Consulte la entrada correspondiente a
este mensaje de error para más información.
Solución rápida
Las directivas de almacenamiento se utilizan para las propiedades declaradas
en la sección Published de un componente. No utilice directivas de almacena-
miento en métodos o fuera de la sección Published.
Información adicional
Si recibe este mensaje de error, y no hay razón aparente para ello, intente
reconstruirlo todo (seleccione Project | Build All).
Si el mensaje de error persiste, borre los archivos que Delphi genera automáti-
camente, especialmente si ha movido el proyecto de una máquina a otra o de
una versión de Delphi a otra. Entre estos archivos están, en dependiencia de
su versión de Delphi y de las opciones que haya seleccionado, <proyecto>.OPT,
<proyecto>.DSK, <proyecto>.DSM, <proyecto>.RES y <proyecto>.DOF.
Para más información, consulte “storage specifiers” en la ayuda de Delphi.
where
SCRIPT_TYPE = :SCRIPT_TYPE
Solución rápida
El parámetro no es reconocido por el SQL Explorer. Para propósitos de prueba,
sustitúyalo por un valor válido. Por ejemplo:
select
SCRIPT_ID,
SCRIPT_DESC,
BUILD_NO,
SCRIPT_TYPE
from
SCRIPTMAIN
where
SCRIPT_TYPE = 2
Información adicional
Consulte la entrada “Field <> is of an unknown type” en este libro.
Solución rápida
Compruebe que el índice que desea crear no exista. Por ejemplo, podría proce-
der de esta manera:
if not Table1.FieldByName('City').IsIndexField then
Table1.AddIndex('sittee','City',[]);
Información adicional
Si intenta añadir un índice del mismo nombre que uno ya existente en el Data-
base Desktop, obtendrá el mensaje: “An index named named <> already
exists. Overwrite?” Si intenta crear un índice sobre un campo que ya tiene
un índice, pero le da al índice un nombre diferente, recibirá el mensaje de error
“An index of this type already exists”. En ese caso, Database Desktop no le
permitirá crear el índice.
308 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
La cláusula Index no es permitida en la sección Automated. Elimine la
cláusula.
Información adicional
Delphi 2 y superiores tienen cinco directivas de visibilidad : Private, Protected,
Public, Published y Automated. Una propiedad de una clase puede incluir una
directiva de almacenamiento Stored, Default o Nodefault. Estas directivas de
almacenamiento, sin embargo, no están permitidas en la sección Automated.
Solución rápida
1. Cree el índice antes de intentar activarlo. Puede llevar a cabo esto utili-
zando el Database Desktop o el Lenguaje de Definición de Datos (DDL - un
subconjunto de SQL utilizado en las bases de datos SQL como InterBase,
Oracle y MS SQL Server) o en el código.
2. Borre el valor de la propiedad IndexName o cámbielo a un valor apropiado
para la tabla actual.
Mensajes de error 309
Información adicional
El código que ocasiona este error compilará, debido a que hasta donde el com-
pilador puede saber, el índice podría ser creado mediante código antes de
intentar activarlo.
Para crear un índice en el código (lo contrario a hacerlo en tiempo de diseño),
utilice el procedimiento AddIndex. Para más información, consulte “AddIndex”
en la ayuda de Delphi.
Solución rápida
1. Elimine los archivos de índice existentes, y luego vuelva a crearlos (en el
Database Desktop o en el código). Para más información sobre cómo crear
índices por código, consulte “AddIndex” en la ayuda de Delphi.
Siempre asegúrese de que los archivos de índice están en el mismo directo-
rio que la tabla cuando añada o edite la tabla.
2. Elimine los archivos de índice existentes, y luego vuelva a crearlos (en el
Database Desktop o en el código). Para más información sobre cómo crear
índices por código, consulte “AddIndex” en la ayuda de Delphi.
Para reducir la probabilidad de que lo mismo suceda de nuevo, siga estos
pasos:
Delphi 1
a. Seleccione Tools | BDE Config.
b. Seleccione Paradox en el cuadro de lista Driver Name.
c. Asegúrese de que el parámetro Strict Integrity tiene el valor True.
d. Seleccione File | Exit.
e. Seleccione Yes para grabar los cambios.
Delphi de 32 bits
a. Seleccione Tools | BDE Administrator.
b. Seleccione la pestaña Configuration.
c. Expanda el nodo Drivers en la vista de árbol.
d. Expanda el nodo Native en la vista de árbol.
e. Seleccione PARADOX.
f. Asigne True a Strict Integrity.
g. Seleccione Object | Exit.
h. Seleccione Yes para guardar los cambios.
3. Elimine los archivos de índice existentes, y luego vuelva a crearlos (en el
Database Desktop o en el código). Para más información sobre cómo crear
índices por código, consulte “AddIndex” en la ayuda de Delphi.
4. Reemplace la versión dañada de VREDIR.VXD. La versión original
(4.00.955) y la 4.00.1116 funcionan correctamente. VREDIR.VXD debería
estar ubicado en C:\Windows\System. Puede bajar una versión actuali-
zada del archivo desde el sitio web de Microsoft.
5. Si va a editar o insertar registros en una tabla, no utilice índices no mante-
nidos. Para configurar un índice de una tabla Paradox como mantenido,
siga estos pasos:
a. Abra el Database Desktop.
b. Abra la tabla con la que quiere trabajar (File | Open | Table).
Mensajes de error 311
Información adicional
Los archivos de índice (.PX, .Xnn y .Ynn) deben estar presentes con la tabla
cuando se añadan registros, de forma que los archivos de índice puedan ser
actualizados. Si no están, la fecha/hora de última actualización de la tabla y de
los archivos de índice no serán iguales, indicando que sus datos no están
sincronizados.
Una descripción de los archivos de índice auxiliares que utiliza Paradox es la
siguiente:
<NombreTabla>.PX
El archivo .PX contiene la información de la clave primaria de la tabla. Si
designa un campo o grupo de campos como clave primaria, este archivo es
creado.
<NombreTabla>.Xnn
Los archivos con extensión .Xnn (donde nn es un número hexadecimal) contie-
nen información de un índice secundario.
<NombreTabla>.Ynn
312 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Asigne True a MultiSelect.
Información adicional
Aún cuando MultiSelect tenga asignado True, puede que no vea la línea aña-
dida al cuadro de lista, a menos que llame a Application.ProcessMessages.
Solución rápida
Configure los índices como mantenidos si quiere editar o insertar registros en
una tabla. Para configurar un índice de una tabla Paradox como mantenido,
siga estos pasos:
a. Abra el Database Desktop.
b. Abra la tabla con la que quiere trabajar (File | Open | Table).
c. Seleccione Tools | Utilities | Restructure (o pulse sobre el icono
Restructure).
d. Seleccione Secondary Indexes en la lista desplegable Properties de la
tabla.
Mensajes de error 313
Información adicional
Si nunca necesitará editar o añadir registros a una tabla (en otras palabras, se
trata de una tabla de sólo lectura), puede mejorar el rendimiento haciendo los
índices no-mantenidos.
Solución rápida
Mueva el archivo de índices de producción (.MDX) al mismo directorio que la
tabla, o elimine la dependencia de la tabla de ese archivo. Para esto último,
consulte el documento TI #2711 en el CD-ROM de Delphi o en el sitio web de
Borland.
Información adicional
TI es la abreviatura de Technical Information. Si no tiene acceso al CD-ROM,
puede encontrar este documento en el sitio web de Borland (www.borland.com).
Solución rápida
Asigne valores a todos los campos de la clave primaria y a los campos indiza-
dos antes de grabar. Puede hacer esto, si lo desea, en el evento BeforePost del
conjunto de datos.
314 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Todas las tablas deberían tener una clave primaria. Consulte la documentación
de InterBase para más información sobre el diseño de bases de datos.
Solución rápida
Asegúrese de proporcionar los métodos de escritura y lectura para las
propiedades.
La sintaxis correcta cuando se declara una variable sin la directiva Index es:
property Zeitgeist: Longint read GetWithIt
write SetEmUpJoe;
Información adicional
Consulte “index specifiers” en la ayuda de Delphi para más información sobre
cuándo utilizar estos elementos.
-O-
insert into "MACABRE.DB"
(OttoIncrease, DrOctopus, EightHead)
values
(:SomeNum, :Villain, :DistinguishingFeature)
Solución rápida
No intentente editar (mediante Update) o asignar (mediante Insert) valores a
campos de tipo Autoincrement.
Información adicional
Los campos Autoincrement son de sólo lectura, y por lo tanto no pueden ser
editados. Un campo Autoincrement, por su propia naturaleza, no debería ser
editado manualmente. Al ser incrementado automáticamente, cada valor será
único. Si pudiera cambiarse manualmente el valor, al final podrían obtenerse
varios valores idénticos, lo que resultaría en una violación de clave. Por esta
razón, los campos Autoincrement son de sólo lectura.
Puede especificar el valor inicial para los campos Autoincrement utilizando la
propiedad Minimum en el Database Desktop. En caso contrario, el valor siem-
pre comenzará a partir de 1 y se incrementará en 1 para cada registro. Los
campos Autoincrement son muy parecidos a los números de los cheques que
usted recibe de su institución financiera.
Solución rápida
Contacte con el vendedor o el fabricante del ordenador para obtener un contro-
lador actualizado de 32 bits del CD-ROM.
Información adicional
El controlador de 16 bits no reconoce nombres de archivo largos; por esa razón,
no puede encontrar algunos de los archivos necesarios para la instalación.
316 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Evite hacer referencia a variables de instancia en el método de clase, o con-
vierta el método de clase en un método normal.
2. Anteponga el nombre de la variable del formulario al nombre del compo-
nente, así:
if Mode = psSingle then begin
frmSingle.Caption := SEnterOrdNum;
frmSingle.GroupBox1.Caption := 0
end;
Información adicional
2. Puede también encerrar el bloque de código entero en una sentencia With,
si necesita hacer referencia a componentes muchas veces, así:
with frmSingle do begin
editVendOrd.Text:=DefaultOrdNum;
if Mode = psSingle then begin
Caption := SEnterOrdNum;
GroupBox1.Caption := SprintSingleInvoice
end;
end;
Solución rápida
1. Borre archivos y programas innecesarios para liberar especio en el disco
duro. Para borrar programas, siga estos pasos:
a. Pulse el botón Inicio en el escritorio de Windows.
b. Seleccione Configuración | Panel de Control.
c. Seleccione Añadir/borrar Programas.
d. Seleccione el programa que quiere desinstalar.
e. Pulse el botón Añadir/Quitar.
2. Asigne True al parámetro Local Share del BDE. Para ello, siga estos pasos:
a. Abra la utilidad BDE Administrator.
b. Seleccione la pestaña Configuration en la sección Drivers & System
(izquierda).
c. Seleccione System | Init.
d. Asigne el valor True a Local Share en la pestaña Definition (a la
derecha).
Información adicional
1. Es una buena idea siempre tener al menos varias docenas de megabytes
libres en el disco duro. En caso contrario, sufrirá numerosos y variados
mensajes de error “extraños”, caídas del sistema y pérdidas de trabajo.
Solución rápida
Llame a Prepare antes de abrir una consulta, y a Unprepare al terminar de
trabajar con ella. Por ejemplo, podría hacer algo como esto:
with Query1 do
begin
SQL.Add('Select * from Bakery');
Prepare;
try
Open;
318 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Si obtiene este mensaje de error durante las operaciones de base de datos,
podría ser ventajoso duplicar el valor del parámetro SHAREDMEMSIZE con la
utilidad BDE Configuration de su valor por defecto 2048 a 4096, o cuadripli-
carlo, si es necesario, a 8192.
Considere la creación de conjuntos de datos mediante programación en tiempo
de ejecución. Esperar hasta que los recursos se necesiten para crearlos (espe-
cialmente si ellos pueden no ser utilizados durante ciertos momentos en la
aplicación), y luego liberarlos lo antes posible puede mejorar el uso de memoria
y el desempeño de la aplicación.
Consulte “BDE Initialization Error $2501”.
Solución rápida
Consulte al administrador del servidor SQL para obtener los derechos necesa-
rios. Si es usted mismo el administrador, consulte la documentación para el
servidor particular (InterBase, MS SQL Server, Oracle, etc.) que esté
utilizando.
Información adicional
Si usted va a administrar la seguridad, considere crear inicialmente grupos,
asignar los derechos a esos grupos, y luego asignar los individuos (usuarios) a
los grupos. Podría también permitir a los usuarios únicamente acceder a las
vistas y los procedimientos almacenados (evitando completamente el acceso a
las tablas).
Mensajes de error 319
Solución rápida
Proporcione la contraseña antes de intentar asignar el valor True a la propie-
dad Active.
Información adicional
Si necesita proteger por contraseña una tabla de Paradox para prevenir el
acceso no autorizado a ella, puede llevarlo a cabo utilizando el Database
Desktop, o puede hacerlo en el código. Para proteger por contraseña una tabla
de Paradox en el Database Desktop, siga estos pasos:
1. Seleccione Tools | Utilities | Restructure (o pulse el icono Structure).
2. Seleccione Password Security de la lista desplegable Table Properties.
3. Pulse el botón Define.
4. Introduzca la contraseña dos veces.
5. Seleccione OK.
La tabla estará ahora encriptada. La tabla podrá ser abierta, pero la informa-
ción no será legible. Por ejemplo, si antes de proteger con contraseña o encrip-
tar una tabla, puede abrirla y ver la información que contiene en este formato:
DE White QB Favre
Solución rápida
1. Manténgase en el rango entre –2.147.483.648 y 2.147.483.647 (ambos
inclusive) en las asignaciones de enteros antes de Delphi 4. Lo siguiente
funciona bien:
procedure OnKeyPress(var Key: Smallint); dispid 2147483647;
2. Esto compilará también:
var
r: double;
. . .
r := 2222222222.22;
Información adicional
Para más información, consulte “integers | integer types” en la ayuda de
Delphi.
Mensajes de error 321
Solución rápida
Necesita instalar InterBase 6, como el mensaje indica, o si lo ha hecho ya, debe
mover IBINSTALL.DLL a la ruta del sistema.
Información adicional
Para descargar InterBase, visite el sitio web de InterBase (www.interbase.com).
Solución rápida
Borre la interfaz redundante (IWatched, en este caso) de la signatura de la
clase.
Información adicional
Puede implementar una misma interfaz de diferentes maneras en múltiples
clases. Por ejemplo, podría hacer esto:
TPostman = class(TInterfacedObject, IWalk)
. . .
THiker = class(TInterfacedObject, IWalk)
. . .
Solución rápida
Añada un GUID a la declaración de la interfaz, pulsando Ctrl+May+G.
Información adicional
Es legal declarar un tipo interfaz sin un GUID, pero es recomendable utilizar
un GUID; así evitará problemas como éste.
Solución rápida
Sustituya la interfaz por alguna de las que aparece en la signatura de la clase,
o añada la interfaz en cuestión a la signatura de la clase, así:
TOopsadaisacal = class(TInterfacedObject, IMPei, IMCake)
. . .
Mensajes de error 323
Información adicional
Si no ha declarado la interfaz, obtendrá el mensaje de error “Undeclared
Identifier: <>”. Puede implementar en una clase tantas interfaces como desee.
Solución rápida
Cuando distribuya una aplicación de base de datos de Delphi, incluya la ver-
sión de BDE con la cual la aplicación fue desarrollada, ya que es posible que el
usuario no la tenga instalada.
En realidad, es una buena idea tener siempre la versión más actual del BDE
en su sistema, ya que mantendrá así la compatibilidad hacia atrás y también
incluirá tanto las nuevas características y funcionalidades como los parches de
los errores anteriores que hayan sido solucionados.
Información adicional
Instalar la versión actualizada del BDE resolverá el problema en el caso de los
programas creados con la versión más actual de Delphi, así como con versiones
más antiguas de Delphi de 32 bits*. Por ejemplo, la versión del BDE que viene
con Delphi 2 (3.5) no es compatible con los programas creados en Delphi 3. La
versión del BDE que viene con Delphi 3, sin embargo, es compatible con Delphi
2 y 3 (o sea, es compatible hacia atrás).
Si necesita instalar la versión más reciente del BDE en las máquinas de los
usuarios, puede utilizar InstallShield Express, que viene con Delphi de 32 bits,
para crear disquetes de instalación con este propósito.
* Las versiones 2-6 de Delphi son todas de 32 bits. Solamente Delphi (Delphi 1)
era de 16 bits. Posiblemente Delphi 7 será de 64 bits.
Solución rápida
Debe utilizar un tipo de clase seguido por un tipo de interfaz en la declaración
de un tipo de clase ActiveForm, así:
TActiveFormX = class(TActiveForm, IActiveFormX)
Información adicional
Consulte “Class type required” para ver el mensaje opuesto a éste (este es
un ejemplo de cómo mantener ocupado a un programador).
Solución rápida
1. Haga una construcción completa (Project | Build All) en vez de una sim-
ple compilación (Project | Compile).
2. Haga una construcción completa, como se indicó en el punto 1, o primero
borre todos los archivos de unidades compiladas del proyecto (.DCU) y los
archivos de paquete (.DCP) y luego recompile. Si esto no resuelve el pro-
blema, cierre Delphi y reinícielo, para reajustarlo de tal forma que no
piense que está tratando con una versión modificada de la unidad System.
3. Actualícese a Delphi 3 o superiores (en donde este problema está
solucionado).
4. Haga un Build All.
Mensajes de error 325
Información adicional
La culpa no debería echársele únicamente a Delphi en el caso de los errores
internos. Estos muchas veces pueden ser evitados siguiendo prácticas de codifi-
cación estándar. Es usualmente el código “extraño” el que provoca esos mensa-
jes de error. Familiariícese con las prácticas de programación “estándar”, y
verá pocos errores de este tipo. De otro modo (si el error no es parcialmente
debido a prácticas de codificación inusuales), el error muchas veces puede ser
eliminado saliendo de Delphi y reiniciándolo de nuevo.
2. Este error normalmente aparece cuando el compilador no puede determi-
nar si un archivo de unidad compilada (.DCU) o de paquete (.DCP) necesita
ser recompilado. Si está utilizando paquetes (de tiempo de ejecución o de
tiempo de diseño), puede encontrar conveniente crear expresamente un
directorio para los archivos de paquete (.DCP). Puede hacer esto seleccio-
nando Tools | Environment y la pestaña Library, e introduciendo la
entrada apropiada en el cuadro de combinación DCP Output Directory.
Esto ayudará a asegurar que el compilador siempre utilice el archivo de
paquete más reciente (.DCP). Si está utilizando paquetes, podría encontrar
conveniente verificar que todos los paquetes tengan la opción del compila-
dor {$IMPLICITBUILD ON} habilitada.
Solución rápida
Siga estos pasos para modificar la configuración del Registro del sistema:
1. Seleccione Inicio | Ejecutar desde el escritorio de Windows.
2. Introduzca regedit en el cuadro de combinación Abrir y pulse el botón
Aceptar.
3. Navegue hasta HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
NT\CurrentVersion\WinLogon\Shell.
4. Cambie el valor del parámetro Shell de ‘Explorer.EXE userhook’ a ‘Explo-
rer.EXE’.
5. Reinicie el equipo para que la configuración tome efecto.
326 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Esa máquina en cuestión hace una configuración especial del Registro para
cargar una extensión del Explorer. ¿No son tales alternativas un engorro? Son
simplemente otra oportunidad para confundir a Joe Sixpack (y ocasionar
incompatibilidades de software).
Solución rápida
Registre la biblioteca de tipos Weblib.
Información adicional
Puede registrar WEB.TLB seleccionando el menú Inicio de Windows y luego
introduciendo tregsvr WEBLIB.TLB.
Site Express apareció por primera vez en Delphi 6.
Solución rápida
Introduzca una dirección válida (entre 00000000 y FFFFFFFF).
Información adicional
Puede acceder al cuadro de diálogo Find Error seleccionando Search | Find
Error....
Mensajes de error 327
Solución rápida
Verifique que los valores que están siendo pasados a los parámetros Year,
Month y Day sean válidos (tomados como un todo) antes de hacer la asigna-
ción. Por ejemplo, puede validar la entrada del usuario intentando hacer una
conversión de tipos dentro de una sentencia Try. . . Except así:
procedure EncodeThisDate(YearValue, MonthValue, DayValue: Word);
var
CoddAndDate: TDateTime;
begin
try
CoddAndDate:= EncodeDate(YearValue,MonthValue,DayValue);
except
on EConvertError do
{Gestionar la excepción}
end;
Información adicional
La función EncodeDate recibe tres parámetros: Year (año), Month (mes) y Day
(día). El rango de valores válidos para el parámetro Year es de 1 hasta 9999.
El rango de valores válidos para el parámetro Month va de 1 a 12. El rango de
valores válidos para el parámetro Day es de 1 hasta 28, 29, 30 ó 31, en depen-
dencia de los valores del mes y el año.
Solución rápida
Verifique que todos los valores que se pasan a través de los parámetros Hour,
Min, Sec y MSec sean válidos antes de una asignación. Por ejemplo, valide la
entrada del usuario intentando hacer una conversión de tipos en una sentencia
Try. . . Except así:
procedure EncodeThisTime(HourVal, MinuteVal, SecondVal,
MillisecondVal: Word);
var
EncodedTime: TDateTime;
begin
try
EncodedTime := EncodeTime(HourVal,MinuteVal,SecondVal,
MillisecondVal);
except
on EConvertError do
{gestionar la excepción}
end;
Información adicional
La función EncodeTime acepta cuatro parámetros: Hour (hora), Min (minuto),
Sec (segundos) y MSec (milisegundos). El rango de valores válidos para el
parámetro Hour es de 0 hasta 23. El rango de valores válidos para los paráme-
tros Min y Sec va de 0 a 59. El rango de valores válidos para el parámetro
MSec es de 0 hasta 999.
Solución rápida
Seleccione diferentes tablas para las propiedades Destination y Source.
Información adicional
Para más información, consulte “TBatchMove” en la ayuda de Delphi.
Mensajes de error 329
Solución rápida
Incremente el parámetro BLOB SIZE con la utilidad BDE Configuration.
Para ello, abra la utilidad BDE Configuration/Administrator y navegue hasta
Configuration | Drivers | <Su base de datos>. Por ejemplo, si está utilizando
InterBase, navegue hasta Configuration | Drivers | Native | INTRBASE |
BLOB SIZE.
Puede que también sea conveniente aumentar el valor de SHAREDMEMSIZE
con el BDE Administrator. Para ello, abra la utilidad BDE Administrator y
siga estos pasos:
1. Seleccione la etiqueta Configuration en la sección Drivers & System
(izquierda).
2. Seleccione System | Init.
3. Incremente el valor de SHAREDMEMSIZE.
Si está utilizando un objeto TQuery, sería conveniente reducir la cantidad de
registros en el conjunto resultado.
Información adicional
Solución rápida
Cree un índice único en cluster para la tabla.
Información adicional
Un índice en cluster está almacenado físicamente en el disco según el orden del
índice. Por esta razón, solamente se puede tener un índice en cluster para una
tabla.
Solución rápida
1. Utilice el formato:
{00000000-0000-0000-0000-000000000000}
2. Proporcione un ServerGUID válido (vea el punto anterior).
Información adicional
1. Debe proporcionar las llaves al inicio y al final del GUID, como se muestra
arriba. Consulte “GUIDs”, “ServerGUID” y “GUIDToString function” en la
ayuda de Delphi para más información.
2. La propiedad ServerName de TRemoteServer es opcional; el ServerGUID
no lo es.
Solución rápida
Convierta la variable a un objeto de su mismo tipo o de un ancestro de aquel
tipo.
Mensajes de error 331
Información adicional
He aquí un ejemplo de código que produce el mensaje de error bajo discusión:
procedure BrandoAsToughGuy;
var
b: TObject;
begin
b := TButton.Create(nil);
{funciona, ya que TButton desciende de TObject}
with B as TMemo do
{esto produce el mensaje de error,
ya que TMemo no es descendiente de TButton}
...
end;
Solución rápida
1. La forma correcta de utilizar las directivas de compilación mostradas
arriba es:
uses
Windows, Messages, SysUtils, Classes,
Graphics, {$IFDEF WIN32} Registry,
{$ELSE} IniFiles, {$ENDIF} Controls;
2. La forma correcta de utilizar las directivas de compilación mostradas
arriba es:
{$IFOPT I+}
. . .
{$ENDIF}
Información adicional
Para más información, consulte “compiler directives” en la ayuda de Delphi.
Invalid directory
Posible causa de error
Puede estar utilizando una versión antigua de Delphi y haber introducido algo
como C:\Archivos de programa\Borland\Database Desktop en la propiedad
DatabaseName de un objeto TTable.
Solución rápida
Necesita introducir algo como: c:\progra~1\borland\databa~1 si la ruta con-
tiene nombres de directorio de más de ocho caracteres.
Información adicional
El método preferido es crear un alias que haga referencia a la ubicación de la
base de datos. Consulte “Invalid file name” en este libro.
Solución rápida
1. Compruebe que solamente intenta acceder a campos que existen realmente
en la base de datos.
2. Puede necesitar poner el nombre de la tabla en mayúsculas y encerrar el
nombre del campo entre comillas dobles. Dada la sentencia SQL de arriba,
puede tener que modificarla así:
SELECT *
FROM CUSTOMERS
WHERE CUSTOMERS."State = 'ID'
Información adicional
Si está conectándose a una base de datos de servidor SQL, familiarícese con la
sintaxis SQL particular del servidor que esté utilizando, así como con las
características que soporta (que cambian de un fabricante a otro).
Solución rápida
Asigne siempre un tamaño a los campos de tipo ftString, ftBCD, ftBytes,
ftVarBytes, ftBlob, ftMemo o ftGraphic.
Información adicional
No solamente el tamaño no es aplicable a ciertos tipos de campos; aún entre
aquellos a los que es aplicable, puede significar diferentes cosas. En el caso de
los campos de tipo cadena y Byte, Size se refiere a la cantidad de bytes que el
campo reservará para cada instancia. Cuando se aplica a un campo BCD, Size
es la cantidad de dígitos después de la coma decimal. Para un campo BLOb,
334 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Aunque es cierto que no se puede editar un campo Autoincrement, puede selec-
cionarlo incluso bajo las circunstancias anteriores actualizando la versión del
BDE a la 4.01 o superior.
Información adicional
Podría no ser bueno permitir que los campos autoincrementales sean actualiza-
dos, ya que son normalmente utilizados como claves primarias generadas
automáticamente.
Solución rápida
1. Si está utilizando la versión 3.5 del BDE (que viene con Delphi 2) y Win-
dows 95B con la opción de nombres de archivo largos habilitada (FAT32),
necesita instalar la versión 3.5f del BDE para poder acceder a las tablas
cuyas rutas incluyen nombres de archivo largos o espacios.
Una alternativa es colocar las tablas en una ruta que no incluya nombres
largos o espacios.
2. Consulte la documentación de Novell para ver cuál es la máxima longitud
de las rutas en su versión de Netware.
3. Renombre el directorio, eliminando el apóstrofe.
4. Vuelva a mapear la unidad G: de su ordenador, de forma que pueda “ver”
el archivo que supuestamente está abriendo.
Información adicional
1. Descargue la versión más reciente del BDE desde el sitio web de Borland.
Puede bajar la versión 3.5 del BDE desde el sitio web de Borland en
www.borland.com/techsupport/bde/utilities.html.
El nombre del parche es ‘BDE v3.5 32-Bit core DLLs including FAT32
enhancement’.
2. Si posteriormente obtiene un mensaje de error “Path too long”, actualice
las tablas de Paradox al nivel 7. Vea las instrucciones para hacer esto en
“Higher table level required” .
Puede comprobar qué versión de Windows utiliza pulsando con el botón
derecho del ratón sobre el icono Mi PC en el escritorio y seleccionando Pro-
piedades en el menú de contexto. El número de versión del sistema
operativo se muestra en la página General.
3. No es una buena práctica utilizar símbolos especiales (como apóstrofes) en
los nombres de directorios o archivos.
Turner := 922337203685477.5807;
McCartney := 922337203685477.5807;
Gates := Turner + McCartney; {el error ocurre aquí}
2. Puede haber tratado de convertir un número real a un entero utilizando las
funciones Round o Trunc, y el número era demasiado grande para ser
almacenado en un entero. Cualquiera de los siguientes ejemplos genera
este error:
var
RolyPoly: Integer;
hyper: Extended;
begin
hyper := 2222222222.22;
RolyPoly := Round(hyper);
var
Line: Integer;
Workmans: Comp;
begin
Workmans := 2222222222.22;
Line := Trunc(Workmans);
3. Puede que la máquina no disponga de coprocesador matemático.
Solución rápida
1. Asegúrese de que no asigna números demasiado grandes, previniéndolo
explícitamente en el código o encerrando las asignaciones en un bloque
T r y . . . Except.
2. Encierre la llamada a Round o Trunc en un bloque Try. . . Except:
const
crlf = #13#10;
. . .
var
WhatGoesAroundComesA: Integer;
bent: double;
try
WhatGoesAroundComesA:= Round(bent);
except
on EInvalidOp do
MessageDlg('El número real es muy grande’ + crlf +
‘para caber en un tipo entero’, mtError, [mbOK], 0);
end;
3. Actualícese a una máquina que tenga coprocesador matemático (que eje-
cuta las operaciones de punto flotante por hardware) o añada la directiva
de compilador {$N-} en la parte superior de la unidad.
Información adicional
1. Para más información, consulte “real types” en la ayuda de Delphi.
Mensajes de error 337
Solución rápida
No utilice File como resultado devuelto por una función.
Información adicional
Para más información, consulte “function declarations” y “function calls” en la
ayuda de Delphi.
Solución rápida
No modifique los GUIDs. Son números especiales que se generan
automáticamente.
Información adicional
GUID significa Globally Unique Identifier (Identificador Global Unico). Para
más información, consulte “GUIDs” en la ayuda de Delphi.
Solución rápida
Utilice solamente tipos de índices apropiados para la tabla con la que está
trabajando.
Información adicional
Para más información, consulte “AddIndex” en la ayuda de Delphi.
Solución rápida
Pase ixExpression en el parámetro IndexOptions del método AddIndex:
Table1.AddIndex('ndxCityState','City+State', [ixExpression]);
Información adicional
Para más información, consulte “AddIndex” en la ayuda de Delphi.
Solución rápida
1. Compruebe que no asigna el mismo nombre de índice más de una vez.
Puede verificar si un índice ya existe de esta manera:
if not Table1Stadt.IsIndexField then
AddIndex('ndxStadt', 'Stadt', []);
2. Asigne el mismo nombre del campo al nombre del índice, así:
AddIndex('Stadt', 'Stadt', []);
o añada la opción de índice ixCaseInsensitive, así:
AddIndex('ndxStadt', 'Stadt', [ixCaseInsensitive]);
3. Asigne las opciones de índice apropiadas para la tabla con la que esté
trabajando.
4. No asigne más de una clave primaria (ixPrimary) por tabla.
Información adicional
2. A los índices compuestos de múltiples columnas se les puede dar nombres
distintos de las columnas sin proporcionar el parámetro de opción de índice
ixCaseInsensitive.
Si asigna a un índice el mismo nombre del campo, no incluya el parámetro
de opción de índice ixCaseInsensitive. Por ejemplo, un índice compuesto
sobre las columnas City y State podría ser definido así:
AddIndex('CityState','Stadt;Land',[]);
3. Para más información, consulte “TTable.AddIndex” en la ayuda de Delphi.
4. Si tiene un índice primario sobre la tabla (recomendable) que consiste de
una única columna, ésta debe ser la primera columna de la tabla. Si tiene
un índice primario compuesto, debe empezar por la primera columna y
estar compuesto de ahí en adelante por las columnas consecutivas. En
otras palabras, un índice primario compuesto puede ser establecido sobre
las columnas 1, 2 y 3, pero no sobre las columnas 1 y 3 (ó 1, 2 y 4, etc.).
340 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Elimine los parámetros adicionales de la declaración.
2. Añada la palabra reservada Var a la declaración.
Información adicional
Un procedimiento de gestión de mensajes de Windows acepta un único paráme-
tro. Debe ser un parámetro Var.
El método de manejo de mensaje de arriba debería ser:
procedure WMChar(var Message: TWMChar); message WM_CHAR;
Solución rápida
1. Seleccione un archivo con extensión .DPL (biblioteca de paquetes de Del-
phi) o una extensión .DPK (paquete de Delphi).
2. Vuelva a crear el archivo de paquete, si es necesario.
Mensajes de error 341
Información adicional
Puede obtener este error si instaló un paquete y luego movió o borró algunos
de los archivos que lo componen. Seleccionar la casilla de verificación para
intentar añadir de nuevo el paquete (y su página sobre la Paleta de Componen-
tes) puede ocasionar este error. Elimine el paquete (pulsando el botón
Remove), coloque los archivos requeridos en uno de los directorios de la ruta
de búsqueda de Delphi, y luego añada de nuevo el paquete utilizando el botón
Add.
Invalid Parameter
Posible causa de error
Puede haber olvidado especificar el valor de TableName en el objeto TTable de
destino mientras ejecuta una operación de movimiento en lote utilizando el
componente TBatchMove.
Solución rápida
Debe especificar tanto las tablas fuente como de destino al utilizar el compo-
nente TBatchMove.
Información adicional
Para más información, consulte “TBatchMove” en la ayuda de Delphi.
Solución rápida
Utilice WideString como el tipo de la propiedad; String no es un tipo de auto-
matización OLE.
Información adicional
Todos los tipos de automatización OLE deben ser compatibles con las varian-
tes. Los siguientes tipos de Delphi pueden ser utilizados en proyectos de auto-
matización: Byte, Currency, Double, IDispatch, Integer, IUnknown,
342 Los Tomos de Delphi: Delphi sin problemas
Invalid path
Consulte “Invalid file name”.
Solución rápida
Asegúrese de que no trata de liberar la memoria que ya ha sido liberada. Por
ejemplo, para garantizar que no se libere de nuevo la memoria que ya ha sido
liberada en el ejemplo de arriba, haga esto:
procedure FinallyFree;
var
Homework: Pointer;
begin
Mensajes de error 343
GetMem(Homework, 32);
try
try
{Acciones...}
except
FreeMem(Homework, 32);
end; //except
finally
{Lo siguiente funciona bien SIEMPRE}
if not Assigned(Homework) then
FreeMem(Homework, 32);
end; //finally
end;
Información adicional
Para más información, consulte “New”, “Dispose”, “FreeMem” y “GetMem” en
la ayuda de Delphi.
Solución rápida
Elimine el tratamiento de propiedades Published que esté haciendo en el
método DefineProperties (y otros métodos relacionados, como ReadData y
WriteData).
Información adicional
Las propiedades que se definen como Published son serializadas automática-
mente por Delphi.
En ocasiones puede que necesite utilizar el método DefineProperties, como
cuando quiera almacenar el estado de propiedades no publicadas.
(una propiedad de tipo Boolean, que acepta solamente los valores True o
False) de un componente generará este mensaje.
2. Un archivo de formulario (.DFM) puede contener una referencia a un
método para el que no hay asignado actualmente ningún manejador de
eventos.
Solución rápida
1. Introduzca un valor que sea válido para la propiedad en cuestión. Siempre
que se proporcione un cuadro de combinación para escoger un valor de una
lista, utilícelo.
2. Elimine la línea en el archivo .DFM o elimine la referencia al método en la
página Events del Inspector de Objetos.
Información adicional
1. Todos los controles situados sobre el formulario se mostrarán en la lista
desplegable para la propiedad ActiveControl (como los objetos TButton,
TEdit, etc.), pero los componentes gráficos (como TLabel, TImage), así como
los cuadros de diálogo, relojes del sistema (timers), etc., no se mostrarán,
ya que no son capaces de recibir el foco y por lo tanto no pueden ser el con-
trol activo.
2. Para recibir este mensaje, puede haber respondido al mensaje “The <>
[method,property] referenced by <> does not exist. Remove the
reference?” pulsando el botón No. Si selecciona Yes, la referencia será
borrada del archivo de formulario (.DFM), y el mensaje de error bajo discu-
sión no será generado.
Solución rápida
Visualice el archivo .DFM en el número de línea indicado en el mensaje de
error para ver qué es lo que está causando el problema (Search | Go to Line
Number. . . ).
Información adicional
Los archivos .DFM son la representación textual de los formularios. Ellos des-
criben qué objetos están sobre el formulario, dónde son mostrados sobre el for-
mulario y su configuración de propiedades.
Mensajes de error 345
Puede editar el archivo .DFM pulsando con el botón derecho del ratón sobre el
formulario y seleccionando View As Text del menú de contexto. Los cambios
que haga en el .DFM se reflejarán sobre el propio formulario, de la misma
forma que los cambios que haga directamente sobre el formulario, como colocar
componentes sobre él y configurar sus propiedades, se reflejarán en el archivo
.DFM. Esto se conoce como edición bidireccional (two-way editing).
En el siguiente fragmento de archivo .DFM aparece una coma incorrecta. Esto
generaría el mensaje de error bajo discusión, indicando la línea 5 como ubica-
ción del problema.
object Form1: Tform1
Left = 200
Top = 106
Width = 544
Height = ,375 {aquí está el problema}
Caption = 'Form1'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
PixelsPerInch = 96
TextHeight = 13
end
Solución rápida
Cargue el recurso en un editor de recursos de 32 bits, como el Image Editor (en
Delphi de 32 bits), y luego guárdelo.
Información adicional
Abrir y luego guardar el recurso en un editor de 32 bits lo grabará como un
recurso de 32 bits.
1. Si Delphi está iniciándose con un proyecto cargado (ha optado por guardar
la configuración del escritorio, y dejó el proyecto abierto en el entorno inte-
grado la última vez que cerró Delphi), un archivo del proyecto puede ser el
causante.
2. Si Delphi está iniciándose sin un proyecto cargado, un paquete es el princi-
pal sospechoso.
Solución rápida
1. Puede que tenga que copiar el código del proyecto, iniciar un proyecto
nuevo, y pegar el código del proyecto viejo al proyecto nuevo.
2. Para determinar cuál es el paquete culpable, elimine los paquetes
siguiendo estos pasos:
a. Seleccione Components | Install Packages.
b. Localice un paquete de terceros fabricantes y desmarque su casilla de
verificación.
c. Cierre y reinicie Delphi.
d. Repita el proceso hasta que Delphi deje de dar el mensaje de error, en
cuyo momento habrá encontrado el paquete “culpable”.
e. Restaure cualquier paquete de terceros “inocente” que haya
deshabilitado y necesite utilizar.
Información adicional
Sea cauteloso al utilizar componentes de terceros provenientes de fuentes en
las que no tenga confianza plena. Vea los estudios de Delphi Informant para
obtener información sobre qué componentes de terceros tienen mejor calidad.
Contacte con el equipo Danysoft para conocer cuales son los que mejor se adap-
tarán a sus necesidades. Podría también ser beneficioso revisar el grupo de
noticias borland.public.delphi.thirdparty y el sistema e-commerce del Grupo
Danysoft: www.danyshop.com.
Invalid type
Posible causa de error
1. Puede estar intentando añadir un método o propiedad miembro a una
interfaz en Delphi 6 o superior, y especificó un tipo de datos no compatible
con COM. Por ejemplo, introducir
property Orwellian: String;
Generará este mensaje de error, ya que String no es un tipo de datos válido
para interfaces.
2. Consulte “Unknown SQL Error”.
Mensajes de error 347
Solución rápida
1. Utilice tipos que sean permitidos en COM, como WideString.
2. Consulte “Unknown SQL Error”.
Información adicional
El menú Edit | Add to Interface apareció en Delphi 6.
Invalid typecast
Posible causa de error
1. Puede estar intentando hacer una conversión de tipos de un objeto o tipo a
un objeto o tipo con el que aquél no es compatible.
2. Puede estar intentando comparar tipos a través de fronteras de módulos
(.EXE a .DLL o .DLL a .DLL).
Solución rápida
1. Haga conversiones de tipos solamente entre tipos compatibles. Puede
comprobar la compatibilidad utilizando los operadores Is y/o As. Por ejem-
plo, para ejecutar una operación sobre un componente solamente si se trata
de un TTable, puede hacer algo como esto:
for i := 0 to ComponentCount-1 do
if Components[i] is TTable then
TTable(Components[i]).Close;
2. Evite hacer conversiones de tipos entre fronteras de módulos. En tales
casos, utilice funciones de respuesta (callback), de forma que todas las veri-
ficaciones/conversiones ocurran en el mismo módulo.
Información adicional
Estos son los tipos de conversión que son permitidos:
Un tipo ordinal o puntero a un tipo ordinal o puntero
Un carácter, cadena, array de char, o PChar a String
Un ordinal, real, cadena o variante a variante
Una variante a ordinal, real, string o variante
Una referencia a una variable a cualquier tipo con el mismo tamaño
348 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Inserte la cláusula FROM junto con el nombre de la(s) tabla(s) de la(s) que
desea seleccionar registros. No puede utilizar parámetros (con la sintaxis
:<parámetro>) en la parte SELECT o FROM de una sentencia SQL. Vea
Información adicional más abajo para más información sobre cómo permitir
que el usuario seleccione las tablas y/o campos en tiempo de ejecución utili-
zando la función Format.
2. Proporcione al menos un nombre de columna a continuación de la palabra
reservada SELECT, y al menos un nombre de tabla después de FROM.
3. Si utiliza una sentencia GROUP BY, proporcione al menos una función de
agregación en la cláusula SELECT, y agrupe por todas las columnas no
agregadas que especificó en la cláusula SELECT. Por ejemplo:
SELECT Fruit, Vegetable, Spice, Count(Dessert)
FROM Speisekarte
WHERE Calories > 1000
GROUP BY Fruit, Vegetable, Spice
4. Escriba todo en mayúsculas en el SQL de Oracle. Por ejemplo:
SELECT
SOMEFIELD
FROM
'SOMEALIAS.SOMETABLE'
WHERE
SOMEFIELD < 0
5. Si hace referencia a un nombre de campo que contiene espacios, debe no
solamente encerrarlo entre comillas (“ ”), sino también anteponer el nom-
bre de tabla o alias. Por ejemplo, si el nombre de campo es:
One Flew Over The Coders Desk
debe hacer referencia a él así:
SELECT
TABLENAME."One Flew Over The Coders Desk"
. . .
6. Añada el “AND” olvidado:
SQL.Add('SELECT Material.WeekBegin, Material.TalkIndicator');
SQL.Add('FROM Material, Week WHERE');
SQL.Add('Material.WeekBegin >= :FirstDate');
350 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Las sentencias SQL que devuelven un conjunto resultado requieren una cláu-
sula SELECT (que especifica las columnas que se retornarán en el conjunto
resultado; puede nombrarlas individualmente o utilizar * para indicar todas
las columnas). Adicionalmente, tales sentencias SQL necesitan una cláusula
FROM (que especifica la tabla o tablas de las que se obtendrán las columnas).
La sentencia ORDER BY de SQL se utiliza para ordenar el conjunto resultado.
Por ejemplo, puede ordenar por el apellido ascendentemente (de la ‘A’ a la ‘Z’).
Por ejemplo, si tuviera una tabla con varios valores en sus columnas City y
State, ordenarlas por el campo City y luego concatenarlas (City + ', ' + State)
podría producir algo así:
Anchorage, Alaska
Angels Camp, California
Arcata, California
Bethany, Oklahoma
Brookfield, Wisconsin
Brooklyn, New York
Coeur d’Alene, Idaho
Eureka, California
Fort Bragg, California
Helena, Montana
Jenny Lind, California
Loleta, California
Mokelumne Hill, California
San Andreas, California
Zenia, California
La sentencia GROUP BY se utiliza para ejecutar operaciones de agregación
(como SUM, COUNT, AVG, MIN, MAX) sobre grupos de registros con un valor
de columna en común. Por ejemplo, si tuviéramos una tabla con nombres de
jugadores de la NBA, el equipo en el que juegan y su salario, podríamos
Mensajes de error 351
agruparlos por equipo y ejecutar una operación SUM sobre la columna Salary,
lo que produciría una tabla en la que habría un registro para cada equipo que
incluiría el salario total de los jugadores del equipo.
6. Esto puede ocurrir si ha eliminado una sección de una sentencia SQL que
no funciona bien durante la depuración y luego olvidó añadir el “AND” de
nuevo.
Solución rápida
Cree una variable local para almacenar el valor de la propiedad, y luego pásela
como parámetro. Por ejemplo:
var
s: String;
begin
s := Woman.EyeColor;
Insert(Source, s, 3);
Información adicional
Las propiedades no pueden ser pasadas como parámetros variables, debido a
que solamente se permite su modificación a través del método de acceso de
escritura (y si no tienen un método de escritura, se trata de propiedades de
sólo lectura). Las propiedades son simplemente una interfaz de acceso a una
localización de memoria, normalmente un campo de la sección Private de la
clase. Por lo tanto, al modificar una propiedad, se estaría modificando el campo
privado, y solamente la propia clase puede hacer eso; por esta razón, las pro-
piedades (un “envoltorio” alrededor de los campos) no pueden ser modificadas.
procedure DivideVariants;
var
v1,v2: variant;
begin
v1 := 100;
v2 := 'Ciao, baby';
v1 := v1 div v2; {error generado aquí}
end;
...
{Table1Area es de tipo TFloatField}
StringGrid1.Cells[1,1] := Table1Area.AsVariant + 'goo';
2. Puede haber intentado asignar el nombre Null a un índice utilizando el
método AddIndex. Por ejemplo, lo siguiente generará este mensaje de
error:
begin
with Table1 do begin
Close;
Exclusive := True;
AddIndex(null, 'ModemAdapter', []);
Solución rápida
1. Utilice conversiones entre variantes solamente de una manera que sea
lógica y pueda ser entendida por el compilador. He aquí un ejemplo de una
conversión de tipos variantes que es permitida:
procedure DivideVariants;
var
v1,v2: variant;
begin
v1 := 100;
v2 := '3';
v1 := v1 div v2; //produce como resultado 33
end
2. Los índices basados en una única columna de la tabla implícita deben tener
el mismo nombre que la columna. Los índices basados en múltiples colum-
nas (índices compuestos) pueden tener nombres descriptivos de los campos
que contienen. No asigne a un índice el nombre Null.
Información adicional
Para más información, consulte “variants: assigning values” en la ayuda de
Delphi.
Mensajes de error 353
Key Violation
Posible causa de error
1. Puede estar intentando añadir un registro con un valor de clave primaria
que ya existe en la tabla.
2. Puede haber intentado añadir registros de una tabla con una clave prima-
ria a una tabla sin clave primaria utilizando el componente TBatchMove
en el modo batAppendUpdate.
Solución rápida
1. Evite que se introduzcan valores primarios duplicados. Puede protegerse de
esta posibilidad encerrando el código en un bloque Try. . . Except si quiere
presentar al usuario un mensaje personalizado, y quizás mover el cursor de
nuevo al control en el que se muestra la clave primaria. Por ejemplo, en el
código que responde a la violación de clave, podría hacer algo así:
const
crlf = #13#10;
. . .
try
Table1.Post;
except
on E: Exception do
if E.Message = 'Key violation' then
begin
MessageDlg('El valor ya existe en la tabla.' + crlf +
‘Por favor, inténtelo de nuevo.', mtError, [mbOK], 0);
Edit1.Color := clRed;
Edit1.SetFocus;
end;
end;
. . .
2. Inténtelo de nuevo después de crear la misma clave primaria en la tabla
Destination, o utilice el modo batAppend de TBatchMove para mover los
registros.
Información adicional
Obtener una violación de clave es mejor que la alternativa — tener múltiples
registros con un mismo valor en una columna primaria. Esta es definitiva-
mente una de las áreas en donde los mensajes de error son sus amigos.
354 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Si utiliza etiquetas y sentencias GoTo, éstas deben aparecer en el mismo
procedimiento.
Información adicional
Borland Object Pascal no permite que las sentencias GoTo atraviesen las fron-
teras de procedimiento, aunque Pascal estándar si. Las etiquetas y sus corres-
pondientes sentencias GoTo son normalmente utilizadas para el manejo de
errores, y Delphi proporciona un mecanismo mucho mejor para esto: la gestión
de excepciones. Para más información, consulte “exceptions” en la ayuda de
Delphi.
En cualquier caso, los verdaderos programadores nunca utilizan sentencias
GoTo ;-)
Solución rápida
Defina las etiquetas una y solamente una vez.
Información adicional
Las etiquetas y sus correspondientes sentencias GoTo son normalmente utili-
zadas para el manejo de errores, y Delphi proporciona un mecanismo mucho
Mensajes de error 355
var
Form1: Tform1;
label GypsiesTrampsAndThieves;
implementation
Solución rápida
No declare etiquetas en la parte Interface de una unidad (antes de la palabra
reservada Implementation).
Información adicional
Las etiquetas y sus correspondientes sentencias GoTo son normalmente utili-
zadas para el manejo de errores, y Delphi proporciona un mecanismo mucho
mejor para esto: la gestión de excepciones. Para más información, consulte
“exceptions” en la ayuda de Delphi.
En cualquier caso, los verdaderos programadores nunca utilizan sentencias
GoTo ;-)
Solución rápida
Debe definir el lugar de la etiqueta:
procedure Alamo;
label SpursThatJingleJangleJingle;
begin
if { condicion } then
goto SpursThatJingleJangleJingle;
. . .
SpursThatJingleJangleJingle:
. . .
end;
Información adicional
Las etiquetas y sus correspondientes sentencias GoTo son normalmente utili-
zadas para el manejo de errores, y Delphi proporciona un mecanismo mucho
mejor para esto: la gestión de excepciones. Para más información, consulte
“exceptions” en la ayuda de Delphi.
En cualquier caso, los verdaderos programadores nunca utilizan sentencias
GoTo ;-)
Label expected
Posible causa de error
Puede haber hecho referencia a una etiqueta en una sentencia GoTo e incluso
haberla definido, pero no la ha declarado. Por ejemplo, lo siguiente generará
este mensaje de error:
function Junction: variant;
begin
if TankIsEmpty then
goto Shell;
{ ... }
Shell:
{ ... }
end;
Solución rápida
Declare y defina la etiqueta antes de hacer referencia a ella:
function Junction: variant;
label Shell;
begin
if TankIsEmpty then
goto Shell;
{ ... }
Mensajes de error 357
Shell:
{ ... }
end;
Información adicional
Las etiquetas y sus correspondientes sentencias GoTo son normalmente utili-
zadas para el manejo de errores, y Delphi proporciona un mecanismo mucho
mejor para esto: la gestión de excepciones. Para más información, consulte
“exceptions” en la ayuda de Delphi.
En cualquier caso, los verdaderos programadores nunca utilizan sentencias
GoTo ;-)
Solución rápida
1. No haga asignaciones a constantes. Borre la sentencia de asignación o cam-
bie la constante por una variable inicializada.
2. No haga asignaciones a parámetros constantes. Borre la sentencia de asig-
nación o cambie el parámetro constante por un parámetro pasado por valor
o por referencia.
3. No haga asignaciones al resultado de una función fuera de la propia
función.
4. Incremente o decremente solamente variables ordinales:
inc(i); { donde i es un variable Integer }
dec(n);
5. La manera correcta de trabajar con el puntero es:
q := @i; // q apunta a la variable i
q^:= 5; // asigna 5 a i a través de q
6. Puede lograr lo mismo de esta manera:
ZipObj.CurrentDisketteNumber :=
ZipObj.CurrentDisketteNumber + 1;
Mensajes de error 359
Información adicional
4. Inc y Dec tienen un segundo parámetro opcional, que especifica en cuánto
incrementar o decrementar la variable que está siendo manipulada. Para
más información, consulte “assignment statements” en la ayuda de Delphi.
6. Para más información, consulte “Invalid variable reference”.
Solución rápida
Introduzca un número que no sea mayor que la cantidad total de líneas que la
unidad actual contiene.
Información adicional
Puede ir directamente a un número de línea en la unidad activa seleccionando
Search | Go To Line Number.. y luego introduciendo un número en el cua-
dro de diálogo Go To Line Number y pulsando OK.
Solución rápida
Asigne a la propiedad Capacity un valor menor o igual que 16.380 en Delphi 1
ó 134.217.727 en Delphi de 32 bits.
Información adicional
Para más información, consulte “Capacity” en la ayuda de Delphi.
for i := 0 to Items.Count-1 do
if Items[i]='' then Items.Delete(i);
end;
end;
3. Puede haber borrado uno o más campos de un índice de una tabla de base
de datos y no ha actualizado todavía las llamadas a FindKey que hacen
referencia a su antiguo formato (donde el índice estaba compuesto de más
campos). Por ejemplo, si modifica los campos de un índice llamado Dude de
FirstName;Nickname;LastName a simplemente FirstName;LastName, y
luego llama a FindKey de la siguiente manera mientras el índice está
activo, obtendrá este mensaje de error:
FindKey('Clarence','Gatemouth','Brown');
4. Puede estar conectándose a una base de datos utilizando una conexión
ODBC, y una o más .DLLs de ODBC no se encuentran.
5. Puede estar intentando acceder a un elemento de una lista antes de que el
elemento haya sido insertado.
6. Puede estar llamando a ExecSQL en lugar de Open en una sentencia
SELECT de SQL y está intentando acceder a un elemento en el array de
campos del conjunto resultado. Por ejemplo, lo siguiente generará este
mensaje de error:
function TAndCrumpets.MaxSrlNum: Byte;
var
aQuery: TQuery;
begin
aQuery := TQuery.Create(nil);
try
with aQuery do
begin
DatabaseName := SomeDB.DatabaseName;
SQL.Add('SELECT MAX(EXCEPTION_LOG_SRLNUM)’
SQL.Add('FROM EXCEPTION_LOG');
SQL.Add('WHERE BAKED_ID = :baked_id');
ParamByName('baked_id').AsFloat := CrumpetNum;
ExecSQL;
Result := Fields[0].Value;
end;
finally
aQuery.Free;
end;
end;
Solución rápida
1. (A) Asegúrese de hacer una asignación al elemento de la lista que quiere
acceder antes de hacer referencia a él. Utilizando el ejemplo de arriba,
podría hacer referencia al elemento 0:
. . .
362 Los Tomos de Delphi: Delphi sin problemas
s := sl.Strings[0];
. . .
o añadir el elemento 1 a la lista antes de intentar acceder a él:
sl.Add('Samuel Langhorne Clemens'); {elemento 0}
sl.Add('John Griffith London'); {elemento 1}
s := sl.Strings[1]; {s = 'John Griffith London'}
1. (B) Asigne valores a los elementos que desea intercambiar antes de llamar
al método Move:
var
NoneAttached: TStrings;
begin
NoneAttached := TStringList.Create;
try
NoneAttached.Add('move me');
NoneAttached.Add('me too');
NoneAttached.Move(0, 1);
. . .
2. Intercambie los valores inicial y final de la variable de control del bucle For
y utilice una construcción For. . . Downto:
var
i: integer;
begin
with ListBox1 do
begin
Items:=ListBox2.Items;
for i := Items.Count-1 downto 0 do
if Items[i]='' then Items.Delete(i);
end;
end;
3. Compruebe que el índice actual (en el momento de la llamada a FindKey)
no contiene menos campos de los que está pasando a FindKey. En el ejem-
plo de arriba, tendría que alterar la sentencia FindKey para que fuera:
FindKey('Clarence','Brown');
4. Asegúrese que todos los archivos de ODBC necesarios estén presentes.
5. Espere hasta que el elemento haya sido almacenado antes de acceder a su
valor.
6. Sustituya la llamada a ExecSQL por una llamada a Open.
Información adicional
El número entre paréntesis (en el mensaje de error) indica el índice que no
existe y al que se intentó acceder.
6. Utilice Open con las sentencias SQL que devuelven un conjunto de resul-
tados (como las sentencias SELECT). Utilice ExecSQL con las sentencias
INSERT, DELETE y UPDATE.
Mensajes de error 363
Solución rápida
Declare todos los tipos de clases como globales, y no locales (dentro de una fun-
ción o procedimiento).
Información adicional
Para más información, consulte “class types” en la ayuda de Delphi.
Solución rápida
1,2. No asigne procedimientos o funciones locales a variables de tipo procedi-
miento ni los pase como parámetros.
Información adicional
La razón para que esto no sea permitido es que la función o procedimiento
local podría ser llamado cuando el procedimiento o función al que pertenece no
esté activo, causando potencialmente violaciones de acceso.
364 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Configure el Directorio Privado para que apunte a un directorio sobre el
disco duro de cada usuario (como C:\Temp\{ Nombre_ejecutable }). Podría
hacerlo de esta manera:
var
Extension, ExecName, PrivDir : String;
ExtensionPos: Integer;
. . .
ExecName := ExtractFileName(Application.ExeName);
Extension := ExtractFileExt(Application.ExeName);
ExtensionPos := Pos(Extension, ExecName);
Delete(ExecName,ExtensionPos,4);
PrivDir := 'C:\Temp\' + ExecName;
if not DirectoryExists(PrivDir) then
CreateDir(PrivDir);
if DirectoryExists(PrivDir) then
Session.PrivateDir := PrivDir
else
raise Exception.Create('El directorio privado no fue creado!');
end;
2,4. Coloque el ejecutable y las tablas en directorios separados.
3. Si no tiene múltiples ejecutables que accedan simultáneamente a las mis-
mas tablas, asigne False a Local Share (en la página System de la utilidad
BDE Configuration/Administration). Asígnele True si las máquinas de una
Mensajes de error 365
Información adicional
2,4. Si deja en blanco la configuración de PrivateDir, el directorio privado será
por defecto el directorio actual (muy probablemente el directorio en el que
la aplicación reside). TSession contiene una propiedad PrivateDir a la que
se puede asignar un valor. Una sesión se crea automáticamente “de forma
oculta” para cada aplicación de BDE. Para más información, consulte
“TSession.PrivateDir”.
5. ApplyUpdates envía la actualización a la base de datos. CommitUpdates
limpia la caché local.
Es preferible utilizar un componente TDatabase y llamar a su método
ApplyUpdates (en lugar de llamar al método ApplyUpdates de un TDataset).
El método ApplyUpdates de TDatabase acepta como parámetro un array de
objetos TDataset (el método ApplyUpdates de TDatasets no tiene parámetros).
El método ApplyUpdates de TDatabase llama a CommitUpdates para cada uno
de los conjuntos de datos que se le proporciona.
Si el ejecutable y las tablas comparten el mismo directorio, el archivo de blo-
queos (.LCK) aumentará de tamaño cada vez que una consulta sea ejecutada.
También debe asignar True a Local Share en caso de que las tablas también
están siendo accedidas por motores de base de datos distintos del BDE, como
JET u ODBC.
Si Local Share tiene asignado False, ningún archivo de bloqueo (.LCK) será
creado.
permite que la otra aplicación tenga una oportunidad para acceder al archivo
de bloqueos y liberar el bloqueo que ha colocado. Después de un intervalo de
tiempo especificado (el período de timeout) durante el que este interbloqueo se
mantiene, el mensaje de error bajo discusión se mostrará.
Solución rápida
Cierre las aplicaciones que están enfrentadas y borre todos los archivos .LCK.
Información adicional
Si no ha codificado específicamente lógica de bloqueos en la aplicación (si per-
mite que el BDE maneje estas situaciones), este mensaje de error puede haber
sido ocasionado por un problema de red (o sea, esto no es necesariamente un
problema de Delphi/BDE).
Lock Violation
Posible causa de error
1. Puede estar ejecutando un programa de base de datos creado en Delphi 1
sobre una máquina ejecutando Windows 95 que también contiene las
tablas de base de datos.
2. Puede estar utilizando el BDE de 16 bits en una red mixta (en la que se
combinan máquinas con Windows 3.x y Windows 95/98/NT).
Solución rápida
1. En este caso hay dos maneras de resolver el problema:
Recompilar la aplicación en una versión de 32 bits de Delphi (versión 2 o
superior).
-O-
Mover las tablas a un máquina que esté ejecutando Windows 3.x.
2. Siga estos pasos sobre cada máquina de Windows 95:
a. Seleccione Inicio | Configuración | Panel de Control.
b. Haga doble clic sobre el icono Sistema.
c. Seleccione la página Rendimiento.
d. Pulse el botón Sistema de Archivos.
e. Seleccione la página Solución de problemas.
f. Seleccione Deshabilitar la nueva semántica de bloqueos y uso
compartido de archivos.
g. Reinicie el sistema.
Mensajes de error 367
Información adicional
1. Si quiere mantener la configuración tal como está, puede ser útil intentar
uno o ambas de estas secuencias:
Solución rápida
No borre componentes o elementos de los cuales dependan otros miembros de
su formulario o proyecto.
Información adicional
Los campos calculados y de búsqueda puede ser útiles para mostrar informa-
ción que puede ser deducida de otras columnas. Esto ahorra espacio en las
tablas y es una manera flexible de mostrar los datos pertinentes. Un ejemplo
común es crear un campo calculado que multiplica la cantidad vendida por el
precio de cada ítem.
368 Los Tomos de Delphi: Delphi sin problemas
-o-
Puede haber declarado un rango de valores en una sentencia Case donde el ele-
mento mayor aparece primero. Por ejemplo, lo siguiente generará este mensaje
de error:
case Vehicles of
0: ShowMessage('Hoofin'' it');
2..1: ShowMessage('Motorin''); {debe ser 1..2}
. . .
Solución rápida
Declare los tipos subrango y los rangos de etiquetas Case linealmente (del
valor más pequeño al más grande).
Información adicional
Para más información, consulte “subrange types” y “case statements” en la
ayuda de Delphi.
Solución rápida
Si quiere borrar un registro maestro que tenga asociados registros hijos en una
tabla de detalle, primero deberá borrar los registros hijos de la tabla Detalle.
Puede hacer esto mediante programación, utilizando una sentencia DELETE
de SQL en el evento BeforeDelete de la tabla maestra. Por ejemplo, si quiere
borrar todas las referencias a un atleta específico de una base de datos, podría
borrar primero los registros de detalle así:
Mensajes de error 369
Información adicional
Los registros de detalle son aquellos relacionados con el maestro a través de un
campo de clave foránea (que es normalmente la clave primaria de la tabla
maestra).
Al utilizar tablas Paradox, puede asignar la regla de actualización a Cascade
(en cascada) o Prohibit (prohibir) cuando configure la integridad referencial.
(La integridad referencial es la causante del mensaje de error — evita que se
borren registros que dejarían registros huérfanos en la tabla de detalle). La
configuración Cascade cambiará el valor relacionado en la tabla de detalle
cuando cambie el valor de la clave primaria en la tabla maestra. La configura-
ción Prohibit impide que se modifiquen o borren los valores primarios en la
tabla maestra si existen hijos en la tabla de detalle.
Solución rápida
Borre primero los registros hijos en la tabla de detalle, y luego borre todo el
contenido de la tabla maestra.
Información adicional
Consulte “Master has detail records. Cannot delete or modify”.
Solución rápida
Si está introduciendo registros en la tabla de detalle (y no en la tabla maestra),
debe asegurarse de seleccionar un valor que exista en la clave primaria de la
tabla maestra utilizando un control TDBLookupComboBox conectado al campo
de clave primaria de la tabla maestra.
Si está introduciendo simultáneamente registros tanto en la tabla maestra
como en la de detalle, asegúrese de que está grabando primero el registro
maestro utilizando el evento BeforeInsert del componente TTable que repre-
senta a la tabla de detalle, así:
procedure TOrderForm.TblDetailBeforeInsert(DataSet: TDataset);
begin
if TblMaster.State = dsInsert then
begin
TblMaster.Post;
TblMaster.Edit;
end;
end;
Información adicional
Para más información, consulte “master tables” en la ayuda de Delphi.
Solución rápida
Incremente el valor de MaxValue en el Database Desktop o asigne un valor
menor o igual que el parámetro configurado al campo. Alternativamente, puede
asignar un valor a la propiedad MaxValue del objeto TField dentro del entorno
integrado de Delphi.
Información adicional
Configurar la propiedad MaxValue dentro del entorno integrado de Delphi oca-
sionará un mensaje más informativo si posteriormente asigna un valor dema-
siado grande: “<> is not a valid value for field <>. The allowed range is
<> to <>”.
Para más información, consulte “MaxValue” en la ayuda de Delphi.
Solución rápida
Descargue el último parche/actualización para MS SQL Server.
Información adicional
Una solución que ha sido sugerida es asignar 1 al parámetro Drivers Flag en
la utilidad BDE Configuration (Drivers | MS SQL | Drivers Flag).
Solución rápida
Asegúrese que cualquier archivo que intente cargar en la propiedad Picture de
un componente TImage sea un archivo gráfico válido.
Información adicional
Delphi proporciona soporte para cuatro formatos gráficos, denominados .BMP
(mapas de bits), .ICO (iconos), .WMF (Windows Metafile), y .EMF (Enhanced
Metafile).
Puede ser que la extensión del archivo fuera cambiada de tal forma que parece
un metaarchivo por su extensión (pero no lo es realmente).
Consulte “Unknown picture file extension: <>”.
Solución rápida
1,2. Añada la directiva Override a un método virtual redefinido una clase
descendiente, así:
type
. . .
Mensajes de error 373
public
constructor Create(AOwner: TComponent); override;
Después, utilice la palabra reservada Inherited para implementar la fun-
cionalidad de la clase ancestro antes de añadir la nueva funcionalidad.
constructor TForTwo.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FGuest := 'Tillerman';
. . .
Información adicional
Puede promover un método o propiedad heredado redeclarándolo en la sección
en la que quiere que aparezca en la clase descendiente. Cuando promueva una
propiedad heredada de una clase ancestro, no necesita especificar el tipo de
propiedad o los métodos de escritura y lectura — simplemente proporcione el
nombre de la propiedad en la sección Public o Published, así:
published
property OfAlcatraz;
Solución rápida
Asegúrese de que cualquier método que intente redefinir exista en la clase
ancestro. Si no existe, elimine la directiva Override.
Información adicional
Para más información, consulte “virtual methods” en la ayuda de Delphi.
ExcelObj := CreateOLEObject('Excel.Application');
. . .
ExcelObj.SaveAll;
//error: method SaveAll not supported by automation object
Solución rápida
Asegúrese de que cualquier método al que llame esté realmente implementado
por el objeto OLE que usted ha instanciado. Puede importar la biblioteca de
tipos (lo que en el caso de Excel producirá el archivo Excel_TLB.PAS) y ver qué
métodos contiene. Para importar la biblioteca de tipos, siga estos pasos:
1. Localice el archivo .OLB (Object LiBrary) (o el archivo *.TLB, *.OCX,
*.DLL, o *.EXE) que desea importar.
2. Seleccione Project | Import Type Library.
3. Pulse el botón Add, navegue hasta el directorio apropiado, y seleccione el
archivo.
4. Seleccione Install para instalarlo dentro de un paquete o Create Unit
para crear una unidad y añadirla al proyecto actual.
Información adicional
Si utiliza enlace temprano (early binding), el compilador puede capturar estos
tipos de errores. Si utiliza enlace tardío (late binding), no notará el problema
hasta que el código sea llamado en tiempo de ejecución. Si importa la biblioteca
de tipos del objeto OLE, puede utilizar el archivo .PAS creado (enlace tem-
prano). Delphi 5 y superiores proporcionan muchos servidores OLE en la
página Servers de la Paleta de Componentes. Puede también evaluar la suite
de componentes para Microsoft Office OfficePartner, distribuida por Danysoft.
Solución rápida
Asegúrese de que cualquier método que intente sobrecargar difiera en cuanto a
signatura de los demás métodos a los que también ha asociado la directiva
Overload. Por ejemplo, en el caso de arriba puede hacer algo así:
Mensajes de error 375
Información adicional
Note que no es válido añadir la directiva Override a más de uno de los métodos
sobrecargados, ya que el método redefinido puede solamente compartir una
lista de parámetros idénticos con sólo uno de los métodos sobrecargados que se
declaren. Si se hubiera añadido la directiva Override a ambos métodos, se
obtendría el mensaje de error “Declaration of <> differs from previous
declaration”.
except
SelectAll;
SetFocus;
raise;
end;
inherited; //aquí está el problema
end;
Solución rápida
1. Borre la ‘T’ del nombre del tipo. Por ejemplo, esto compilaría bien (asu-
miendo que la variable de formulario es Form1):
procedure loopdeloop;
begin
Form1.Label1.Caption := IntToStr(SizeOf(Byte));
end;
2. Las propiedades en las secciones Automated deben hacer referencia a
métodos, y no a campos, en sus cláusulas Read y Write.
3. Añada el nombre del método a la llamada, así:
procedure TascY2KDBComboBox.DoExit;
begin
try
if length(Self.Text)<10 then
begin
SelectAll;
SetFocus;
raise EFullDateNotSupplied.Create(SEnterAFourDigitYear);
end;
except
SelectAll;
SetFocus;
raise;
end;
inherited DoExit;
end;
Información adicional
Para más información, consulte “object-oriented programming | programming
with Delphi objects” en la ayuda de Delphi.
type
IDelawareIgnoresSourPatch = dispinterface
['{00000000-0000-0000-0000-000000000000}']
procedure RoverDover; register;
end;
Solución rápida
Elimine la directiva.
Información adicional
Este elemento de menú está disponible solamente en Delphi 4. Está deshabili-
tado, a menos que haya añadido un Módulo de Datos MTS a su proyecto. Pre-
sumiblemente, usted no seleccionará el elemento de menú Run | Install MTS
Objects. . . a menos que haya instalado MTS. En otras palabras, probable-
mente sólo obtendrá este mensaje de error si está haciendo experimentos.
Solución rápida
Disminuya el valor del parámetro MinValue en el Database Desktop, o asigne
un valor mayor o igual que el parámetro MinValue al campo. Alternativa-
mente, puede asignar un valor a la propiedad MinValue de un objeto TField en
el entorno integrado de Delphi.
Información adicional
Configurar la propiedad MinValue en el entorno integrado de Delphi producirá
un mensaje de error más informativo si posteriormente se asigna un valor
menor que el mínimo: “<> is not a valid value for field <>. The allowed
range is <> to <>”.
Para más información, consulte “MinValue” en la ayuda de Delphi.
378 Los Tomos de Delphi: Delphi sin problemas
Mismatch in datapacket
Posible causa de error
Puede estar intentando leer de un flujo (stream) sin haberse posicionado al ini-
cio antes de leer. Por ejemplo, lo siguiente generará este mensaje de error:
var
Consciousness: TMemoryStream;
begin
Consciousness := TMemoryStream.Create;
try
ClientDataSet1.SaveToStream(Consciousness);
ClientDataSet1.LoadFromStream(Consciousness);
finally
Consciousness.Free;
end;
end;
Solución rápida
Asigne 0 a la posición actual del flujo antes de intentar leer de él:
var
Consciousness: TMemoryStream;
begin
Consciousness:= TMemoryStream.Create;
try
ClientDataSet1.SaveToStream(Consciousness);
Consciousness.Position := 0; { añada esta línea }
ClientDataSet1.LoadFromStream(Consciousness);
finally
Consciousness.Free;
end;
end;
Información adicional
Consulte “TClientDataset” en la ayuda de Delphi para información relacionada
sobre el almacenamiento de datos en memoria.
Missing comma
Posible causa de error
Puede estar utilizando Delphi 1 y haber proporcionado varios parámetros a la
propiedad SQL de un TQuery.
Mensajes de error 379
Solución rápida
Obtenga el parche 1.02 de Delphi 1 del sitio Web de Borland.
Información adicional
Aplique siempre la última versión de los parches de Delphi y del BDE (así
como de la base de datos de servidor SQL, si puede) para un mejor
funcionamiento.
Para más información, consulte “queries” en la ayuda de Delphi.
Solución rápida
1,2. Conecte el componente TADOQuery o TADODataset a un componente
TADOConnection a través de su propiedad Connection, así:
Connection := ADOConnection1;
Información adicional
Alternativamente, puede especificar una cadena de conexión para el compo-
nente TADOQuery o TADODataSet. Si lo hace, pulse sobre el botón … a la
derecha de la propiedad ConnectionString para desplegar su editor de propie-
dades. Es preferible utilizar un componente TADOConnection para toda la
380 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Proporcione un componente TProvider en la propiedad ProviderName del
componente TClientDataSet.
2. Proporcione código que valide y responda a la posibilidad de no obtener
datos del servidor de aplicación. Por ejemplo, podría intentar algo como lo
siguiente:
if ClientDataSet1.RecordCount = 0 then
{ ... }
if ClientDataSet1.IsEmpty then
{ ... }
if (cds.BOF) and (cds.BOF) then
{ ... }
3. Asigne un archivo .CDS (binario) o .XML a la propiedad FileName del com-
ponente ClientDataSet.
4. No se puede utilizar SQL sobre conjuntos locales (de una capa), que son
almacenados en disco en lugar de una base de datos. O sea, la propiedad
CommandText no está disponible en este contexto. Para insertar, actuali-
zar y borrar datos, puede utilizar los métodos InsertRecord y Delete de
Mensajes de error 381
Información adicional
2. Para más información, consulte “RecordCount”, “BOF”, “EOF” y “IsEmpty”
en la ayuda de Delphi.
3. Vea los métodos SaveToFile y SaveToStream de TClientDataSet, los cuales
(a partir de Delphi 6) tienen un segundo parámetro, que puede ser dfBi-
nary, dfXML o dfXMLUTF8.
Solución rápida
Asegúrese de que cada sentencia {$IFDEF} tenga un sentencia {$ENDIF}
correspondiente.
Información adicional
Consulte “Invalid compiler directive: <>”.
Solución rápida
1. Siempre añada un punto y coma al final de cada línea, a menos que esté
partiendo una sentencia If en muchas líneas.
2. Añada el operador o palabra reservada que falta (Do en este caso):
with Table1 do
begin
3. Si tiene una cadena dividida a lo largo de varias líneas, concaténelas utili-
zando el operador de concatenación (+).
4. Borre la comilla simple sobrante.
5. Cualifique la llamada, anteponiendo el nombre de la unidad en la que el
procedimiento que quiere utilizar está declarado. Por ejemplo, para resol-
ver la situación antes descrita, utilice System.Delete. Alternativamente,
mueva la unidad que contiene el identificador al que quiere acceder para
que quede detrás de la unidad que contiene un identificador con el mismo
nombre en la cláusula Uses. Por ejemplo, si está intentando utilizar el pro-
cedimiento DeleteFile de la unidad SysUtils, sitúe esa unidad detrás de la
unidad Windows en la cláusula Uses, ya que la unidad Windows en Delphi
de 32 bits también contiene un procedimiento DeleteFile.
Información adicional
1. Note que es necesario añadir un punto y coma al final de cada sentencia.
Normalmente, es lo mismo que añadir un punto y coma al final de cada
línea; sin embargo, esto no es siempre cierto. Una sentencia If, por ejemplo,
puede extenderse a lo largo de varias líneas. Debe esperar hasta el final de
la sentencia para añadir un punto y coma.
3. Esta es la forma de concatenar una cadena en varias líneas (no añadir el
operador de concatenación (+) genera el mensaje de error bajo discusión):
s := 'What would you rather eat: the fat from '
+ 'Behind a caribou’‘s eyeball or a frosted '
+ 'portart. (McFee)';
Puede también concatenar las cadenas en la misma línea y mostrarlas en
múltiples líneas, o concatenar valores de propiedades con cadenas
Mensajes de error 383
Solución rápida
Debe especificar qué símbolo está verificando, definiendo o indefiniendo, así:
uses
Windows, Messages, SysUtils, Classes,
Graphics, {$IFDEF WIN32} Registry, {$ELSE}
IniFiles, {$ENDIF}
Información adicional
Para más información, consulte “conditional directives” en la ayuda de Delphi.
Solución rápida
Debe especificar el tipo de datos cuando declare procedimientos o funciones que
acepten parámetros por valor. Por ejemplo, para solucionar la declaración de
arriba, podría hacer esto:
procedure fudgsicle(a: byte);
Información adicional
Puede declarar procedimientos y funciones que acepten parámetros variables
(Var) o constantes (Const) sin especificar los tipos de datos. Las siguientes dos
declaraciones son legales:
procedure fudgsicle2(var a);
procedure fudgsicle3(const a);
Solución rápida
Borre el apóstrofe solitario o añádale su pareja.
Información adicional
Consulte “QuotedStr” en la ayuda de Delphi.
Solución rápida
1. Seleccione uno de los alias del BDE que han sido creados en su sistema de
la lista desplegable de la propiedad DatabaseName.
Alternativamente, proporcione la ruta completa del directorio en el que las
tablas residen. Por ejemplo, en una instalación por defecto de Delphi,
podría asignar el alias DBDEMOS, seleccionándolo de la lista desplegable,
o introducir directamente una ruta como: C:\Archivos de programa\Bor-
land\Delphi X\Demos\Data.
2,3. Seleccione una tabla del cuadro de combinación que ofrece la propiedad
TableName del componente TTable y luego reintente la operación. Si no
aparece ninguna tabla en la lista, primero tendrá que asignar la propiedad
DatabaseName. Para hacer esto, seleccione un alias del cuadro de combina-
ción de la propiedad DatabaseName o introduzca la ruta (si utiliza tablas
locales en lugar de tablas SQL). Ahora tendrá una lista de las tablas que
pertenecen al alias (o están situadas en el directorio indicado). Seleccione
una de ellas.
Información adicional
Puede configurar la propiedad DatabaseName para que busque en las tablas
situadas en el mismo directorio donde reside el ejecutable introduciendo “/.”
(una barra seguida de un punto) como valor de la propiedad DatabaseName.
Esto es un compromiso entre utilizar un alias y una ruta indicada explícita-
mente. No es tan rígido como una ruta fija, ni tan flexible como un alias.
Solución rápida
1. Cierre todas las instancias innecesarias de Delphi.
2. Si era su intención hacerlo (grabar una versión diferente del archivo), pulse
el botón Yes para desechar el diálogo y reemplazar el archivo existente por
el que se ha marcado.
386 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Podría ver este mensaje de error si selecciona varios archivos de Delphi en el
Explorador y luego accidentalmente pulsa dos veces sucesivamente sobre uno
de ellos. Esto ejecuta una acción de doble clic sobre todos los archivos seleccio-
nados, y una instancia de Delphi es iniciada para cada archivo individual. Si
esto ocurre, puede obtener este mensaje de error “One or more lines were
too long and have been truncated”.
Solución rápida
1. Cambie el nombre del archivo de nuevo a su nombre original, o cámbielo en
el entorno integrado al nombre que le asignó fuera.
2. Reincorpore la cláusula Uses e incluya al menos una unidad en ella.
3. Borre los archivos .DSK y/o .DOF, ya que pueden hacer referencia a archi-
vos en el directorio anterior.
Información adicional
1. Si cambia un nombre de unidad fuera de Delphi, este cambio no es automá-
ticamente transmitido al resto del proyecto, que lo conoce por el nombre
anterior. Por lo tanto, no haga esto.
2. Puede incluir una unidad pequeña para satisfacer la necesidad de utilizar
al menos una unidad. Podría crear una unidad falsa que simplemente con-
tenga lo mínimo indispensable para ser sintácticamente correcta, pero que
no proporcione ninguna funcionalidad. Por ejemplo, si simplemente añade
una unidad a su proyecto, éste se verá así:
unit Unit2;
interface
implementation
end.
Puede entonces cambiar su nombre a “Whatever” (o el nombre que desee) y
utilizarla en la otra unidad.
Mensajes de error 387
Solución rápida
1. Configure cada máquina de usuario de tal manera que todas utilicen el
mismo archivo de control de red (PDOXUSRS.NET). Puede hacer esto
siguiendo los pasos apropiados según la versión de Delphi que tenga:
Delphi 1
Si cada usuario tiene su propia copia de BDE en su máquina, puede utilizar la
utilidad BDE Configuration para asignar el directorio del archivo de control de
red. Para hacer esto, siga estos pasos:
a. Abra la utilidad de configuración de BDE.
b. Con la entrada Paradox seleccionada en el cuadro de lista Driver
Name, introduzca la ruta completa del directorio de red compartido en
donde se almacena el archivo de control de red (PDOXUSRS.NET) en
el parámetro NET DIR.
c. Seleccione File | Exit para grabar los cambios.
Si algún usuario no tiene una copia de la utilidad BDE Configuration, asegú-
rese de que la ubicación actual del archivo IDAPI.CFG (C:\IDAPI por defecto)
coincide con la que está almacenada para la entrada CONFIGFILE01 en la
sección [IDAPI] de WIN.INI.
Si es necesario, mueva el archivo para que cumpla con lo indicado en la
entrada de WIN.INI, o modifique la entrada en WIN.INI para que apunte a la
ubicación actual del archivo.
Delphi 2
Si cada usuario tiene su propia copia del BDE, puede utilizar la utilidad BDE
Configuration para asignar el directorio del archivo de control de red de Para-
dox. Para hacer esto, siga estos pasos:
388 Los Tomos de Delphi: Delphi sin problemas
Delphi 3 y 4
Si cada usuario tiene su propia copia del BDE, puede utilizar la utilidad BDE
Administrator para asignar el directorio del archivo de control de red de Para-
dox. Para hacer esto, siga estos pasos:
a. Abra la utilidad de configuración del BDE (Inicio | Programas |
Borland Delphi X | BDE [Configuration, Administration]).
b. Seleccione Object | Open Configuration. . . .
c. Abra IDAPI32.CFG.
d. Navegue hasta Configuration\Drivers\Native\Paradox en la vista de
árbol en la parte Configuration, en el panel izquierdo del BDE
Administrator.
e. Introduzca la ruta completa del directorio en donde quiere que resida el
archivo de control de red. Seleccione un directorio de red compartido
para el que todos los usuarios de las tablas Paradox tengan derechos de
lectura, escritura y borrado.
f. Seleccione Object | Exit y luego Yes para grabar los cambios
realizados.
Delphi de 32 bits
Si algún usuario no tiene una copia de la utilidad BDE Configuration/Adminis-
tration, puede consultar su configuración del Registro de Windows para asegu-
rarse de que la ubicación física real de IDAPI32.CFG (por defecto C:\Archivos
de programa\Borland\Common files\BDE) coincide con la que se indica en el
Registro.
Si es necesario, mueva el archivo para que su localización sea igual a la indi-
cada en la entrada del Registro, o modifique la entrada en el Registro para que
coincida con la ubicación del archivo.
2. Asegúrese que ningún usuario esté conectado a las tablas del directorio en
el que el archivo .LCK está ubicado, y bórrelo.
3. Verifique que no haya usuarios del BDE sobre la red utilizando las tablas y
luego borre los archivos PDOXUSRS.NET y/o PDOXUSRS.LCK dañados.
Los archivos serán regenerados automáticamente cuando se necesiten.
Mensajes de error 389
Información adicional
1. Esto puede suceder cuando se pone una base de datos a disposición de múl-
tiples usuarios que antes solamente accedían a tablas de BDE locales (en
su disco duro). En este caso, el parámetro NET DIR de cada usuario podría
estar apuntando a su propio directorio raíz (C:\). Esto resultaría en lo
siguiente:
a. El primer usuario accedió a las tablas, y proporcionó su propia unidad
de disco duro como directorio NetDir. Ningún problema.
b. El segundo usuario intenta acceder a las tablas, y también proporciona
su propia unidad de disco duro como directorio NetDir. Hay dos
archivos diferentes PDOXUSRS.NET intentando controlar el acceso a
las tablas, y el mensaje de error bajo discusión es generado.
3. Los archivos PDOXUSR.NET y PDOXUSRS.LCK pueden dañarse si un
programa que utiliza el BDE termina anormalmente (como en el caso de
una caída del sistema).
El BDE puede detectar si las tablas están en una unidad de red, pero no puede
detectar si las tablas están en una máquina que sirve como servidor dedicado o
si la máquina es un cliente a la vez que un servidor (en otras palabras, es un
‘punto’ de una red punto-a-punto).
Los servidores dedicados notifican a las aplicaciones cliente cuando un archivo
es bloqueado o ha sido modificado. Las redes punto-a-punto no ofrecen normal-
mente esta funcionalidad (incluso una máquina servidora en una red
punto-a-punto no es un servidor dedicado verdadero). Para lograr este tipo de
funcionalidad en una red de punto-a-punto, asigne el valor True a Local Share
con la utilidad BDE Configuration (página/nodo System) en todas las máquinas
clientes que acceden a las tablas.
Para más información, consulte “Directory is controlled by other .NET
file”.
Solución rápida
Si las actualizaciones están pendientes, no hay nada que refrescar. Llame a
ApplyUpdates y luego, si es necesario, a Refresh.
Información adicional
Consulte “TClientDataSet’s UpdateStatus property” y “SavePoint methods” en
la ayuda de Delphi.
Name conflicting
Posible causa de error
Puede estar conectándose a un servidor DCOM de múltiples instancias y uti-
lizando un componente TDatabase cuya propiedad HandleShared tiene el valor
False.
Solución rápida
Asigne True a la propiedad HandleShared del componente TDatabase.
Información adicional
Para más información, consulte “COM” en la ayuda de Delphi.
Solución rápida
Asigne True a la propiedad HandleShared del componente TDatabase.
Información adicional
HandleShared es una propiedad de tipo Boolean que indica si un componente
TDatabase puede compartir su manejador (handle) de BDE en una sesión.
Configurando HandleShared a True, evita conflictos de espacios de nombres.
Hay dos situaciones donde esto es potencialmente un problema:
El componente TDatabase está situado en un módulo de datos remoto.
El componente TDatabase está situado en un módulo de datos que ha
heredado del Almacén de Objetos.
Mensajes de error 391
Solución rápida
Añada el argumento que indica el tamaño a SetLength, así:
procedure ShortestProcedureNameKnownToWesternCivilization;
var
ABunchOfIntegers: array of integer;
begin
SetLength(ABunchOfIntegers, 52);
end.
Información adicional
Para más información, consulte “SetLength” en la ayuda de Delphi.
Solución rápida
Recompile manualmente el paquete al que se hace referencia en el mensaje.
392 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Para más información, consulte “packages” en la ayuda de Delphi.
Solución rápida
Cambie la directiva de no construir en el paquete que requiere o la directiva de
construir siempre en el paquete requerido.
Información adicional
Ya que la interfaz de un paquete “construir siempre” puede cambiar en cual-
quier momento, y puesto que la bandera de “no construir” indica al compilador
que asuma que el paquete está totalmente actualizado, cada paquete de tipo
“no construir” puede solamente requerir otro paquete que también esté mar-
cado como “no construir”. Para más información, consulte “weak packaging” y
“implicit build” en la ayuda de Delphi.
Solución rápida
Utilice SetLength en lugar de New:
procedure Newby;
var
ArrayOfScores: array of integer;
begin
SetLength(ArrayOfScores, StrToInt(edtNumberOfGames));
Mensajes de error 393
end.
Información adicional
Para más información, consulte “SetLength” en la ayuda de Delphi.
No address specified
Posible causa de error
Puede haber intentado asignar True a la propiedad Connected de un objeto
TSocketConnection sin haber proporcionado un valor para la propiedad
Address.
Solución rápida
Especifique la dirección apropiada en la notación de punto estándar de Inter-
net (cuatro valores de un byte). Puede proporcionar el valor en el Inspector de
Objetos o en el código; por ejemplo, proporcione la dirección en el código:
SocketConnection1.Address := ‘131.228.6.1’;
Información adicional
La propiedad Address de TSocketConnection se refiere a la dirección IP del
servidor en el que el objeto DCOM reside. Si no sabe la dirección, puede pro-
porcionar el nombre del servidor en la propiedad Host. Esto, sin embargo, es
más lento que configurar directamente la propiedad Address, ya que la direc-
ción del servidor deberá ser buscada.
Solución rápida
Proporcione un argumento para cada especificador de formato que utilice. Por
ejemplo, para solucionar el ejemplo de arriba, hágalo de esta manera:
394 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Para más información, consulte “Format function”, “format specifier”, y “format
strings” en la ayuda de Delphi.
Solución rápida
1,2. Borre el punto de ruptura (breakpoint). Si lo desea, coloque el cursor sobre
una línea de código en el proyecto actual que genere código, como una sen-
tencia de asignación dentro de un procedimiento o función que sea llamada
en el proyecto.
3. Añada la unidad a la cláusula Uses de al menos una de las unidades que
son parte del proyecto. Para añadir una unidad que exista en otra ubica-
ción/directorio al proyecto, seleccione Project | Add to Project. . . ,
navegue hasta la unidad, selecciónela y pulse el botón Open.
Mensajes de error 395
Información adicional
2. El enlazador inteligente de Delphi elimina los procedimientos que no son
utilizados por el programa (a menos que sean métodos virtuales de un
objeto que es enlazado).
3,4. Para más información, consulte “Project Manager” en la ayuda de Delphi.
Solución rápida
Asigne una base de datos por defecto al componente TIBTransaction antes de
llamar a cualquiera de sus métodos, así:
IBTrans.DefaultDatabase := dm.IBDB;
IBTrans.StartTransaction;
Información adicional
En el código de arriba, IBTrans es un componente IBTransaction al que se le
ha asignado en su propiedad DefaultDatabase un componente TIBDatabase
denominado IBDB que reside sobre un módulo de datos llamado dm.
TIBTransaction y TIBDatabase son componentes IBX que aparecen en la
página Interbase de la Paleta de Componentes y son utilizados en las aplicacio-
nes que acceden a la información almacenada en bases de datos InterBase (sin
necesidad del BDE). A partir de Delphi 6, también se tiene la opción de utilizar
los componentes DBExpress para acceder a InterBase sin necesidad del BDE.
Solución rápida
Borre la definición de la función o la directiva Abstract de la declaración del
método.
Información adicional
No se puede definir un método abstracto en la misma clase donde ha sido defi-
nido. Abstracto significa que debe ser redefinido. Ya que debe ser redefinido,
no puede haber una implementación en la clase base de un método abstracto
para que un descendiente la herede.
Solución rápida
Especifique qué campos quiere que el conjunto de datos contenga antes de
intentar crearlo. Por ejemplo, puede seguir el patrón mostrado en el fragmento
de código de abajo para definir los campos y luego crear el conjunto de datos a
partir de esos campos. Un conjunto de datos vacío será entonces creado
exitosamente.
with ClientDataSet1 do
begin
with FieldDefs.AddFieldDef do
begin
DataType := ftString;
Size := 58;
Name := 'CaptainHumboldtEpisode';
end;
with FieldDefs.AddFieldDef do
begin
DataType := ftInteger;
Name := 'CaptPabstBarrels';
Mensajes de error 397
end;
with IndexDefs.AddIndexDef do
begin
Fields := 'CaptainHumboldtEpisode';
Name := 'CaptainHumboldtEpisodeIndex';
end;
CreateDataSet;
end;
Información adicional
Como se puede ver en el ejemplo de arriba, puede también añadir definiciones
de índices al conjunto de datos.
Anteriormente el descendiente TDataset “olvidado”, TClientDataSet es induda-
blemente (a partir de Delphi 6) el más importante de todos.
No frames in project
Posible causa de error
Puede haber intentado colocar un componente TFrame sobre un formulario
antes de crear un marco para el proyecto.
Solución rápida
Seleccione File | New Frame, y añada los componentes que quiere utilizar.
Después podrá soltar un componente TFrame sobre el formulario.
Información adicional
Cuando coloque un componente TFrame sobre un formulario (asumiendo que el
proyecto tenía al menos un marco creado), el diálogo Select Frame to Insert
aparecerá, mostrando una lista de los marcos disponibles.
Solución rápida
Asigne un valor apropiado a la propiedad IndexName o IndexFieldNames del
conjunto.
398 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Si está creando un conjunto de datos mediante programación, utilice el método
AddIndexDef.
Solución rápida
1. Asigne a la propiedad FormStyle del formulario principal el valor
fsMDIForm.
2. Permita que Delphi cree automáticamente el formulario principal. Este
debe ser creado antes que los formularios hijos.
Información adicional
Los programas de Interfaz de Múltiples Documentos (MDI) son considerados
pasados de moda en Windows de 32 bits. Por supuesto, no hay ninguna ley en
contra de lo pasado de moda.
Solución rápida
Verifique que los tipos de datos utilizados cuando se hace una llamada a un
método sobrecargado correspondan a alguna de las signaturas del método.
Información adicional
Puede declarar cualquier número de métodos sobrecargados, siempre que todos
tengan signaturas únicas. Por supuesto, pueden tener cantidades diferentes de
parámetros, así:
function BTOSong(AName: String): Integer; overload;
function BTOSong (ALengthInSeconds: Integer): String; overload;
function BTOSong(AName: String; ALength: Integer): Boolean;
overload;
function BTOSong (AName: String; ALength: Double): Boolean;
overload;
No Provider Available
Posible causa de error
Puede haber asignado la propiedad Data de una propiedad Provider de un
TDataSet a la propiedad Data de un TClientDataSet sin añadir BDEProv a la
sección Uses. Por ejemplo, lo siguiente generará este mensaje de error (si
BDEProv no está en la sección Uses):
procedure TForm1.FormCreate(Sender: TObject);
begin
ClientDataSet1.Data := Table1.Provider.Data;
end;
Solución rápida
Añada BDEProv a la sección Uses.
Información adicional
Los proveedores son asociados generalmente con MIDAS y aparecieron con
Delphi 3. Si está utilizando Delphi 3, asegúrese que tenga la última actualiza-
ción y/o parche para una funcionalidad plena y un mejor rendimiento. En par-
ticular y entre otras cosas, el archivo DBClient.DLL fue actualizado y
mejorado a partir de su versión 3.0.
400 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Borre la llamada a Prepare o asigne una sentencia SQL al componente
TQuery en tiempo de diseño o en el código antes de llamar a Prepare.
2. Asigne una sentencia SQL válida a la propiedad SQL del componente
TQuery antes de intentar crear los campos en tiempo de diseño.
3. Asegúrese que solamente llama al método ExecSQL de TQuery cuando la
propiedad SQL no está vacía. Por ejemplo, podría verificar esta condición
con el siguiente código:
procedure TForm1.ExecuteAndClearClick(Sender: TObject);
begin
with Query1 do begin
if SQL.Count <> 0 then begin
ExecSQL;
SQL.Clear;
end;
end;
end;
4. Proporcione una sentencia SQL, en el entorno integrado o en el código,
para la propiedad SQL del objeto TDecisionQuery.
5. Asigne una sentencia SQL a la propiedad SQL, en tiempo de diseño en el
Inspector de Objetos o en tiempo de ejecución, antes de activar el compo-
nente TSQLQuery.
Información adicional
1. Para añadir una sentencia SQL a un componente TQuery en el código, siga
este ejemplo:
Mensajes de error 401
with Query1 do
begin
SQL.Add('Select * from RoundTablePizza');
SQL.Add('Where Kind = ‘'ItalianGarlic'’');
Prepare; {opcional}
Open;
end;
Puede partir la sentencia SQL en tantas líneas como desee. Es recomenda-
ble separar la sentencia en las partes lógicas que la constituyen.
2. Las ventajas de crear instancias de los campos para un componente
TQuery son (a) que tiene acceso a las propiedades de los campos (inclu-
yendo los gestores de eventos, como OnValidate) en tiempo de diseño, y (b)
que puede crear campos calculados utilizando el Editor de Campos. Para
más información sobre la creación de campos calculados, consulte “New
Field dialog box” en la ayuda de Delphi.
Solución rápida
Llame a StartTransaction antes de intentar confirmar las operaciones hechas
durante la transacción.
Información adicional
Con la utilización de un componente TDatabase, puede agrupar un conjunto de
operaciones sobre una base de datos en una transacción, y luego confirmarlas o
rechazarlas como un todo. Inicie una transacción mediante StartTransaction y
luego llame a Commit o Rollback en dependencia de si quiere conservar o des-
cartar los cambios o adiciones que realizó durante la transacción.
He aquí un ejemplo sencillo de la utilización de transacciones en bases de
datos:
begin
with Database1 do begin
StartTransaction;
try
{ Hacer algo aquí }
if { condición } then
Commit;
else
402 Los Tomos de Delphi: Delphi sin problemas
Rollback;
except
Rollback;
end; {bloque except}
end; {bloque with}
end;
Solución rápida
Instale un navegador de Intenet. No lo mueva o borre del directorio en el que
está instalado.
Información adicional
En algunas versiones de Delphi, Microsoft Internet Explorer es proporcionado
en el CD de Delphi. Si no tiene un navegador y quiere uno, esta es una opción.
El navegador de Netscape es otra opción atractiva. Adicionalmente, están dis-
ponibles otros navegadores, tanto comerciales como freeware. Además, usted
podría crear su propio navegador utilizando Delphi.
Solución rápida
La cláusula Nodefault no es permitida en una sección Automated. Elimínela.
Información adicional
Delphi 2 y posteriores tienen cinco directivas de visibilidad: Private, Protected,
Public, Published y Automated (la directiva Automated no estaba disponible en
Delphi 1). A las propiedades de una clase se pueden asociar las cláusulas
Mensajes de error 403
Solución rápida
1. Proporcione los parámetros que faltan. Por ejemplo, para solucionar el pro-
blema de arriba, añada el parámetro final, así:
{Debe proporcionar el parámetro,
aunque no haya un tema de ayuda}
MessageDlg('Eat at Joe''s’, mtCustom, [mbOK], 0);
{Si hay un ID de contexto de ayuda, por ejemplo #11,
podría hacer esto:}
404 Los Tomos de Delphi: Delphi sin problemas
Información adicional
1. Seleccione el nombre de la función en el código y pulse <F1> para ver la
ayuda (en la que podrá averiguar la cantidad, tipos y orden de los paráme-
tros esperados).
2. El constructor de TObject no tiene parámetros. Sin embargo, el constructor
de TComponent sí tiene un parámetro. Vea la declaración de TObject en la
unidad System y la declaración de TComponent en la unidad Classes para
los detalles más específicos.
Solución rápida
Incremente el parámetro Files en el archivo CONFIG.SYS. Increméntelo a un
número entre su valor actual y 255.
Incrementar el parámetro MaxFileHandles en el nodo/página System de la uti-
lidad BDE Configuration a un número un poco menor del que asignó en Files
en el archivo CONFIG.SYS .
Mensajes de error 405
Información adicional
Las tablas Paradox constan de varios archivos relacionados, como .DB, .MB,
.PX, .Xnn, .Ynn, etc. Varios de estos archivos puede estar abiertos simultánea-
mente, y cada uno necesita su propio manejador.
Solución rápida
Reconstruya la tabla utilizando TUtility.
Información adicional
Si no tiene la utilidad TUtility, puede obtenerla en:
http://www.borland.com/devsupport/bde/files/tutil32d.zip
Solución rápida
Asigne True a la propiedad CachedUpdates del conjunto de datos antes de
intentar acceder a la propiedad OldValue de un registro.
Información adicional
Puede asegurarse mediante programación de que CachedUpdates tiene el valor
True de esta manera:
if Table1.CachedUpdates = True then
ClassicVal := OldValue;
Solución rápida
1. Asigne al parámetro NetDir en la sección Drivers | Paradox de la utilidad
BDE Configuration un directorio de red compartido sobre el que todos los
usuarios que accederán a las tablas tengan derechos de lectura, escritura y
creación.
2. Siga las instrucciones específicas para su versión de Delphi:
Delphi 1
Compruebe que la línea CONFIGFILE01= de la sección [IDAPI] del archivo
WIN.INI apunte a la ubicación correcta. Por ejemplo, si el archivo de configu-
ración del BDE IDAPI.CFG está ubicado en C:\IDAPI (el valor por defecto), la
sección se leería:
[IDAPI]
ConfigFile01=C:\IDAPI
Delphi de 32 bits
Verifique que la ubicación de IDAPI32.CFG (por defecto C:\Archivos de pro-
grama\Borland\Common files\BDE) coincida con la que se indica en el Regis-
tro del sistema.
Si es necesario, mueva el archivo para que su ubicación coincida con lo indi-
cado por la entrada del Registro, o modifique la entrada del Registro para que
apunte a la ubicación actual del archivo.
Información adicional
El directorio de red contiene el archivo PDOXUSRS.NET, que controla el
acceso a las tablas y administra los bloqueos.
Mensajes de error 407
Solución rápida
1. Solamente puede tener un índice primario por tabla. Puede añadir índices
secundarios en el código a las tablas dBASE y Paradox 7, pero no a las
tablas Paradox 3.5, 4 ó 5.
2. Utilice como índice primario solamente el primer campo de la tabla. En el
caso de un índice/clave primaria compuesta, los campos deben ser los pri-
meros de la tabla (consecutivos, empezando por el primer campo).
Información adicional
Este es un error de tipo EDatabaseEngine. Si una tabla ya tiene una clave pri-
maria (requerida para una tabla Paradox), lo siguiente producirá este mensaje
de error:
Table1.AddIndex('P2','RedGreenBlue',[ixPrimary]);
Si está utilizando una tabla de Paradox 7, puede, sin embargo, crear índices
únicos adicionales, así:
Table1.AddIndex('U2','IrishRockers',[ixUnique]);
const
LeadingLeadingMen: array[0..4] of string =
('Brando','Bogart','DeNiro','Duvall');
{ Demasiados elementos proporcionados }
const
LeadingLeadingMen: array[0..4] of string =
('Brando', 'Bogart', 'DeNiro', 'Duvall', 'Peck', 'Sinise');
Solución rápida
Cambie el tamaño del array que está declarando, o añada o elimine la cantidad
necesaria de elementos.
Información adicional
Para más información, consulte “arrays” en la ayuda de Delphi.
Solución rápida
Registre la biblioteca de tipos de Webbrokerscript. Detenga y reinicie
SRVINFO.EXE.
Información adicional
Puede registrar WEBBROKERSCRIPT.TLB seleccionando la opción Inicio |
Ejecutar de Windows y luego introduciendo el comado tregsvr
WEBBROKERSCRIPT.TLB.
Site Express apareció por primera vez con Delphi 6.
var
s: String;
tnwdp: TNumberWithoutDecimalPoints;
begin
tnwdp := 8;
s := TNumberWithoutDecimalPoints.AsString;
Solución rápida
Sustituya el tipo problemático por un objeto o tipo de clase.
Información adicional
Para más información, consulte “objects”, “classes”, y “types” en la ayuda de
Delphi.
Solución rápida
Añada el cuaderno (workbook) antes de intentar añadir valores a las celdas:
. . .
begin
xl.Workbooks.Add;
SetColumnTitles;
xl.Visible := True;
end;
Mensajes de error 411
Información adicional
Delphi 5 y superiores hacen más fácil el uso de los servidores COM como Word,
Excel, Access, PowerPoint y Outlook a través de los componentes de la página
Servers. Los objetos de Automatización no serán visibles por defecto, por lo
tanto deberá asignar True a la propiedad Visible si quiere que aparezcan en
pantalla.
One or more lines were too long and have been truncated
Posible causa de error
1. Puede haber iniciado, quizás inadvertidamente, varias instancias de
Delphi.
2. Puede haber intentado abrir un archivo que no es de Delphi en el entorno
integrado. Por ejemplo, puede haber seleccionado File | Open..., luego
haber seleccionado Any File (*.*) en el cuadro de combinación de tipos de
fichero, y luego haber intentado abrir un archivo .DOC (Microsoft Word).
Solución rápida
1. Cierre todas las instancias innecesarias de Delphi.
2. Abra el archivo que no es de Delphi con el programa apropiado o desde el
Explorador de Windows.
Información adicional
Podría ver este mensaje de error si selecciona muchos archivos de Delphi en el
Explorador y luego accidentalmente pulsa dos veces en rápida sucesión sobre
uno de los archivos. Esto, en efecto, ejecuta la acción de doble clic sobre todos
los archivos resaltados, y una instancia de Delphi individual es iniciada para
cada archivo.
Puede también obtener el mensaje de error “Module <>s time/date changed.
Reload?” conjuntamente con el mensaje de error bajo discusión.
Solución rápida
Mueva uno a ambos métodos sobrecargados a un alcance de visibilidad menor
(Public, Protected o Private).
Información adicional
La directiva Overload permite crear múltiples métodos con un mismo nombre y
cantidad o tipos de parámetros diferentes. Estos pueden ser especialmente
útiles cuando uno o más de los parámetros es innecesario en situaciones parti-
culares: puede crear una versión “completa” del método, y una o más que
puedan ser llamadas con un número de parámetros menor. Un ejemplo de esto
sería:
function GetScripture(ABook, AChapter, Averse: String): String;
overload;
function GetScripture(ABook, Averse: String): String; overload;
Solución rápida
Utilice a lo sumo un componente TIDAntiFreeze por aplicación. No coloque uno
sobre un formulario que pueda ser creado varias veces.
Información adicional
Un buen lugar para un componente TIDAntiFreeze es un módulo de datos.
Aún si la aplicación no es una aplicación de base de datos, los módulos de datos
son útiles como almacenes de componentes no visibles compartidos. Podría
encontrar conveniente pensar en los módulos de datos, por lo tanto, como
módulos de componentes “no visuales”.
TIDAntiFreeze es parte del juego de componentes Internet Direct (Indy), cono-
cido como Winshoes en una versión anterior. Internet Direct se ha convertido
en parte tanto de Delphi 6 como de Kylix.
La característica principal en la que Internet Direct difiere de AsyncPro (dis-
tribuido por Danysoft) es que, como su nombre implica, AsyncPro trabaja
asíncroncamente (sin bloqueo), mientras Internet Direct es síncrono (con blo-
queo). El modelo de sincronismo o de bloqueo tiene potencialmente un aspecto
negativo, ya que normalmente una operación acapara todo el tiempo de CPU
hasta que termina, haciendo que la interfaz de usuario no responda. El
Mensajes de error 413
Solución rápida
No especifique un convenio de llamada diferente de Register (el convenio por
defecto) en una sección Automated.
Información adicional
La sección Automated apareció por primera vez con Delphi 2 y perdió apoyo en
las versiones posteriores de Delphi. Se mantiene principalmente por
compatibilidad.
Solución rápida
1. Conecte el DBGrid a un ClientDataSet conectado a un DataSetProvider
que a su vez esté conectado al conjunto de datos de DBExpress.
2. Asigne False a la propiedad Unidirectional.
414 Los Tomos de Delphi: Delphi sin problemas
Información adicional
1. Si se conecta al conjunto de datos DBExpress indirectamente (a través del
ClientDataSet), podrá desplazarse por el conjunto resultado en cualquier
dirección. La tecnología MIDAS está “por doquier” en DBExpress.
DBExpress fue introducido en Delphi 6.
2. Si está rellenando una rejilla de base de datos, puede que desee asignar
False a la propiedad Unidirectional del conjunto de datos. De otra manera,
si es posible, es una optimización asignar el valor True a Unidirectional.
Solución rápida
1. Solamente utilice expresiones de filtros lógicas (como es razonable). En el
ejemplo de arriba, un valor de cadena es comparado con un gráfico. Esto es
ilógico (no tiene sentido).
2. Asigne False a la propiedad Sorted antes de intentar esta operación:
TStringList(slTemp).Sorted := False;
Información adicional
Si la lista ordenada de cadenas realmente necesita una operación, llévela al
Hospital General de Bitbucket ;-)
Solución rápida
1. Actualícese a la última versión disponible del BDE para su versión de
Delphi.
2. Llame a Query.Last antes de acceder a la propiedad RecordCount. Por
ejemplo:
. . .
var
Retrieved: Integer;
begin
416 Los Tomos de Delphi: Delphi sin problemas
with qryQuarry do
begin
Open;
Last;
Retrieved := RecordCount;
. . .
Close;
end;
end;
3. Elimine el campo memo de la sentencia SELECT de SQL.
4. Convierta la aplicación CGI en una aplicación ISAPI.
5. Asigne un valor válido al parámetro. De otra manera, verifique esta condi-
ción y evite el fallo del procedimiento, así:
Params.ParamByName('Food').AsString := HungryFor;
if HungryFor = '' then begin
Exit;
ShowMessage(‘You must not be hungry’);
end;
Información adicional
Las aplicaciones cliente multicapa (ligeras) requieren que DBClient.DLL sea
distribuido a todas las máquinas que estén ejecutando la aplicación cliente. A
lo que antes se llamaba DBClient.DLL se le cambió el nombre a MIDAS.DLL a
a partir de Delphi 5.
4. Delphi 6 tiene una tercera opción disponible— las aplicaciones Web de
Apache.
Solución rápida
1. Examine la sentencia SQL detenidamente. Consulte la documentación de
la base de datos que esté utilizando. La sintaxis difiere entre las distintas
implementaciones.
2. Recuerde encerrar los índices de arrays entre corchetes, así:
i := Synergy[0];
3. Pulse con el botón derecho sobre el alias y seleccione Apply; luego intente
expandir el alias de nuevo.
Información adicional
1. Los errores comunes de sintaxis SQL son:
Utilizar apóstrofes donde se necesitan comillas dobles (y viceversa).
Olvidar colocar los nombres de las tablas en mayúsculas (donde esto
es requerido por el tipo particular del SQL que esté utilizando).
var
p: pointer;
begin
p^ := 5;
-O-
type
TParty = (Boston, DelFuegos, JGeils);
var
JustAnotherBand: TParty;
BradleyDelp: pointer;
begin
JustAnotherBand := Boston;
BradleyDelp^ := JustAnotherBand;
5. Puede estar llamando a un procedimiento como si fuera una función que
devuelve un valor Boolean. Por ejemplo, puede estar llamando a un proce-
dimiento denominado ValidateState así:
if not ValidateState then
6. Puede haber intentado utilizar los operadores Is o As sobre uno o más ope-
randos de tipo Variant. Por ejemplo, si GoodEnough y WellAndGood son
variables de tipo Variant, cualquiera de los siguientes fragmentos de código
generará este mensaje de error:
if GoodEnough is WellAndGood then . . .
if GoodEnough is Integer then...
with GoodEnough as WellAndGood do...
with WellAndGood as Boolean do...
7. Puede haber estado intentando asignar el resultado de una expresión de
tipo Boolean que utiliza el operador Not a una variable o propiedad de tipo
Boolean, y olvidó encerrar la expresión que será evaluada entre paréntesis.
Por ejemplo, lo siguiente generará este mensaje de error:
btnNew.Enabled := not CurrentMode = Restrict;
Solución rápida
1. No utilice Div sobre valores de tipo float; utilice / en su lugar:
. . .
Table1Percentage.Value :=
Table1MySalary.Value / Table1AllTheMoneyInTheWorld.Value;
. . .
2. Hágalo de esta manera:
if State in [dsEdit, dsInsert] then
. . .
3. Borre el signo (+) adicional del código.
4. Utilice un tipo de puntero con tipo, así:
procedure ThatWasAGood;
Mensajes de error 419
type
iptr = ^Integer;
var
i,j: integer;
p: pointer;
q: iptr;
begin
p := @i;
q := p;
q^ := j;
i := q^;
end;
-O-
type
TParty = (Boston, DelFuegos, JGeils);
var
JustAnotherBand: TParty;
TomScholz: ^TParty;
begin
JustAnotherBand:=Boston;
TomScholz^ := JustAnotherBand;
5. Llame al procedimiento directamente o cambie el procedimiento por una
función que devuelva un valor Boolean.
6. No utilice los operadores Is o As sobre operandos Variant.
7. Encierre la expresión Boolean a negar entre paréntesis, así:
btnNew.Enabled := not (CurrentMode = Restrict);
Información adicional
3. Dos signos más consecutivos (++) son utilizados en el lenguaje de progra-
mación C como operador de incremento. Quizás C++ debería ser leído como
“C incrementado” (en lugar de “C más más”).
6. Es también ilegal utilizar el operador ^ sobre operandos Variant.
Para más información, consulte “operators” en la ayuda de Delphi.
Solución rápida
En el editor de parámetros, asígnele al REF CURSOR un valor por defecto de
0.
Información adicional
Si el único parámetro del procedimiento almacenado es un REF CURSOR, este
error no es generado.
Solución rápida
Inicialice los valores en el mismo orden en que aparecen en la declaración Type
(registro):
var
TresHombres : TTresHombres
= (Z: 'Dusty'; Zee: 'Billy'; Top: 'Frank');
Información adicional
Como se sobreentiende, las constantes con tipo son realmente variables inicia-
lizadas, aunque sean declaradas en secciones Const.
Mensajes de error 421
Solución rápida
Utilice únicamente tipos ordinales en las situaciones de arriba. Por ejemplo,
todo lo siguiente es legal:
{ a }
type
TGilligansIsland = (Ginger, MaryAnne, Professor, Gilligan,
Skip, MrHowell, MrsHowell);
{ b }
var
i,j: Integer;
begin
for i := 0 to ColCount-1 do
strgrd.Cells[i,j];
{ c }
Type
TChoppers = set of byte;
{ d }
procedure GetLabel(WineChoice: TDryRedWine);
422 Los Tomos de Delphi: Delphi sin problemas
var
Etikett: String;
begin
case WineChoice of
Zinfandel: Etikett := 'Stevenot';
CabernetSauvignon:Etikett := 'Sutter Home';
Burgundy: Etikett := 'Almaden';
end;
Información adicional
Hay cuatro tipos ordinales predefinidos en Object Pascal: Integer, Char,
WideChar y Boolean. Object Pascal también permite al usuario (programador)
declarar y crear tipos enumerados definidos por el usuario, que son otro tipo
ordinal.
Out of memory
Posible causa de error
1. Puede haberse quedado sin memoria.
2. Puede haber proporcionado a la función Format demasiados argumentos
para que gestione.
3. Puede estar utilizando una combinación de Delphi 3 ó 4, ciertos controlado-
res de vídeo (como Diamond Fire GL 1000 Pro o STB Velocity 4400) y
puede tener una gran cantidad de componentes adicionales en su Paleta de
Componentes.
Solución rápida
1. Verifique que tiene suficiente memoria RAM, que el archivo de intercambio
de Windows tenga el tamaño suficiente, y que tenga al menos el 10 por
ciento de espacio libre en el disco duro.
2. Parta la cadena que quiere formatear en varias cadenas, y luego concatene
el resultado al finalizar.
3. Quizás la manera más fácil de solucionar esto es reducir el número de
paquetes/componentes instalados o actualizarse a Delphi 5 o superior (pre-
ferido). Otras posibles opciones son:
Obtener la última versión del controlador (www.s3.com, www.stb.com, o
su fabricante).
Iniciar Delphi con la opción -ns.
Debajo de la sección [display] del archivo SYSTEM.INI añadir la
siguiente línea:
BusThrottle=1 (reiniciar después)
Reducir la aceleración de hardware de la tarjeta de vídeo.
Mensajes de error 423
Información adicional
Para más información, consulte “memory” y “format strings” en la ayuda de
Delphi.
3. El entorno integrado de Delphi utiliza una lista de imágenes para los ico-
nos que se muestran en la Paleta de Componentes. Cuando Delphi es
cargado, esta lista de imágenes crece en tamaño. Si el tamaño de la lista de
imágenes es superior a la capacidad soportada por la memoria de la tarjeta
de vídeo, se utiliza memoria principal para almacenar el resto de la lista de
imágenes. Durante esta operación, el controlador de vídeo algunas veces
falla.
Solución rápida
Siempre que sea posible, cree dinámicamente los formularios para minimizar
la cantidad de recursos utilizados en un momento dado. Por ejemplo, cree un
cuadro de diálogo ‘Acerca de...’ solamente cuando sea necesario, añadiendo
código similar a éste al evento que se utiliza para crear el cuadro:
Form1 := TForm1.Create(Self);
try
Form1.ShowModal;
finally
Form1.Free;
end;
Información adicional
Recuerde que todos los controles de Windows que tienen asociado un maneja-
dor (handle) son considerados ventanas por Windows. Podría obtener este men-
saje de error por tener un montón de botones, etc. activos al mismo tiempo.
424 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Siga estos pasos para determinar qué archivo .DCU está dañado y luego
reconstruirlo:
1. Haga copias de sus archivos .DCU.
2. Borre un .DCU del directorio del proyecto.
3. Recompile el proyecto.
4. Repita los pasos 2 y 3 (borrando un .DCU diferente cada vez) hasta que no
obtenga el mensaje de error.
Información adicional
El archivo .DCU que borró inmediatamente antes de que el proyecto compilara
sin errores es el causante del problema.
Solución rápida
Añada la directiva Overload a ambos métodos, así:
constructor Create(AOwner: TComponent); overload; override;
constructor Create(AOwner: TComponent; i:integer); overload;
Información adicional
Para más información, consulte “overload” en la ayuda de Delphi.
Mensajes de error 425
Solución rápida
Utilice el disp-id asignado originalmente al procedimiento en todos los
descendientes.
Información adicional
Para más información, consulte “automated components” en la ayuda de
Delphi.
Solución rápida
Elimine la unidad mencionada en el mensaje de error de uno de los paquetes, o
elimine el paquete mencionado en el mensaje de error de la cláusula Requires
del paquete que está intentando compilar.
Información adicional
Dos paquetes que se utilizan entre sí no pueden contener la misma unidad.
Solución rápida
1. Evite instalar el mismo paquete varias veces.
2. Para instalar un componente dentro de un paquete existente, seleccione la
página Into Existing Package en el cuadro de diálogo Install Component.
Información adicional
Para más información, consulte “packages | about packages” en la ayuda de
Delphi.
Solución rápida
Localice el paquete de tiempo de diseño correspondiente e instálelo.
Información adicional
Puede fácilmente determinar si un paquete es de tiempo de diseño o de tiempo
de ejecución abriéndolo, seleccionando el botón Options, y comprobando el
valor en las opciones Description | Usage.
Los paquetes de tiempo de ejecución contienen el código necesario para que las
aplicaciones puede ser construidas “con paquetes”, y los paquetes se distri-
buyan una sola vez (de modo que múltiples aplicaciones compartan un
paquete). Los paquetes de tiempo de ejecución (.DPL en Delphi 3, .BPL en las
versiones posteriores) deberían residir en \Windows\System (Windows 9X) o
\Winnt\System32 (Windows NT, 2000 y XP). Los paquetes de tiempo de
diseño contienen código específico para tiempo de diseño para su utilización
dentro del entorno integrado de Delphi, como iconos de componentes, editores
de propiedades y editores de componentes.
Es una buena práctica que los desarrolladores de componentes establezcan un
convenio de nombres que haga que los paquetes de tiempo de diseño y de
tiempo de ejecución sean fácilmente distinguibles. Una manera estándar de
Mensajes de error 427
hacerlo es añadir una “D” a los paquetes de tiempo de diseño; para propósitos
de control de versión, la base de código del compilador se añade al final del
nombre del archivo (por ejemplo, DCLIB60.BPL para el paquete de tiempo de
diseño de InterBase).
Solución rápida
No tiene sentido, y además es ilegal, que un paquete se requiera a sí mismo.
Elimine el nombre del paquete de su propia cláusula Requires.
Información adicional
Normalmente, los paquetes de tiempo de ejecución contienen las unidades que
implementan la funcionalidad principal del paquete, y requieren la VCL de la
base de código actual de Delphi (por ejemplo, VCL60.DCP para los paquetes de
Delphi 6). Los paquetes de tiempo de diseño contienen posiblemente una uni-
dad de registro, los recursos de iconos de componentes, y requieren el paquete
de tiempo de ejecución.
Solución rápida
Los paquetes pueden contener y utilizar unidades, pero no otros paquetes
(colecciones de unidades).
Información adicional
Puede ser que haya una unidad y un paquete con el mismo nombre, y el compi-
lador encontró el paquete antes que la unidad. Si es así, mueva el paquete con
el mismo nombre que la unidad que quiere utilizar o contener fuera de la ruta
de búsqueda de Delphi.
428 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Evite utilizar uno de los paquetes, o cambie el nombre a una de las unidades
que tienen el mismo nombre.
Información adicional
Tener dos paquetes en el mismo proyecto que contienen ambos una unidad con
el mismo nombre ocasiona ambigüedad al compilador. Es una buen práctica
utilizar un convenio de nombres personalizado para sus componentes y unida-
des, para evitar que este error se produzca.
Solución rápida
Utilice solamente la palabra reservada Packed sobre los tipos antes
mencionados.
Información adicional
Para más información, consulte “packed keyword” en la ayuda de Delphi.
Mensajes de error 429
Solución rápida
Busque un formulario abierto del tipo que desee para crearlo mediante código
de la siguiente manera:
var
i, Chihuahua: Integer;
begin
Chihuahua := -1;
for i := 0 to Screen.FormCount-1 do
if Screen.Forms[i] is TForm1 then
Chihuahua := I;
if Chihuahua >= 0 then
Screen.Forms[Chihuahua].Show
else
begin
Form1 := TForm1.Create(Self);
Form1.Show;
end;
end;
Información adicional
Consulte “Access Violation”.
Solución rápida
Introduzca un nombre en el cuadro de combinación Palette Page, o seleccione
uno de la lista desplegable.
430 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Palette Page es la página de la Paleta de Componentes en la que el nuevo com-
ponente será instalado.
Pero aún se hace referencia al parámetro :sysDate en algún lugar del código,
por ejemplo:
Params.ParamByName('sysDate').AsDateTime := Now;
Solución rápida
Elimine (o comente) la referencia al parámetro.
Información adicional
Alternativamente, puede mantener el parámetro pero suministrarle un valor
Null. Dado el ejemplo de arriba, podría hacerlo de esta manera:
INSERT INTO ABC.Alphabet
(SQU_ID, LetterCode, ReportedOn, EffectiveDate)
VALUES (:squid, :ltrcode, NULL, :effDate')
Solución rápida
Coloque la segunda variable (k, en el caso de arriba) en su propia sección deli-
mitada, así:
procedure PTBoat(i: Integer; j: Integer = 0; k: Integer = 0);
Información adicional
Los parámetros por defecto aparecieron por primera vez en Delphi 4.
Solución rápida
Configure la propiedad SQLConnection del objeto TSQLQuery, asignándole un
componente TSQLConnection apropiado.
Información adicional
DBExpress apareció por primera vez en Delphi 6.
Solución rápida
Elimine los valores por defecto.
432 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Para más información, consulte “default property values” en la ayuda de
Delphi.
Solución rápida
Descargue e instale el parche de Delphi 3.02, e importe la biblioteca de tipos
utilizando Tlibimp.EXE.
Información adicional
Vea el artículo de Dan Miser “The Upgrade Game” en la edición de Abril de
1998 de The Delphi Informant o en la dirección http://www.delphizine.com/opi-
nion/1998/04/di199804ft_o/di199804ft_o.asp, o visite http://www.danyshop.com
para conocer las razones por las que es conveniente actualizarse.
Solución rápida
Asigne el valor SHARED AUTOCOMMIT (Drivers | Access | SHARED
AUTOCOMMIT) al parámetro SQLPASSTHRU MODE para el controlador de
Access utilizando la utilidad BDE Configuration.
Información adicional
Para más información, consulte “using Passthru SQL” en la ayuda de Delphi.
Solución rápida
Mueva la tabla a la ubicación especificada en el mensaje de error (es decir, a
donde Delphi está buscándola).
Alternativamente, si la tabla está ubicada en el lugar que usted desea que
esté, pero el alias está apuntando a algún otro lugar (como indica el mensaje
de error y la ruta indicada), modifique la configuración del alias con la herra-
mienta BDE Configuration/Administration, para que apunte a la ruta correcta.
Información adicional
Para más información, consulte “TTable” en la ayuda de Delphi.
Solución rápida
Aumente el nivel de la tabla a 7 utilizando la utilidad BDE Configuration.
Consulte “Higher table level required” para ver las instrucciones concretas
de cómo hacer esto.
Información adicional
Consulte “Higher table level required” e “Invalid file name”.
{ Ejemplo B }
procedure ItsNotPoliteTo;
var
i, j: Integer;
p, q: Pointer;
begin
p := @i;
q := i^; //esto provoca el error, ya que i no es un puntero
//y no puede aplicársele el operador ^
Solución rápida
Utilice únicamente el operador de derreferenciación (^) con punteros. He aquí
un ejemplo correcto de la utilización del operador:
procedure ThanksForThe;
type
iptr = ^Integer;
var
i, j: Integer;
p: Pointer;
q: iptr;
begin
p := @i;
q := p;
q^ := j;
i := q^;
end;
Información adicional
Consulte “pointer types” en la ayuda de Delphi para más información sobre los
punteros.
Solución rápida
Encierre el valor de DefaultExpression entre apóstrofes. Por ejemplo, para
hacer que True sea el valor por defecto de un campo Boolean, introduzca
‘True’.
Información adicional
Consulte “TField” en la ayuda de Delphi para los detalles más específicos sobre
las propiedades, métodos y eventos de esta importante clase de objetos.
Solución rápida
1. Añada la directiva Overload a la declaración del método en la sección
Interface.
2. Corrija la definición o declaración para que ambas sean iguales.
Información adicional
Este mensaje de error es único para Delphi 4 y superiores, ya que la directiva
Overload fue introducida en Delphi 4.
Printing in Progress
Posible causa de error
Puede estar intentando imprimir un archivo de texto, pero ha olvidado cerrar
el archivo. Por ejemplo, puede estar haciendo algo así:
procedure TfmRSXL.btnPrintClick(Sender: TObject);
436 Los Tomos de Delphi: Delphi sin problemas
var
Palindrome: System.Text;
begin
AssignPrn(Palindrome);
Rewrite(Palindrome);
Writeln(Palindrome,'SIT ON A POTATO PAN OTIS');
Solución rápida
Cierre el archivo de texto cuando haya terminado de trabajar con él, así:
procedure TfmRSXL.btnPrintClick(Sender: TObject);
var
Palindrome: System.Text;
begin
AssignPrn(Palindrome);
try
Rewrite(Palindrome);
Writeln(Palindrome,'SIT ON A POTATO PAN OTIS');
. . .
finally
CloseFile(Palindrome);
end;
end;
Información adicional
Además del procedimiento estándar Writeln, puede también utilizar el método
TextOut de Printer.Canvas de la unidad TPrinters para imprimir texto. Para
más información, consulte “TextOut method” y “Printers unit” en la ayuda de
Delphi.
Solución rápida
Reemplace la palabra reservada Procedure por la palabra reservada Function,
o borre el tipo de resultado.
Información adicional
Si necesita o prefiere utilizar un procedimiento, pero también desea que el pro-
cedimiento devuelva un valor, puede pasar un parámetro Var al procedimiento:
Mensajes de error 437
Solución rápida
Llame a Fail solamente desde un constructor.
Información adicional
Incluso dentro de un constructor, no es buena costumbre llamar a Fail.
Solución rápida
Especifique el tipo del elemento si está añadiendo un procedimiento, función o
propiedad. Por ejemplo, podría introducir “property Condemned: WideString”.
Información adicional
La posibilidad de añadir métodos y propiedades a las interfaces a través de
Edit | Add to Interface apareció por primera vez en Delphi 6.
Si va a añadir un procedimiento a la interfaz, todo lo que necesita añadir es:
procedure <nombre>. Si añade una función, también deberá especificar un tipo
438 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Añada Procedure o Function a la palabra reservada Class, así:
class procedure a;
Información adicional
Los procedimiento de clase actúan sobre la propia clase, y no sobre una instan-
cia concreta de la clase. Un uso común para un procedimiento de clase es
implementar un formulario modal, así:
type
TfrmTMSExpressMaterial = class(TForm)
StatusBar1: TStatusBar;
private
{ Private declarations }
public
class procedure Cre8Thyself;
end;
// OJO! No hay una variable disponible, como:
//var
// frmTMSExpressMaterial: TfrmTMSExpressMaterial;
implementation
{$R *.DFM}
class procedure TfrmTMSExpressMaterial.Cre8Thyself;
begin
with Self.Create(nil) do
try
ShowModal;
finally
Free;
end;
end;
Solución rápida
Solamente los procedimientos y funciones de la unidad actual pueden ser
exportados. Por ejemplo, si DutyFree es el nombre de un procedimiento o fun-
ción en la .DLL, lo siguiente es un uso válido de la palabra reservada Exports:
exports
DutyFree;
Información adicional
Para más información, consulte “DLLs” en la ayuda de Delphi.
Solución rápida
Elimine la referencia a sí misma de la cláusula Uses.
Información adicional
Consulte “Circular Unit Reference [to <>]”.
440 Los Tomos de Delphi: Delphi sin problemas
Project <> raised exception class <> with message <>. Process
stopped. Use Step or Run to continue.
Posible causa de error
Este mensaje de error es bastante genérico. Simplemente dice el nombre del
proyecto que estaba activo cuando se produjo el mensaje de error (que debería
ser obvio en cualquier caso), la clase de excepción involucrada (que será bas-
tante general, como ERangeError, EInvalidCast, EInvalidPointer, EString-
ListError) y el mensaje exacto que la clase de excepción proporciona para este
error específico.
Solución rápida
El mensaje de error debería darle una buena pista sobre cuál es el problema
real. Por ejemplo, el texto completo del mensaje de error puede ser algo como
“Project Manhattan raised exception class ERangeError with message
Range Check Error. Process stopped. Use Step or Run to continue”.
Asimismo, podrá ver exactamente cuál es la sentencia en la que se ha produ-
cido el error, puesto que el depurador integrado normalmente se detiene en la
línea siguiente a la que ocasionó el error (si tiene habilitada la opción Break
on Exceptions).
Información adicional
Para continuar trazando la ejecución o ejecutando, como el mensaje invita a
hacer, pulse F8 para trazar o F9 para ejecutar. Cualquiera de estas acciones
pasará por la línea en la que ocurrió el error y mostrará el error que el usuario
final vería en esta situación en un cuadro de mensaje (el error bajo discusión
no es visto por el usuario final, sino solamente por el desarrollador; de hecho,
el propio desarrollador no lo vería si la opción Break On Exceptions no estu-
viera activada)*.
Para volver al entorno de tiempo de diseño para trabajar con el problema:
Pulse Ctrl+F2.
-O-
Pulse Alt+R, E.
-O-
Seleccione Run | Program Reset.
* Para activar la opción Break on Exceptions, siga estos pasos:
1. Seleccione Tools | Environment Options.
2. Seleccione la página Preferences.
Mensajes de error 441
Solución rápida
Si la propiedad es nueva para la clase, debe añadir el tipo de datos de la pro-
piedad, así como los campos o métodos de lectura (read) y escritura (write). Por
ejemplo, la declaración de arriba debería ser algo así:
published
property ValuesKeepSkyrocketing: Integer
read FOrbes write SetSkyrocketingValues;
Información adicional
Para promover una propiedad definida en la clase ancestro a una sección de
mayor visibilidad (de Private o Protected a Public o Published, o de Public a
Published), todo lo que hay que hacer es introducir su nombre en la sección a
la que se quiere promoverla — no es necesario añadir la declaración completa
(esta es la razón de por qué el compilador está esperando encontrar esta pro-
piedad en la clase base cuando no se ha proporcionado una declaración
completa).
Declarar una propiedad por su nombre solamente (omitiendo el tipo de datos y
los métodos de lectura y escritura) es la manera correcta de redeclarar una
propiedad de una clase ancestro. Esta es la razón de por qué el mensaje de
error indica que el compilador trata de localizar la propiedad en la clase base
(ancestro). Haga esto cuando quiera promover la propiedad para que sea más
visible (por ejemplo, de Private a Public). Por ejemplo, si en un descendiente de
TNotebook quiere aumentar la visibilidad de la propiedad Brush heredada de
Public a Published, podría hacer esto:
published
Brush;
Si está declarando una nueva propiedad, sin embargo, debe especificar su tipo
de datos y las claúsulas de acceso de lectura y escritura como se muestra a con-
tinuación, donde se está utilizando acceso directo a un campo para obtener y
asignar el valor de la propiedad:
442 Los Tomos de Delphi: Delphi sin problemas
private
FRealEstate: Currency;
protected
{ }
public
{ }
published
property RealEstate: Currency read FRealEstate write FRealEstate;
Si está utilizando acceso directo para leer el valor, pero utiliza un método para
asignar el valor de la propiedad (lo más adecuado en la mayoría de los casos),
utilice la siguiente metodología:
private
FRealEstate: Currency;
procedure SetRealEstate(Value: Currency);
protected
{ }
public
{ }
published
property RealEstate: Currency read FRealEstate
write SetRealEstate;
Solución rápida
No haga referencia a los miembros de una clase dentro de un método de clase.
Los métodos de clase actúan sobre la propia clase, no sobre instancias concre-
tas de la clase.
Información adicional
Consulte “Instance variable <> inaccessible here” en este libro.
Mensajes de error 443
Solución rápida
Abra el proyecto con la versión más nueva de Delphi, pulse con el botón dere-
cho del ratón sobre el formulario del proyecto, seleccione View as Text, y
luego borre la línea en la que se declara la propiedad OldCreateOrder del
archivo .DFM. ¡No seleccione View as Form! Cierre el proyecto. Podrá abrir el
proyecto en una versión anterior de Delphi.
Información adicional
La propiedad OldCreateOrder fue introducida en Delphi 4.
Solución rápida
Borre la directiva Overload de todos los métodos de acceso y elimine una ver-
sión de cada uno de los métodos sobrecargados.
Información adicional
Lamento parecer pretensioso, pero “getters” y “setters” suena un poco infantil
para mis oídos. Prefiero “método de acceso” (accessor) y “método de modifica-
ción” (mutator). Tampoco me gusta nada la tendencia a nombrarlo todo con el
prefijo “Mi”: “Mi” esto y “Mi” aquello, que se ve mucho en los ejemplos de
programación.
444 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Borre o renombre la propiedad en la interfaz derivada.
Información adicional
Si simplemente quiere que la propiedad esté disponible en la interfaz derivada,
no necesita hacer nada — la herencia de interfaz hace que la propiedad esté
automáticamente disponible.
Solución rápida
Seleccione Project |Build All.
Información adicional
Para más información, consulte “multi-tiered aplications” en la ayuda de
Delphi.
Mensajes de error 445
Solución rápida
1. Declare solamente propiedades en la sección Published. Por ejemplo, lo
siguiente compilará, ya que la clase tiene un miembro Integer (Feye):
type
TScantyClass = class
public
Feye: Integer;
published
property eye: Integer read Feye;
2. Proporcione un especificador de visibilidad, así:
type
TMyClass = class(TComponent)
private
FInteger: Integer;
. . .
end;
Información adicional
Para más información, consulte “class types” y “class type compatibility rules”
en la ayuda de Delphi.
446 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Declare únicamente propiedades con los siguientes tipos: ordinales, Single,
Double, Extended, Comp, String, Set (hasta 16 elementos en Delphi 1; hasta
32 elementos en Delphi de 32 bits), o punteros a métodos.
Información adicional
Entre los tipos más populares que no se permiten para las propiedades están
los arrays y Real.
Para más información, consulte “class types” y “class type compatibility rules”
en la ayuda de Delphi.
Solución rápida
Cambie la declaración de Real a Single, Double o Extended. Por ejemplo, cam-
biar lo anterior a:
. . .
private
FElCamino: Single;
public
{ Public declarations }
Mensajes de error 447
published
property ElCamino: Single read FElCamino
write SetElCamino;
Información adicional
Para más información, consulte “class types” y “class type compatibility rules”
en la ayuda de Delphi.
Solución rápida
Asigne una cadena antes de intentar asignar un objeto correspondiente. Puede
utilizar una cadena vacía, si quiere.
Información adicional
Si no necesita una cadena correspondiente, utilice la clase TList en lugar de
TStringList para almacenar los objetos.
Solución rápida
Cambiar la propiedad UpdateMode del TQuery a UpWhereKeyOnly o
UpWhereChanged.
Información adicional
UpdateMode localiza el registro que usted ha modificado para verificar que no
ha sido cambiado desde la primera vez que usted lo leyó hasta que intentó gra-
bar la nueva versión. Se puede localizar el registro en base a la verificación de
los siguientes campos:
El campo(s) clave solamente (si UpdateMode es igual a UpWhereKeyOnly).
El campo(s) clave más lo que se ha modificado (si UpdateMode es igual a
UpWhereChanged).
448 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Especifique los parámetros o valores literales en la sentencia INSERT de SQL.
Por ejemplo, para utilizar los parámetros, hágalo de esta manera:
with qryUpTheMiddle do
begin
if Active then
Close;
SQL.Clear;
SQL.Add('INSERT INTO TEAM VALUES(:Catcher,:Pitcher,’
+ ‘:Shortstop,:Centerfield)');
ParamByName('Catcher').AsString := edtCatcher.Text;
ParamByName('Pitcher').AsString := edtPitcher.Text;
ParamByName('Shortstop').AsString := edtShortstop.Text;
ParamByName('Centerfield').AsString := edtCenterfield.Text;
ExecSQL;
end;
Información adicional
Consulte la documentación de su base de datos para conocer los detalles especí-
ficos de SQL y su sintaxis.
Mensajes de error 449
Solución rápida
Intente reducir la sentencia SQL para que incluya sólo los registros de interés,
como:
SELECT * FROM TEXAS
WHERE FAVORITE_EXPRESSION = 'Go Packers! Beat the Cowboys!'
Información adicional
Las consultas funcionan mejor cuando se restringen no sólo los registros a
devolver, sino también las columnas, como en:
SELECT EMAILADDRESS, PHONE_NO FROM TEXAS
WHERE FAVORITE_EXPRESSION = 'Go Bucks! Beat the Spurs!'
Solución rápida
1. Cuando haga referencia a un elemento de un array, verifique que el índice
del elemento del array al que está intentando acceder esté dentro de las
dimensiones declaradas del array.
2. Declare las variables con tipos de datos que incluyan todo el rango de valo-
res que la variable puede necesitar manejar.
Información adicional
Para más información, consulte “range checking” en la ayuda de Delphi.
Solución rápida
Borre el archivo .VAL correspondiente de la tabla. Por ejemplo, si la tabla se
llama AGNES, el archivo que debe borrar y volver a crear se llamaría
AGNES.VAL.
Información adicional
Los archivos .VAL son creados cuando se especifican valores mínimos,
máximos y por defecto para los campos de una tabla Paradox utilizando Data-
base Desktop.
En lugar de especificar estos parámetros en el Database Desktop, puede
hacerlo directamente en Delphi, creando los campos persistentes en tiempo de
diseño utilizando el Editor de Campos (Fields Editor), y luego configurando las
propiedades DefaultValue, MaxValue y MinValue de éstos. Consulte “Fields
Editor” en la ayuda de Delphi para detalles más específicos.
Solución rápida
Añada un especificador Read junto con el campo o función correspondiente a
la declaración, así:
FSomeInterface: ISomeInterface;
property SomeInterface: ISomeInterface read FSomeInterface
implements ISomeInterface;
Información adicional
Consulte “Implements getter must be register calling convention” en
este libro, e “Implementing Interfaces by delegation” en la ayuda de Delphi (4 o
superior) para más información.
Solución rápida
1. Borre uno u otro o ambos archivos.
2. Asigne False a la propiedad Active del conjunto de datos en tiempo de
diseño, o ejecute la aplicación fuera del entorno integrado de Delphi (cierre
Delphi primero).
Información adicional
1. Usted, el testeador, y usted, el programador, pueden estar peleándose por
un mismo registro del conjunto de datos (una instancia abierta en el
entorno integrado/tiempo de diseño, y una instancia en ejecución).
Solución rápida
Cambie el tipo de datos a ShortDateTime o trunque el último dígito en la parte
de los milisegundos antes de que el registro sea grabado.
Información adicional
Entre el momento en que se reciben los datos para que sean traducidos y luego
actualizados por el BDE, el valor DateTime puede cambiar.
Solución rápida
Utilice una versión anterior del controlador ODBC, o utilice los componentes
ADO Express para acceder a las tablas de Access.
Información adicional
Microsoft cambió el tamaño de los campos en uno de sus controladores, pero
Delphi todavía está esperando el tamaño de campo publicado anteriormente.
Record/Key Deleted
Posible causa de error
1. Puede haber asignado una marca (bookmark), haber cambiado de índice, y
luego haber intentado volver a la posición especificada por la marca.
2. Puede haber colocado un filtro sobre un conjunto resultado y luego haber
alterado la definición del filtro añadiendo o borrando un campo o campos
del filtro.
Solución rápida
1. No cambie de índices mientras una marca esté activa.
2. Deshabilite el filtro, realice la edición, y luego vuelva a habilitar el filtro.
Información adicional
Para más información, consulte “bookmarks”, “indexes” y “filters” en la ayuda
de Delphi.
Mensajes de error 453
Solución rápida
Intente editar de nuevo el registro, verificando primero si el cambio que está
intentando hacer no fue hecho ya por otro usuario.
Información adicional
Solamente un usuario puede colocar un bloqueo de escritura sobre un registro.
Muchos usuarios pueden simultáneamente ver el mismo registro (cada uno de
ellos colocando un bloqueo de lectura en el proceso), pero solamente uno puede
editarlo (para lo que debe obtener un bloqueo de escritura).
Solución rápida
Especifique la variable explícitamente, así:
if JAndJWentUpTheVerticallyChallengedMountain = True then
JAndJWentUpTheVerticallyChallengedMountain := False;
Información adicional
Utilice la palabra reservada With solamente en combinación con los tipos men-
cionados en el mensaje de error, como componentes TQuery, etc.
454 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Borre la directiva de compilación que hace referencia a sí misma en el archivo
incluido.
Información adicional
Puede incluir en un archivo el contenido de un archivo diferente a través de
una referencia a un archivo incluido. El compilador trata el archivo incluido
como si su contenido estuviera situado directamente en la unidad. Por ejemplo,
si añadió:
{$I Murder.inc}
Solución rápida
1. Si quiere heredar la funcionalidad del método original, utilice la palabra
reservada Override cuando lo declare. Si quiere declarar un método nuevo,
asígnele un nombre diferente de los que ya se utilizan en la clase base.
2. Renombre la propiedad o método en la clase descendiente.
Información adicional
1. Si quiere ocultar un método de una clase base, puede hacerlo declarando
deliberadamente un método con el mismo nombre. Consulte “Method <>
hides virtual method of base class <>”.
Solución rápida
Quite la propiedad de la sección Automated. Promuévala a otra sección (como
Public o Published), si lo desea.
Información adicional
El especificador de visibilidad Automated apareció por primera vez en Delphi
2. Se mantiene en Delphi 3 y posteriores principalmente por razones de
compatibilidad.
Solución rápida
Asegúrese de que ha escrito correctamente el nombre del archivo de paquete
requerido, y que cualquier unidad a la que se hace referencia reside en un
directorio que está en la ruta de búsqueda de Delphi.
456 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Para verificar y/o modificar la ruta de búsqueda de Delphi, seleccione Tools |
Environment Options, luego la pestaña Library y el cuadro de combinación
Library Path. Generalmente, los paquetes deben estar instalados en el directo-
rio \Windows\System.
Solución rápida
Asegúrese de que los archivos de paquete listados no contengan extensiones de
archivos y que la lista esté terminada con un punto y coma.
Información adicional
Cualquiera de las siguientes declaraciones producirá este mensaje de error:
requires
Vcl30 { falta el punto y coma final }
requires
Vcl30, { coma incorrecta; falta punto y coma }
requires
vcl30.dpk; { extensión no permitida }
Asegúrese de que la cláusula Requires sea parecida a ésta (aunque puede que
se listen múltiples paquetes):
requires
Vcl30;
Solución rápida
1. Solamente relance las excepciones dentro de un bloque de excepción.
2. Sustituya la palabra reservada Raise por una llamada al método
ShowException del objeto Application, pasándole el objeto E de tipo Excep-
tion, así:
if ReportObj.ProgramMode = pmBatch then begin
ReportObj.WriteToLogFile(
SReportName, SDelphiErrorMessage+E.Message,
SWindowsErrorCode+IntToStr(GetLastError),
DateToStr(Now), TimeToStr(Now));
Abort;
end else
Application.ShowException(E);
Información adicional
El gestor OnException “sustituto” debe tener la siguiente signatura:
procedure FilterExceptions(Sender: TObject; E: Exception);
Los bloques Try. . . Except tienden a ser sobreutilizados por muchos desarrolla-
dores. Una regla general empírica es que los bloques Try. . . Finally deberían
exceder en número a los bloques Try. . . Except en una razón de 10:1. Delphi
manejará las excepciones que no maneje usted específicamente a través de su
propio mecanismo de detección y gestión de errores. Si no se hace un manejo
anterior, el gestor de excepciones por defecto de Delphi gestionará las excepcio-
nes que lleguen a ese punto. Sin embargo, no liberará los recursos por sí
mismo — eso es responsabilidad del desarrollador.
Solución rápida
Verifique la ortografía, o mueva el archivo .RES al mismo directorio que el
.DPR que lo necesita.
Información adicional
No coloque recursos personalizados dentro del archivo .RES que tiene el mismo
nombre del proyecto (es decir, si el proyecto se llama Project1.DPR, habrá un
archivo .RES llamado Project1.RES). Permita que Delphi tenga total control
sobre este archivo.
Solución rápida
Si realmente necesita especificar una dirección, utilice una dirección de memo-
ria “plana”, como $0040.
Información adicional
Las direcciones absolutas no deberían ser utilizadas en programas de modo
protegido de 32 bits. La palabra reservada Absolute es normalmente utilizada
en la programación a bajo nivel, por ejemplo cuando se escriben controladores
de dispositivos.
Solución rápida
No intente eliminar cualquier componente que haya sido heredado del
ancestro.
Información adicional
Este mensaje de error apunta a la necesidad de evitar heredar de clases que
contengan más de lo que quiera que tenga el descendiente. Al mismo tiempo, si
está creando una clase ancestro de la que va a heredar posteriormente, como
puede ser un formulario que podría ser heredado utilizando la herencia visual
de formularios (disponible en Delphi de 32 bits), manténgala tan genérica como
sea posible para permitir que sea utilizada en su totalidad por los formularios
descendientes.
Cuando hereda de una clase o componente, puede solamente añadir, pero no
quitar nada del ancestro. Una mirada al código fuente que subyace a un formu-
lario ancestro simple y su descendiente (creado utilizando herencia visual),
muestra cómo esto funciona en segundo plano.
Este es el código fuente para un formulario ancestro simple:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
Button1: TButton;
private
{ Declaraciones Private }
public
{ Declaraciones Public }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
end.
Solución rápida
Proporcione en la propiedad ServerName o ServerGUID un valor correspon-
diente a un servidor que haya sido registrado en su máquina.
Información adicional
Los componentes MIDAS sólo se proporcionan con la versión Cliente/Servidor
de Delphi 3 o superiores.
Solución rápida
Proporcione un valor para la propiedad SessionName del componente TSession
o asigne True a su propiedad AutoSessionName.
Información adicional
No confunda las propiedades Name y SessionName del componente TSession.
La propiedad Name, que tienen todos los componentes, se refiere al nombre del
objeto en sí. La propiedad SessionName de un componente TSession es el nom-
bre de la sesión a la que los componentes TDatabase y TDataset (TTable,
TQuery y TStoredProc en todas las versiones de Delphi; TClientDataSet en la
versión de Delphi Cliente/Servidor 3, 4 y superiores; TNestedTable en Delphi 4
y superiores) se refieren a través de su propiedad SessionName para indicar a
qué sesión están conectados (útil en aplicaciones multihilo, que pueden conte-
ner muchas sesiones).
Por lo tanto, el componente TSession proporciona un nombre de sesión bien
directamente (cuando introduce el nombre en tiempo de diseño o se propor-
ciona uno en el código) o indirectamente (cuando se asigna True a la propiedad
AutoSessionName), y los componentes TDatabase y TDataset seleccionan uno
de los nombres de sesión disponibles de un cuadro de combinación.
Solución rápida
El tipo de datos base del conjunto no debe contener más de 255 elementos. Las
siguientes declaraciones funcionan bien:
type
sob = set of Byte;
soc = set of Char;
Información adicional
El tipo base no puede tener más de 256 posibles valores, y sus ordinales deben
estar entre 0 y 255. Debido a estas limitaciones, los tipos conjunto normal-
mente se definen sobre subrangos, así:
462 Los Tomos de Delphi: Delphi sin problemas
type
TAWholeMessOfIntegers = 2..243;
TIntegerSet = set of TAWholeMessOfIntegers;
var
SetTopBox, Settee: TIntegerSet;
begin
SetTopBox := [1, 3, 5, 7, 9];
Solución rápida
Añada DEVICE=*vshare a la sección [386Enh] del archivo SYSTEM.INI, o
añada SHARE.EXE al archivo AUTOEXEC.BAT, y luego reinicie.
Información adicional
Para editar el archivo SYSTEM.INI desde el Explorador de Windows, siga es-
tos pasos:
1. Localice SYSTEM.INI. Debería estar situado en el directorio de Windows.
Pulse dos veces sobre él para abrirlo.
2. Localice la sección [386Enh].
3. Añada DEVICE=*vshare si no está ya en la sección [386Enh].
4. Cierre SYSTEM.INI y guarde los cambios.
5. Reinicie.
Para editar el archivo AUTOEXEC.BAT desde el Explorador de Windows, siga
estos pasos:
1. Localice y pulse con el botón derecho sobre AUTOEXEC.BAT. Debería es-
tar situado en el directorio raíz (C:\).
2. Seleccione Edit del menú de contexto.
3. Al final del archivo, introduzca SET SHARE=C:\dos\share /F:4096
/L:40.
4. Reinicie.
Mensajes de error 463
Solución rápida
Reduzca el tamaño del conjunto a una cantidad menor o igual que 32 elemen-
tos. Por ejemplo, en el conjunto de arriba, podría eliminar TWaterboy (o podría
borrar TQuarterback, pero…).
Información adicional
Los conjuntos se utilizan frecuentemente para incluir múltiples elementos de
un tipo enumerado. Un ejemplo es el tipo TFontStyle:
464 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Slice puede ser utilizado únicamente para enviar un subconjunto de un array
abierto a un procedimiento o un array que espera un argumento de array
abierto. He aquí un ejemplo de cómo puede ser utilizado Slice:
var
Form1: TForm1;
pare: array[0..11] of integer;
. . .
function Dice(EightWillSuffice: array of integer): integer;
var
i,sum: Integer;
begin
sum := 0;
for i := low(EightWillSuffice) to High(EightWillSuffice) do
sum := sum + EightWillSuffice[i];
Result := sum;
end;
procedure Peel;
begin
Dice(Slice(pare,3));
end;
Mensajes de error 465
Información adicional
Para más información, consulte “Slice” en la ayuda de Delphi.
Solución rápida
1. Inicie el servidor antes de intentar conectarse a él.
2. Compruebe que la propiedad Host de TIdTCPClient especifica una
máquina que es accesible, y la propiedad Port se refiere a un servicio que
está disponible en la máquina Host.
Información adicional
Un socket es una combinación de un servidor (host) y un puerto. El servidor es
una máquina, y el puerto es un servicio que esa máquina ejecuta. Consulte los
archivos Hosts y Services en su ordenador para ver ejemplos de máquinas y
servicios disponibles.
Los componentes TIdTCPClient y TIdTCPServer son parte del conjunto de
componentes Indy, incluidos en Delphi por primera vez en la versión 6.
Solución rápida
Compruebe que el valor que introduzca en la propiedad Host de TIdTCPClient
represente un máquina que sea accesible desde el ordenador cliente.
466 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Un socket es una combinación de un servidor (host) y un puerto. El servidor es
una máquina, y el puerto es un servicio que esa máquina ejecuta. Consulte los
archivos Hosts y Services en su ordenador para ver ejemplos de máquinas y
servicios disponibles.
Los componentes TIdTCPClient y TIdTCPServer son parte del conjunto de
componentes Indy, incluidos en Delphi por primera vez en la versión 6.
Solución rápida
Conéctese a Internet o la red necesaria para localizar la máquina en cuestión.
Información adicional
Los errores de sockets provienen de los componentes Indy, incluidos en Delphi
por primera vez en la versión 6.
Solución rápida
1. Llévele un donuts al administrador de su red y coméntele el problema.
2. Vea si puede reducir la cantidad de filas y/o columnas que está obteniendo
del servidor. Si está utilizando componentes TTable para acceder a grandes
cantidades de datos, considere el uso de un TQuery o TStoredProc.
3. Si está utilizando el BDE, ejecute la utilidad BDE Configuration y estudie
los valores de los parámetros del controlador para su sistema de base de
Mensajes de error 467
Información adicional
MS SQL Server y Sybase (su madre) tienen una propiedad del controlador
MAXQUERYTIME que puede ser configurada a través de BDE Configuratoion.
Solución rápida
Mantenga el valor de la propiedad SQLDialect en 1, o actualícese a InterBase
6.
Información adicional
InterBase 6 añade algunas mejoras fundamentales sobre las versiones anterio-
res. Para hacer uso de ellas, sin embargo, debe asignar 3 a SQLDialect. El
valor 1 de SQLDialect se ha creado para las versiones de InterBase anteriores
a la 6. El valor 2 de SQLDialect se utiliza para probar la compatibilidad de las
aplicaciones antiguas creadas con InterBase. Para más información, consulte
la documentación de InterBase (www.interbase.com).
Solución rápida
Utilice UpWhereChanged o UpWhereKeyOnly como valor para UpdateMode en
lugar de UpWhereAll.
Información adicional
El valor UpWhereAll del parámetro UpdateMode puede (internamente) crear
una sentencia SQL muy compleja. Aunque de por sí no está mal utilizar el
468 Los Tomos de Delphi: Delphi sin problemas
Stack overflow
Posible causa de error
1. Puede haber declarado muchas variables (o unas pocas variables muy
grandes, como arrays) en un procedimiento o función situado en una uni-
dad compilada con la directiva de compilador {$S+} (verificación de pila
activada).
2. Puede haber declarado muchas variables globales (o unas pocas variables
globales muy grandes).
3. Puede estar utilizando recursión profunda (intencional) o tener una recur-
sión infinita (no intencional) en el programa.
4. Puede estar pasando un registro muy grande como parámetro.
5. Puede estar utilizando muchos procedimientos o funciones muy grandes
que se llaman mutuamente.
6. Puede estar pasando parámetros muy grandes por valor.
Solución rápida
1. Reduzca el número de variables que esté utilizando o aumente el tamaño
de la pila. Puede incrementar el tamaño de la pila utilizando la directiva
de compilación {$M}. La sintaxis para utilizarla es:
{$M minstacksize, maxstacksize}
Los valores por defecto son 16.384 y 1.048.576. El primero es el tamaño ini-
cial confirmado de la pila; el segundo es el tamaño total reservado para la
pila. Para duplicar el tamaño inicial confirmado, así como el tamaño total
reservado, añada lo siguiente en el archivo .DPR del programa:
{$M 32768, 209752}
Información adicional
Este es el error de tiempo de ejecución 202.
3. Obtener este error cuando se utiliza deliberadamente la recursión es más
un problema de Delphi 1 que de Delphi de 32 bits, aunque la recursión infi-
nita (como la descrita antes en relación con el evento OnChange) será un
problema también en Delphi/Windows de 32 bits.
5. Si un procedimiento o función ocupa más de una pantalla de texto, sería
conveniente dividirlo en varios procedimientos más pequeños.
6. Los parámetros pasados como Var o Const ocupan cuatro bytes cada uno,
ya que son punteros.
Para más información, consulte “stack overflow” en la ayuda de Delphi.
Solución rápida
Cualifique la llamada a Abort anteponiéndole el nombre de la unidad:
SysUtils.Abort;
Información adicional
Ambas unidades, SysUtils y DbiProcs (Delphi 1) o BDE (Delphi de 32 bits) con-
tienen un procedimiento llamado Abort. En este tipo de situaciones, sea explí-
cito sobre cuál desea utilizar, anteponiendo el nombre de la unidad en la que
reside el procedimiento o función, al nombre del procedimiento o función que
desea utilizar.
end;
implementation
Solución rápida
Mueva el cuerpo del procedimiento a la parte Implementation de la unidad.
Información adicional
La parte Interface de una unidad puede solamente contener declaraciones, no
sentencias. Mueva los cuerpos de procedimientos a la parte Implementation.
Solución rápida
Elimine la cláusula Stored de la sección Automated.
Información adicional
Delphi 2 y superiores ofrecen cinco directivas de visibilidad: Private, Protected,
Public, Published y Automated (Delphi 1 no tiene la directiva Automated). Las
propiedades de una clase pueden utilizar una de las directiva de almacena-
miento Stored, Default o Nodefault. No obstante, estas directivas de almacena-
miento no están permitidas en la sección Automated.
Solución rápida
Si es factible, actualícese a una versión de Delphi de 32 bits, preferiblemente
la versión más reciente. Si persiste en utilizar en Delphi 1 el formulario creado
con Delphi de 32 bits, borre todas las características específicas de Delphi de
32 bits del archivo de formulario (.DFM). Cargue el archivo en un editor de
texto corriente, como el Bloc de Notas, para hacer eso.
Mensajes de error 471
Información adicional
Algunas de las cosas que hacen que los archivos de formulario (.DFM) de Del-
phi de 32 bits no puedan ser utilizados en Delphi 1 son las cadenas largas, el
tipo TCollection, y la herencia de formularios.
Solución rápida
Modifique el tamaño de la cadena, o asigne una cadena que quepa en la varia-
ble. Por ejemplo, cualquier de las siguientes soluciones funcionará:
var
s: String[6];
begin
s := ’string’;
-O-
var
s: String[3];
begin
s := ’str’;
Información adicional
Para más información, consulte “strings” en la ayuda de Delphi.
2. Puede haber asignado una cadena de más de 255 caracteres a una cadena
corta. Por ejemplo, si declara una variable ShortString:
var
s: ShortString;
y luego intenta asignarle una cadena de más de 255 caracteres, obtendrá
este mensaje de error.
3. Puede haber asignado una cadena con más de 255 caracteres en una única
línea del editor de código (en esta situación, el error se producirá incluso si
se trabaja con cadenas largas).
4. Puede haber declarado una constante de cadena con más de 255 caracteres.
Por ejemplo, si asignara el texto de la dirección completa de Gettysburg a
una constante de cadena, obtendría este mensaje de error.
Solución rápida
1. Asegúrese de que el tamaño que declara cuando utiliza un ShortString es
menor que 256.
2. No asigne una cadena de más de 255 caracteres a una variable de tipo
ShortString.
3. Divida la cadena en varias líneas, y utilice el operador de concatenación
(+).
4. Reduzca el tamaño de la constante de cadena o declare varias constantes y
concaténelas, así:
const
SomewhatLong = ’{Cadena de hasta 255}’;
KindOfLong = ’{Cadena de hasta 255}’;
SortOfLong = ’{Cadena de hasta 255}’;
WorkAroundVeryLongString =
SomewhatLong + KindOfLong + SortOfLong;
Información adicional
Para más infomación, consulte “string types” en la ayuda de Delphi.
ExecSQL;
finally
Free;
end;
end;
debido a que esa no es la sintaxis apropiada para añadir un índice a una tabla.
ADO cree que usted está intentando crear una nueva columna para la tabla,
pero esa tampoco es la sintaxis adecuada para ello.
Solución rápida
Utilice la sintaxis apropiada. En el caso de arriba, sería:
with TADOQuery.Create(nil) do begin
try
Connection := ADOConnection1;
SQL.Add(’CREATE INDEX ORD_SEQ ON SCRIPTURES(ORDER_SEQUENCE)’);
ExecSQL;
finally
Free;
end;
end;
Información adicional
Utilice la referencia de SQL de la base de datos que esté utilizando para deter-
minar la sintaxis correcta. La sintaxis es generalmente la misma entre las
diferentes bases de datos, pero hay ligeras variaciones. Si no tiene o no puede
encontrar la documentación de SQL de la base de datos, puede encontrar un
ejemplo buscando en el disco duro, y seguramente podrá encontrar un ejemplo
buscando en sitios de Internet como www.tamaracka.com o www.dejanews.com.
Por ejemplo, en el caso de arriba busque “CREATE INDEX”.
Solución rápida
Encierre el nombre de la tabla entre corchetes, así:
SELECT *
FROM [ROUND TABLE]
Información adicional
Consulte el archivo LOCALSQL.HLP de Delphi, así como la documentación del
SQL de la base de datos que esté utilizando, para conocer la sintaxis de SQL
específica del fabricante.
Solución rápida
Añada un número al factor de escala (E):
var
Mint: Double;
begin
Mint := 123.E7;
Información adicional
E significa “diez elevado a”.
Solución rápida
Compruebe que la ruta de búsqueda de bibliotecas no apunte a una versión
“errónea” de SYSTEM.DCU, por ejemplo a una unidad de terceros llamada
System. Seleccione Tools | Environment Options | Library | Library
Path. Una manera “rápida” de buscar unidades “renegadas” es utilizar la bús-
queda de archivos y carpetas del Explorador de Windows. Si no encuentra nin-
guna anomalía de esta naturaleza, reinstale SYSTEM.DCU del CD.
Información adicional
Nunca dé a una unidad suya el mismo nombre que una unidad de Delphi. No
asuma que conoce los nombres de todas las unidades de Delphi. Ya no estamos
en el terreno de Delphi 1 (al menos la mayoría de nosotros). A menos que haya
prestado atención a los nombres de las unidades y tenga una memoria fotográ-
fica, lo más probable es que las olvide. El método preferido es utilizar un con-
venio de nombres para sus propias unidades, del mismo modo que deben
hacerlo los desarollladores de componentes. Puede anteponer sus iniciales, o
las iniciales de su compañía, y podrá estar bastante seguro que no tratará con
nombres de unidades duplicados. Por ejemplo, si trabaja para una compañía
denominada Drywall Roofing & Insulation Supply, podría asignar a sus unida-
des nombres como DRISStrUtils, DRISConsts, DRISGlobal, etc.
Solución rápida
Cierre primero la tabla llamando al método Close de TTable, o asigne False a
su propiedad Active. Luego puede llevar a cabo la acción, después de la cual
podrá llamar al método Open de TTable o asignar True a la propiedad Active.
Información adicional
Open es un método de TTable, que puede llamarse así:
Table1.Open;
Solución rápida
Asignar True al parámetro Local Share (en la página System de la utilidad
BDE Configuration) en todos los clientes y deshabilite los bloqueos
oportunistas.
Información adicional
Para deshabilitar los bloqueos oportunistas, debe editar (o crear, si es necesa-
rio) dos valores en el Registro del sistema siguiendo estos pasos:
1. Seleccione Inicio | Ejecutar en el escritorio de Windows.
2. Introduzca regedit en el cuadro de combinación Abrir y pulse el botón
Aceptar.
3. Navegue hasta HKEY_LOCAL_MACHINE\System\CurrentControlSet\
Services\LanmanServer\Parameters.
4. Edite o cree la clave EnableOplock y asígnele el valor 0.
5. Edite o cree la clave UseOpportunisticLocking y asígnele el valor 0.
6. Reinicie para que la configuración tenga efecto.
Solución rápida
1. Si falta el nombre de la tabla, modifique la sentencia SQL.
2. Proporcione el nombre de un alias válido en la propiedad DatabaseName
del objeto TTable.
3. Compruebe que el conjunto de datos que ha especificado como fuente
(TQuery, TStoredProc o TTable) exista y que el TTable que ha especificado
como destino exista.
4. Escriba en mayúsculas los nombres de las tablas cuando acceda a Oracle.
5. Anteponga dbo. al nombre de la tabla. Por ejemplo:
SELECT * FROM dbo.Cooper
6. Compruebe que la tabla a la que está intentando acceder está abierta en el
hilo actual (si su aplicación es una aplicación multihilo). Compruebe el
valor del parámetro SQLPASSTHRU MODE para el controlador de su base
de datos con la utilidad BDE Configuration. Si está asignada a NOT
SHARED, puede estar intentando leer los datos de una tabla temporal que
está disponible a través de otra conexión.
Información adicional
5. dbo significa “database owner” (propietario de la base de datos).
Solución rápida
1. Si está llamando a RecordCount para determinar si la cantidad de regis-
tros es 0, podría verificar en su lugar si la tabla está simultáneamente al
comienzo y al final del archivo, así:
if (tblHollow.bof) and (tblHollow.eof) then
Si quiere saber cuántos registros tiene la tabla, puede utilizar una senten-
cia SQL como:
SELECT COUNT(*) FROM MONTECRISTO
2. Anteponga dbo. al nombre de la tabla. Por ejemplo:
SELECT * FROM dbo.UHF
3. Llame al método Close del objeto TDataset y luego al método Open en
lugar de llamar a Refresh si tiene este problema con Refresh.
Información adicional
Consulte la documentación específica de su base de datos para conocer las par-
ticularidades del SQL que soporta.
Table is busy
Posible causa de error
1. Puede haber intentado añadir un índice en el código (utilizando el método
AddIndex de TTable) sin tener acceso exclusivo a la tabla.
2. Puede haber intentado copiar registros de una tabla a otra utilizando el
componente TBatchMove en modo batCopy mientras la tabla de destino
estaba abierta.
3. Puede haber intentado abrir una tabla en modo Exclusive cuando otro
usuario tenía la tabla abierta.
4. Puede tener una tabla abierta en el entorno integrado (o en el Database
Desktop), y está intentando posteriormente abrirla en tiempo de ejecución
en su proyecto.
5. Puede estar llamando al método EmptyTable de TTable y la tabla está
activa o abierta.
Mensajes de error 479
Solución rápida
1. Cierre primero el TTable y asigne True a la propiedad Exclusive.
2. Cierre la tabla de destino antes de copiar los registros a ella. Puede hacer
esto llamando al método Close de TTable o asignándole False a la propie-
dad Active del componente.
3. Encierre la sentencia que asigna True a la propiedad Exclusive en un blo-
que Try. . . Except, para proporcionarle al usuario un mensaje informativo
del problema si es imposible utilizar la tabla en modo exclusivo debido a
que otro usuario la tiene abierta.
4. Asigne False a la propiedad Active del TTable en el entorno integrado.
5. Llame al método Close de TTable o asigne False a su propiedad Active
antes de intentar llamar a EmptyTable.
Información adicional
Varios usuarios pueden ver la misma información simultáneamente, pero no
pueden editar la misma información al mismo tiempo.
5. Debe tener uso exclusivo de la tabla antes de llamar a EmptyTable.
Intentar asignar True a la propiedad Exclusive de la tabla mientras la pro-
piedad Active tiene el valor True produce el mensaje de error “Cannot
perform this operation on an open dataset”. Consulte esa entrada
para más información.
Si otro usuario tiene una tabla abierta en modo exclusivo y usted la intenta
abrir, recibirá el mensaje de error “File is Locked. Table: <> User: <>”.
Consulte esa entrada para información más especifica.
Table is full
Posible causa de error
Puede estar excediendo la capacidad máxima de una tabla Paradox.
Solución rápida
Tendrá que incrementar el tamaño del bloque con la utilidad BDE Configura-
tion/Administration, o evaluar el paso a una base de datos de servidor SQL
como InterBase (u Oracle, MS SQL Server, etc.).
Para incrementar el tamaño de bloque en la utilidad BDE Configuration, modi-
fique el valor del parámetro Block Size en la página/nodo Drivers | Paradox
de la utilidad BDE Configuration. Todas la tablas de Paradox que cree a partir
de ese momento reflejarán la nueva configuración. Para aplicar la configura-
ción a una tabla ya existente, cree una nueva tabla utilizando la estructura de
la tabla existente, y luego copie los datos de la tabla original a la nueva tabla.
480 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Las tablas Paradox pueden disponer de un máximo de 65.536 (64 K) bloques.
El tamaño por defecto del bloque es de 2.048 bytes (2 KB), y por lo tanto el
tamaño máximo por defecto de una tabla Paradox es de 128 MB. Incrementar
el tamaño del bloque a 32.768 (32 KB) le permitirá crear tablas de hasta 2 GB.
La siguiente tabla muestra el tamaño máximo de una tabla en base a la confi-
guración del parámetro Block Size en la configuración del BDE:
Solución rápida
Cree un índice primario para la tabla antes de crear un índice secundario.
Puede hacer esto utilizando el Database Desktop o en el código. Para crear el
índice primario utilizando el Database Desktop, marque la columna Key (o
pulse la barra espaciadora) de las n primeras columnas de la tabla.
Para crear un índice primario mediante código, siga el siguiente ejemplo:
AddIndex('Stadt', 'Stadt', [ixPrimary]);
Información adicional
Si la clave primaria consta de solamente una columna, ésta debe ser la pri-
mera columna de la tabla. Si es una clave compuesta, debe comenzar con la
primera columna y luego incluir todas las columnas consecutivas siguientes,
hasta la última columna que quiera utilizar (por ejemplo, si quiere utilizar la
primera y tercera columnas en la clave compuesta, deberá utilizar también la
segunda). Si está añadiendo el índice mediante código, separe los nombres de
las columnas que componen la clave primaria compuesta con puntos y comas,
así:
Mensajes de error 481
AddIndex('DogfaceIndex', 'Name;Rank;SerialNumber',
[ixPrimary]);
Solución rápida
1. Asigne primero False a la propiedad ReadOnly, y luego llame al método
Edit o Delete. Asegúrese de que la propiedad Active del objeto TTable
tenga asignado False antes de intentar asignar valor a la propiedad
ReadOnly.
2. Utilice actualizaciones en caché (cached updates) para editar el conjunto
resultado de una consulta sobre varias tablas.
3. Asigne True a RequestLive.
Información adicional
El método Delete de TTable borra el registro actual únicamente. Para borrar
todos los registros de una tabla, utilice el método EmptyTable. Para borrar no
sólo todos los registros, sino también la propia tabla (la estructura), utilice el
método DeleteTable. La tabla debe estar cerrada antes de la llamada a
DeleteTable.
Para borrar selectivamente registros que cumplan cierto criterio, utilice un
componente TQuery y asigne su propiedad SQL según los siguientes patrones:
DELETE FROM Expendable {para borrar todos los registros}
DELETE FROM OutstandingDebts WHERE Amount > 10
{para borrar todos los registros que tengan
un valor mayor que 10 en el campo Amount}
482 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Si tiene derechos para asignar derechos, asígneselos para que pueda ver la
tabla o vista. Si no tiene derechos para asignar derechos, consulte al admi-
nistrador de la base de datos.
2. Si asigna True a la propiedad RequestLive de un componente TQuery, uti-
lice letras mayúsculas para especificar el nombre de la tabla. Por ejemplo:
SELECT * FROM ROUND
Información adicional
Consulte la documentación específica de la base de datos que esté utilizando en
relación con las particularidades de la versión de SQL que ésta soporta. Por
ejemplo, Oracle utiliza PL/SQL, Microsoft MS SQL Server utiliza Transact
SQL, etc.
Solución rápida
Edite el archivo de formulario (.DFM) pulsando con el botón derecho del ratón
sobre el formulario y seleccionando View As Text del menú de contexto.
Encuentre la línea:
object ActiveFormX: TActiveFormX
Luego pulse el botón derecho del ratón sobre el archivo .DFM y seleccione
View As Form del menú de contexto.
Información adicional
Para más información, consulte “ActiveX applications” en la ayuda de Delphi.
Solución rápida
Borre las líneas que sobran.
Información adicional
Este error muchas veces continúa aún después de borrar el texto que está des-
pués del End final, pero no impide la compilación. En este caso, la frase “igno-
red by compiler” se añade al mensaje de error.
Solución rápida
Actualice el ejecutable si actualiza uno o más de los paquetes que éste utiliza.
Alternativamente, renombre el paquete cuando lo actualice para asegurarse de
que la versión antigua del ejecutable todavía puede ser ejecutada (utilizando la
versión antigua del paquete).
Información adicional
Si renombra los paquetes que actualiza, la versión antigua del ejecutable bus-
cará la versión antigua del paquete. El nuevo paquete solamente será encon-
trado por una nueva versión del ejecutable.
Puede también recibir el mensaje de error “A device attached to the system
is not functioning” después de este mensaje de error.
484 Los Tomos de Delphi: Delphi sin problemas
The <> method referenced by <>.<> does not exist. Remove the
reference?
Posible causa de error
Puede haber borrado un método del código, pero el formulario mantiene una
referencia a él en la página de eventos.
Alternativamente, puede estar intentando asignar un gestor de eventos a un
evento que puede que exista (a pesar del mensaje de error), pero el gestor de
eventos no está declarado en la parte Published de la declaración del tipo.
Solución rápida
Seleccione Yes para borrar la referencia al código que no existe.
Información adicional
Si selecciona Yes, la referencia al método será borrada de la página de eventos
del formulario (éste no quedará asociado a ningún evento en particular).
Si borra un método de la parte Implementation sin borrar su declaración en la
parte Interface, obtendrá un mensaje de error de referencia no resuelta. Si
borra la declaración de la parte Interface sin borrar el método de la parte
Implementation, obtendrá un mensaje de error de identificador no declarado.
Si borra los dos (pero ha asociado el método a un evento en el Inspector de
Objetos), el mensaje bajo discusión se mostrará cuando intente compilar.
En un formulario normal o archivo de unidad .PAS, no hay ninguna declara-
ción Published explícita. Todos los métodos que usted añade son automática-
mente colocados en la sección inicial de la declaración del formulario, que es
Published aunque no se designe explícitamente como tal. Cualquier miembro
que no se designe explícitamente de otra manera (por ejemplo, Private o
Public) es Published. Los métodos que utilice como gestores de eventos deben
ser declarados en la sección Published para que produzcan RTTI (Run-Time
Type Information - información de tipos en tiempo de ejecución) y por lo tanto
estén disponibles como métodos apropiados para ser asociados a un evento. El
esqueleto de este tipo de archivo que es producido por Delphi cuando añade su
primer formulario a un proyecto es similar a esto:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
{ésta es la sección Published}
private
{ Declaraciones Private }
Mensajes de error 485
public
{ Declaraciones Public }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
end.
{ Declaraciones Protected }
public
{ Declaraciones Public }
published
{ Declaraciones Published }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TStringGrid1]);
end;
end.
Solución rápida
Modifique la lista de parámetros del método en la parte Interface para que se
corresponda con la definición en la parte Implementation.
Información adicional
Si selecciona Yes, la referencia al método será borrada de la página de eventos
del formulario (éste no quedará asociado a ningún evento en particular).
Solución rápida
Seleccione Run | Parameters, introduzca <Proyecto> /regserver, y pulse
F9 (ejecutar).
Mensajes de error 487
Información adicional
Si escribe <Proyecto> /regserver en la línea de comandos, Windows le avi-
sará que debe especificar una extensión. Puede también utilizar la utilidad
TRegSvr de Borland. Consulte el proyecto de demostración “\Demos\ActiveX\
TRegSvr”.
The changes you requested to the table were not successful because
they would create duplicate values in the index, primary key, or
relationship. Change the data in the field or fields that contain
duplicate data, remove the index, or redefine the index to permit
duplicate entries and try again.
Posible causa de error
Puede estar intentando grabar a través de ADO un registro que ocasionaría
una violación de clave.
Solución rápida
El mensaje de error dice todo lo que necesita usted saber: “Modifique el valor
del campo o campos que contienen datos duplicados, borre el índice o redefínalo
para permitir entradas duplicadas e inténtelo de nuevo”.
Información adicional
Este mensaje de error es inusual, en el sentido de que es muy explícito sobre lo
que puede ser la causa del error y explica cómo rectificar la situación. También
es, indudablemente, el mensaje de error más largo en este libro.
Solución rápida
Marque el archivo como apto para escritura, y luego haga los cambios.
488 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Puede estar indirectamente intentando editar el archivo. Por ejemplo, puede
haber intentado colocar un componente sobre un formulario, lo cual produce
modificaciones tanto en la unidad (.PAS) como en el archivo de formulario
(.DFM) correspondiente.
Solución rápida
Seleccione un componente TDataSource como la propiedad MasterSource del
objeto TTable, y luego asigne la propiedad MasterFields.
Información adicional
Para más información, consulte “Master/Detail forms” en la ayuda de Delphi.
The OLE control may possibly require support libraries that are not
on the current search path or are not present on your system
Posible causa de error
Puede estar intentando instalar un VBX de 16 bits (control de Visual Basic) en
Delphi de 32 bits.
Solución rápida
Instale los controles VBX de 16 bits en Delphi 1 solamente (no en Delphi de 32
bits).
Información adicional
Para Delphi de 32 bits (y Windows en general), necesitará OCXs de 32 bits (en
lugar de VBXs).
Mensajes de error 489
Solución rápida
Compruebe si la unidad que está tratando de instalar ya existe en el paquete
(es contraposición a un componente con una funcionalidad distinta pero con el
mismo nombre).
Si la unidad es realmente la misma, simplemente desista de tratar de insta-
larla otra vez. Si es diferente en funcionalidad pero no en el nombre, renombre
la unidad que está intentando instalar e inténtelo de nuevo.
Información adicional
Como la mayoría de las cosas, los paquetes tienen ventajas y desventajas. Pri-
mero las malas noticias: los paquetes añaden complejidad al proceso de desa-
rrollo y distribución e introducen más problemas potenciales. Una de las
principales ventajas de Delphi 1 (sobre Visual Basic, en particular) era que
permitía crear una solución de un archivo: todo lo que se necesita distribuir es
un simple .EXE (por supuesto, esto no tiene en cuenta las aplicaciones de bases
de datos, donde otros archivos necesitan ser distribuidos). El uso de paquetes
obliga a distribuir varios archivos al usuario.
Las buenas noticias en relación con los paquetes es que pueden ahorrar espacio
de RAM y disco duro si la máquina de destino tiene instaladas varias aplicacio-
nes escritas en Delphi. En lugar de tener el núcleo de la funcionalidad de Del-
phi embebida cada ejecutable, los paquetes permiten distribuir un ejecutable
reducido que llama a los paquetes (.DLLs específicas de Delphi) cuando nece-
sita cierta funcionalidad.
Solución rápida
Seleccione OK. El paquete no es añadido por segunda vez.
490 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Para más información, consulte “packages” en la ayuda de Delphi.
Solución rápida
Compruebe que la aplicación servidora está configurada para escuchar por el
puerto correcto, y que la aplicación cliente está intentando conectarse al mismo
puerto.
Información adicional
Si está probando una aplicación Site Express, puede utilizar el siguiente tipo
de URL: http://localhost:1024/Svrinfo.exe
Localhost es su máquina (IP # 127.0.0.1); está intentando conectarse al puerto
1024 y ejecutar la aplicación Svrinfo.
Site Express apareció por primera vez en Delphi 6.
Solución rápida
Introduzca directamente o navegue hasta (utilizando el botón Browse) una
ruta válida en donde guardar la aplicación.
Información adicional
La ruta no solamente debe ser una unidad y un nombre válido, sino que debe
existir — Delphi no creará el directorio si no existe.
Mensajes de error 491
The procedure entry point <> cannot be found in the dynamic link
library <>.DLL
Posible causa de error
1. Puede haber escrito mal o no haber utilizado la combinación adecuada de
mayúsculas/minúsculas en el nombre de un procedimiento o función en la
aplicación que hace la llamada.
2. Puede haber olvidado colocar el procedimiento o función en la sección
Exports de la .DLL.
Solución rápida
1. Compruebe que el nombre del procedimiento o función esté escrito
correctamente.
2. Coloque el procedimiento o función en la sección Exports de la .DLL .
Información adicional
Aunque .DLL significa “Librería de Enlace Dinámico” (Dynamic Link Library),
puede ser realmente enlazada estáticamente (en cuyo caso el programa no se
podrá ejecutar si hay un problema con la .DLL) o dinámicamente, utilizando
las funciones LoadLibrary y GetProcAddress.
Solución rápida
Especifique un nombre único para el formulario o unidad.
Información adicional
El nombre que asigne a un formulario en el Inspector de Objetos será el nom-
bre de la clase (Form1 por defecto). La clase se convierte en un objeto en
tiempo de ejecución, cuando se crea su instancia.
492 Los Tomos de Delphi: Delphi sin problemas
El nombre bajo el que grabe la unidad será el nombre del archivo (Unit1 por
defecto). Este es el nombre que verá en los cuadros de diálogo Open y Save, en
el Explorador de Windows, etc.
En el código, haga referencia al formulario por su nombre de objeto/clase,
excepto en la sección Uses. Por ejemplo, ésta es una declaración de formulario
sencilla:
unit Unit1; {nombre por defecto del primer formulario
o unidad del proyecto}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs;
type
TForm1 = class(TForm) {nombre por defecto de la clase
del primer formulario del proyecto}
private
{ Declaraciones Private }
public
{ Declaraciones Public }
end;
var
Form1: TForm1; {variable de objeto por defecto y nombre de
clase del primer formulario del proyecto}
implementation
uses {sección Uses auxiliar opcional; útil para evitar
errores de referencia circular entre unidades}
Unit2; {se hace referencia a otros formularios del proyecto
por sus nombres de archivos (y no por sus nombres
de componentes)}
{$R *.DFM}
end.
Solución rápida
Abra un proyecto antes de ejecutar el Asistente para crear .DLLs de recursos.
Información adicional
Las .DLLs de recursos son utilizadas por los proyectos — los proyectos utilizan
los recursos almacenados en las .DLLs. El uso más común de esta característi-
cas está probablemente relacionado con el Entorno de Traducción Integrado de
Mensajes de error 493
Delphi, que hace posible crear varias .DLLs de recursos para cada uno de los
idiomas que desea soportar.
Solución rápida
Introduzca la cadena a buscar.
Información adicional
Para que el texto situado bajo el cursor sea introducido automáticamente en el
cuadro de combinación ‘Text to Find’ del cuadro de diálogo Find Text una vez
se active el diálogo, siga estos pasos:
1. Seleccione Tools | Environment Options.
2. Seleccione la página Editor.
3. Marque la casilla de verificación Find Text at Cursor.
El diálogo Find Text permite configurar muchas características. Pulse el botón
Help para aprender más sobre éstas.
Solución rápida
Seleccione un mapa de bits que sea como máximo un cuadrado de 24 píxeles
como mapa de bits del icono de la paleta para representar la plantilla de
componente.
Información adicional
El icono por defecto para una plantilla de componente es a) el del primer com-
ponente seleccionado, si seleccionó los componentes utilizando el ratón y la
494 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Registre la biblioteca de tipos Webbrokerscript. Pare y reinicie SRVINFO.EXE.
Información adicional
Puede registrar WEBBROKERSCRIPT.TLB seleccionando la opción Ejecutar
del menú de Inicio de Windows e introduciendo el comando tregsvr
WEBBROKERSCRIPT.TLB.
Site Express apareció por primera vez en Delphi 6.
The transaction isolation level must be dirty read for local databases
Posible causa de error
Puede haber asignado uno de los valores tiReadCommitted o tiRepeatableRead
a la propiedad TransIsolation de un componente TDatabase mientras utiliza
una base de datos local o de escritorio, como Paradox o dBASE.
Mensajes de error 495
Solución rápida
Cambie el valor de TransIsolation a tiDirtyRead si el objeto TDatabase hace
referencia a tablas locales (como Paradox y dBASE).
Información adicional
tiDirtyRead (”lectura sucia”) hace que se muestren todos los cambios que se
producen sobre la base de datos (aún si se trata de cambios realizados por otro
usuario que luego no lleguen a ser confirmados). La mayoría de las bases de
datos de servidor SQL, como InterBase, Oracle, MS SQL Server, etc., no sopor-
tan el modo tiDirtyRead. Si asigna tiDirtyRead a la propiedad TransIsolation
cuando utiliza estas bases de datos, ellas promoverán esta configuración a la
próxima disponible (la menos restrictiva disponible para la plataforma
particular).
tiRepeatableRead (”lectura repetible”) garantiza que la vista que tiene un
usuario de un registro no cambie mientras lo está consultando. Aún si otro
usuario edita el registro (e incluso confirma los cambios), la instantánea del
registro continuará siendo visible a este usuario.
tiReadCommitted (”lectura confirmada”) sólo muestras los cambios hechos a los
registros después de que la transacción que los modifica haya sido confirmada.
Para más información, consulte “TransIsolation” en la ayuda de Delphi.
Solución rápida
Apoyándose en el mensaje de error más especifico que se muestra en la barra
de estado en la parte inferior del Editor de Bibliotecas de Tipos, corrija el error
de sintaxis.
Información adicional
Un error que puede aparecer en la barra de estado del Editor de Bibliotecas de
Tipos después del mensaje de error bajo discusión (que aparece en un cuadro
de mensaje) es “A CoClass must implement at least one interface”. Con-
sulte la discusión sobre este mensaje de error para detalles más específicos.
496 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Abra primero una aplicación del Panel de Control, seleccionando File | New |
Control Panel Application.
Solución rápida
Establezca una impresora por defecto para NT.
Información adicional
Citrix Winframe es una tecnología que envía las pulsaciones de teclas y ratón
de la máquina cliente al servidor, y la pantalla se actualiza desde el servidor al
cliente.
Solución rápida
1. Utilice la función de conversión correcta:
HollywoodSquare :=
FloatToStr(Sqr(StrToInt(edtNum2Square.Text)));
2. Asigne el valor de la propiedad a una variable de tipo String, y luego pase
la cadena a la función:
NewPayrollFileLocation := TaxSolver.FileLocation;
. . .
if SelectDirectory(NewPayrollFileLocation,
[sdAllowCreate, sdPerformCreate, sdPrompt], 0) then
Información adicional
1. Como el parámetro de la función Sqr debe ser un número real (Extended),
la conversión debe ser FloatToStr, y no IntToStr, aún en el caso de que el
argumento que envíe y el valor que espere recibir sean enteros. La función
StrToInt funcionará siempre que se introduzca realmente un entero en el
cuadro de edición. Para mayor seguridad, (¡practique la programación
defensiva!) cambie también la llamada a StrToInt por StrToFloat, así:
HollywoodSquare := FloatToStr(
Sqr(StrToFloat(edtNum2Square.Text)));
2. Las propiedades no pueden ser utilizadas como parámetros Var.
Solución rápida
1. Cuando sea necesario, asegúrese de que utiliza una instancia, o variable,
del tipo, en lugar del propio tipo.
2. Compruebe que está anteponiendo el tipo de la clase al nombre del método.
Por ejemplo, si ha declarado un método ToMyMadness como parte de una
declaración de tipo de un formulario, la siguiente definición en la parte
Implementation producirá el mensaje de error bajo discusión:
procedure ToMyMadness(var Dogweight: Byte);
begin
if dogweight < 100 then Kick(hard) else Run;
end;
Lo siguiente compilará bien (anteponiendo el nombre de la clase al nombre
del método):
procedure TForm1.ToMyMadness(var Dogweight: Byte);
begin
if dogweight < 100 then Kick(hard) else Run;
end;
La solución puede ser tan simple como borrar la ‘T’ inicial del nombre del
tipo de clase. Por ejemplo, si intenta esto (crear dinámicamente un cuadro
de diálogo ‘Acerca de’):
TAboutBox := TAboutBox.Create(nil);
try
TAboutBox.ShowModal;
finally
TAboutBox.Free;
end;
recibirá el mensaje de error bajo discusión. Debe hacerlo de esta manera:
AboutBox := TAboutBox.Create(nil);
try
AboutBox.ShowModal;
finally
AboutBox.Free;
end;
3. No llame a métodos abstractos dentro de la unidad en la que estan
declarados.
Información adicional
3. Para redefinir un método abstracto, debe crear una clase que descienda de
la clase en la que el método abstracto está declarado y luego utilizar la
directiva Override. Por ejemplo, si la declaración de tipo de la clase base se
parece a ésta:
type
TBassist = class
procedure Walk; virtual; abstract;
Mensajes de error 499
Solución rápida
Anteponga el nombre del tipo al nombre del método:
procedure TascY2KComboBox.KeyPress(var Key: Char);
var
TextLength, i: Integer;
begin
inherited KeyPress; //TWinControl
Información adicional
Para poder heredar algo, se debe estar en una clase descendiente. El código de
cada método es visto por el compilador como si estuviera incluido dentro de un
bloque un With Self Do invisible. Por esta razón, en el segundo caso la llamada
Inherited KeyPress se interpreta como Inherited TascY3KComboBox.KeyPress,
y esta clase sí hereda un evento KeyPress de TWinControl.
500 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Si la unidad de hecho es la misma unidad, simplemente evite instalarla por
segunda vez. Si se trata de unidades diferentes pero con el mismo nombre,
renombre la segunda unidad y luego añada el componente.
Información adicional
A partir de Delphi 3, cuando se instala un componente, éste es colocado dentro
de un paquete. Puede colocar un componente en un paquete existente o en uno
nuevo. Lo normal es colocar cualquier componente que se añada dentro del
archivo DCLUSR[30,40,50,60].DPK (Componentes de Usuario de Delphi).
Solución rápida
Sustituya el tipo inválido por uno permitido, como:
argyle: array[0..1] of string = ('zig','zag');
Información adicional
Para más información, consulte “initialized variables” en la ayuda de Delphi.
Mensajes de error 501
Solución rápida
Borre la palabra reservada Absolute. El compilador debe poder asignar la
dirección que sea necesaria a la variable local de hilo.
Información adicional
¡Ah, los hilos! Hablando de ellos, si quiere ver un ejemplo elegante de la utili-
zación de hilos, estudie ConnectThread.pas en \Indy\Demos\Newsreader. Jon
Shemitz describe una aproximación similar en un artículo que puede ser
encontrado en www.midnightbeach.com.
Solución rápida
Mueva la declaración Threadvar a una sección global.
Información adicional
Las variables locales de hilo son globales al hilo (pueden ser accedidas desde
cualquier lugar del código del hilo), pero son locales a cualquier instancia del
hilo. Esto quiere decir que si dos instancias del hilo están en ejecución, cada
una tendrá su propia copia de la variable. Si la primera instancia cambia el
valor de la variable local del hilo, y luego la segunda instancia del hilo cambia
el valor de la variable del hilo para hacer algo, la primera instancia no verá el
cambio que la segunda instancia ha hecho (y viceversa).
502 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Introduzca el elemento necesario que falta. En el caso de arriba, se trata de la
parte SELECT <ListaCampos>.
Información adicional
Una sentencia SELECT básica de SQL tiene el formato:
SELECT * { lista de campos }
FROM
Customer { lista de tablas }
WHERE { cláusula where opcional}
AmountOwed > 0
Solución rápida
Encierre el nombre del propietario (dbo) y el nombre de la tabla entre comillas
dobles:
SELECT *
FROM “dbo.COOPER”
Información adicional
Para más información, consulte “RequestLive” en la ayuda de Delphi.
Mensajes de error 503
Solución rápida
1. Consulte la declaración del procedimiento o función para ver la cantidad,
tipo y orden de los argumentos que espera.
2. No pase más de 255 argumentos a un procedimiento o función de automati-
zación OLE.
3. Anteponga el nombre de la unidad en donde está definido el procedimiento
o función que intenta llamar al nombre de procedimiento o función.
Información adicional
3. Un par de casos frecuentes donde esto ocurre es con los procedimientos
Append y Abort. El procedimiento Append está declarado en la unidad
System; el método Append de TDataSet está en la unidad DB (dbiProcs en
Delphi 1). La clase TStrings también tiene un método Append, en la
unidad Classes. Abort está definido como un procedimiento en SysUtils y
es además un método de la clase TPrinter, definida en la unidad Printers.
Para más información, consulte “open-array parameters” en la ayuda de
Delphi.
Solución rápida
Utilice un componente TDatabase. Asigne a la propiedad Alias del componente
TDatabase el alias del BDE (o nombre de ruta). Asigne el valor de la propiedad
504 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Al utilizar un componente TDatabase, se reduce el número de conexiones que
la aplicación utiliza a una sola (todos los objetos comparten la conexión que se
establece en el componente TDatabase). Los componentes TTable, TQuery y
TStoredProc utilizan un alias local para hacer referencia al componente
TDatabase en su propiedad DatabaseName.
Solución rápida
1. CD-ROM significa Compact Disc-Read Only Memory (Memoria de sólo lec-
tura en disco compacto); ya que de hecho es un dispositivo de sólo lectura,
no se puede escribir en un CD-ROM.
2. Asegúrese siempre de llamar a CloseFile cuando termine de utilizar un
archivo. Por ejemplo:
var
texan: TextFile;
begin
AssignFile(texans, 'LoneDove.txt');
Rewrite(texans);
Writeln(texans,
'L. McMurtry wrote about the cattle drive to Montana’);
CloseFile(texan);
end;
3. Configure la línea Files= en CONFIG.SYS a un valor mayor que el actual,
por ejemplo a 100 o aún a 255, si es necesario.
4. Mueva su proyecto a una ubicación que tenga una ruta más corta, como
C:\MeFeelMe.
Información adicional
2. Olvidarse de llamar a CloseFile para un archivo puede ocasionar la pérdida
de algunos o todos los datos escritos en el archivo.
Mensajes de error 505
Solución rápida
Limite la cantidad de ediciones realizadas dentro de una misma transacción.
Información adicional
Si utiliza un componente TDatabase, puede utilizar su método
StartTransaction (terminado por un Commit o Rollback) para tratar un grupo
de operaciones como una transacción — todas ellas fracasarán como grupo
(Rollback) o serán confirmadas como grupo (Commit).
Cada registro que es modificado consume un bloqueo. El máximo número de
bloqueos por tabla es de 255, así que esa es la cantidad máxima de registros
que se pueden modificar en una transacción.
Solución rápida
Cierre las tablas cuando termine de utilizarlas. Si utiliza una cantidad relati-
vamente pequeña de tablas (hasta varias docenas), probablemente podrá espe-
rar hasta que se cierre el programa para cerrar las tablas. Si utiliza más de
cien tablas, deberá cerrar las tablas tan pronto como termine de utilizarlas.
Información adicional
No es posible incrementar la cantidad de cursores disponibles al BDE. El
número de tablas que se puede tener abiertas a la vez es de 127. Si recibe este
error mientras tiene menos de 127 tablas abiertas, puede haber encontrado
una limitación de su base de datos particular, y no del BDE. Por ejemplo, en
Oracle el número máximo de cursores abiertos simultáneamente puede ser
506 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Configure la línea Files= en CONFIG.SYS a un valor más alto que el
actual, por ejemplo a 100 o aún a 255, si es necesario.
2. Incremente el valor del parámetro MAXFILEHANDLES en la página
System de la utilidad BDE Configuration/Administration o en el nodo
System | Init.
Información adicional
Consulte “Too many files open”.
. . .
var
Gitfiddle: TGramps;
begin
Gitfiddle:= TYoungWhipperSnapper.Create;
Gitfiddle.NoteOrTriad(1, 2, 3)
Solución rápida
1. Consulte la definición del procedimiento o método que esté llamando para
determinar la signatura (número, tipo, y secuencia de parámetros) que
necesita.
2. Para llamar al método NoteOrTriad de TYoungWhipperSnapper, declare
Gitfiddle como TYoungWhipperSnapper, o declare NoteOrTriad como
virtual en TGramps y redefínalo en TYoungWhipperSnapper.
Información adicional
Consulte “Not enough actual parameters”.
Transaction Is Active
Posible causa de error
Puede haber llamado a StartTransaction sobre un componente IBTransaction
que ya estaba activo. Por ejemplo, lo siguiente generaría este mensaje de error:
. . .
IBTrans.Active := True;
try
with IBQry do begin
Unidirectional := True;
Database := dm.IBDB;
Transaction := IBTrans;
SQL.Add('INSERT INTO LIABILITY (');
SQL.Add('AGENCY_ID,EMPLOYER_ID,PAYROLL_DATE,’
+ ‘LIABILITY_AMOUNT,DUE_DATE)');
SQL.Add('VALUES (');
SQL.Add(':AgencyID,:EmployerID,:PayrollDate,’
+ ‘:LiabilityAmount,:DueDate)');
Params.ParamByName('AgencyID').AsString := AAgencyID;
Params.ParamByName('EmployerID').AsString :=
AEmployerID;
Params.ParamByName('PayrollDate').AsDate :=
APayrollDate;
Params.ParamByName('LiabilityAmount').AsCurrency :=
ALiabilityAmount;
Params.ParamByName('DueDate').AsDate := dDueDate;
IBTrans.DefaultDatabase := dm.IBDB;
508 Los Tomos de Delphi: Delphi sin problemas
IBTrans.StartTransaction;
. . .
Solución rápida
Active la transacción solamente una vez. Para el ejemplo mostrado arriba,
simplemente borre la línea:
IBTrans.Active := True;
Información adicional
Si en un punto particular del programa la transacción puede o no puede estar
activa, puede comprobarlo del siguiente modo:
if not IBTrans.Active then
IBTrans.StartTransaction;
Solución rápida
Cierre explícitamente todos los conjuntos de datos antes de que la aplicación
termine. Por ejemplo:
procedure TViewEditTables.FormDestroy(Sender: TObject);
begin
IBtbl.Active := False;
end;
Información adicional
Esto realmente no debería ser absolutamente necesario, aunque es una buena
práctica cerrar todos los conjuntos de datos antes de terminar.
2. Puede estar copiando datos de un tipo de base de datos a otro, y los for-
matos de fechas no son iguales.
3. Puede estar trabajando con una tabla dBASE y estar utilizando un contro-
lador de lenguaje distinto al utilizado originalmente (con el que se creó la
tabla y/o se añadieron datos posteriormente).
Solución rápida
1. Utilice el mismo formato de fecha en ambas máquinas.
2. Convierta el formato de fecha al de la máquina destino antes o durante la
copia.
3. Con la utilidad BDE Configuration (Drivers | dBASE | LangDriver),
cambie el parámetro ‘Language Driver’ al que originalmente utilizó.
Información adicional
Las fechas nulas o vacías en Delphi de 32 bits no están realmente ‘en blanco’,
sino que contienen el valor Diciembre 31 de 1899. En Delphi 1, la fecha de
inicio era 01/01/01. Este valor inicial fue cambiado para garantizar la compati-
bilidad con la automatización OLE.
Solución rápida
Marque un bloque para buscar, o cambie la opción de búsqueda a global, mar-
cando la casilla de verificación Global en la sección Scope del diálogo Find.
Información adicional
Estudie las demás opciones de búsqueda que están disponibles en el diálogo
Find.
Solución rápida
Puede utilizar TypeInfo solamente para los tipos que pueden ser utilizados en
propiedades Published, como Integer, Extended, String, TMethod y Variant.
Información adicional
Para más información, consulte “TypeInfo” en la ayuda de Delphi.
Solución rápida
Cambie la clase de la que desea heredar (la clase ancestro) por una válida. Por
ejemplo, en el caso de arriba, lo siguiente evitaría que el error ocurriera de
nuevo:
type
TForm3 = class(TForm)
Información adicional
Para más información, consulte “forms” en la ayuda de Delphi.
type
TStendahl = Object
RedAndBlack: TMemo;
published
Languages: Integer;
Solución rápida
Cambie el tipo a una clase o borre la sección Published.
type
TStendahl = class { hereda de TObject si no se especifica }
. . .
Información adicional
Para más información, consulte “class declarations” en la ayuda de Delphi.
Solución rápida
Cambie el tipo a una clase o borre la sección Automated.
type
TModel = class { hereda de TObject si no se especifica }
. . .
Información adicional
Para más informacion, consulte “Automation” en la ayuda de Delphi.
512 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Elimine la cadena del registro o declárela como una cadena corta
explícitamente (declarándola como de tipo ShortString) o implícitamente
(proporcionándole una longitud, como String[20]). Por ejemplo, para solucionar
el problema de arriba, utilice esto:
type
TDateRec = File of record
FlowSnakes, Snirt: Integer;
Bouldershades: string[20];
end;
Información adicional
No se permite utilizar cadenas largas en un fichero de registros, debido a que
las propias cadenas (y no punteros a ellas) se deberán almacenar en los regis-
tros, y en este caso el tamaño del registro no podría ser determinado por
adelantado.
Solución rápida
Utilice identificadores de tipo válidos. A continuación se muestran ejemplos de
declaraciones de un tipo de clase, un tipo enumerado y un tipo subrango:
{clase}
type
Mensajes de error 513
TForm1 = class(TForm)
. . .
{enumerado}
type
Cartwrights = (Dunn, Nelson, Owen, ShannonC, ShannonJ, StSure, Szajki);
{subrango}
type
Ratings = 1..4;
Información adicional
Este mensaje de error es normalmente el resultado de un error tipográfico u
omisión.
Para evitar el error, debe teclear el segundo punto entre los límites inferior y
superior del array (0 y 143 en el ejemplo):
type
gross = array[0..143] of integer;
Solución rápida
Proporcione el segundo punto en la declaración del tipo array, entre los límites
inferior y superior del array.
Información adicional
Así es como se declara y utiliza un array:
type
gross = array[0..143] of integer;
...
var
grody: gross;
...
grody[0] := StrToInt(Edit1.Text);
grody[1] := StrToInt(Edit2.Text);
...
514 Los Tomos de Delphi: Delphi sin problemas
Puede inicializar todos los valores del array en el evento OnCreate del
formulario así:
procedure TForm1.FormCreate(Sender: TObject);
var
w: word;
begin
for w:=0 to sizeof(gross)-1 do grody[w]:=0;
end;
Solución rápida
Utilice el mismo tipo de datos para almacenamiento en disco y procesamiento
en memoria. Por ejemplo, si graba datos utilizando AsString, cree un tipo de
campo correspondiente de tipo String en el ClientDataSet.
Información adicional
TClientDataSet puede leer y escribir datos tanto en formato binario (.CDS)
como en XML.
Solución rápida
Ejecute operaciones matemáticas sólo sobre campos numéricos, por ejemplo:
SELECT AVG(Salary) FROM NFLQBacks
Mensajes de error 515
Información adicional
Para más información, consulte “types” en la ayuda de Delphi.
Solución rápida
Utilice únicamente tipos de automatización cuando haga llamadas de automa-
tización OLE.
Información adicional
Todos los tipos de automatización OLE deben ser compatibles con Variant. Los
siguientes tipos de Delphi pueden ser utilizados en la automatización: Byte,
Currency, Double, IDispatch, Integer, IUnknown, OLEVariant, SmallInt,
Single, TDateTime, WideString, WordBool, SCode, TColor y TSafeArray.
Solución rápida
1. Asegúrese de utilizar condiciones Boolean donde el compilador espera un
valor que se evalúe a True/False. Por ejemplo, esto compilará:
if Form1.Name = 'Sake' then
2. En este caso, necesita añadir el operador de alcance ‘.’ entre la conversión
de tipos Sender As TDBEdit y la propiedad Tag:
if (Sender as TDBEdit).Tag = 8 then
Información adicional
Algunos lenguajes y entornos se refieren al tipo Boolean como Logical
(incluyendo Paradox).
Y también lo siguiente:
Huckleberry: String[3.14];
Solución rápida
Si va a declarar implícitamente una cadena corta, proporciónele un valor
entero entre 1 y 255 (si quiere una cadena de longitud 1, no obstante, puede
utilizar en vez de String el tipo Char).
Información adicional
Para más información, consulte “integers” en la ayuda de Delphi.
BirdDog := TypeInfo('yowza-bop');
Solución rápida
Proporcione a la función TypeInfo solamente tipos que puedan ser utilizados en
las propiedades Published, como Integer, Extended, String, TMethod y
Variant.
Información adicional
Para más información, consulte “TypeInfo” en la ayuda de Delphi.
Solución rápida
Haga virtual como mínimo un método de la clase. Por ejemplo, podría añadir la
directiva Virtual a un método existente, o añadir un método virtual sin sentido
para que una VMT sea creada y TypeOf esté disponible.
Información adicional
VMT significa “virtual method table”. Para más información, consulte “virtual
method table” y “dynamic methods” en la ayuda de Delphi.
518 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
1. Compruebe que todos los parámetros que pasa son del mismo tipo de datos
que el parámetro formal correspondiente del procedimiento o función.
2. Sustituya Integer por DWord:
function WinExecAndWait32(FileName: String;
Visibility : Integer; DoWait : Boolean): DWord;
Información adicional
1. Si el parámetro formal no es un parámetro Var, el mensaje de error es
“Incompatible Types: <> and <>”. En el caso de arriba, el mensaje
exacto sería: “Incompatible Types: Variant and TQuery”.
Mensajes de error 519
Solución rápida
Asigne una sentencia SQL a la propiedad SQL, bien en tiempo de diseño en el
Inspector de Objetos, o en tiempo de ejecución, antes de activar el componente
TSQLQuery.
Información adicional
Los componentes DBExpress aparecieron por primera vez en Delphi 6.
Solución rápida
Sustituya los archivos que faltan.
Información adicional
Delphi almacena los proyectos del Almacén de Objetos en el directorio
\DelphiX\Objrepos.
Solución rápida
Añada los elementos necesarios a la lista de cadenas antes de intentar acceder
al correspondiente índice. Por ejemplo:
ListBox1.Items.Add('AWopBopALooBopALopBamBoom');
ListBox1.Items.Insert('SuperCalifragilisticexpealidocious');
ListBox1.Items.Add('Antidisestablishmentarianism');
ListBox1.Items.Insert('deoxyribonucleic acid');
Información adicional
Las listas de cadenas son utilizadas internamente por muchas clases y
controles de Delphi.
Solución rápida
Si no instaló InterBase cuando instaló Delphi, instale la versión local de Inter-
Base que viene con Delphi desde el CD-ROM.
Información adicional
Para más información, consulte la documentación de InterBase que recibió con
Delphi.
Solución rápida
Abra DELPHI.INI (situado por defecto en el directorio de Windows) y añada o
modifique la entrada ReportSmith para que refleje la ubicación actual de
ReportSmith. Por defecto, la entrada será:
[ReportSmith]
ExePath=C:\RPTSMITH
Mensajes de error 521
Información adicional
Delphi 1 contiene ReportSmith. Delphi 2 contiene ReportSmith y Quick
Reports (aunque ReportSmith estaba en cierto modo escondido). Delphi 3 y
superiores incluyen solamente QuickReports. Por supuesto, usted no está limi-
tado a utilizar una de esas dos herramientas de generación de informes. Puede
utilizar otras herramientas, como ReportBuilder, Crystal Reports, o incluso
crear sus informes personalizados sin utilizar un motor de informes.
['{51DDE8C0-CBE2-11D1-9BDB-444553540000}']
function FetchedPaper: Boolean;
function getBarkType: string;
procedure setBarkType(Value: string);
property BarkType: string read getBarkType
write setBarkType;
end;
TPoodle = class(TInterfacedObject, ILittleDog)
FBarkType: string;
function FetchedPaper: Boolean;
function getBarkType: string;
procedure setBarkType(Value: string);
. . .
procedure TForm1.Button1Click(Sender: TObject);
var
Fifi: ILittleDog;
begin
Fifi := TPoodle.Create;
try
. . .
finally
Fifi.Free;
end;
end;
9. Puede haber añadido un punto y coma a la declaración de un objeto de
interfaz, así:
type
TClassThatImplementsAnInterface =
class(TGr8OoglyMoogly, IChihuahua);
10. Puede estar haciendo una referencia a un valor Resourcestring situado en
la sección Implementation de otra unidad, por ejemplo:
unit NGCDialogMessages;
interface
implementation
const
AppName = 'NGC';
resourcestring
SEntriesMustMatch = 'New password entries did not match’;
SEntriesDoNotMatch =
'New password entries do not match. Please try again.';
SAppWillClose_LogOnWithNewPassword =
AppName + ' will now close. Execute ' +
AppName + ' again to log on with the new password.';
11. Puede haber intentado asignar un valor a una variable Result en un proce-
dimiento. Esta variable está implícitamente disponible sólo en las
funciones.
12. Puede estar haciendo una referencia a un miembro de un tipo Set o
enumerado en el código, como por ejemplo:
Mensajes de error 523
if IncludeArchiveFiles then
frmZipster.lstbxROFiles.FileType :=
frmZipster.lstbxROFiles.FileType + [ftArchive] // problema
else
. . .
13. Puede estar llamando a un método de clase en una sección Initialization o
Finalization.
Solución rápida
1. Compruebe que cualquier variable a la que esté haciendo una asignación
esté declarada y en ámbito. Si se trata de una variable global, declárela en
la parte Interface de la unidad o en una unidad Globals destinada expresa-
mente a las variables a las que quiera hacer referencia desde varias
unidades. Si se supone que la variable es local, compruebe que la ha
declarado. Si el identificador es un procedimiento o función, verifique que
la unidad que lo contiene esté incluida en la sección Uses (de la parte
Interface o Implementation).
2. Asigne a las variables o propiedades valores que sean del tipo apropiado.
3. Borre el nombre de la clase del método en la sección Interface. Ya es asig-
nado implícitamente.
4. Verifique que ha escrito bien el identificador en su declaración y definición,
así como en cualquier asignación relacionada con él.
5. Añada la unidad necesaria a la sección Uses. Para determinar qué unidad
necesita añadir cuando llama un procedimiento o función de Object Pascal,
busque el procedimiento o función en la ayuda de Delphi y vea en qué
unidad está definido (y luego añádala a la sección Uses).
6. Revierta la declaración del tipo a su estado anterior.
7. No intente llamar a un método declarado en la sección Private de otra
clase. No intente acceder directamente a un campo declarado en la sección
Private de otra clase. Acceda al valor, si es posible, a través de la
propiedad Public o Published asociada al campo privado. Por ejemplo, la
clase TSpeedButton, declarada en BUTTONS.PAS, contiene lo siguiente:
private
. . .
FFlat: Boolean;
published
. . .
property Flat: Boolean read Fflat
write SetFlat default False;
Puede acceder indirectamente al campo privado FFlat asignándolo o leyén-
dolo desde la propiedad Flat, pero no puede leer o escribir directamente en
el campo FFlat. Dependiendo de su punto de vista, puede considerar esto
mejor o peor.
8. No llame a Free para instancias de interfaces.
524 Los Tomos de Delphi: Delphi sin problemas
Información adicional
5. En Delphi 6, los procedimientos y funciones que dan soporte al tipo
Variant, incluyendo los procedimientos y funciones que manipulan arrays
variantes, como VarArrayCreate y VarArrayOf, han sido movidos de
SYSTEM.PAS a VARIANTS.PAS. Si porta una aplicación que utiliza
variantes de una versión anterior de Delphi a Delphi 6 o superior,
necesitará añadir Variants a la cláusula Uses. Consulte VARUTILS.PAS,
que utiliza Variants, para ver la implementación específica (en dependen-
cia de la plataforma bajo la cual esté desarrollando).
En Delphi 6, TModalResult ha sido movido de FORMS.PAS a
CONTROLS.PAS. Cuando porte una aplicación de una versión anterior de
Delphi a Delphi 6 o superior, puede que necesite añadir Controls a la cláu-
sula Uses (preferiblemente a la cláusula Uses de la sección
Implementation) si recibe este mensaje de error debido a que no se ha
encontrado TModalResult.
Mensajes de error 525
Solución rápida
Añada Variants a la cláusula Uses de la parte Implementation, o si es
necesario, a la cláusula Uses de la parte Interface.
526 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Puede obtener este mensaje de error cuando recompile en Delphi 6 una aplica-
ción que compila correctamente en versiones anteriores de Delphi. La declara-
ción de EmptyParam ha sido movida a la unidad Variants (Variants ha
experimentado extraordinarias mejoras, no solamente relacionadas con COM).
Solución rápida
Rehabilite la sintaxis extendida (está habilitada por defecto) marcando la casi-
lla Compiler | Syntax Options | Extended Syntax o introduciendo la
directiva {$X+} o {$EXTENDEDSYNTAX ON}.
Información adicional
Para más información, consulte “Extended Syntax” y “Result variable” en la
ayuda de Delphi.
Solución rápida
Proporcione el elemento que falta en la sentencia, por ejemplo, el nombre de la
columna primaria:
ALTER TABLE Placemats
ADD CONSTRAINT pkSlogan PRIMARY KEY (Slogan)
Información adicional
No imponga una restricción de clave primaria sobre una columna que pueda
ser nula. Una clave primaria debe contener valores únicos, y por lo tanto podrá
contener a lo sumo un valor nulo.
Solución rápida
1. Renombre la unidad.
2. Escoja una de las siguientes soluciones:
a. Si es posible, localice la primera unidad mencionada en el mensaje de
error, muévala al mismo directorio en el que reside el archivo de
unidad compilada correspondiente (.DCU) y recompile.
b. Utilice una versión anterior de la segunda unidad mencionada en el
mensaje de error (una que sea anterior a la modificación).
Información adicional
1. Adopte un convenio de nombres que haga difícil que se produzcan colisio-
nes de nombres. Por ejemplo, si su nombre es Rupert Pupkin, puede añadir
rp a los nombres de sus unidades, como rpMain, rpGlobal, etc.
2. Es altamente recomendable que no cambie el contenido de la sección
Interface del código fuente de Delphi. Es altamente recomendable que
tampoco cambie la sección Implementation del código fuente de Delphi. Si
sabe lo que está haciendo (es decir, si cree que sabe más que el equipo de
desarrollo de Delphi, y no puede esperar a un parche), hágalo a su propio
528 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Borre los archivos .DCU y recompile.
Información adicional
El mensaje de error puede mostrar una línea del archivo de proyecto (.DPR).
Solución rápida
Cambie los nombres de las unidades seleccionando File | Save (si se llama
actualmente Unit1) o File | Save As.
Información adicional
Al cambiar indirectamente el nombre de la unidad (cambiándolo a través de
File | Save [As] en lugar modificar el antiguo nombre en el código), Delphi
también cambiará el nombre del archivo, manteniendo la sincronización.
Por supuesto, si cambia el nombre de la unidad a través de File | Save [As]
después de haber añadido la unidad a la cláusula Uses de otras unidades, ten-
drá que actualizar éstas.
Solución rápida
1. Utilice nombres únicos para sus unidades; trate de establecer un convenio
de nombres que garantice la unicidad, como anteponer o añadir sus
iniciales, las iniciales de la compañía, etc.
2. No modifique el código fuente de la VCL a menos que tenga una muy
buena razón para hacerlo, y esté dispuesto a proporcionar su propio soporte
técnico a partir de ese momento.
Información adicional
1. El compilador no le impedirá que nombre a su unidad de la misma forma
que una ya existente, por ejemplo, Buttons.
2. El código fuente de la VCL está destinado principalmente para referencia;
no es recomendable modificarlo.
Unknown Column
Consulte “Unknown SQL Error”.
Unknown database
Posible causa de error
1. Puede haber especificado un alias de base de datos o una ruta para la
propiedad DatabaseName de un componente TDatabase o de un TDataset
(TTable, TQuery, o TStoredProc en todas las versiones de Delphi;
TClientDataset en las versiones 3 y superiores de Delphi Cliente/Servidor;
TNestedTable en Delphi 4 y superiores) que no ha sido reconocido.
2. Puede haber intentado asignar el valor True a la propiedad Connected de
un componente TDatabase sin proporcionar un valor para la propiedad
AliasName.
3. El archivo de configuración del BDE (IDAPI32.CFG en Delphi de 32 bits,
IDAPI.CFG en Delphi 1) puede haber sido movido o borrado.
Solución rápida
1. Si proporciona una ruta para esta propiedad, la ruta debería ser
plenamente cualificada* y la base de datos utilizada debe ser Paradox o
dBASE. Si la propiedad DatabaseName corresponde a un alias, asegúrese
de que el alias haya sido configurado apropiadamente.
530 Los Tomos de Delphi: Delphi sin problemas
Información adicional
1. * Plenamente cualificada significa que el nombre de ruta es explícito o
absoluto (a diferencia de un nombre de ruta relativo). Borland\Delphi 3 es
un ejemplo de un nombre de ruta relativa. C:\No\Evel\Hear\No\Knevel
es un ejemplo de ruta absoluta.
Para crear un alias del BDE, siga estos pasos:
a. Seleccione Database | Explore.
b. En SQL Explorer/Database Explorer, seleccione Object | New.
c. Seleccione el tipo de controlador deseado en el cuadro de combinación
(seleccione Standard si está trabajando con tablas Paradox o dBASE)
y pulse el botón OK.
d. El nuevo alias se mostrará en el panel izquierdo de la página Database
con un nombre por defecto, como Standard1.
e. Pulse con el botón derecho sobre el nuevo alias, seleccione Rename del
menú de contexto, e introduzca el nombre que desee darle al alias.
f. En la página Definition del panel derecho, seleccione el controlador
apropiado en el cuadro de combinación Default Driver.
g. Introduzca la ruta a la base de datos en el cuadro de edición Path.
h. Seleccione Object | Exit, y luego Yes para grabar los cambios que
haya hecho.
3. La ubicación por defecto para el archivo de configuración del motor
(IDAPI32.CFG) es:
C:\Archivos de programa\Borland\Common files\BDE
Para verificar el valor que indica el Registro del sistema para la ubicación
de IDAPI32.CFG, siga estos pasos:
a. Seleccione Inicio | Ejecutar.
b. Introduzca regedit en el cuadro de combinación Abrir y pulse el botón
OK (o presione la tecla Enter).
c. Navegue hasta
HKEY_LOCAL_MACHINE\Software\Borland\Database Engine.
El dato CONFIGFILE01 mostrará la ruta donde está ubicado el archivo de
configuración. Si difiere de la ubicación de su copia de IDAPI32.CFG, mueva el
archivo a la localización apuntada por la configuración del Registro (lo más
recomendable), o modifique la configuración del Registro para que apunte a la
localización actual del archivo.
Mensajes de error 531
Solución rápida
1. Asegúrese de que la sintaxis que está utilizando es correcta y que lo que
está tratando de hacer es aceptable para el compilador de Delphi.
2. Declare todos los métodos Virtual, Dynamic, Abstract u Overload dentro de
la declaración de un tipo de clase.
532 Los Tomos de Delphi: Delphi sin problemas
Información adicional
2. Para que sean de utilidad, los métodos virtuales, dinámicos o abstractos
deben ser miembros de una clase, de modo que otra clase puede heredar de
ésta y redefinir los métodos. Los métodos virtuales incluyen la directiva
Virtual; los métodos dinámicos - la directiva Dynamic; y los métodos
abstractos - la directiva Virtual o Dynamic seguida de la directiva
Abstract. Los métodos sobrecargados añaden la palabra reservada
Overload a su declaración.
3. Puede utilizar los mensajes de Windows como una herramienta de
depuración o de educación. Por ejemplo, para determinar con qué
frecuencia y cuándo su programa recibe el mensaje WM_ACTIVATE de
Windows, declare este procedimiento:
procedure wmactivate(var Message: TMessage); message WM_ACTIVATE;
y luego escriba un mensaje en un archivo de texto cada vez que Windows
envíe este mensaje a su aplicación:
var {Esto está en la sección Interface}
TForm1: TForm;
tf: TextFile;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
AssignFile(tF,'trakmsgs.txt');
if FileExists('trakmsgs.txt') then
Append(tF)
else
Rewrite(tF);
WriteLn(tF, DateTimeToStr(Now));
end;
...
procedure TForm1.wmactivate(var Message: TMessage);
begin
{Hereder la respuesta de Delphi al mensaje}
inherited;
Writeln(tf,'Se ha recibido el mensaje WM_Activate');
end;
...
procedure TForm1.FormDestroy(Sender: TObject);
begin
CloseFile(tF);
end;
Mensajes de error 533
Por supuesto, puede hacer esto para tantos mensajes de Windows como
desee (busque “WM_” en la ayuda de Delphi para ver una lista de mensajes
de Windows), y es aún más fácil crear un registro de mensajes parecido
para los gestores de eventos de su aplicación. Simplemente pulse dos veces
sobre el evento de su interés en la página Events para cualquiera de los
formularios o componentes e introduzca una sentencia Writeln similar a la
mostrada arriba. Por ejemplo, se podría rastrear el evento OnPaint de un
formulario así:
procedure TForm1.FormPaint(Sender: TObject);
begin
Writeln(tf,'Se ha disparado el evento Paint');
end;
Solución rápida
Coloque la directiva Override solamente en la sección Interface.
Información adicional
Para que sea posible redefinir un método, el método debe haber sido declarado
como virtual en la clase base.
Unknown Identifier
Posible causa de error
Puede estar haciendo referencia a algo que está declarado en una unidad que
no ha sido añadida a la cláusula Uses de su unidad.
Solución rápida
Determine la unidad que falta basándose en el identificador con el que el com-
pilador está tropezando. Si es un identificador de Delphi, puede hacer esto
colocando el cursor sobre el identificador y pulsando la tecla F1. La pantalla de
ayuda relativa al identificador mostrará la unidad en la que éste está decla-
rado. Si el identificador no es un identificador de Delphi, es de un tercero o
suyo propio. En cualquier caso, una vez determine la unidad en la que el iden-
tificador está declarado, añada esta unidad a su cláusula Uses.
534 Los Tomos de Delphi: Delphi sin problemas
Información adicional
Puede utilizar otra unidad añadiéndola a la cláusula Uses en la parte Interface
(creada automáticamente por Delphi e inicialmente poblada con muchas
unidades estándar), o añadiendo su propia cláusula Uses directamente bajo la
palabra reservada Implementation.
Solución rápida
1. Solamente cargue archivos de los tipos apropiados dentro de la propiedad
Picture de TImage.
2. Incluya explícitamente siempre la extensión del archivo gráfico (.BMP,
.ICO, .WMF o .EMF).
Información adicional
Debe especificar archivos de imágenes en alguno de los formatos gráficos
reconocidos por Delphi. Por ejemplo, cualquiera de los siguientes son válidos:
Image1.Picture.LoadFromFile('C:\VG\WheatFieldWithCrows.BMP');
Image2.Picture.LoadFromFile('C:\VG\TheStarryNight.ICO');
Image3.Picture.LoadFromFile('C:\VG\SelfPortraitWithHat.WMF');
Image4.Picture.LoadFromFile('C:\VG\ThePotatoEaters.EMF');
Solución rápida
Asigne False a ENABLE SCHEMA CACHE con la utilidad BDE Configuration
antes de hacer cualquier cambio en la estructura de las tablas de la base de
datos.
Pulse el botón Help en la utilidad BDE Configuration para información especí-
fica sobre estos parámetros para el controlador que está utilizando.
Información adicional
Si el esquema está en caché (ENABLE SCHEMA CACHE tiene asignado
True), los cambios hechos al esquema de base de datos durante el tiempo de
ejecución no serán reconocidos por el BDE. El esquema de la base de datos
debe permanecer estático si desea tener la caché de esquemas en True. Ade-
más de la opción ENABLE SCHEMA CACHE, para las bases de datos de servi-
dor SQL (como InterBase, MS SQL Server, Sybase, Oracle, etc.) también
existen los parámetros SCHEMA CACHE DIR, SCHEMA CACHE SIZE y
SCHEMA CACHE TIME en la página/nodo Driver de la utilidad BDE
Configuration.
Solución rápida
Proporcione la contraseña correcta en el cuadro de diálogo Database Login y
pulse el botón OK.
Información adicional
Puede evitar tener que introducir continuamente una contraseña mientras está
desarrollando su aplicación configurando la contraseña en el código o a través
de la sección Parameter Overrides del componente TDatabase.
Para asignar la contraseña en el código, añada una línea como la siguiente en
algún punto del código antes de intentar acceder a la base de datos (por
ejemplo, en el evento OnCreate del formulario):
536 Los Tomos de Delphi: Delphi sin problemas
Session.AddPassword('Kennwort');
Solución rápida
Elimine el argumento con nombre:
procedure BackwardsCoding;
var
v: Variant;
begin
v.Tail('Cartwrights', 'Beech');
var
v: Variant;
begin
v.Tail('Beech', Bonanza := 'Cartwrights');
Información adicional
Para más información, consulte “named parameters” en la ayuda de Delphi.
Solución rápida
Verifique que los parámetros que haya introducido estén exactamente como
son requeridos. En el ejemplo de arriba, es necesario que sea añadido un guión
bajo al parámetro user_name:
user_name=SYSDBA
password=masterkey
Información adicional
Durante el desarrollo, es conveniente asignar False a la propiedad Login de
IBDatabase, y proporcionar la información necesaria (nombre de usuario y
contraseña) en la propiedad Params. Antes de distribuir, sin embargo, puede
encontrar conveniente forzar al usuario a introducir sus datos para acceder a
la base de datos (dependiendo, por supuesto, del tipo de aplicación/datos que
esté manejando). En ese caso, es recomendable cambiar el nombre de usuario y
la contraseña a otros que no sean sus valores por defecto SYSDBA y
masterkey.
quizás simplemente su nombre esté mal escrito. Note que una declaración
de procedimiento o función en la parte Interface de una unidad es equiva-
lente a una declaración adelantada — usted deberá proporcionar su
implementación en la parte Implementation. De forma similar, la declara-
ción de un método en una clase o tipo de objeto es equivalente a una
declaración adelantada. Puede necesitar anteponer el nombre de la clase al
procedimiento. Por ejemplo, si ha declarado en la parte Interface un
método llamado PlayBaseball, su definición en la parte Implementation
debe ser la siguiente (asumiendo que la clase es TForm1):
TForm1.PlayBaseball;
2. Puede haber olvidado añadir la palabra reservada External a la
declaración formal de un procedimiento (o función) situado en una .DLL.
Solución rápida
1. Defina el procedimiento o función declarado en la parte Interface de la
unidad en la parte Implementation de la unidad.
2. Añadir la palabra reservada External.
Información adicional
Declarar un método en la sección Interface equivale a prometer que se propor-
cionará el resto de la información más adelante (en la sección Implementation
que sigue). Debe cumplir su promesa haciéndolo.
Solución rápida
Cargue el archivo .DCR en el Image Editor de cualquier versión de 32 bits de
Delphi y guárdelo (será grabado en formato de 32 bits). Intente de nuevo insta-
lar el componente.
Información adicional
Puede necesitar editar el archivo .DCR en el Image Editor para que el cambio
a 32 bits tenga efecto. Por ejemplo, puede cambiar un píxel, deshacer el cambio
(pulsando Ctrl+Z), y luego guardarlo.
Mensajes de error 539
Unterminated string
Posible causa de error
1. Puede haber olvidado el apóstrofe (comilla simple) de cierre al final de una
cadena.
2. Puede haber partido una cadena en varias líneas en el editor de código de
Delphi, pero olvidó terminar cada línea con un apóstrofe.
Solución rápida
1. Incluya un apóstrofe al final de cada cadena.
2. Incluya un apóstrofe al final de cada línea en una cadena multilínea.
Información adicional
Para partir una cadena en varias líneas, utilice el operador + para concatenar
las líneas. He aquí un ejemplo:
s := 'Das fesche Umherstolzieren des Hahns '
+ 'ist ein bekannter Anblick.'
+ 'Was fehlt dir, mein Junge?';
Solución rápida
Verifique que haya una coma entre todas las unidades que aparecen
referenciadas en la cláusula Uses y un punto y coma al final.
Información adicional
En Delphi 1, puede también obtener este mensaje de error si no tiene una cláu-
sula Uses en un archivo de biblioteca (.DLL).
similar al siguiente para insertar en una tabla que tiene una columna llamada
TAX_CODE definida como “NOT NULL” :
SQL.Add('INSERT INTO LIABILITY (');
SQL.Add('AGENCY_ID,EMPLOYER_ID,PAYROLL_DATE,’
+ ‘LIABILITY_AMOUNT,DUE_DATE)');
SQL.Add('VALUES (');
SQL.Add(':AgencyID,:EmployerID,:PayrollDate,’
+ ‘:LiabilityAmount,:DueDate)');
Params.ParamByName('AgencyID').AsString := AAgencyID;
Params.ParamByName('EmployerID').AsString := AEmployerID;
Params.ParamByName('PayrollDate').Adate := APayrollDate;
Params.ParamByName('LiabilityAmount').AsCurrency :=
ALiabilityAmount;
Params.ParamByName('DueDate').Adate := dDueDate;
. . .
Solución rápida
Asegúrese de que la columna siempre tenga un valor, o elimine la restricción
NOT NULL para esa columna. Si opta por lo primero, puede seguir este
patrón:
SQL.Add('INSERT INTO LIABILITY (');
SQL.Add('AGENCY_ID,EMPLOYER_ID,TAX_CODE,PAYROLL_DATE,’
+ ‘LIABILITY_AMOUNT,DUE_DATE)');
SQL.Add('VALUES (');
SQL.Add(':AgencyID,:EmployerID,:TaxCode,:PayrollDate,’
+ ‘:LiabilityAmount,:DueDate)');
Params.ParamByName('AgencyID').AsString := AAgencyID;
Params.ParamByName('EmployerID').AsString := AEmployerID;
Params.ParamByName('TaxCode').AsString := ATaxCode;
Params.ParamByName('PayrollDate').Adate := APayrollDate;
Params.ParamByName('LiabilityAmount').AsCurrency :=
ALiabilityAmount;
Params.ParamByName('DueDate').Adate := dDueDate;
. . .
Información adicional
Esto puede pasar fácilmente cuando modifica las estructuras de las tablas
después que el código ha sido escrito. Hasta donde sea posible, evite cambiar
las estructuras de las tablas, realizando un análisis y diseño exhaustivos antes
de iniciar la codificación.
Mensajes de error 541
Solución rápida
Desactive la opción de optimización del compilador, añadiendo una de las
siguientes directivas:
{$O-}
{$OPTIMIZATION OFF}
Información adicional
Para más información, consulte “optimization” en la ayuda de Delphi.
Solución rápida
Borre la directiva Absolute.
Información adicional
Delphi para Linux (conocido como Kylix) ha hecho que este cambio sea
necesario, ya que no se pueden declarar variables con direcciones absolutas en
Linux, porque esto no es soportado por el formato PIC (Position-Independent
Code). C++ Builder también tiene sus efectos sobre Delphi. Por ejemplo, la
palabra reservada Register es la única sensible a mayúsculas/minúsculas en
Delphi. Esto fue hecho para permitir la utilización de los componentes VCL de
Delphi en C++ Builder. C++ distingue entre mayúsculas y minúsculas, y
register (el convenio de llamada) no es lo mismo que Register (el nombre del
método utilizado para la instalación de componentes en la Paleta de
Componentes).
542 Los Tomos de Delphi: Delphi sin problemas
Variable required
Posible causa de error
Puede estar intentando pasar un array a un procedimiento o función, pero ha
olvidado encerrar el array entre corchetes. Por ejemplo, lo siguiente generará
este mensaje de error:
procedure MeinVaterWarEinWandersmann(Sender: TObject);
procedure LiliMarlene(fournums: array of integer);
begin
. . .
end;
begin
LiliMarlene(StrToInt(Edit1.Text),
StrToInt(Edit2.Text),
StrToInt(Edit3.Text));
end;
Solución rápida
Encierre el array entre corchetes:
. . .
LiliMarlene([StrToInt(Edit1.Text),
StrToInt(Edit2.Text),
StrToInt(Edit3.Text)]);
Información adicional
Delphi 4 introdujo los arrays dinámicos.
procedure SetColumnTitles;
begin
xl.Cells[1,1].Value := 'ORDER NUM';
xl.Cells[1,2].Value := 'VENDOR';
end;
Mensajes de error 543
begin
xl.Workbooks.Add;
SetColumnTitles;
xl.Visible := True;
end;
Solución rápida
Añada la llamada a CreateOLEObject, asignando el objeto de automatización a
la variable OLEVariant antes de llamar a sus métodos:
procedure TForm1.Button1Click(Sender: TObject);
var
xl: OleVariant;
procedure SetColumnTitles;
begin
xl.Cells[1,1].Value := 'ORDER NUM';
xl.Cells[1,2].Value := 'VENDOR';
end;
begin
xl := CreateOLEObject('Excel.Application'); // Necesario!
xl.Workbooks.Add;
SetColumnTitles;
xl.Visible := True;
end;
Información adicional
Consulte “Variant does not reference an OLE object” en este libro.
Solución rápida
Registre el objeto OLE en todas las máquinas en las que se haga referencia a
él. Consulte “Class not registered” para información más específica.
Información adicional
Consulte “Variant does not reference an automation object” en este libro
y “Variant types” en la ayuda de Delphi para más información.
544 Los Tomos de Delphi: Delphi sin problemas
Variant error
Posible causa de error
Debe estar llamando al método ExecSQL de un objeto TQuery en lugar de su
método Open, cuando un conjunto resultado debería estar a disposición.
Solución rápida
Llame siempre a Open en el caso de sentencias SELECT (que, al menos en
teoría, devuelven un conjunto resultado). Llame a ExecSQL en el caso de las
sentencias que manipulan los datos (INSERT, UPDATE y DELETE).
Información adicional
Si está trabajando con bases de datos SQL (a diferencia de las bases de datos
de escritorio como Paradox o Access), estudie el componente TStoredProc.
Solución rápida
No intente acceder a través de un índice a un Variant al que se haya asignado
un valor de cadena.
Información adicional
Para más información, consulte “VarArrayCreate” y “VarIsArray” en la ayuda
de Delphi.
Mensajes de error 545
Solución rápida
Determine qué versión de ORA*.DLL está instalada en la máquina. Utilizando
la utilidad de Administración/Configuración del BDE, introduzca el nombre de
este archivo en el parámetro Vendor Init. Este archivo debería estar situado en
el subdirectorio \BIN del directorio de Oracle, por ejemplo
C:\ORAWIN95\BIN.
Información adicional
Consulte la documentación de Oracle para más información sobre las .DLLs
requeridas para su versión de Oracle.
Solución rápida
1. Actualícese a Delphi 5 o una versión superior, o al menos aplique el
Update Pack 3 de Delphi 4. Si no puede hacerlo, o por alguna razón no lo
desea, utilice la solución alternativa del problema que se describe en el
documento http://www.pbe.com/kudzu/Delphi/FAQ/402SConnect.html.
2. Verifique la dirección IP correcta de la máquina del servidor, e introduzca
ese valor en la propiedad Address del objeto TClientSocket.
Información adicional
2. La propiedad Address especifica la dirección IP del servidor con el que se
está intentando conectar.
546 Los Tomos de Delphi: Delphi sin problemas
Solución rápida
Ejecute el programa Scktsrvr (SCKTSRVR.EXE) en la máquina del servidor de
aplicación. Este programa se encuentra por defecto en C:\Archivos de
programa\Borland\Delphi X\Bin.
Información adicional
Consulte “MIDAS” en la ayuda de Delphi para más información.
Solución rápida
Borre los archivos innecesarios de la unidad e inténtelo de nuevo. Por ejemplo,
los documentos grandes y archivos gráficos que no se necesiten pueden ser
copiados a un dispositivo independiente y luego borrados.
Información adicional
Utilice periódicamente la utilidad de defragmentación de Windows para
reorganizar el disco duro. Esto mejorará el rendimiento, ya que los archivos
utilizarán menos áreas separadas (o preferiblemente un área contigua) en vez
de estar esparcidos por todo el disco duro.
Solución rápida
Pulse OK para cerrar el proyecto actual, abra un nuevo proyecto ActiveX
Library, y añada el elemento que había seleccionado.
Información adicional
Consulte “ActiveX applications” en la ayuda de Delphi para más información.
Solución rápida
Borre primero el valor de la columna Size, y luego cambie el tipo de datos en la
columna Type.
Información adicional
Algunos tipos de datos requieren un valor de tamaño, otros permiten un valor
de tamaño que no es obligatorio, y otros no permiten un valor de tamaño.
Consulte “Paradox field types and sizes” en la ayuda en línea del Database
Desktop para más información.
You must open a project before you can add an Automation Object
Posible causa de error
Puede haber intentado crear un objeto de automatización sin tener un proyecto
abierto. Por ejemplo, puede haber seleccionado File| New..., y luego haber
seleccionado Remote Data Module en la página New.
Solución rápida
Abra un proyecto existente o cree un nuevo proyecto antes de intentar añadir
un objeto de automatización.
548 Los Tomos de Delphi: Delphi sin problemas
Información Adicional
Una vez que el proyecto esté abierto, se puede crear un nuevo objeto de auto-
matización seleccionando File | New. . . , pulsando la pestaña ActiveX, y
entonces pulsando dos veces sobre el icono Automation object.
Solución rápida
Seleccione un nombre de componente en el cuadro de combinación ‘VCL Class
Name’ o teclee uno.
Información adicional
Para crear un control ActiveX utilizando el Asistente de Controles ActiveX, se
debe partir de un componente de Delphi y entonces convertirlo en un control
ActiveX.
De esta manera se podrán utilizar los componentes de Delphi en otros entornos
que soporten controles ActiveX, como C++ Builder, Visual Basic, PowerBuilder,
etc.
Solución rápida
1. Actualícese a la versión Cliente/Servidor o utilice tablas Paradox, dBASE u
ODBC.
2. Actualícese a Delphi Profesional o utilice tablas Paradox o dBASE.
Mensajes de error 549
Información adicional
Consulte “Application is not licensed to use this feature”.
Your username and password are not defined. Ask your database
administrator to set up an InterBase login
Posible causa de error
Puede haber intentado activar un componente IBDatabase cuando la propiedad
Login tenía el valor False, pero la propiedad Params no contenía el nombre de
usuario y la contraseña necesarias.
Solución rápida
Añada el nombre de usuario y la contraseña a la propiedad Params, o cambie
el valor de la propiedad Login a True en tiempo de ejecución, y entonces sumi-
nistre los valores adecuados.
Información adicional
Durante el desarrollo, es conveniente asignar el valor False a la propiedad
Login del componente IBDatabase, y suministrar la información necesaria
(nombre de usuario y contraseña) en la propiedad Params. Sin embargo, des-
pués de la implantación puede ser conveniente forzar al usuario a introducir su
nombre y contraseña para acceder a la base de datos (dependiendo, por
supuesto, del tipo de aplicación o datos de que se trate). En este caso, es
recomendable cambiar los valores de usuario y contraseña por defecto,
SYSDBA y masterkey.
550 Los Tomos de Delphi: Delphi sin problemas
Indice
! .EMF, 64
Readln, 293 .ICO, 64
$2108, 51 .INI, 244
$2109, 51 .LCK, 365
$220B, 159 .mb, 405
$2501, 62 .MB, 156
$2B05, 229 .MDX, 313
$2C08, 51 .OBJ, 27 ,60
$2C09, 51 .OPT, 387
$3E06, 102 .PAS, 25 ,34 ,119 ,201 ,214 ,234 ,254
$DENYPACKAGEUNIT, 2 .PX, 155 ,309 ,311 ,405
$DESIGNONLY, 2 .RES, 198 ,215 ,227 ,458
$ENDIF, 381 .VAL , 155 ,450
$IFDEF, 381 .WMF, 534
$IFNDEF, 381 10014, 545
$IFOPT, 381 10022, 545
$L, 60 10049, 545
$LINK, 60 25, 175
$R *.DFM, 215 800A03EC, 410
$RUNONLY, 2
$WEAKPACKAGEUNIT, 4 A
.BMP, 63 Abort, 469
.BPL, 38 ,74 Absolute, 458 ,501
.DCR, 80 ,188 abstractas, clases, 149
.DCU, 61 ,235 ,266 ,424 abstractos, métodos, 44 ,149 ,498
.DFM, 11 ,34 ,108 ,128 ,201 ,214 ,215 ,223 ,225 Access, (Microsoft Access), 250
,231 ,234 ,344 ,443 ,470 Active, 106 ,110
.DLL, 33 ,37 ,75 ,89 ,119 ,225 ,439 ,491 ,492 ,538 ActiveControl, 93
,539 ,545 ActiveForms, 89 ,216 ,235
.DOF, 386 ActiveX
.DPK, 264 Asistente, 13 ,37 ,548
.DPL, 74 biblioteca, 88 ,134 ,547
.DPR, 26 ,109 ,457 controles, 29 ,37 ,89 ,133 ,162 ,216 ,235 ,548
.DSK, 234 ,386
.DSM, 234 Add, 41
i
AddIndex, 9 ,252 CLX, 541
AddIndexDef, 398 CoClass, 28 ,482
address, 393 Code Insight, 137
ADO, 473 CoInitialize, 138
ADO Express, 143 COM, xxxiv ,29 ,138
Alias, 104 CommandText, 142
alias del BDE, 159 ,503 ,530 Commit, 401
Apache, 416 CommitUpdates, 364
API, xxxiv compilación condicional, 381
Append, 264 ,503 Componentes
ApplyUpdates, 120 ,364 eliminación, 36 ,51 ,231
arrays, 392 ,446 ,524 instalación, 28 ,231
Assert, 55 CONFIG.SYS, 404
AssignFile, 264 ConfigFile01, 100
AsyncPro, 412 CONFIGFILE01, 91 ,161
AUTOEXEC.BAT, 462 connect, 83
Autoincrement, campos, 314 ,315 Connect, 460
automatización, 341 Connected, 111 ,112 ,133 ,168 ,173 ,393
AutoSessionName, 78 ,89 ,90 ,106 ,114 ,199 ,233 Connection, 379
,279 ,391 ,461 ConnectionString, 22 ,379
Available Forms, 48 ConnectType, 173
Const, 241
B ConstraintErrorMessage, 42
BDE, 1 constructores, 150
BDE Administración/configuración, 186 Contains, 151
BDEProv, 399 Continue, 67
BLOB SIZE, 329 contraseña, 83 ,164 ,167 ,319 ,535
Boolean, 9 ,516 conversiones, 347
Break, 67 convert (utilidad), 224
Break on Exceptions, 239 ,440 CoUninitialize, 138
CREATE INDEX, 227
C CreateDataSet, 396
C++ Builder, 89 ,541 CreateOLEObject, 212 ,543
C0000006, 241 CustomConstraint, 42
C0000008, 242
C0000012, 242 D
C3254, 324 Database Desktop, 287
CachedUpdates, 58 DatabaseName, 115 ,168 ,194 ,384 ,504 ,529
Campos DateTime, 451
calculado, 252 Datos
calculados, 258 de Automatización, 341
obligatorios, 251 del Registro, 243
capacity, 359 en Paradox, 298
case, 124 ,193 dBASE, 167 ,337 ,338 ,494 ,509
CGI, 415 DBClient.DLL, 415 ,416
Chr , 276 DBCLIENT.DLL, 98
Citrix Winframe, 496 DBExpress, 38 ,110 ,142 ,395 ,400 ,413 ,519
clases abstractas, 149 DCOM, 173 ,393
class , 497 Dec, 359
Close, 115 Default, 179 ,255
ii
DefaultExpression, 251 ,434 Fail, 437
DefineProperties, 343 FetchAll, 141
Delete, 114 ficheros
DeleteTable, 115 conversión, 224
Delphi 3, 422 localización, 85
Delphi 4, 419 ,431 nombrado, 60
Delphi 5, 75 FieldDefs, 396
Delphi 6, 26 ,27 ,33 ,75 ,93 ,111 ,113 ,140 ,143 FieldKind, 258 ,261
,289 ,326 ,346 ,381 ,395 ,409 ,412 ,427 ,431 Fields Editor, 172 ,379
,437 ,490 ,494 ,519 ,524 File of Record, 512
Delphi/400, 243 FillChar, 49
destructores, 150 filtros, 415 ,452
dfBinary, 113 ,381 Finalization, 176
dfXML, 113 ,381 Finally, 237
dfXMLUTF8, 381 FindKey, 258 ,361 ,397
DisableControls, 283 FindNearest, 258
dispid, 190 ,425 FixedCols, 273
dispinterface, 33 FixedRows, 274
Dispose, 191 For , 56
DLLPATH, 100 ,103 format, 58 ,60 ,393
duplicados formularios
nombres, 196 ,198 ,258 creación, 45 ,71 ,78 ,105
propiedades, 199 ,200 herencia, 220
recursos, 197 visualización, 221
valores, 196 ,199
G
E General Protection Fault GPF, 45
EditMask, 40 GetLastError, 59 ,457
EmptyTable, 115 GetMem, 49 ,284 ,342
ENABLE SCHEMA CACHE, 535 GetProcAddress, 230 ,240
EncodeDate, 327 GExperts, 233
EncodeTime, 327 GoTo, 282 ,354
End, 209 ,483 gráfico, API, xxxiv
Entrada/Salida, error 100, 189 gráficos, formatos, 63
Entrada/Salida, error 101, 190 GROUP BY, 256 ,283 ,348
Entrada/Salida, error 102, 265 GUID, 34
Entrada/Salida, error 105, 272
Erase, 264 H
error, 205 ,272 Halt, 67
Error, 204 HandleShared, 233 ,390
Error de Protección General, 45 High, 284
Excel, 374 ,410 Host, 393
excepciones, 457
Except, 210 I
Exclusive, 264 ibinstall.dll, 321
ExecSQL, 85 ,219 ,362 ,544 IBX, 170 ,395
Exit, 68 icono, 493
Exports, 240 ,439 iconos, 80
IDAPI.CFG, 91 ,121 ,160
F IDAPI.DLL, 100
iii
IDAPI01.DLL, 102 M
IDAPI32.CFG, 91 ,121 ,160 ,186 MasterFields, 488
IDAPI32.DLL, 2 ,51 ,101 ,103 MasterSource, 126 ,488
IDataBroker, 157 ,158 MAXQUERYTIME, 467
identificadores, 289 MaxValue, 23 ,371
IDPROV32.DLL, 98 MDI, 87
Image Editor, 494 formularios, 398
Implementation, 294 hijos, 398
Implements, 295 memoria, 77
ImportedConstraint, 42 liberación, 342
Inc , 358 limitaciones, 422
Index, 227 ,257 ,282 ,307 metaarchivos, 136 ,207 ,371
IndexField, 247 métodos abstractos, 44 ,149 ,498
IndexFieldNames, 9 ,155 ,247 ,397 Microsoft Access, 250
IndexName, 9 ,155 ,245 ,248 ,308 ,309 ,397 Microsoft Excel, 374 ,410
índices, 475 MIDAS, 113 ,170 ,173 ,399 ,414 ,460
crear por código, 310 MIDAS.DLL, 416
mantenidos, 310 ,312 MinValue, 23 ,377
primarios, 408 Miser, Dan, 250 ,432
secundarios, 408 MTS, 377
Indy, 412 ,465 multi-hilos, 106 ,199 ,236 ,391 ,461 ,477
Initialization, 11 ,15 ,62 ,176 ,523 MultiSelect, 312
InstallShield Express, 1 ,38 ,100 ,323
InterBase, 73 ,104 ,169 ,170 ,321 ,520 N
InterBase 6, 73 ,321 ,467 Name , 460
InterBase Express, 110 ,143 ,380 ,508 NetDir, 171
Interface, 7 ,235 ,321 configuración, 185
interfaces, 7 New, 392
Internet Direct -Indy, 412 Nodefault, 255 ,402
Is, 347 NOT NULL, 540
IsValidDateMonthWeek, 26 Null, 237
IUnknown, 177
O
K Object Pascal
KeepConnection, 112 directivas, 11
KeyPress, 19 ,21 ,499 palabras reservadas, 11
Kylix, 412 ,541 tipos ordinales, 421
ODBC, 361 ,365 ,452 ,548
L OldCreateOrder, 232 ,242 ,443
L1086, 324 OldValue, 58 ,405
L1317, 324 OLEVariant, 543
L721, 324 OnActivate, 80
Label, 354 OnHide, 81
Last, 141 OnShow, 81
Length, 208 OnValidate, 42
Library Path, 60 ,151 ,456 open, 107
LoadFromFile, 86 optimización, 109 ,541
LoadLibrary, 230 ,240 Oracle .DLL, 545
Local Share, 317 ,364 ORDER BY, 123 ,256 ,350
Locate, 397 ordinal, 275
iv
overload, 299 ,374 ,411 ,412 ,424 ,435 Rename, 258
override, 109 ,149 ,372 ,375 ,444 ,533 ReportSmith, 140 ,265 ,520
RequestLive, 249 ,317 ,477 ,481 ,502
P Required, 203 ,244 ,262
Packed, 428 Requires, 425 ,455
PageIndex, 13 Reset, 264 ,265
paquetes, 7 ,75 ,422 ,425 ,456 ,483 resourcestring, 11
borrado, 341 Resourcestring, 165 ,522
recompilación, 61 Rewrite, 264 ,265
Paradox, 240 ,479 RLINK32.DLL, 161
compartición, 171 Round, 336
integridad referencial, 369 RTTI, 484
limitaciones, 167 Run-time error 202, 469
Tipos de datos, 65 ,66 ,303 Runtime Error 215, 54
parámetros, 171 ,420 ,486
Params, 245 ,289 ,537 S
PDOXUSRS.LCK, 387 SaveToFile, 85
PDOXUSRS.NET, 387 SDI, 87
Prepare, 142 ,317 SELECT, 256 ,257 ,348
propiedades, 343 ServerGUID, 83 ,330 ,460
declaración, 434 ServerName, 460
tipos, 437 SessionName, 90 ,106 ,116 ,199 ,233 ,460
Published, 509 SetDatabaseName, 118
puertos, 57 ,465 SetFocus, 93
punteros, 45 ,143 ,164 ,165 ,180 ,301 ,342 ,347 SetLength, 208 ,391 ,393
,358 ,434 ,446 ,509 ,512 SHAREDMEMSIZE, 62 ,318 ,329
ShortDateTime, 452
Q ShowModal, 105
Query Builder, 163 Site Express, 32 ,92 ,326 ,490 ,494
QuickReports, 232 ,521 Slice, 464
sockets, 466
R SortFieldNames, 142
R938, 324 SQL, 115 ,219
Raise, 135 ,456 SQLDialect, 467
Read, 11 ,79 ,450 SQLPASSTHRU MODE, 432
ReadBinaryData, 214 StartTransaction, 38 ,110 ,169 ,281 ,395 ,401
Readln, 270 ,505 ,507
ReadOnly, 106 ,116 STDOLE.TLB, 161
Real, 446 STDOLE2.TLB, 161
recursión, 439 ,468 Stored, 255 ,470
recursos StoredProcName, 219
conservación, 214 Synchronize, 236
DLLs, 492 SYSTEM.DCU, 474
renombrar, 197 SYSTEM.INI, 422
REF CURSOR, 420
Referencial, integridad, 10 T
Refresh, 389 TableName, 9 ,115 ,252 ,308 ,384
Register, 202 ,413 TableType, 116
RegisterClass, 72 ,204 TADOConnection, 22
RegisterComponents, 28 ,72 ,202 ,486 TBatchMove, 183 ,184 ,298
v
TBits, 64 V
TClientDataSet, 514 validación, 40 ,251
TClientDataSetGrid, 113 Var, 131
TClientSocket, 57 ,72 ,545 parámetros, 497
TDatabase, 168 variables
TDataSet, 112 declaración, 146
TDateTime, 16 ,22 inicialización, 95
TDateTimePicker, 17 variantes, 515 ,524
Terminate, 67 VARIANTS.PAS, 524
TextOut, 301 VBX, 488
TField, descendientes para los tipos de Paradox, VCL, 30 ,139
66 ,299 virtual, 372
TFileAttr, 525 VMT, 517
TFrame, 397
Threadvar, 97 ,501 W
TIBDatabase, 110 WaitFor, 236
TIBInstall, 321 Webbrokerscript, 409 ,494
TIBTransaction, 110 ,395 Weblib, 326
TIBUninstall, 321 WideString, 7 ,98 ,177 ,341 ,347 ,515
TIDAntiFreeze, 412 WIN.INI, 91
tiDirtyRead, 495 WinCRT, 271
TModalResult, 524 Windows, 1 ,47 ,62 ,65 ,76 ,87 ,91 ,121 ,138 ,225
TObject, 179 ,309 ,325 ,334 ,366 ,371 ,407 ,426 ,476 ,496
TObjectList, 411 With , 453
TPageControl, 221 Write, 77 ,450
TQuery, 400 ,447 Writeln, 269 ,294
TQueryClientDataSet, 170
TransIsolation, 494 X
TRegSvr, 157 ,158 ,230 ,326 ,409 ,487 ,494 XML, 113 ,380 ,514
TReport, 140 ,265
Trunc, 336
Try, 237
Try...Except, 237 ,457
Try...Finally, 237 ,457
TSession, 78 ,90 ,106 ,114 ,199 ,460
TSQLConnection, 110
TTabbedNotebook, 221
TTable, 467
TThread, 98
TThreadList, 411
TUtility, 405
type, 131 ,229
TypeInfo, 510 ,516
U
unidirectional, 413
Unprepare, 116 ,141 ,317
UpdateMode, 447 ,467
UseBroker, 173
Uses, 521
vi