Los Tomos de Delphi : “Delphi sin problemas” ® Clay Shannon © 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. Traducido de: The Tomes of Delphi: Developer’s Guide to Troubleshooting © Wordware Publishing - ISBN 1-55622-816-3 DERECHOS RESERVADOS. El contenido de esta publicación tiene todos los derechos reservados, por lo que no se puede reproducir, transcribir, transmitir, almacenar en un sistema de recuperación o traducir a otro idioma de ninguna forma o por ningún medio mecánico, manual, electrónico, magnético, químico, óptico, o de otro modo. La persecución de una reproducción no autorizada tiene como consecuencia la cárcel y/o multas. LIMITACIÓN DE LA RESPONSABILIDAD. Tanto los autores como el equipo de Danysoft hemos revisado el texto para evitar cualquier tipo de error, pero no podemos prometerle que el libro estará siempre libre de errores. Por ello, y para que esto no sea una molestia para usted, hemos habilitado en http://www.danypress.com un apartado especial para que cada libro que publiquemos permanezca "vivo". Asimismo, podrá enviarnos por e-mail a editorial@danysoft.com sus comentarios sobre el libro. DESCUENTOS ESPECIALES. Recuerde que Danypress ofrece descuentos especiales a centros de formación y en compras por volumen. Para más detalles, consulte con editorial@danysoft.com en España o con america@danysoft.com en Latinoamérica. Todos los productos y marcas se mencionan únicamente con fines de identificación y están registrados por sus respectivas compañías. Delphi es una marca registrada de Borland Software Corporation. Otros nombres de productos mencionados son utilizados únicamente para propósitos de identificación y pueden ser marcas comerciales registradas de sus respectivas compañías. Dedicatoria Para: Mi esposa, Cherri. Mis hijos, Kelvin Caleb Mordecai “Immerfort Purify” Shannon y Morgan Tell Mackenzie “Immerfort Purify” (“Sluggo”) Shannon. Mis padres, Thedore Russell Shannon y Alice Rosalie Shannon. Mis hermanos y hermanos políticos, Theodore Patrick “Ted” Shannon; Jonathan Kelly “Barn” Shannon y Melinda “Mindiana” Shannon; Patricia Maureen “Trish” Baugus y Jimmy Don “Jim” Baugus. Roger “S”. L. Hugi. “The Cartwrights” (Jerry Dunn, Eddie J. Nelson, Alex Szajki y otros). Sin su apoyo, amor, sacrificio, peleas con almohadas, ejemplo y lealtad, este esfuerzo, y la vida misma, habrían perdido gran parte de su significado y su belleza. Finalmente, también quiero extender mi agradecimiento a las siguientes personas, que han hecho mi vida más agradable gracias a su inteligencia creativa o habilidades deportivas: Johann Sebastian Bach, Bruce Springsteen, Dwight Yoakam, the Desert Rose Band, Mark Twain, Jack London, Marlon Brando, David Muench y Ansel Adams, Baltimore Orioles, Green Bay Packers y Milwaukee Bucks. iii Comentarios sobre: Los Tomos de Delphi: “Delphi sin problemas” de Clay Shannon “Una referencia que he encontrado particularmente útil ha sido ‘Delphi sin problemas’, de Clay Shannon, que es esencialmente una enciclopedia de mensajes de error de Delphi. Si ha programado durante años en Delphi (o Turbo Pascal), encontrará algunos ‘viejos conocidos’ aquí. Al principio me preguntaba si habría algo nuevo para mí en este libro. No tuve que esperar mucho tiempo. A los pocos días de recibir esta valiosa referencia, una explicación sobre un error me ahorró horas de esfuerzo a la hora de conseguir que una llamada a la API de Windows funcionara”. Alan C. Moore Columnista de “File | New”, Delphi Informant “Es muy útil cuando tienes que dar solución a problemas”. Bill Artemik Droste Consultants, Inc. “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 recomendaría adquirir este libro”. Barry McClure President Grebar Systems, Inc. “Otro libro que yo recomendaría es ‘Delphi sin problemas’, de Clay S h a n n o n . . . Este libro es una referencia completa de los mensajes de error de Delphi y sus causas comunes”. David R. Robinson Director of Development Carpe Diem Electronic Time Sheet Sage U.S. Holdings, 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 Data Base Error: Database access resulted in error. . . . . . . . . Data Segment Too Large . . . . . . . . . . . . . . . . . . . . . . Data Structure Corruption . . . . . . . . . . . . . . . . . . . . . Data Type too large: exceeds 2 GB . . . . . . . . . . . . . . . . . Database name missing . . . . . . . . . . . . . . . . . . . . . . Database not Assigned . . . . . . . . . . . . . . . . . . . . . . . Dataset is not a query . . . . . . . . . . . . . . . . . . . . . . . Dataset not configured for network access . . . . . . . . . . . . . Dataset [is] not in edit or insert mode . . . . . . . . . . . . . . . DAX Error: Class not registered. . . . . . . . . . . . . . . . . . . DAX Error: Name not unique in this context . . . . . . . . . . . . DAX Error: Unexpected failure . . . . . . . . . . . . . . . . . . . DCOM not installed . . . . . . . . . . . . . . . . . . . . . . . . Debug process is already running . . . . . . . . . . . . . . . . . . Debug session in progress. Terminate? . . . . . . . . . . . . . . . Debugger kernel error. Error code: <> . . . . . . . . . . . . . . . Decla ration expected but <> found . . . . . . . . . . . . . . . . Decla ration of <> differs from declaration in interface <> . . . . Decla ration of <> differs from previous declaration . . . . . . . . Decla ration of class <> is missing or incorrect . . . . . . . . . . DEFAULT clause not allowed in OLE automation section . . . . . . Default parameter ‘<>’ must be by-value or const . . . . . . . . Default property must be an array property . . . . . . . . . . . . Default value required for <> . . . . . . . . . . . . . . . . . . . Default values must be of ordinal, pointer, or small set type . . . . Destination must be indexed . . . . . . . . . . . . . . . . . . . . Directory Is Busy . . . . . . . . . . . . . . . . . . . . . . . . . . Directory is controlled by other .NET file . . . . . . . . . . . . . . Disk Error. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Disk full. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Disk read error . . . . . . . . . . . . . . . . . . . . . . . . . . . Disk write error . . . . . . . . . . . . . . . . . . . . . . . . . . . Dispid <> already used by <> . . . . . . . . . . . . . . . . . . Dispid clause only allowed in OLE automation section . . . . . . . Dispose not supported (nor necessary) for dynamic arrays . . . . . Division by zero . . . . . . . . . . . . . . . . . . . . . . . . . . . Duplicate case label . . . . . . . . . . . . . . . . . . . . . . . . Duplicate database name <> . . . . . . . . . . . . . . . . . . . Duplicate dynamic method index . . . . . . . . . . . . . . . . . . Duplicate field name <> . . . . . . . . . . . . . . . . . . . . . Duplicate implements clause for interface <> . . . . . . . . . . . Duplicate message method index . . . . . . . . . . . . . . . . . . Duplicate resource . . . . . . . . . . . . . . . . . . . . . . . . . x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 163 164 166 168 168 169 170 171 171 172 173 173 173 173 174 175 176 177 177 178 179 179 180 181 181 183 184 185 188 188 189 189 190 191 191 192 193 194 195 195 196 197 197 Duplicate session name <> . . . . . . . . . . . . . . . . . . . . . . . . . . Duplicate Tag Value. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dynamic method or message handler not allowed here . . . . . . . . . . . . . Dynamic method or message handlers not allowed in OLE automation sections EAccessViolation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EBitsError. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EClassNotFound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EComponentError. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EConvertError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EDatabaseError. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EDivByZero. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EFCreateError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EFilerError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EGPFault . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EInOutError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EIntOverflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EInvalidCast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EInvalidGraphic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EInvalidGraphicOperation . . . . . . . . . . . . . . . . . . . . . . . . . . . EInvalidOp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EInvalidOperation: Cannot create form. No MDI forms are currently active . . EInvalidOperation: Cannot make a visible window modal . . . . . . . . . . . . EInvalidPointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Element 0 Inaccessible—use Length or SetLength . . . . . . . . . . . . . . . END expected but <> found . . . . . . . . . . . . . . . . . . . . . . . . . END expected but implementation found . . . . . . . . . . . . . . . . . . . END. missing at end of module . . . . . . . . . . . . . . . . . . . . . . . . . EOLEError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EOLEException . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EOleSysClass not Registered . . . . . . . . . . . . . . . . . . . . . . . . . . EOleSysError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EOleSysOperation Unavailable . . . . . . . . . . . . . . . . . . . . . . . . . EOutOfMemory. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EOutOfResources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ERangeError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EReadError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ERegistryException . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EResNotFound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Error 0: RLINK32 Error opening file <TypeLibrary>.tlb . . . . . . . . . . . . Error 2—File not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Error 4—Too many open files . . . . . . . . . . . . . . . . . . . . . . . . . . Error 68—Circular Unit Reference . . . . . . . . . . . . . . . . . . . . . . . Error 76—Constant out of range . . . . . . . . . . . . . . . . . . . . . . . . Error 94—“.” Expected. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 199 200 201 201 201 201 202 202 203 204 204 204 205 205 206 206 206 207 207 207 207 208 208 209 209 210 211 211 211 211 212 212 213 214 214 214 215 216 216 216 217 217 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 continue? 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 <> . . . . . . . . . Error reading <Session>.SessionName. Duplicate session name <> . . . . . . . . . . . Error reading symbol file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Error saving I(Interface): The parameter is incorrect . . . . . . . . . . . . . . . . . . . . Error setting debug exception hook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Error starting Program. The <>.DLL file appears to be corrupt. Reinstall the file, and then EStackOverflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EStringListError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EThread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EVariantError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Except or Finally expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exception <> in module <> at <>.<>. . . . . . . . . . . . . . . . . . . . . . . . . Expected an identifier but function found . . . . . . . . . . . . . . . . . . . . . . . . . . Expecting a column separator in table [header] . . . . . . . . . . . . . . . . . . . . . . Exports allowed only at global scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . Expression expected but <> found . . . . . . . . . . . . . . . . . . . . . . . . . . . . External error C0000006 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . External error C0000012 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . External exception C0000008 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . F004 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Failed to get data for <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Failed to load stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fatal Error: <>: Required Package <> not found . . . . . . . . . . . . . . . . . . . . . Field <> cannot be modified. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field <> cannot be used in a filter expression . . . . . . . . . . . . . . . . . . . . . . . Field <>.<> does not have a corresponding component. Remove the declaration? . . . . Field <> is not indexed and cannot be modified . . . . . . . . . . . . . . . . . . . . . . Field <> is not of the expected type . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field <> is of an unknown type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field <> is of an unsupported type . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field <> must have a value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field <> should be of type <> but is declared as <>. Correct the declaration? . . . . . Field declarations not allowed in interface type . . . . . . . . . . . . . . . . . . . . . . . Field definition not allowed after methods or properties . . . . . . . . . . . . . . . . . . Field in group by must be in result set . . . . . . . . . . . . . . . . . . . . . . . . . . . Field in order by must be in result set . . . . . . . . . . . . . . . . . . . . . . . . . . . Field index out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field name already exists. Rename one of the fields . . . . . . . . . . . . . . . . . . . . Field not found in table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field or method identifier expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field types do not match . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Field value required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . try again. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 233 234 235 235 236 236 236 236 237 237 239 239 240 240 240 241 242 242 243 243 244 244 245 245 246 247 248 249 250 251 252 253 254 255 256 256 257 258 259 259 261 261 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Illegal type in OLE automation section: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Illegal type in Read/Readln statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Illegal type in Write/Writeln statement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IMPLEMENTATION part is missing or incorrect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . Implementation part USES clause incorrect. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Implements clause only allowed for properties of class or interface type . . . . . . . . . . . . . . . . Implements clause only allowed for readable property . . . . . . . . . . . . . . . . . . . . . . . . . Implements clause only allowed within class types . . . . . . . . . . . . . . . . . . . . . . . . . . . Implements getter must be register calling convention . . . . . . . . . . . . . . . . . . . . . . . . . Improper GUID syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Incompatible Record Structures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Incompatible Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Incompatible types: <> and <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Incompatible types: Parameter lists differ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Incorrect field declaration: class <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Incorrect method declaration in class <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Incorrect syntax near ':' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Index already exists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INDEX clause not allowed in OLE automation section . . . . . . . . . . . . . . . . . . . . . . . . . Index does not exist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Index is out of date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Index is out of range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Index is read only . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Index not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Index or Primary Key cannot contain a Null value . . . . . . . . . . . . . . . . . . . . . . . . . . . . INDEX, READ, OR WRITE clause expected but ‘;’ found . . . . . . . . . . . . . . . . . . . . . . . . INSERT and UPDATE operations are not supported on autoincrement field type . . . . . . . . . . . . Installation error –113 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Instance variable <> inaccessible here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Insufficient disk space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Insufficient memory for this operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Insufficient SQL rights for operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Insufficient table rights for operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Integer constant too large . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . InterBase install DLL ibinstall.dll not found in path. Please install InterBase 6 to use this fun ctionality. Interface <> already implemented by <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interface <> has no interface identification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interface <> not mentioned in interface list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interface mismatch. Engine version different . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interface type required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Internal error: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Internal Error; Near: query shellmgr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Internal Error 500. Interface not supported . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 293 293 294 294 295 295 296 297 297 298 298 299 299 304 305 306 306 307 308 308 309 312 312 313 313 314 314 315 316 316 317 318 319 320 321 321 322 322 323 323 324 325 326 xv Internal Server Error 500 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid address value. Must be a hexadecimal value in the range 00000000-FFFFFFFF . Invalid argument to date encode . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid argument to time encode . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid Batch Move Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid Bind Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid BLOb handle [in record buffer] . . . . . . . . . . . . . . . . . . . . . . . . . Invalid BLOb Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid class string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid class typecast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid compiler directive: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid directory. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid field name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid field size. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid field type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid file name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid floating point operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid function result type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid GUID format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid index descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid index expression. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid index/tag name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid message parameter list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid package file <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid parameter type: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid pointer operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid property path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid property value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid property value on line <> . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid resource format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid Stream Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid Type Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid typecast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid use of keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid variable reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invalid variant type conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Key Violation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Label <> is not declared in current procedure . . . . . . . . . . . . . . . . . . . . . Label already defined: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Label declaration not allowed in interface part . . . . . . . . . . . . . . . . . . . . . Label declared and referenced, but not set . . . . . . . . . . . . . . . . . . . . . . . xvi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 326 327 327 328 329 329 329 330 330 331 332 332 333 334 334 335 337 337 337 338 338 340 340 341 341 342 342 343 343 344 345 345 346 347 347 348 351 351 353 354 354 355 355 Label expected . . . . . . . . . . . . . . . . . . . . . . . . Left side cannot be assigned to . . . . . . . . . . . . . . . . Line number must be between 1 and <> . . . . . . . . . . Line too long [more than 255 characters] . . . . . . . . . . List capacity out of bounds (<>) . . . . . . . . . . . . . . List index out of bounds (<>) . . . . . . . . . . . . . . . . Local class, interface or object types not allowed . . . . . . . Local class or object types not allowed . . . . . . . . . . . . Local procedure/function <> assigned to procedure variable. Lock file [has grown] too large . . . . . . . . . . . . . . . . Lock time out . . . . . . . . . . . . . . . . . . . . . . . . . Lock Violation. . . . . . . . . . . . . . . . . . . . . . . . . Lookup information for field <> is incomplete . . . . . . . . Low bound exceeds High bound. . . . . . . . . . . . . . . . Master has detail records. Cannot delete or modify. . . . . . Master has detail records. Cannot empty it. . . . . . . . . . Master record missing . . . . . . . . . . . . . . . . . . . . Maximum Validity Check Failed. . . . . . . . . . . . . . . . Memo too large. . . . . . . . . . . . . . . . . . . . . . . . Metafile is not valid. . . . . . . . . . . . . . . . . . . . . . Method <> hides virtual method of base class <> . . . . . Method <> not found in base class . . . . . . . . . . . . . Method “<>” not supported by automation object . . . . . Method <> with identical parameters exists already . . . . Method identifier expected . . . . . . . . . . . . . . . . . . Microsoft Transaction Server is not installed . . . . . . . . . Minimum Validity Check failed . . . . . . . . . . . . . . . . Mismatch in datapacket . . . . . . . . . . . . . . . . . . . Missing comma . . . . . . . . . . . . . . . . . . . . . . . . Missing Connection or Connection String . . . . . . . . . . . Missing Data Provider or Data Packet . . . . . . . . . . . . Missing ENDIF directive . . . . . . . . . . . . . . . . . . . Missing operator or semicolon . . . . . . . . . . . . . . . . Missing or invalid conditional symbol in <$> directive . . . . Missing parameter type. . . . . . . . . . . . . . . . . . . . Missing right quote . . . . . . . . . . . . . . . . . . . . . . Missing TableName property . . . . . . . . . . . . . . . . . Module <>s time/date changed. Reload? . . . . . . . . . . Module header is missing or incorrect . . . . . . . . . . . . Multiple Net Files found . . . . . . . . . . . . . . . . . . . Multiple Paradox Net files found/in use . . . . . . . . . . . . Must apply updates before refreshing data . . . . . . . . . . Name conflicting . . . . . . . . . . . . . . . . . . . . . . . Name not unique in this context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 357 359 359 359 360 363 363 363 364 365 366 367 368 368 369 370 370 371 371 372 373 373 374 375 376 377 378 378 379 380 381 381 383 383 384 384 385 386 387 389 389 390 390 xvii Need to specify at least one dimension for SetLength of dynamic array . Never-build package <> must be recompiled . . . . . . . . . . . . . Never-build package <> requires always-build package <> . . . . . New not supported for dynamic arrays—use SetLength . . . . . . . . No address specified . . . . . . . . . . . . . . . . . . . . . . . . . . No argument for format <> . . . . . . . . . . . . . . . . . . . . . . No code was generated for the current line . . . . . . . . . . . . . . . No Databases Are Listed In Transaction Component . . . . . . . . . . No definition for abstract method <> allowed . . . . . . . . . . . . . No fields defined—cannot create dataset . . . . . . . . . . . . . . . No frames in project . . . . . . . . . . . . . . . . . . . . . . . . . . No index currently active . . . . . . . . . . . . . . . . . . . . . . . . No MDI forms are currently active . . . . . . . . . . . . . . . . . . . No MDI Parent Active . . . . . . . . . . . . . . . . . . . . . . . . . No overloaded method of <> with this parameter list exists . . . . . No Provider Available . . . . . . . . . . . . . . . . . . . . . . . . . . No SQL statement available . . . . . . . . . . . . . . . . . . . . . . No user transaction is currently in progress. . . . . . . . . . . . . . . No Web browser could be located . . . . . . . . . . . . . . . . . . . NODEFAULT clause not allowed in OLE automation section . . . . . . Not enough actual parameters . . . . . . . . . . . . . . . . . . . . . Not enough file handles. . . . . . . . . . . . . . . . . . . . . . . . . Not exact read/write in <>.mb and <>.mb . . . . . . . . . . . . . Not in cached update mode . . . . . . . . . . . . . . . . . . . . . . Not initialized for accessing network files. . . . . . . . . . . . . . . . Number is out of range . . . . . . . . . . . . . . . . . . . . . . . . . Number of elements differs from declaration . . . . . . . . . . . . . . Object Factory for TwebResponse Missing . . . . . . . . . . . . . . . Object or class type required . . . . . . . . . . . . . . . . . . . . . . OLE error 800A03EC . . . . . . . . . . . . . . . . . . . . . . . . . . One or more lines were too long and have been truncated . . . . . . . Only one of a set of overloaded methods can be published . . . . . . . Only one TIDAntiFreeze can exist per application . . . . . . . . . . . Only register calling convention allowed in OLE automation section . . Operation not allowed on a unidirectional dataset . . . . . . . . . . . Operation not allowed on sorted string list . . . . . . . . . . . . . . . Operation not applicable . . . . . . . . . . . . . . . . . . . . . . . . Operation not supported . . . . . . . . . . . . . . . . . . . . . . . . Operator not applicable to this operand type . . . . . . . . . . . . . . ORA-1001 invalid cursor . . . . . . . . . . . . . . . . . . . . . . . . Order of fields in record constant differs from declaration . . . . . . . Ordinal type required . . . . . . . . . . . . . . . . . . . . . . . . . . Out of memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Out of system resources . . . . . . . . . . . . . . . . . . . . . . . . xviii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391 391 392 392 393 393 394 395 395 396 397 397 398 398 398 399 400 401 402 402 403 404 405 405 406 408 408 409 409 410 411 411 412 413 413 414 415 416 417 419 420 421 422 423 Overflow in conversion or arithmetic operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Overloaded procedure <> must be marked with the overload directive . . . . . . . . . . . . . . . . . . . Overriding automated virtual method <> cannot specify a dispid . . . . . . . . . . . . . . . . . . . . . . Package <> already contains unit <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Package <> can’t be installed because another package with the same base name is already load ed (<>) Package <> can’t be installed because it is not a design time package . . . . . . . . . . . . . . . . . . . Package <> is recursively required. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Package unit <> cannot appear in contains or uses clauses . . . . . . . . . . . . . . . . . . . . . . . . . Packages <> and <> both contain unit <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PACKED not allowed here. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Page Fault in module <> at <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Page name cannot be blank. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Param <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameter <> not allowed here due to default value . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameter <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameters of this type cannot have default values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parent Interface must be Dispatchable for dual interface . . . . . . . . . . . . . . . . . . . . . . . . . . . Passthrough SQL connection must be shared . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Path not found. File <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Path too long . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Pointer type required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Preparation of default expression failed with error “Type mismatch in expression” . . . . . . . . . . . . . . Previous declaration of <> was not marked with the ‘overload’ directive . . . . . . . . . . . . . . . . . . Printing in Progress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Procedure cannot have a result type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Procedure FAIL only allowed in constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Procedure, function or property expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Procedure or Function expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Procedure or Function name expected . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Program or unit <> recursively uses itself . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Project <> raised exception class <> with message <>. Process stopped. Use Step or Run to continue. . Property <> does not exist in base class. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Property <> inaccessible here . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Property does not exist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Property getters and setters cannot be overloaded . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Property overrides not allowed in interface type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Provider name was not recognized by the server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Published field <> not a class nor interface type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Published property <> cannot be of type <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Published real[48] property <> must be Single, Double, or Extended . . . . . . . . . . . . . . . . . . . . PutObject to undefined item . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Query Is Too Complex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Query makes no sense . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Query may take a long time to process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424 424 425 425 425 426 427 427 428 428 429 429 430 430 431 431 432 432 432 433 433 434 435 435 436 437 437 438 439 439 440 441 442 443 443 444 444 445 446 446 447 447 448 449 xix Range check error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Read failure. File: <>.val . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Read or Write clause expected but identifier <> found . . . . . . . . . . . . . . . . . Record already locked by this session . . . . . . . . . . . . . . . . . . . . . . . . . . . Record changed by another user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Record Key deleted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Record/Key Deleted. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Record Locked by another User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Record, object or class type required . . . . . . . . . . . . . . . . . . . . . . . . . . . Recursive include file <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Redeclaration of <> hides a member in the base class . . . . . . . . . . . . . . . . . Redeclaration of property not allowed in OLE automation section . . . . . . . . . . . . Required package <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . REQUIRES clause is incorrect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Re-raising an exception only allowed in exception handler . . . . . . . . . . . . . . . . Resource <> not found . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Segment/Offset pairs not supported in Borland 32-bit Pascal . . . . . . . . . . . . . . . Selection contains a component introduced in an ancestor form which cannot be deleted Server Execution Failed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Session name missing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sets may have at most 256 elements . . . . . . . . . . . . . . . . . . . . . . . . . . . Share not loaded. It is required to share local files . . . . . . . . . . . . . . . . . . . . Size mismatch error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Size of published set <> is greater than [4 bytes, 32 bits] . . . . . . . . . . . . . . . Slice standard function is only allowed as open array argument . . . . . . . . . . . . . . Socket Error # 10061 – Connection Refused . . . . . . . . . . . . . . . . . . . . . . . Socket Error # 10065 – No route to host . . . . . . . . . . . . . . . . . . . . . . . . Socket Error # 11001 – Host not found . . . . . . . . . . . . . . . . . . . . . . . . . SQL Connection timed out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SQL Dialect Invalid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SQL is too complex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Stack overflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Statement expected, but expression of type <> found. . . . . . . . . . . . . . . . . . Statements not allowed in interface part . . . . . . . . . . . . . . . . . . . . . . . . . STORED clause not allowed in OLE automation section . . . . . . . . . . . . . . . . . Stream Read Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . String constant truncated to fit STRING[ ] . . . . . . . . . . . . . . . . . . . . . . . . String [literal]s may have at most 255 elements . . . . . . . . . . . . . . . . . . . . . Syntax Error in Field Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Syntax error in query. Incomplete query clause . . . . . . . . . . . . . . . . . . . . . . Syntax error in real number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . System unit out of date or corrupted . . . . . . . . . . . . . . . . . . . . . . . . . . . Table cannot be opened for exclusive use . . . . . . . . . . . . . . . . . . . . . . . . . Table corrupt—other than header . . . . . . . . . . . . . . . . . . . . . . . . . . . . xx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 450 450 451 451 452 452 453 453 454 454 455 455 456 456 457 458 458 460 460 461 462 463 463 464 465 465 466 466 467 467 468 469 469 470 470 471 471 472 473 474 474 475 476 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 redefine 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 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Too many files open . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Too many locks on table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Too many open cursors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Too many open files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Too many parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Transaction Is Active . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Transaction not Assigned . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Translate error, value out of bounds. . . . . . . . . . . . . . . . . . . . . . . . . . . . Tried to search marked block but it is invalid . . . . . . . . . . . . . . . . . . . . . . . Type <> has no type info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Type <> is not yet completely defined . . . . . . . . . . . . . . . . . . . . . . . . . . Type <> must be a class to have a PUBLISHED section . . . . . . . . . . . . . . . . . Type <> must be a class to have OLE automation . . . . . . . . . . . . . . . . . . . . Type <> needs finalization—not allowed in file type . . . . . . . . . . . . . . . . . . Type expected but <> found. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Type expected but real constant found . . . . . . . . . . . . . . . . . . . . . . . . . . Type mismatch for field <FieldName>, expecting: <Field type>, actual: <Field type> Type mismatch [in expression] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Type not allowed in OLE Automation call . . . . . . . . . . . . . . . . . . . . . . . . . Type of expression must be BOOLEAN . . . . . . . . . . . . . . . . . . . . . . . . . . Type of expression must be INTEGER . . . . . . . . . . . . . . . . . . . . . . . . . . . TYPEINFO standard function expects a type identifier . . . . . . . . . . . . . . . . . . TYPEOF can only be applied to object types with a VMT . . . . . . . . . . . . . . . . . Types of actual and formal var parameters must be identical . . . . . . . . . . . . . . . Unable to Execute a Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unable to find both a form and a source file . . . . . . . . . . . . . . . . . . . . . . . Unable to insert a line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unable to load GDS[32].DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unable to load RPTSMITH.EXE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Undeclared Identifier: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Undeclared Identifier: 'EmptyParam' . . . . . . . . . . . . . . . . . . . . . . . . . . . Undeclared Identifier: 'Result'. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Undeclared Identifier: 'Unassigned' . . . . . . . . . . . . . . . . . . . . . . . . . . . . Undeclared Identifier: 'VarToStr' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unexpected end of command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unit <> was compiled with a different version of <> . . . . . . . . . . . . . . . . . . Unit File Format Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unit name mismatch: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unit version mismatch: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unknown Column. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unknown database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unknown directive: <> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Unknown directive (already exists) . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 504 505 505 506 506 507 508 508 509 509 510 510 511 512 512 513 514 514 515 515 516 516 517 518 519 519 519 520 520 521 525 526 526 526 526 527 528 528 528 529 529 531 533 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 library 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 consideració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 actualización de Windows, una DLL descarriada que ha quedado en memoria, o alguna aplicación incorrectamente programada que comparte el ordenador 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, francamente estarían perdidos sin ellos. No obstante, históricamente el proceso de resolver los problemas de una aplicación que se comporta incorrectamente 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 ocurrido. 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 usuario se rasca la cabeza y comienza a investigar el problema, muchas veces yendo 180 grados en la dirección equivocada. Personalmente he perdido días enteros por culpa de errores de ese tipo. Esto es lo que hace que este libro sea único y valioso. El autor ha creado un mapa del campo de minas para nosotros. Incluso nos indica cuándo un mensaje de error es realmente un falso señuelo que puede dejar al desarrollador perdido durante días. Hay muchos libros disponibles sobre Delphi, pero muy pocos tienen el enfoque tan definido de éste. Está dedicado íntegramente a un único tema, pero es claramente el libro que Ud. buscará cuando necesite ayuda durante la solución de problemas. Hacer un libro que no sigue las fórmulas usuales exige mucho valor. Mi alabanza a Mr. Shannon por preparar tan indispensable referencia Robert Vivrette, Editor Técnico The Delphi Informant Magazine xxvi Agradecimientos Agradecimientos Ningún libro es una isla. Aunque mucha de la información que se presenta aquí fue adquirida a través de la aproximación directa (¡programando!), 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, grupos 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 normalmente 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 Kohler, 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 Software 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 fotografí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 codificació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 California), 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 Brookfield, WI; Source Services (Romac International) en New Berlin, WI; Stratagem 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 Cómo este libro se diferencia de los demás Una excelente colección de libros de Delphi está disponible en el mercado. Pocos, sin embargo, contienen suficiente información sobre los mensajes de error específicos de Delphi, qué significan y cómo resolverlos. Averiguar las causas y dar soluciones a los mensajes de error leyendo los archivos de ayuda de Delphi y escudriñando los índices de los libros tradicionales de Delphi puede ser un proceso que consuma mucho tiempo. Este libro llena ese vacío y sirve como una referencia rápida para implementar soluciones rápidas a más de 800 mensajes de error que podrá recibir mientras trabaja con Delphi. Además, cada mensaje de error se explica con suficiente detalle para que pueda entender cómo evitar la reaparición del mismo problema en el futuro. Los mensajes de error son sus amigos Mientras trabaja con Delphi, podrá encontrar mensajes de error en tres etapas distintas del desarrollo: tiempo de diseño, tiempo de compilación y tiempo de ejecución. Los errores de tiempo de diseño y tiempo de compilación los ve el desarrollador solamente. Los errores de tiempo de ejecución pueden ser vistos tanto por el desarrollador como por el usuario final. Los errores de tiempo de ejecución no son necesariamente culpa del desarrollador — aunque el desarrollador debería contar con la posibilidad de que ocurran, y codificar defensivamente para anticipar tal posibilidad. Una categoría de error de la cual este libro no trata son los errores lógicos. Los errores lógicos no generan directamente mensajes de error. De hecho, puede que ni siquiera provoquen mensajes de error indirectamente (aunque los resultados no sean los esperados). Los errores lógicos pueden subsistir indefinidamente sin ser detectados, y si son descubiertos después de la implantación del software, lo son generalmente por los usuarios finales. Este libro le ayudará a determinar la causa y la solución para los errores de tiempo de diseño, tiempo de compilación y tiempo de ejecución. xxix Introducción Cuando obtenga un error de tiempo de diseño (un cuadro de mensaje que le dice, a veces de forma misteriosa, que ha hecho algo mal), consulte este libro para más información. La primera acción a realizar cuando reciba un mensaje de error de tiempo de compilación debe ser pulsar la tecla F1 para obtener la ayuda sensible al contexto de Delphi. Muchas veces esto le proporcionará información suficiente para resolver rápidamente el problema que ha producido el mensaje de error. En los casos en que la información no sea suficientemente clara y específica, consulte este libro. Delphi le ayudará a determinar la causa del error colocando el cursor sobre la línea de código en que se ha producido el error o la situada inmediatamente después. Si está experimentando un error de tiempo de ejecución, consulte este libro para obtener una explicación. Adicionalmente, las teclas F4, F7 y F8 resultan útiles de cara a la depuración. Si tiene activada la opción Break on Exception (seleccione Tools | Environment Options, y compruebe que la casilla de verificación Break on Exception en la sección Debugging de la página Preferences esté marcada), Delphi deberá mostrarle el lugar del código donde se ha producido el error. Coloque el cursor un poco antes de este sitio, y pulse la tecla F4 para ejecutar hasta la posición del cursor. El programa se ejecutará hasta que alcance ese sitio, y hará una parada. Entonces usted podrá saltar a través del código de línea en línea utilizando las teclas F7 (Trace Into) ó F8 (Step), evaluando el estado del programa y los valores de las variables a lo largo de la ejecución. Para más información, consulte “debugger” en la ayuda de Delphi. Cómo encontrar mensajes de error específicos en este libro Por lo general, localizar información en este libro es muy simple, ya que los mensajes de error se presentan en orden alfabético. Por ejemplo, para encontrar la discusión relacionada con el mensaje de error “A CoClass must have at least one default interface”, simplemente búsquelo en la tabla de contenido, situada al inicio del libro (entre “A class named <> is already installed” y “A CoClass must implement at least one interface”, para ser más exactos). Mensajes de error que contienen variables Algunos mensajes de error son dinámicos o están parametrizados, ya que su redacción exacta será diferente de acuerdo con la situación específica con la que esté tratando. Por ejemplo, el mensaje listado en este libro como “Package <> already contains unit <>” contiene dos variables, que dependen del paquete al que se está intentando añadir una unidad y el nombre de la unidad que ya existe en ese paquete. Si el paquete al que xxx Introducción está intentando añadir una unidad es dclusr40.dpk, y la unidad que está intentando añadir es XProcs.PAS, pero de hecho esa unidad ya ha sido añadida al paquete, el mensaje de error será “Package dclusr40.dpk already contains unit XProcs.PAS”. Esto no debería ser un problema a la hora de localizar un mensaje, excepto quizás en el caso en que una variable se encuentre al inicio de un mensaje de error. Aún así, esto no es un gran obstáculo si toma conciencia del hecho de que el inicio del mensaje de error podría ser una variable. Por ejemplo, si recibe el mensaje de error “; expected but END found”, podría ser un poco confuso saber exactamente dónde encontrar la discusión sobre ese mensaje de error en este libro. Aún cuando sepa dónde está situado el punto y coma en el orden alfabético, no encontrará el mensaje de error en ese lugar, ya que el mensaje de error contiene variables. Si se da cuenta, sin embargo, de que este mensaje de error puede desplegarse bajo diversas circunstancias, sabrá que debe buscarlo bajo “<> expected but <> found”. La moraleja de todo lo dicho anteriormente es la siguiente: si no está seguro de qué parte de un mensaje de error puede ser variable, busque primero el mensaje de error exacto por orden alfabético; si no puede localizarlo utilizando ese método, búsquelo a lo largo de la sección de la tabla de contenido donde se ubican los mensajes de error que comienzan con una variable (<>). Mensajes de error encapsulados Algunas veces Delphi le dará un mensaje de error muy largo que encapsula un mensaje de error más específico en su interior. Por ejemplo, podrá obtener un error como: “Project <> raised exception class EClassNotFound with message ‘Class <> not found. Process stopped’”. En casos como éste, busque el mensaje de error más interno (en este caso “Class <> not found”). De la misma forma, si el mensaje de error comienza con “Fatal Error”, “Run-time Error”, “I/O Error”, “Error in Module <>” u otra categoría de error genérica, busque el mensaje de error más específico que sigue a la clasificación general. Por ejemplo, si obtiene el mensaje “Fatal Error <>: Required Package <> not found”, búsquelo bajo “Required Package <> not found”. Cuando hay muchas causas potenciales para el mismo error Algunos mensajes de error pueden ser provocados por más de una acción claramente definida. En muchos de esos casos, las diferentes causas potenciales del mensaje de error son enumeradas y discutidas xxxi Introducción separadamente en las tres secciones que componen cada entrada (‘Posible causa de error’, ‘Solución rápida’ e ‘Información adicional’). En tales casos, haga corresponder el número en la sección ‘Posible causa de error’ con su correspondiente discusión en la sección ‘Solución rápida’ (en ocasiones, ciertas causas de error específicas se discuten también individualmente en la sección ‘Información adicional’). Cuando necesite más información Habrá ocasiones en las que deseará información más detallada que la contenida en este libro. Afortunadamente, existen numerosos recursos a disposición de los programadores de Delphi, tales como publicaciones periódicas, grupos de usuarios, grupos de noticias de Internet, sitios web, y por supuesto, otros libros que puede encontrar en www.danypress.com. Aquí están algunos de los mejores recursos disponibles en cada categoría: 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 también descargar todas las ediciones anteriores de UNDU de su sitio web: Http://www.undu.com Sitios web dedicados a Delphi Existe una gran cantidad de sitios web excelentes dedicados a Delphi. Aquí se listan algunos de ellos, desde los cuales podrá conectarse a otros: 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. Grupos de noticias de Internet He aquí algunos grupos de noticias de Internet relacionados con Delphi: alt.lang.delphi comp.lang.pascal.delphi.databases comp.lang.pascal.delphi.misc comp.lang.pascal.delphi.components.misc comp.lang.pascal.delphi.components.usage comp.lang.pascal.delphi.components.writing Y éstos son algunos de los grupos de noticias sobre Delphi de Borland: borland.public.delphi.objectpascal borland.public.delphi.database.desktop borland.public.delphi.database.sqlservers borland.public.delphi.ide borland.public.delphi.components.using xxxiii Introducción borland.public.delphi.multi-tier borland.public.delphi.winapi borland.public.delphi.internet Para obtener un lista completa y actualizada de los grupos de noticias sobre Delphi de Borland, visite http://www.borland.com Grupo de noticias/sitio web En una categoría especial debemos incluir el sitio web de Tamarack Associates (www.tamaracka.com). Este sitio mantiene un archivo actualizado de todos los mensajes enviados a los grupos de noticias de Borland, y permite hacer sobre ellos búsquedas de palabras específicas, frases, fragmentos de código, signaturas de métodos, etc. Grupos de Usuarios de Delphi Visite http://www.borland.com/programs/usergroups/uglist.html#Delphi, donde podrá encontrar el Grupo de Usuarios de Delphi más cercano a Ud. 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: procedure TForm1.WhateverClick(Sender: TObject); var DiamondbackPitcher: String; begin DiamondbackPitcher := BigUnit; end; 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í: procedure TForm1.WhateverClick(Sender: TObject); var DiamondbackPitcher: String; begin DiamondbackPitcher := 'BigUnit'; end; 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, unidades, componentes, variables y constantes. $2109 Cannot initialize the BDE Posible causa de error Puede haber distribuido utilizando InstallShield Express una aplicación que necesita el BDE, pero la entrada requerida no ha sido añadida al Registro de Windows. 2 Los Tomos de Delphi: Delphi sin problemas 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. $DENYPACKAGEUNIT <> cannot be put into a package Posible causa de error Puede estar intentando colocar una unidad compilada con la directiva $DENYPACKAGEUNIT dentro de un paquete. 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 unidad que la contiene pueda ser colocada en un paquete. {$DENYPACKAGEUNIT OFF} es la configuración por defecto. $DESIGNONLY and $RUNONLY both specified Posible causa de error Puede haber utilizado las directivas de compilador $DESIGNONLY y $RUNONLY al mismo tiempo. Estas directivas proveen una funcionalidad opuesta, por lo que no pueden ser especificadas simultáneamente. Mensajes de error 3 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} El valor por defecto para ambas directivas de compilador es desactivado (off). En realidad, ambas directivas de compilador pueden ser especificadas simultáneamente, pero si es así, al menos una de ellas debe estar desactivada (que es de todas formas su estado por defecto). La directiva de compilador {$DESIGNONLY ON} ocasiona que el archivo de paquete (archivo .DPK) en el que ésta aparece sea compilado para su instalación dentro del entorno integrado de Delphi. La directiva de compilador {$RUNONLY ON} ocasiona que el paquete (archivo .DPK) sea compilado como un paquete de tiempo de ejecución solamente. Utilice ambas directivas de compilador $DESIGNONLY y $RUNONLY solamente en archivos .DPK. $DESIGNONLY and $RUNONLY only allowed in package unit Posible causa de error Puede haber incluido la directiva de compilador $DESIGNONLY o $RUNONLY (o ambas) en un archivo fuente que no es un archivo de paquete (.DPK). 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 pueden estar contenidas en archivos fuente de paquetes (.DPK). 4 Los Tomos de Delphi: Delphi sin problemas $WEAKPACKAGEUNIT & $DENYPACKAGEUNIT both specified Posible causa de error Puede haber especificado ambas directivas de compilador $WEAKPACKAGEUNIT y $DENYPACKAGEUNIT en el mismo archivo fuente. 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 unidad que contenga variables globales, secciones Initialization o secciones Finalization. $WEAKPACKAGEUNIT <> cannot have initialization or finalization code Posible causa de error Puede haber utilizado la directiva de compilador $WEAKPACKAGEUNIT en una unidad que también contiene una sección Initialization o secciones Initialization y 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 finalizació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 Finalization, 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} $WEAKPACKAGEUNIT <> contains global data Posible causa de error Puede haber utilizado la directiva de compilador $WEAKPACKAGEUNIT en una unidad que también contiene datos globales. 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 finalizació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. ‘;’ not allowed before ‘Else’ Posible causa de error Puede haber colocado un punto y coma justo antes de la palabra reservada Else en una sentencia If. 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; La forma correcta de hacer esto es: if SunIsShining then PlayBaseball {sin punto y coma, no hay error} else PlayBasketballIndoors; <> already exists Posible causa de error Está intentando añadir como miembro de un objeto de automatización o biblioteca de tipos un procedimiento, función o propiedad que ya está declarada. 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. <> clause not allowed in interface type Posible causa de error Puede estar utilizando en una declaración de interfaz una cláusula que no es válida para las interfaces. Por ejemplo, lo siguiente generará este mensaje de error, debido a que la cláusula Stored se utiliza para almacenar (o no) el valor de un campo en un archivo .DFM de formulario, y no puede estar presente en una propiedad de interfaz: 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 almacenamiento 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. <> directive not allowed in interface type Posible causa de error Puede estar utilizando en una declaración de interfaz una directiva que no es válida para interfaces. Por ejemplo, lo siguiente generará este mensaje de error 8 Los Tomos de Delphi: Delphi sin problemas debido a que Private se utiliza en las clases de Delphi como especificador de visibilidad, y no es aplicable a tipos de interfaz: 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 “implements” en la ayuda de Delphi para más información sobre la implementación de interfaces en las clases de Delphi. <> expected but <> found Posible causa de error 1. Basado en el código anterior, el compilador estaba esperando encontrar una cosa, pero se le ha proporcionado algo inesperado. Por ejemplo, puede haber tratado de hacer una asignación utilizando el signo igual (=), como en BASIC, en lugar de dos puntos igual (:=), escribiendo algo parecido a: ActiveControl = btnClose; 2. Puede haber omitido algo necesario, como por ejemplo la palabra reservada End en una sentencia Case. 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, utiliza el símbolo = como operador de comparación (igualdad) y como símbolo Mensajes de error 9 de asignación, tendrá que cambiar su manera de pensar. En Object Pascal, = se utiliza sólo para la comparación y debe producir un resultado de tipo Boolean (True o False). Por ejemplo, las dos siguientes sentencias que utilizan el operador = son válidas, ya que ambas producen resultados Boolean. if ActiveControl = btnClose then BattenTheHatches := (ActiveControl = btnClose); <> has no index for fields <> Posible causa de error 1. Puede estar intentando cambiar el índice de una tabla a un índice que no existe a través de la propiedad IndexFieldNames, ya sea directamente en tiempo de diseño o en el código en tiempo de ejecución. Por ejemplo, la siguiente línea: Table1.IndexFieldNames := ‘PeanutGallery’; provocará este error si la tabla no tiene un índice sobre el campo PeanutGallery. 2. Puede haber cambiado la propiedad TableName de un componente TTable, y el valor de la propiedad IndexFieldNames estaba asignado para la tabla anterior. 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 apropiado 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 exclusivas. 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 Repository), haber luego añadido el objeto heredado al Almacén (presumiblemente después de hacerle algunos cambios), y ahora intenta eliminar el objeto original 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. <> is a read-only file Posible causa de error 1. Está intentando modificar un archivo que es de sólo lectura. 2. Puede estar intentando grabar un archivo .PAS mientras trabaja con un sistema de control de versiones (como PVCS) sin haber marcado (check out) el archivo. Solución rápida 1. Puede cambiar el atributo de sólo lectura del archivo de True a False utilizando 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. <> is a reserved word Posible causa de error Puede estar intentando utilizar una palabra reservada de Object Pascal para nombrar a un identificador. 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: Palabras reservadas de Object Pascal and, array, as, asm, begin, case, class, const, constructor, destructor, dispinterface, 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. Aunque Delphi no impide hacerlo, es aconsejable no nombrar los identificadores mediante alguna de las siguientes directivas de Object Pascal: Directivas de Object Pascal absolute, abstract, assembler, automated, cdecl, contains, default, dispid, dynamic, export, external, far, forward, implements, index, message, name, near, nodefault, overload, override, package, pascal, private, protected, public, published, read, readonly, register, reintroduce, requires, resident, safecall, stdcall, stored, virtual, write, writeonly. 12 Los Tomos de Delphi: Delphi sin problemas El lenguaje no hace distinción entre mayúsculas y minúsculas en los identificadores y directivas. <> is already in the Repository. Replace it? Posible causa de error Puede estar intentando añadir al Almacén de Objetos un objeto que ya existe. Solución rápida Pulse el botón Cancel. Información adicional Los objetos en el Almacén pueden ser compartidos entre desarrolladores y proyectos. 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á trabajando 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. <> is already in use by <> Posible causa de error 1. Puede estar intentando ver o editar la estructura de una tabla de base de datos en el Database Desktop o ejecutar alguna otra operación (o utilidad, como las denomina el Database Desktop) mientras la tabla está abierta todavía. 2. Puede ser que uno o más componentes TTable o TDatabase estén abiertos en el entorno de desarrollo 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 componentes 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. <> is an invalid filename Posible causa de error Puede haber asignado para un nombre de archivo una extensión que no es adecuada para el tipo de archivo con el cual está trabajando. Solución rápida Borre la extensión, de modo que la extensión apropiada sea añadida automáticamente, 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 ActiveX 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 asociación usted mismo). <> is an invalid PageIndex value. PageIndex must be between 0 and <> Posible causa de error Puede haber tratado de asignar a la propiedad PageIndex de un componente TTabSheet un valor de índice de página que no existe. Por ejemplo, puede haber escrito un código similar a este: TabSheet1.PageIndex := 3; cuando hay solamente tres páginas (con índices 0, 1, y 2, pero no 3). 14 Los Tomos de Delphi: Delphi sin problemas 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 compilador supone que la página podrá ser creada en el código antes de ser activada mediante un código similar al de arriba. <> is not a type identifier Posible causa de error Puede haber utilizado un tipo de datos que no existe en un procedimiento o función. En todo caso, se esperaba un identificador de tipo en el lugar donde ocurrió el error, pero un nombre de tipo reconocido no fue encontrado allí. 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á tratando de escribir una versión más corta de un tipo de datos. Por ejemplo, podría intentar esto: var s: Str; i: Int; tidy: Bool; wooly: Boolean; {se debe declarar string, no str} {se debe declarar integer, no int} {sin embargo, esto está bien ...} {...al igual que la forma larga} <> is not a unique name Posible causa de error Puede haber intentado asignar un nombre que ya existe a una base de datos mediante el Database Explorer o SQL Explorer (en la edición Enterprise de Delphi). 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 distinguir a unos de otros. Si dos nombres coinciden hasta un cierto nivel de detalle (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. <> is not a valid component name Posible causa de error Puede haber asignado a un componente un nombre que no es permitido en el lenguaje Object Pascal. 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, dispinterface, 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 Aunque es posible hacerlo sin recibir un mensaje de error, es aconsejable no utilizar las siguientes directivas estándar de Object Pascal: absolute, abstract, assembler, automated, cdecl, contains, default, dispid, dynamic, export, external, far, forward, implements, index, message, name, near, nodefault, overload, override, package, pascal, private, protected, public, published, read, readonly, register, reintroduce, requires, resident, safecall, stdcall, stored, virtual, write, writeonly. De forma similar, evite utilizar identificadores ya definidos en el lenguaje Object Pascal (tales como Writeln, Exit, String, Word, etc.) para nombrar los componentes. No cambie los nombres de los componentes en tiempo de ejecución. En otras palabras, no cambie los nombres en el código. Asigne nombres a componentes solamente desde el entorno de desarrollo en tiempo de diseño (en el Inspector de Objetos). <> is not a valid date Posible causa de error Puede haber intentado almacenar una fecha inválida en un campo de una tabla de base de datos, o convertir una fecha inválida de un formato de cadena a un formato de fecha. 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 Si está utilizando Delphi 3 o superior, considere la utilización del componente TDateTimePicker para obtener del usuario valores de tipo fecha. El componente TDateTimePicker no permite que el usuario seleccione fechas inválidas, y de esta manera proporciona una solución sin necesidad de escribir código alguno. Si está utilizando Delphi 4 o superior, tenga en cuenta además el componente TMonthCalendar. <> is not a valid date and time Posible causa de error Puede haber intentado convertir una fecha inválida desde una cadena de caracteres al tipo TDateTime, o de alguna otra manera almacenar un valor inválido en una variable de tipo TDateTime. 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} Si convierte desde una cadena, utilice este formato: var TheDay: TDateTime; begin TheDay := StrToDateTime('18/11/2001 2:11 am'); 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) 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.). 18 Los Tomos de Delphi: Delphi sin problemas 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 := StrToDateTime(Edit1.Text); except on EConvertError do ... <> is not a valid floating point value Posible causa de error Puede estar intentando convertir a un valor de punto flotante una cadena de caracteres que no es reconocida como valor de punto flotante por el compilador. Por ejemplo, si el código es similar a éste: var Trouble: Double; begin Trouble := StrToFloat(Edit1.Text); y el usuario introduce cualquier número en el campo Edit1, el valor será convertido a un número de punto flotante y almacenado en la variable indicada. Pero si el usuario introduce cualquier cosa que no puede ser interpretada como un número real, el mensaje de error bajo discusión se desplegará. 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 ejemplo), se obtendrá el error “Incompatible types: <> and <>” en tiempo de compilación. Mensajes de error 19 <> is not a valid floating point value for field “<>” Posible causa de error Puede estar intentando asignar algo que no es un valor de punto flotante a un campo de punto flotante de una base de datos. Por ejemplo, el siguiente código generará este error si el usuario introduce la cadena “Insuficiente” en el control TDBEdit (dbedtSalary) y pulsa el botón (btnSalary): procedure TfrmGetNosy.btnSalaryClick(Sender: TObject); begin tblPersonalInfo.FieldByName('Salary').AsFloat := dbedtSalary.Text; end; 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). <> is not a valid identifier Posible causa de error 1. Puede haber pulsado un botón OK sin suministrar la información necesaria. 2. Puede estar intentando grabar un archivo de unidad con una extensión distinta a .PAS o un archivo de proyecto con una extensión distinta a .DPR. 20 Los Tomos de Delphi: Delphi sin problemas 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. <> is not a valid integer value Posible causa de error 1. Puede estar intentando convertir una cadena de caracteres que no es reconocida como un valor entero a un tipo entero. Por ejemplo, si su código es similar a éste: var CountOfMonteCarlo: Integer; begin CountOfMonteCarlo := StrToInt(Edit1.Text); y el usuario introduce un valor entero en el campo Edit1, el valor será convertido a un entero y almacenado en la variable correspondiente. Pero si el usuario introduce algo que no se puede interpretar como un entero, el mensaje de error bajo discusión se visualizará. 2. Puede estar intentando abrir un proyecto con una versión de Delphi anterior a la versión utilizada la última vez que lo compiló, en cuyo caso puede hacerse referencia a un formulario como el valor entero inválido 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. <> is not a valid integer value for field “<>” Posible causa de error Puede estar intentando asignar algo que no puede ser interpretado como un valor entero a un campo entero de una base de datos. Por ejemplo, el siguiente código generará este error si el usuario introduce “Fig!” en el control TDBEdit (dbedtWaynesWorld) y pulsa el botón btnLoungeLizard: procedure TfrmLilBigCity.btnLoungeLizardClick(Sender: TObject); begin tblAlteredCities.FieldByName( 'TimesIveBeenToRenoButDidNotSeeWayneNewton').AsInteger := dbedtWaynesWorld.Text; end; 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ñadiendo 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). <> is not a valid time Posible causa de error Puede estar intentando convertir un valor inválido desde una cadena de caracteres a una variable TDateTime, o de algún otro modo intentando almacenar un valor inválido en una variable TDateTime. Solución rápida Asegúrese de que el valor a convertir sea válido. Mensajes de error 23 Sí está almacenando directamente un valor en una variable TDateTime, utilice este formato: var TheTimeOfOurLives: TDateTime; begin TheTimeOfOurLives := 0.8125; Sí convierte desde una cadena, utilice este formato: var TheTimeOfOurLives: TDateTime; begin TheTimeOfOurLives := StrToTime('7:30 pm'); 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 incrementando 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. <> must be saved before adding to Repository. Save now? Posible causa de error Puede estar intentando añadir al Almacén de Objetos un formulario que aún no ha sido guardado. 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 Repository, o bien seleccione Project | Add to Repository. Información adicional Si está trabajando en un entorno de programación en equipo, se puede configurar 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. <> or <> expected but <> found Posible causa de error 1. Puede haber utilizado un paréntesis donde debería haber un corchete, o viceversa. 2. Puede haber utilizado un punto y coma donde debería haber un punto, o viceversa. Mensajes de error 25 3. Puede haber proporcionado una cantidad de argumentos errónea en una llamada a procedimiento o función (en cuyo caso el compilador estará esperando una coma, en lugar de un paréntesis derecho/de cierre). 4. Puede haber omitido el punto y coma de la línea anterior. 5. Puede haber insertado algún código entre las partes Unit e Interface de una unidad. Por ejemplo, puede haber insertado ahí una sección Var y/o Const. 6. Puede estar utilizando un archivo .PAS en el cual se ha omitido una palabra reservada necesaria, por ejemplo, Unit. 7. Puede haber intentado declarar un tipo en una sección Var, de la siguiente manera: var TForm1 = class(TForm) En este caso, el mensaje de error específico será “, or : expected but = found”. 8. Puede haber antepuesto el nombre de la unidad en lugar del nombre de la clase a un método (por ejemplo, escribiendo la signatura de un método en la parte Implementation como Unit1.ProcedureName, en lugar de TForm1.ProcedureName). 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. <> property out of range Posible causa de error Puede haber asignado un valor inválido a una propiedad de un control TrackBar, ProgressBar, TabControl o PageControl. Por ejemplo, si asigna un valor negativo a las propiedades TabHeight o TabWidth de un TabControl o PageControl, obtendrá este mensaje de error. 26 Los Tomos de Delphi: Delphi sin problemas 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. {$R *.RES} missing or incorrect Posible causa de error Puede haber borrado o modificado la directiva de compilador $R del archivo de proyecto (.DPR). 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 aplicació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. (<>, <>, <>, <>) is not a valid DateMonthWeek quad Posible causa de error Puede haber llamado a la función IsValidDateMonthWeek (que apareció con Delphi 6, en la unidad DateUtils), ya sea directa o indirectamente, y haberle proporcionado un año, mes, semana del mes, o día de la semana inválido. Mensajes de error 27 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. (<>, <>, <>) is not a valid DateWeek triplet Posible causa de error Puede haber llamado a IsValidDateMonthWeek (que apareció con Delphi 6, en la unidad DateUtils), ya sea directa o indirectamente, y haberle proporcionado un año, semana del año, o día de la semana inválido. 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. 16-Bit segment encountered in object file <> Posible causa de error Un segmento de 16 bits ha sido encontrado en el archivo objeto (.OBJ) enlazado al programa a través de la directiva de compilador $L . 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 A class named <> is already installed Posible causa de error Puede haber intentado instalar un nuevo componente, pero un mensaje de error (referente al código de la unidad del componente, por ejemplo) se lo ha impedido. Algunas veces parece que el componente está “instalado a medias”: se ha instalado lo suficiente como para que Delphi piense que el componente está instalado, pero no lo suficiente para que esté disponible en la Paleta de Componentes. Por ejemplo, puede haber intentado instalar el control de calendario de Microsoft y habérsele informado que “A class named TCalendar already exists”. 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 adecuada 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 componentes 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. A CoClass must have at least one default interface Posible causa de error Puede haber desmarcado la casilla que indica que una interfaz miembro de un objeto CoClass es la interfaz por defecto del objeto. 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 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, 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. A CoClass must implement at least one interface Posible causa de error Puede haber intentado guardar una biblioteca de tipos que contiene un objeto CoClass sin ninguna interfaz asociada. 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 interfaces (parecido a una raqueta de ping-pong roja). 30 Los Tomos de Delphi: Delphi sin problemas 2. Pulse la página Members para activarla. 3. Pulse con el botón derecho en la página Members y seleccione la opción Insert Interface del menú de contexto. 4. Seleccione la interfaz que desea añadir en el cuadro de diálogo Insert Interface y pulse el botón OK. Ahora puede guardar la biblioteca de tipos. 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, 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. A component class named <> already exists Posible causa de error Al crear un nuevo componente mediante el Asistente para Nuevos Componentes (File | New | Component o Component | New Component), puede haber introducido en el cuadro de edición Class Name el nombre de un componente que ya existe en su VCL. Por ejemplo, puede haber intentado utilizar el nombre TBatchMove (que ya existe). 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 componentes VCL. Seguramente tendrá el núcleo de los componentes de la VCL de Delphi 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 variados 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. A component named <> already exists Posible causa de error Puede haber intentado asignarle a un componente un nombre que ya existe. 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 formulario un nombre único basado en el tipo de componente y un número incremental. 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. A component named <> already exists in a descendent form Posible causa de error Puede haber utilizado la característica de herencia visual de formularios, disponible en Delphi a partir de la versión 2, y luego haber renombrado el formulario del cual ha heredado (o un componente de ese formulario) utilizando un nombre de componente que ya está siendo utilizado en un formulario descendiente. 32 Los Tomos de Delphi: Delphi sin problemas 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 descendientes 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 tienen el mismo nombre. Los componentes colocados sobre el formulario descendiente 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 descendiente (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. A connection with the server could not be established Posible causa de error Puede haber especificado el puerto equivocado en el URL, o ningún puerto en absoluto, o está escuchando por el puerto equivocado en una aplicación Site Express. 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. A device attached to the system is not functioning Posible causa de error 1. Puede estar intentando instalar un paquete que requiere un archivo .DLL que no está en el camino de búsqueda de Delphi. La DLL no encontrada puede ser también una unidad de paquete. 2. El paquete puede haber sido compilado con una versión de Delphi diferente de la que está utilizando. 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, pestañ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 contactar 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 indicaciones 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. A dispinterface type cannot have an ancestor interface Posible causa de error Puede haber especificado una disp-interfaz (interfaz de automatización) como ancestro para un tipo disp-interfaz. 34 Los Tomos de Delphi: Delphi sin problemas 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. A dispinterface type requires an interface identification Posible causa de error Puede haber dejado de especificar un GUID en un tipo disp-interfaz. 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). A field or method named <> already exists Posible causa de error Su archivo .PAS puede contener una referencia al objeto o método que está intentando añadir al formulario, pero no se encuentra la referencia correspondiente en el archivo .DFM de formulario. Por ejemplo, puede haber añadido el botón Button1 a un formulario, luego haber borrado manualmente la referencia a Button1 del archivo de formulario (.DFM), y luego añadido otro botón al formulario. Los archivos .DFM y .PAS no están sincronizados, ya que el archivo .PAS cree que hay dos controles TButton, mientras que el archivo .DFM solamente conoce la existencia de uno. 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 referencia 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. A module called <> is already installed Posible causa de error Puede estar intentando instalar un componente que anteriormente trató de instalar sin éxito. 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éndole 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 instalan 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áginas de la Paleta de Componentes en Delphi 3 y superiores, seleccione Component | 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 A page must be empty before it can be deleted Posible causa de error Puede estar intentando eliminar una página de la Paleta de Componentes que contiene todavía componentes. 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á eliminar 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é componentes 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 deshacer 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 eliminación del paquete. A reference to <> already exists in the Type Library Posible causa de error Puede estar intentando crear un control ActiveX basado en un componente VCL, y el nombre dado al control ActiveX ya ha sido utilizado. 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 eliminando 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 ocasiones subsiguientes o recibirá el mensaje de error bajo discusión. A required .DLL file, <>, was not found Posible causa de error Puede estar tratando de ejecutar un programa que ha sido compilado para utilizar paquetes de tiempo de ejecución, y uno (o más) de esos paquetes, por 38 Los Tomos de Delphi: Delphi sin problemas ejemplo VCL30.DPL, no está instalado en la máquina o no está situado en el directorio adecuado. Solución rápida Asegúrese de que todos los paquetes requeridos estén instalados en el directorio 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 parcialmente 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. A transaction is already active Posible causa de error Puede haber iniciado una transacción en DBExpress mientras otra transacción ya estaba en curso. Por ejemplo, puede haber hecho una segunda llamada al método StartTransaction sin antes confirmar o deshacer la primera transacción. 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 Cuando se encierra un conjunto de operaciones sobre una base de datos en una transacción, se deben confirmar los cambios o deshacerlos al final de la ejecución de las operaciones. Por ejemplo: SQLConnection1.StartTransaction(1); try {Aquí las operaciones sobre la base de datos} SQLConnection1.Commit(1); except SQLConnection1.Rollback(1); end; A user transaction is already in progress Posible causa de error Puede estar intentando iniciar una transacción de base de datos mientras una transacción anterior está todavía en curso. Por ejemplo, el siguiente código ocasionará el mensaje de error bajo discusión: begin with Database1 do begin Connected := True; StartTransaction; try Query1.Active := True; StartTransaction; {borre esta línea para evitar el error} Commit; except Rollback; end; end; end; 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 A value must be specified for <> Posible causa de error No se ha asignado valor a un campo de una tabla de base de datos que fue especificado como obligatorio (en el momento en que la tabla fue diseñada o posteriormente mediante código). 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 OnKeyDown 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 caracterí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 primaria. Consulte “TTable.AddIndex” en la ayuda de Delphi para más información. Adicionalmente, puede designar campos como obligatorios (required) para evitar 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 sección Field Roster. Mensajes de error 41 Si crea la tabla mediante código, puede utilizar el método FieldDefs.Add de TTable y asignar el valor True al parámetro Required. Por ejemplo, si desea crear cuatro definiciones de campo, estableciendo los dos primeros como obligatorios y los dos siguientes como opcionales, podría hacerlo de esta manera: Table1.FieldDefs.Add('OfDreams', ftString, 20, True); Table1.FieldDefs.Add('WC', ftBlob, 256, True); Table1.FieldDefs.Add('DepthOf', ftInteger, 0, False); Table1.FieldDefs.Add('Mrs', ftBytes, 32, False); Los parámetros del método Add son: 1. El nombre que se asigna al campo. 2. El tipo de datos que se asigna al campo. 3. El tamaño del campo (0 en caso de que la elección del tamaño no sea posible para el tipo de datos, como en el caso de un campo Integer) 4. El parámetro booleano Required, para indicar si el campo es obligatorio o no. Consulte “TDataSet.FieldDefs” en la ayuda de Delphi para más información. La validación a nivel de tabla solamente, sin embargo, no evita que el usuario introduzca un valor incorrecto del tipo de datos correcto. Por ejemplo, la introducción de 15/10/1879 como fecha de nacimiento o de K6%l3^b6&n como el apellido de un empleado será aceptado como una entrada válida (a menos que se haya implementado algún código defensivo para prevenir estos tipos de errores). La validación a nivel de registro también se proporciona durante el diseño de la tabla, cuando es posible designar un campo como clave primaria (Delphi garantizará que no se introduzca el mismo valor para ese campo en dos registros diferentes), designar un campo como obligatorio (Delphi no permitirá que sea dejado en blanco), o asignar los valores mínimos o máximos que pueden ser aceptados por el campo, etc. La validación a nivel de tabla y de registro es realizada por Delphi siempre que usted intente moverse del registro que está insertando o modificando a otro registro diferente. Si los valores de cualquiera de los campos violan las reglas de validación incorporadas a la base de datos, recibirá los mensajes de error apropiados en ese momento. Si prefiere proporcionar la validación a nivel de registro mediante código, utilice el evento BeforePost de TDataSet (TTable, TQuery y TStoredProc son todos descendientes de TDataSet que están disponibles en todas las versiones de Delphi; TClientDataset está disponible a partir de Delphi 3 y 4 edición Cliente/Servidor; TNestedTable apareció por primera vez en Delphi 4). Para más información, consulte “TDataSet.BeforePost” en la ayuda de Delphi. Si lo desea, puede también proporcionar validación a nivel de campo, que se ejecuta inmediatamente después de que se introduzca un valor para un campo 42 Los Tomos de Delphi: Delphi sin problemas (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; La excepción que es creada “al vuelo” mediante la llamada a Exception.Create evita que el valor sea introducido en el campo. Las dos siguientes líneas de código mueven el cursor al control en el que el usuario introdujo el valor y lo resaltan en rojo, para que el usuario vuelva a introducir un valor adecuado. Hay todavía otra forma de implementar la validación a nivel de campo: utilizando las propiedades CustomConstraint y ConstraintErrorMessage de TField. CustomConstraint es una sentencia SQL que debe evaluarse a True para que la entrada sea considerada válida. ConstraintErrorMessage es el mensaje que el usuario verá cuando la restricción falle (la entrada no sea válida). Para utilizar estas dos propiedades para implementar la validación mostrada en el procedimiento Table1QuantityValidate, asigne a CustomConstraint el valor x > 0 y a ConstraintErrorMessage el valor “Cada ítem requiere una cantidad de al menos 1. De lo contrario, iremos a la quiebra y se quedará sin trabajo”. Existe también una propiedad de sólo lectura llamada ImportedConstraint, que muestra las restricciones creadas del lado del servidor (si está conectándose a un servidor SQL). No puede alterar esta propiedad, pero sí puede añadir nuevas restricciones a las importadas asignándole un valor a la propiedad CustomConstraint. Consulte en la ayuda de Delphi “TField.CustomConstraint” y “TField.ConstraintErrorMessage” para más información. Si quiere una retroalimentación aún más inmediata para los usuarios cuando éstos introduzcan datos, especialmente en el caso de datos que demanden un formato muy preciso, puede utilizar la propiedad EditMask de TField. Esto se Mensajes de error 43 conoce como validación a nivel de caracteres. Mientras el evento OnValidate de TField valida una asignación de valor a un campo como un todo, la propiedad EditMask de TField permite la validación de los datos carácter a carácter en el momento en que son introducidos por el usuario. La propiedad EditMask proporciona muchas máscaras predefinidas para validar números de teléfono, códigos postales, fechas y horas. Usted puede también crear sus propias máscaras para los tipos específicos de entradas requeridas por su aplicación. Si asigna valor a un campo mediante programación, la validación establecida por EditMask no es realizada; en este caso, utilice el evento OnValidate de TField para validar la entrada antes de que sea enviada a la tabla. Para más información, consulte “TField.EditMask” en la ayuda de Delphi. Si todas las posibles entradas válidas para un campo son conocidas de antemano o están contenidas en una tabla, otra manera efectiva de asegurar que todas las entradas de usuario sean válidas es utilizar los componentes TDBLookupListBox y/o TDBLookupComboBox. De esta manera, se puede limitar a los usuarios a seleccionar uno de los posibles valores del campo. Para más información, consulte “TDBLookupListBox” y “TDBLookupComboBox” en la ayuda de Delphi. A Win32 API function failed Consulte “EOutOfResources”. Abstract method error Posible causa de error 1. Puede estar intentando ejecutar un método virtual abstracto. Por ejemplo, puede haber creado un descendiente de TCustomGrid sin redefinir el método virtual abstracto DrawCell de TCustomGrid, y haber intentado llamar a ese método. 2. De modo similar al punto anterior, puede estar intentando llamar a los métodos Delete o Insert de TStringGrid. 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 Y luego impleméntelo, de esta forma: procedure TGridIron.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); begin {Hágalo a su manera} end; 2. No llame a los métodos Delete o Insert de una rejilla de cadenas, ya que estos métodos virtuales abstractos no son redefinidos en la clase descendiente de TStrings (TStringGridStrings) que las propiedades Rows y Columns utilizan. 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. Abstract methods must be virtual or dynamic Posible causa de error Puede estar intentando declarar un método abstracto, pero haber omitido la directiva Virtual o Dynamic. 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, redefiniendo 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} Sin embargo, declarar un método abstracto como el siguiente producirá el error bajo discusión: procedure Extrapolate(Interpolate: Extended); abstract; Mensajes de error 45 Para evitar el error, declare el método de una de las siguientes formas: procedure Extrapolate(Interpolate: Extended); virtual; abstract; procedure Extrapolate(Interpolate: Extended); dynamic; abstract; Para más información sobre las diferencias y las ventajas/desventajas de utilizar métodos estáticos, virtuales y dinámicos en diferentes circunstancias, consulte “dispatching methods” en la ayuda de Delphi. Access violation (General Protection Fault) Posible causa de error Algunas veces parece ser que hay más maneras de obtener una violación de acceso que partículas subatómicas en el universo. Este es un mensaje de error bastante genérico, común y serio. 1. Puede estar intentando hacer referencia a un objeto que no existe todavía o que ha dejado de existir. Por ejemplo, puede estar intentando abrir un TTable en el evento OnCreate del formulario principal cuando el TTable está localizado en un formulario o módulo de datos que no ha sido creado todavía (preferentemente un módulo de datos). 2. Puede haber creado un componente que hace referencia a otro componente a través de una de sus propiedades, pero ha olvidado redefinir el método Notification. Por esta razón, su componente puede seguir haciendo referencia a un componente ya inexistente si se elimina el componente al que la propiedad de su componente hace referencia. 3. Puede haber colocado en el formulario un componente que no hace la llamada a Inherited en su constructor. 4. Puede haber publicado una propiedad del tipo de dato Real en un componente en Delphi 1, 2, o 3 (el tipo Real es admitido en los componentes en Delphi 4 y posteriores, donde se implementan de una manera distinta a las versiones anteriores de Delphi). Por ejemplo, el siguiente código generará el mensaje de error bajo discusión (anterior a Delphi 4): unit NoRealityAllowed; interface uses WinTypes, WinProcs, Classes, Controls, Forms; type TDontGetReal = class(TWinControl) private FEstate: Real; published Estate: Real read FEstate write FEstate; end; 5. Puede estar pasando un parámetro inválido a una llamada a la API de Windows. Por ejemplo, puede estar pasando un puntero inválido como parámetro de buffer. 46 Los Tomos de Delphi: Delphi sin problemas 6. Puede estar utilizando punteros y haber olvidado reservar la memoria antes de acceder a ella través de un puntero, o estar intentando hacer referencia a una zona de memoria que ya ha sido liberada. 7. Puede tener una configuración del parámetro del BDE SHAREDMEMLOCATION que es contradictoria con otros procesos. Solución rápida 1. Asegúrese de que los objetos a los que hace referencia ya hayan sido creados, 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 destruido) 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 4. Si necesita utilizar un número de punto flotante en la sección Published del componente (en Delphi 1, 2, o 3), no utilice el tipo de datos Real; en lugar de ello, utilice Single, Double, Extended o Comp. 5. Consulte la ayuda de la API de Windows para obtener información sobre la función de la API y los parámetros y tipos de parámetros que espera. Si necesita más información de la que el archivo de ayuda ofrece (¡es un producto de Microsoft, no de Borland!), consulte “Los Tomos de Delphi: Núcleo del API Win32”, de John Ayres y otros, editada en castellano por Danypress (http://www.danypress.com), que ofrece un enfoque orientado a Delphi de las funciones de la API de Windows, con ejemplos específicos de cómo utilizarlas desde Delphi. 6. Siempre reserve memoria antes de hacer referencia a ella a través de un puntero, y libere la memoria cuando termine de trabajar con ella. Por ejemplo, podría reservar cierta memoria en la sección Initialization de la unidad, y liberar la memoria en su sección Finalization, de esta manera: initialization New(ptrOne); New(ptrTwo); . . . finalization Dispose(ptrOne); Dispose(ptrTwo); . . . end; Si está trabajando con Delphi 1, no dispondrá de una sección Finalization. Tendrá que liberar la memoria en cualquier otro lugar, o crear un procedimiento de salida, de esta manera: procedure GarbageCollection; far; begin Dispose(ptrOne); Dispose(ptrTwo); . . . end; initialization New(ptrOne); New(ptrTwo); . . . AddExitProc(GarbageCollection); end. 7. Si está ejecutando Windows 95/98, asigne a SHAREDMEMLOCATION un valor entre $9000 y $FFFF; si es Windows NT/2000, entre $1000 y $7F00. 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 b. Pulse el botón Options. c. En el cuadro de lista Auto-Create Forms, seleccione el formulario que desea crear dinámicamente. d. Pulse el botón de flecha a la derecha, para mover el formulario a la lista Available Forms. e. Pulse el botón OK. f. Modifique el código que utilizó para mostrar el formulario de la siguiente manera: 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 About antes de crearlo, como en este caso: AboutBox.ShowModal: AboutBox := TAboutBox.Create(Application); AboutBox.Free; o si omite completamente la llamada a Create, provocará el mensaje de error bajo discusión. Es una buena idea crear dinámicamente los formularios en el código, especialmente cuando éstos no son utilizados durante todo el tiempo que el programa está en ejecución. Si no crea los formularios dinámicamente, éstos serán automáticamente creados por Delphi durante el arranque de la aplicación. Casi siempre querrá que Delphi cree automáticamente el formulario principal, pero debería considerar posponer la creación de los demás formularios hasta tanto se necesiten. 7. Consulte “BDE Initialization Error $2501”. Access violation at address <>.<> of address <> Posible causa de error Puede haber sobrescrito la pila manipulando directamente un puntero en lugar del área de memoria a la que él apunta. En otras palabras, puede haber olvidado derreferenciar un puntero. Por ejemplo, el siguiente código provocará este mensaje de error (“… Read of address 00000000”): var ptrBuf: Pointer; //o cualquier otro tipo puntero, como PChar begin Mensajes de error 49 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 sintá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). Ambiguous overloaded call to <> Posible causa de error Puede haber utilizado una combinación de sobrecarga de métodos y parámetros por defecto (ambas características fueron introducidas en Delphi 4), y luego haber hecho una llamada a procedimiento o función que podría corresponder a varios de esos métodos sobrecargados. Por ejemplo, si declara los siguientes métodos sobrecargados: procedure PTBoat(I: Integer; J: Integer = 0); overload; procedure PTBoat(Size: Integer); overload; . . . Y luego intenta llamar a uno de ellos de esta manera: procedure TForm1.Button1Click(Sender: TObject); begin PTBoat(109); end; Obtendrá este mensaje de error, ya que es imposible para el compilador determinar a cuál de los dos procedimientos está llamando. 50 Los Tomos de Delphi: Delphi sin problemas 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: procedure TForm1.Button1Click(Sender: TObject); begin PTBoat(109, 0) {llama al segundo método PTBoat} end; 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 cualquiera de los métodos. Ancestor component not found Posible causa de error Puede haber cambiado un formulario que heredaba de otro tipo de formulario (herencia visual) para hacerlo descendiente de un TForm “genérico”, y luego haber seleccionado View As Text seguido de View As Form desde el menú de contexto del formulario. Por ejemplo, puede haber cambiado una declaración de tipo de un formulario de: TFormMaintenanceScript = class(Tss_BaseStatusForm) 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 An error occurred while attempting to initialize the Borland Database Engine (error <>) Posible causa de error Puede haber dejado de llamar a Sessions.OpenSession antes de llamar a una función del BDE. 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 network 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 named <> is already on the search path Consulte el mensaje “Another file with the same base name (<>) is already on the search path”. 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 Si el archivo no es una nueva versión de un archivo existente, pero tiene el mismo nombre de otro archivo ya existente (y desea conservar el archivo original en su biblioteca de componentes), simplemente cambie el nombre del nuevo componente e intente instalarlo de nuevo. 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 suficiente 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é componentes 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 deshacerse 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úsqueda que Delphi está utilizando. Puede luego buscar el archivo en esos directorios 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 Componentes, 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. Application is not licensed to use this feature Posible causa de error Puede estar intentando ejecutar un programa de demostración incluido en Delphi Cliente/Server (Enterprise) con la edición Standard o Professional. 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 1. Seleccione Inicio | Configuración | Panel de control | Agregar/Quitar Programas. 2. En la página Instalar/Desinstalar, seleccione la versión de Delphi que tenga sobre su sistema. 3. Pulse el botón Aceptar y siga las indicaciones. 4. Reinstale Delphi Enterprise. Información adicional Como las diferentes ediciones de Delphi difieren en características y componentes, no es posible mezclar y combinar proyectos creados con diferentes ediciones. 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”. Arithmetic Overflow Error Posible causa de error Puede estar intentando asignar a una variable entera un valor que supera la capacidad de representación del tipo entero. Por ejemplo, obtendrá este error si intenta asignar el valor 256 a un variable de tipo Byte. 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. Array type required Posible causa de error Puede estar intentando aplicar un índice a un identificador que no es un tipo de array. 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 efectivamente 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; El parámetro de cadena opcional es el mensaje de error que se despliega en caso de que la aserción falle. Assignment to FOR-Loop variable <> Posible causa de error Puede estar intentando asignar un valor a la variable de control de un bucle For en cualquier versión de Delphi de 32 bits. 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 variable 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 determina 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 Lo siguiente, sin embargo, no es aceptable y producirá el mensaje de error bajo discusión: procedure BadLoop(TimesToLoop: integer); var i: integer; begin for i := 0 to TimesToLoop do i := i + IntToStr(i); {No se permite asignar a la variable de control del bucle} end; Si quiere abandonar condicionalmente un bucle For en dependencia del valor de la variable de control del bucle, compruebe el valor y llame al procedimiento Exit o Break si desea abandonar el bucle. Puede hacer esto de la siguiente manera: procedure SimpleLoop(TimesToLoop: integer); var i: integer; s: string[10]; begin s := ''; for i := 0 to TimesToLoop do begin if i > 10 then Break; s := s + IntToStr(i); end; end; Asynchronous socket error <> Posible causa de error Puede estar intentando establecer una comunicación entre un componente TClientSocket y un componente TServerSocket, pero ha olvidado asignar a sus propiedades Port el mismo valor. 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 Telnet smtp 21/tcp 23/tcp 25/tcp At end of table Posible causa de error Puede estar intentando acceder a la propiedad OldValue de un campo al insertar un nuevo registro en modo de actualizaciones en caché (CachedUpdates). Debido a que no existe una versión anterior de este registro, es imposible acceder 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; Alternativamente, puede encerrar la lectura de OldValue en un bloque Try. . . Except, así: try GeezerVal := OldValue; except MessageBox('No hay un valor anterior disponible’); Abort; end; 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). Bad argument type in variable type array constructor Posible causa de error 1. Puede haber utilizado un procedimiento (que no devuelve ningún valor, y por lo tanto no puede proporcionar el valor necesario) como argumento de la función Format. Por ejemplo, el siguiente código generará este mensaje de error, ya que RaiseLastWin32Error es un procedimiento que potencialmente produce un mensaje de error (en lugar de devolver una cadena): Mensajes de error 59 SlErrMsgs.Add( Format(SErrorMessage, [E.Message, RaiseLastWin32Error, DateTimeToStr(Now)]); 2. Puede haber intentado insertar una sentencia en el lugar donde se esperaba 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 Bad global symbol definition: <> in object file <> Posible causa de error Puede haber enlazado a su aplicación un archivo objeto (.OBJ) que contiene una definición de un símbolo que no fue declarado en Pascal como un procedimiento externo. El símbolo puede haber sido declarado como variable. Solución rápida Ignore el error si la definición especificada en el mensaje de error no es necesaria 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 provoca el error sea ignorado. Las directivas $L y $LINK son sinónimas, y se utilizan para enlazar procedimientos y funciones escritos en otros lenguajes y declarados en Delphi como externos. La sintaxis que se utiliza para ello es: $L[INK] <Archivo objeto> Por ejemplo, si quiere enlazar el archivo CBUILDER.OBJ (situado en el camino de búsqueda de Delphi), podría introducir cualquiera de las dos directivas siguientes: $L CBUILDER $LINK CBUILDER Si no incluye un camino en el nombre del archivo, Delphi buscará en el mismo directorio del módulo actual, seguido por los caminos especificados en Tools | Environment Options | Library | Library Path. Bad packaged unit format: <>.<> Posible causa de error El archivo nombrado en el mensaje de error puede estar corrupto. Podría ser el resultado de una terminación anormal del compilador durante la escritura del archivo de paquete, tal vez como resultado de la pérdida de energía en ese momento. Mensajes de error 61 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. Bad unit format: <> Posible causa de error Un archivo de unidad compilada (.DCU) probablemente se ha dañado. 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 2. Seleccione la pestaña apropiada en el cuadro de diálogo Install Component (Into Existing Package o Into New Package), en dependencia de dónde desea instalar el componente. 3. Pulse el botón Browse. 4. En el cuadro de diálogo Unit File Name, navegue y seleccione el archivo .PAS. 5. Pulse el botón Open. 6. Pulse el botón OK en el cuadro de diálogo Install Component. Si el archivo .DCU es un archivo de unidad compilada tradicional (no un archivo de componente), siga estos pasos para recompilar el archivo fuente (.PAS) y producir una nuevo archivo de unidad compilada (.DCU): 1. Borre el archivo .DCU (o muévalo a un lugar distinto del sitio donde reside el proyecto al que pertenece). 2. Cargue el proyecto del cual es parte la unidad .PAS correspondiente. 3. Recompile el proyecto (F9). Si recompilar el archivo fuente no resuelve el problema, puede que desinstalar y volver a instalar Delphi sí lo haga. BDE Initialization Error $2501 Posible causa de error Puede estar utilizando un componente TDatabase o TSession en una aplicación de múltiples capas, y necesita modificar los parámetros SHAREDMEMLOCATION y/o SHAREDMEMSIZE. 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” (memoria 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. Bitmap image is not valid Posible causa de error 1. Puede haber intentado cargar en la propiedad Picture de un componente TImage un archivo que, aunque tiene una extensión .BMP, no es realmente una imagen en formato BMP, o el archivo .BMP puede estar corrupto. 2. Puede que exista una falta de coordinación entre el mapa de bits y la propiedad PixelFormat de Picture.Bitmap. 3. Puede estar intentando cargar un gráfico BLOb de MS Access, MS SQL Server o MS Fox Pro en un componente TDBImage. 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 procedure TWhatever.<DatasetName>AfterScroll(Dataset: TDataset); const LENGTH_OF_HEADER_INFO = 78; var bm: TBitmap; bs: TBLObStream; begin bx := TBLObStream.Create(<TFieldName>, bmRead); try bs.Seek(LENGTH_OF_HEADER_INFO, soFromBeginning); bm := Tbitmap.Create; try bm.LoadFromStream(bs); DBImage.Picture.Graphic := bm; finally bm.Free; end; finally bs.Free; end; end; Información adicional 3. Las bases de datos de Microsoft antes mencionadas almacenan los gráficos como objetos OLE y no como datos puros. Nota: <TFieldName> es la concatenación de un nombre de Dataset y un nombre de campo. Delphi proporciona soporte nativo para cuatro formatos de archivos gráficos, concretamente .BMP (mapas de bits), .ICO (iconos), .WMF (Windows Metafile) y .EMF (Enhanced Metafile). Puede ser que alguien haya cambiado la extensión de un archivo, de modo que parezca ser un archivo de mapa de bits por su extensión aunque realmente no lo es. Bits index out of range Posible causa de error Puede haber intentado hacer referencia a un elemento de un array de valores de tipo Boolean mediante un índice que es mayor que el tamaño del objeto TBits o menor que 0. Por ejemplo, ambas asignaciones a la variable little en el siguiente fragmento de código provocan este mensaje de error, ya que en la primera se intenta acceder a un elemento con un índice que supera el tamaño del objeto TBits, y en la segunda se utiliza un índice menor que 0: Mensajes de error 65 procedure TForm1.BitsUnderOverExample(Sender: TObject); var kibbles: TBits; little: Boolean; begin kibbles := TBits.Create; try kibbles.Size := 7; little := kibbles.Bits[8]; little := kibbles.Bits[-1]; finally Kibbles.Free; end; end; 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 propiedad 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 implementa 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). BLOb has been modified Posible causa de error 1. Múltiples aplicaciones pueden estar accediendo a una tabla desde una máquina que ejecuta Windows 95 con la versión 4.00.1111 o la versión 4.00.1113 del Redirector de Redes Virtuales de Microsoft (VREDIR.VXD). 2. Puede estar intentando mostrar el contenido de un campo BLOb (como por ejemplo un campo memo con formato de Paradox) en un control TDBRichEdit. 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 localizado en C:\Windows\System. También puede descargar un archivo actualizado del sitio web de Microsoft. 2. Utilice un campo Memo de Paradox (TMemo en Delphi) en lugar de un campo Formatted Memo si desea mostrar el contenido del campo en un control TDBRichEdit. Entonces podrá mediante programación formatear el contenido del control TRichEdit. 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: Tipo de dato Paradox Descendiente TField de Delphi Alpha TStringField Autoincrement TAutoIncField BCD TBCDField Binary TBlobField Byte TBytesField Date TDateField Formatted Memo TBlobField Graphic TGraphicField Logical TBooleanField Long Integer TIntegerField Memo TMemoField Money TCurrencyField Number TFloatField OLE TBlobField Short TSmallIntField Time TTimeField Timestamp TDateTimeField Mensajes de error 67 Break or Continue outside of loop Posible causa de error Puede estar llamando al procedimiento Break o Continue fuera de un bucle For, While o Repeat. 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 consideran 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; Para evitar el mensaje de error, encierre la llamada al procedimiento Break o Continue dentro de un bloque Begin. . . End, así: procedure SaturdayNightAtTheMovies; begin while WatchingMovie do begin EatPopcorn; if TheaterCatchesFire then Break; {ahora esto es parte del bucle} end; end; Lo mismo, por supuesto, es aplicable al procedimiento Continue. Para más información sobre las sentencias For, While y Repeat, consulte “writing loops” en la ayuda de Delphi. Hay cuatro procedimientos de control del flujo que pueden ser utilizados en diversas circunstancias: Continue, Break, Exit y Halt. Adicionalmente, la clase TApplication ofrece un procedimiento Terminate. Para explicar estos procedimientos en pocas palabras, diremos que Continue provoca un salto a la próxima iteración del bucle; Break transfiere el control fuera del bucle; Exit transfiere el control fuera del procedimiento o función; y Halt implica la terminación del programa entero (como Application.Terminate). 68 Los Tomos de Delphi: Delphi sin problemas Examinemos estos procedimientos con más detalle: Una llamada al procedimiento Continue devuelve el flujo de control al inicio de la sentencia For, While o Repeat. En otras palabras, la próxima iteración del bucle se inicia inmediatamente cuando el procedimiento Continue es llamado. Por ejemplo, observe el código a continuación: function OneForTheThumb: Boolean; var i: integer; begin i := 0; Result := False; repeat Play(RegularSeasonGames); if not WinTheDivision then Continue; Play(Playoffs); if not WinThePlayoffs then Continue; Play(ChampionshipGame); if not WinTheChampionshipGame then Continue; i := i + 1; until i = 5; Result := True; end; Una llamada al procedimiento Break ocasiona que el flujo de control se interrumpa para un bucle For, While o Repeat y se prosiga con la próxima sentencia después del bucle. Por ejemplo, analice el siguiente ejemplo: procedure ForAllTheTeaInChina(widgets: integer); var i: integer; s: string; begin for i := 0 to widgets do begin if i >= 1000 then Break; {el bucle es abandonado} s := IntToStr(i); {si i >= 1000, esta línea no será ejecutada} end; Order('TsingTao', i * 2); Order('HotPepperBeefStick', i); end; Una llamada al procedimiento Exit transfiere el control inmediatamente de vuelta al procedimiento que llamó al procedimiento actual, donde el programa continuará a partir de la línea siguiente a la llamada del procedimiento dentro del que se llamó a Exit. Mensajes de error 69 Por ejemplo, la llamada a Exit en el siguiente código provoca que el procedimiento CheckItOut sea abandonado y se retorne a donde se hizo la llamada: type TGenre = (BaroqueChamber, Blues, CountryRock, Disco, Opera, Rap, Reggae, Rock, Soul); . . . procedure CheckItOut(MusicStyle: TGenre); begin if MusicStyle in [Disco..Rap] then Exit else if MusicStyle in [BaroqueChamber..CountryRock] then ListenToTheMusic else if MusicStyle in [Reggae..Soul] then DanceToTheMusic else ShowMessage('¿Qué música es ésta?'); end; procedure DetermineCourseOfAction; begin CheckItOut(Soul); CashItOut(Retirement); end; Una llamada al procedimiento Terminate de TApplication provoca un cierre ordenado de la aplicación, aunque ésta no necesariamente se detendrá inmediatamente. He aquí un ejemplo de cómo utilizar este procedimiento: procedure StopInTheNameOfTheLaw; begin if YouNeedToShutDownTheApp then Application.Terminate; end; Para más información, consulte “Application.Terminate” en la ayuda de Delphi. Una llamada al procedimiento Halt ocasiona una terminación anormal del programa y el retorno al sistema operativo. He aquí un ejemplo de cómo se usa este procedimiento: procedure StopInTheNameOfTheLaw; begin if YouNeedToQuitNowAndIMeanNow then Halt; {Esto provocará la terminación inmediata de su programa} end; La terminación normal de un programa tiene lugar automáticamente cuando se cierra su formulario principal (no es necesaria ninguna llamada). 70 Los Tomos de Delphi: Delphi sin problemas Breakpoint is set on line that may have been removed by the optimizer or contains no debug information. Run anyway? Posible causa de error Puede estar intentando establecer un punto de ruptura sobre una línea del código fuente para la cual el compilador no genera código; por lo tanto, no puede hacer una parada ahí. 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 (obviamente, no ignorando las líneas que usted ha escrito, sino sólo en lo que al compilador 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 secció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!”: procedure SaturdayNightAtTheMovies; {¡aquí no!} begin while WatchingMovie do begin {¡aquí no!} EatPopcorn; TheaterCatchesFire := OLearysCowIsHere; if TheaterCatchesFire then Break; end; {¡aquí no!} end; Call to Application.CreateForm is missing or incorrect Posible causa de error Puede haber modificado la línea del archivo de proyecto (.DPR) que contiene la llamada a Application.CreateForm. Mensajes de error 71 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 principal) pueden ser cargados dinámicamente cuando sean necesarios. Esto amortiza 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, especialmente 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 automáticamente por Delphi cuando la aplicación arranque. Siempre querrá que Delphi cree automáticamente el formulario principal, pero podría posponer la creación de los demás formularios hasta el momento en que se necesiten. Call to RegisterClass is missing or incorrect Posible causa de error Independientemente del texto del mensaje de error, la causa real del problema puede ser que ha comentado o borrado el End final (el único que debería terminar con un punto, en lugar de un punto y coma) en una unidad. Solución rápida Asegúrese de que el End final está intacto y que no ha sido comentado. Verifique que todo Begin tiene un End correspondiente, y que todos los comentarios que empiezan con una llave izquierda ({ ) estén emparejados con su correspondiente 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 componente 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). Can’t change value while socket is active Posible causa de error 1. Puede estar intentando cambiar el valor de las propiedades Address, Host, Port o Service de un componente TClientSocket mientras su propiedad Active tiene asignado el valor True. 2. Puede estar intentando cambiar el valor de la propiedad Port o Service del componente TServerSocket mientras su propiedad Active tiene asignado el valor True. 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 componentes de la página Internet. Las versiones anteriores de Delphi tenían una Mensajes de error 73 página Internet en la Paleta de Componentes, pero se utilizaba para los controles ActiveX; el nuevo conjunto de componentes lo componen controles nativos de Delphi. Can’t compile Complib. Too many files in project Posible causa de error Puede tener “demasiados” archivos en el proyecto, o tenerlos situados en demasiadas localizaciones diferentes (directorios). 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. Can’t delete or change record. Since related record exists in table =‘xxx’, referential integrity rules would be violated Posible causa de error 1. Puede estar intentando borrar o modificar un registro maestro que tiene registros dependientes en otra tabla. En otras palabras, puede estar intentando modificar un valor de clave o borrar un registro del que otros registros dependen. 2. Puede estar utilizando Access 95 e intentando hacer uso de la integridad referencial. Lo último es una buena idea, pero no cuando utilice Access 95. Solución rápida 1. Si necesita modificar un registro maestro, no cambie los valores de los campos 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. Can’t load [complib.dcl, cmplib32.dcl, vcl30.dpl, vcl40.bpl, vcl50.bpl, vcl.bpl] Posible causa de error 1. Puede haber movido o borrado el archivo mencionado en el mensaje de error. 2. La VCL de Delphi puede haberse dañado debido a cambios realizados en el código fuente de la VCL. 3. Puede haber intentado sin éxito instalar un componente en su VCL. 4. Puede haber intentado instalar un componente que hace referencia a otro componente o una DLL que no está disponible o no está en el camino de búsqueda del ordenador. 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 4. Asegúrese de distribuir todos los módulos requeridos con cualquier componente o programa que distribuya. 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 paquetes 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/Server) contiene 40 archivos .BPL, y la misma edición de Delphi 6 contiene aproximadamente 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é instalado 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 (preferentemente 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 Delphi 3 y extensión .BPL en Delphi 4 y superiores) que aparecieron por primera 76 Los Tomos de Delphi: Delphi sin problemas vez en Delphi 3. Cuando se compilan los paquetes de tiempo de ejecución, los archivos .DPL/.BPL y .DCP son creados en diferentes lugares en dependencia de la versión de Delphi que esté utilizando. En Delphi 3, los archivos son grabados en el mismo directorio que el archivo de paquete (.DPK); en Delphi 4, el .BPL se almacena en el mismo directorio que el paquete, y el .DCP en \Delphi4\Lib; en Delphi 5 y 6, ambos archivos son grabados en \Delphi X\Projects\BPL. Copie el archivo .BPL desde allí hacia el lugar apropiado para el sistema operativo que esté utilizando (\Windows\System en Windows 95/98, \WinNt\System32 en Windows NT/2000). Para más información, consulte “about packages” en la ayuda de Delphi. La mayoría de los paquetes vienen en parejas para tiempo de ejecución y tiempo de diseño. Los paquetes runtime (de tiempo de ejecución) contienen la “sustancia” del código, y permiten la compilación de aplicaciones que utilicen paquetes de tiempo de ejecución. Los paquetes de tiempo de diseño contienen los elementos específicos necesarios durante el diseño, tales como el icono del componente, las unidades de registro, los editores de propiedades y los editores de componentes. Los paquetes de tiempo de diseño contienen estas unidades específicas, y necesitan el archivo .DCP del paquete de tiempo de ejecución. En otras palabras, un paquete de tiempo de ejecución contiene el código de tiempo de ejecución (!) y para su compilación requieren de VCLX0.DCP (VCL50.DCP para los paquetes de Delphi 5, VCL60.DCP para los paquetes de Delphi 6, etc). Los paquetes de tiempo de diseño contienen el código específico de tiempo de diseño (*REG.PAS, *REG.DCR, etc.) y requieren el archivo .DCP creado cuando el paquete de tiempo de ejecución es compilado. Nota: No instale un paquete de tiempo de ejecución pulsando el botón Install después de compilar. El botón Install en el editor de paquetes es sólo para paquetes de tiempo de diseño. Una vez que haya registrado un componente en Delphi al instalarlo, no podrá instalar otro componente con ese nombre en otro paquete. En otras palabras, instalar el paquete de tiempo de ejecución le impedirá instalar el paquete de tiempo de diseño (que es lo que realmente quiere hacer). 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 Eliminar el paquete de la lista de paquetes de tiempo de diseño (Component | Install packages, seleccione el paquete correspondiente, pulse el botón Remove, y responda Yes al mensaje de confirmación), y luego volverlo a añadir desde su nueva localización. 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 posteriormente 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”. Can’t write .EXE file. Disk full? Posible causa de error Puede no tener suficiente RAM o memoria virtual disponible. 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 aplicació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 innecesarios. 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 sistema (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 1. 2. 3. 4. 5. Seleccione Inicio | Configuración | Panel de Control. Haga doble clic sobre el icono Sistema. Seleccione la página Rendimiento. Pulse el botón Memoria Virtual. Marque el botón de radio Permitir que Windows administre la configuración de memoria virtual. 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áticamente 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 desarrolladores 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 propiedad 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. Cannot assign to a read-only property Posible causa de error Puede estar intentando asignar un valor a una propiedad de sólo lectura. Mensajes de error 79 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 ejemplo 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; Si declara una propiedad como ScottFitzgerald (que es una propiedad de sólo lectura, ya que no incluye un especificador Write en su declaración), y luego intenta escribir en ella, de la siguiente forma: ScottFitzgerald := 'Los millonarios son diferentes a usted y a mí'; obtendrá el mensaje de error bajo discusión. Cannot break, continue, or exit out of a finally clause Posible causa de error Puede haber colocado una llamada a Break, Continue o Exit en la parte Finally de una sentencia Try. . . Finally. 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. Cannot change the size of an icon Posible causa de error Puede estar intentando cambiar el tamaño de un icono. Por ejemplo, el siguiente código generaría este error: Image1.Picture.Icon.Width := 23; 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. Cannot change Visible in OnShow or OnHide Posible causa de error 1. Puede haber intentado cambiar el valor de la propiedad FormStyle de un formulario en sus eventos OnActivate u OnShow. Por ejemplo, lo siguiente generará el mensaje de error bajo discusión: procedure TForm1.FormShow(Sender: TObject); begin Mensajes de error 81 FormStyle := fsStayOnTop; end; 2. Puede haber intentado asignar un valor a la propiedad Visible de un formulario 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 eventos 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á automá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 aplicación se inicie, lo cual podría provocar que la interfaz de usuario no sea intuitiva 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; Si quiere que el formulario aparezca en pantalla y obligue al usuario a emitir una respuesta en él antes de que pueda continuar trabajando con los demás formularios, puede hacerlo así: procedure TForm1.Button12Click(Sender: TObject); begin Form3.ShowModal; end; ShowModal mostrará el formulario modalmente, de forma similar a un cuadro de diálogo, y exigirá que el usuario le dé respuesta y lo cierre antes de poder continuar trabajando con otros formularios. Un ejemplo de este tipo de 82 Los Tomos de Delphi: Delphi sin problemas formularios o cuadros de diálogo son los componentes de Delphi que encapsulan los cuadros de diálogo comunes de Windows, que están situados en la página Dialogs de la Paleta de Componentes (TOpenDialog, TSaveDialog, etc.). Puede también crear formularios dinámicamente, en el momento en que sean necesarios. Esto ayuda a conservar los recursos del sistema y es especialmente útil cuando se tienen formularios que podrían no ser utilizados en una ejecución dada de la aplicación, como por ejemplo un cuadro ‘Acerca de’. Para crear un formulario dinámicamente, 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 haya utilizado para mostrar el formulario a lo siguiente: procedure TForm1.Button12Click(Sender: TObject); begin Form3 := TForm3.Create(nil); try Form3.ShowModal; finally Form3.Free; end; end; Cannot complete a class with incomplete methods implementations Posible causa de error Puede haber intentado invocar la característica de completamiento de código (Code completion) cuando la unidad tenía un error de sintaxis. Solución rápida Solucione cualquier error de sintaxis que exista (seleccione Alt+P, S para verificar la sintaxis), y luego inténtelo de nuevo. Información adicional Consulte “class completion” en la ayuda de Delphi. Mensajes de error 83 Cannot connect, <> must contain a valid ServerName or ServerGUID Posible causa de error Puede haber intentado asignar True a la propiedad Connect de un componente TDCOMConnection, TMIDASConnection o TRemoteServer sin haber especificado un valor válido para la propiedad ServerName o ServerGUID. Solución rápida Introduzca un GUID válido en la propiedad ServerGUID con este formato: 98ED7140-EE18-11D3-A238-80584EC12700 o introduzca el nombre de un servidor registrado en la propiedad ServerName. 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. Cannot connect to database <> Posible causa de error Puede haber intentado conectarse a una base de datos por uno de los siguientes métodos: a. Ha intentado asignar True a la propiedad Connected de un componente TDatabase, en tiempo de diseño o en tiempo de ejecución (por código). b. Ha llamado al método Open de un componente TDatabase o TTable. c. Ha intentado asignar True a la propiedad Active de un TTable, en tiempo de diseño o en tiempo de ejecución (por código), y luego ha pulsado el botón Cancel en respuesta al cuadro de diálogo Database Login (Conexión a Base de Datos). 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 travé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 formulario o módulo de datos): Session.AddPassword('Kennwort'); Para asignar la contraseña utilizando la sección Parameter Overrides del editor del componente TDatabase, siga estos pasos: 1. Haga doble clic sobre el componente TDatabase. 2. Verifique que se muestran el Alias de la base de datos y el nombre de usuario (Name) correcto. 3. Desmarque la casilla de verificación Login Prompt. 4. Pulse el botón Defaults. 5. Añada la contraseña en la línea Password= en el cuadro de lista Parameter Overrides. Alternativamente, puede proporcionar un manejador para el evento OnLogin del componente TDatabase. Para más información, consulte “OnLogin” en la ayuda de Delphi. Cannot copy a Repository Project to a directory underneath itself Posible causa de error Puede haber intentado copiar un proyecto que ha seleccionado del Almacén de Objetos (Repository) a un directorio que está bajo el directorio en que el proyecto del Almacén reside. 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 Cannot create cursor handle Posible causa de error 1. Puede haber intentado llamar al método Open de un componente TQuery cuando la sentencia SQL no devuelve un conjunto de valores. Por ejemplo, lo siguiente produciría este mensaje de error: with Query1.SQL do begin Add('INSERT (LastName) VALUES'); Add('(Murray)'); Add('INTO RBIHRKINGS'); Open; {Reemplace esto por ExecSQL para que funcione} end; 2. La propiedad SQL del componente TQuery puede estar vacía. 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. Cannot create file <> Posible causa de error 1. Puede haber intentado grabar un archivo en una localización que no existe utilizando el método SaveToFile. Por ejemplo, puede haber intentado hacer esto: Image1.Picture.SaveToFile('C:\dotbumps\road.BMP'); sin que exista un directorio llamado dotbumps en la unidad C. 2. Puede haber intentado modificar y luego guardar un archivo de sólo lectura utilizando el método SaveToFile. Por ejemplo, si el archivo SNAPSHOT.TXT es de sólo lectura, lo siguiente generaría el mensaje de error bajo discusión: var Annotate: TStrings; . . . 86 Los Tomos de Delphi: Delphi sin problemas 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 utilizados 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; Cannot create form. No MDI forms are currently active Posible causa de error 1. Puede haber intentado crear un formulario hijo MDI (un formulario que tiene la propiedad FormStyle asignada a fsMDIChild) antes de que el formulario principal (su padre, con el valor fsMDIForm en la propiedad FormStyle) haya sido creado. 2. Puede haber designado un formulario como hijo MDI configurando su propiedad FormStyle a fsMDIChild mientras la propiedad FormStyle del formulario principal no ha sido configurada a fsMDIForm. Solución rápida 1. Asegúrese de que la propiedad FormStyle del formulario padre (el formulario 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 alternativo 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 contenidos 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 Administrador, 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 Componentes, 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 Cannot create Window Posible causa de error 1. Puede estar utilizando una cantidad excesiva de controles TEdit y TComboBox, y se está quedando sin espacio en el heap local. Estos controles utilizan el heap local para almacenar su contenido. 2. Puede tener una cantidad excesiva de descendientes de TWinControl en la aplicación, y estarse quedando sin manejadores de ventana (handles) disponibles. 3. Puede haber experimentado anteriormente un fallo del sistema, y la memoria no fue liberada, por lo que la cantidad de memoria disponible para crear nuevas ventanas está limitada. 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 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). 2. Reduzca si es posible el número de descendientes de TWinControl (controles 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. Cannot debug project unless a host application is defined. Use the Run|Parameters. . . dialog box Posible causa de error 1. Puede haber creado un ActiveForm o biblioteca ActiveX e intentado ejecutarla sin especificar la aplicación desde la que se accede a la biblioteca. 2. Puede haber intentado ejecutar directamente una .DLL seleccionando la opción Run | Run o pulsando la tecla F9. Solución rápida 1. Siga estos pasos: Mensajes de error 89 a. Seleccione Run | Parameters. b. En el cuadro de combinación Host Application, puede: Seleccionar la aplicación principal (host application) de la lista. -OIntroducir el camino de la aplicación principal. -ONavegar hasta la aplicación principal utilizando el botón Browse. 2. En Delphi 4 y superiores, puede añadir una .DLL a un proyecto seleccionando Project | Add to Project. . . , y luego ejecutar indirectamente la .DLL ejecutando el .EXE que la llama. Para más información, consulte “Project Manager”, “remote debugging” y “Resource .DLLs” en la ayuda de Delphi. 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. Cannot enable AutoSessionName property with more than one session on a form or data module Posible causa de error Puede haber intentado asignar True a la propiedad AutoSessionName de un componente TSession cuando hay uno o más componentes TSession adicionales en el formulario o módulo de datos. 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 asignar automáticamente los nombres de sesión (y garantizar que las sesiones 90 Los Tomos de Delphi: Delphi sin problemas generadas en tiempo de ejecución tengan nombres únicos) sólo cuando se utiliza un único componente TSession. Cuando la propiedad AutoSessionName tiene el valor False (como debe ser en caso de que haya más de un componente TSession sobre un formulario), usted es el responsable de asignar un nombre de sesión a través de la propiedad SessionName, ya sea en tiempo de diseño o en tiempo de ejecución (en el código). Para más información sobre las restricciones a tener en cuenta cuando se trabaja con componentes TSession, consulte “Cannot modify SessionName while AutoSessionName is enabled”. Cannot find <> on the search path Posible causa de error Puede haber intentado ver el código fuente de una unidad en el Package Editor (Editor de Paquetes), pero esta no está en el camino de búsqueda de Delphi. Solución rápida Localice el archivo y colóquelo en el camino de búsqueda de Delphi, o modifique 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 representa 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 Cannot find Engine configuration file Posible causa de error Puede que IDAPI.CFG (Windows 3.x) o IDAPI32.CFG (Windows/Delphi de 32 bits) no pueda ser encontrado donde debería estar. 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 secció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 localizació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 Windows 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 configuració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 Cannot find implementation of method <> Posible causa de error Puede haber borrado (o comentado) un método de la sección Implementation sin borrar la declaración del método en la sección Interface, dejando una referencia a él en la página de eventos del Inspector de Objetos. Luego intentó volver a crear el gestor de eventos pulsando dos veces sobre la columna derecha de la página de eventos (Events) del Inspector de Objetos (o sobre un objeto para crear un gestor para su evento por defecto). 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 Delphi 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. Cannot find server Posible causa de error Puede haber especificado incorrectamente el número de puerto en un URL, o ningún puerto en absoluto, o está escuchando por un puerto incorrecto en su aplicación Site Express. 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 Localhost es su máquina (IP #127.0.0.1); está intentando conectarse al puerto 1024 y ejecutar la aplicación Svrinfo. Site Express hizo su aparición en Delphi 6. Cannot focus a disabled or invisible window Posible causa de error 1. Puede haber intentando llamar al método SetFocus para un control cuya propiedad Visible o Enabled tienen el valor False. Por ejemplo, si no hay ningún texto seleccionado en el componente RichEdit1, lo siguiente generará este mensaje de error: procedure DisableAndFocus(Sender: TObject); begin Button1.Enabled := RichEdit1.SelLength > 0; ... {Otro procesamiento} Button1.SetFocus; end; Lo mismo sucedería si la propiedad Visible estuviera siendo comprobada de una manera similar y su valor fuera False. Por ejemplo, en caso de que no hayan datos de texto en el portapapeles, el siguiente código generaría el mensaje de error bajo discusión: procedure HideAndFocus(Sender: TObject); begin Button1.Visible := Clipboard.HasFormat(CF_TEXT); ... {Otro procesamiento} Button1.SetFocus; end; 2. Puede haber utilizado un componente TPageControl en Delphi 2 (este componente no estaba disponible en Delphi 1; esto no ocurre en Delphi 3 y superiores) y asignó a la propiedad ActiveControl un control que no estaba visible la última vez que el proyecto fue cerrado. 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. -OSeleccionando 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 diferencia de concepto entre lo que Ud. puede considerar normalmente como una ventana 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 componentes que descienden de TWinControl son ventanas. Cannot hide an MDI Child Form Posible causa de error Puede estar intentando esconder un formulario hijo MDI de cualquiera de las siguientes maneras: procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caHide; { el valor por defecto es caMinimize } end; procedure TMDIChild.Button1Click(Sender: TObject); begin Hide; {puede mostrarlo, pero no puede esconderlo} end; procedure TMDIChild.Button1Click(Sender: TObject); begin Visible := False; {esto hace lo mismo} end; 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 formulario 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 minimizado, 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; Cannot inherit from form <>. It contains a component with a blank name property Consulte “Error Creating Form: Cannot inherit from form <>. It contains a component with a blank name property”. Cannot initialize local variables Posible causa de error Puede haber intentado asignar un valor a una variable local en el momento de su declaración. Por ejemplo, lo siguiente generará el mensaje de error bajo discusión: procedure TForm2.Button1Click(Sender: TObject); var ThisIsThis: Boolean = True; . . . Lo siguiente también generará el mensaje de error bajo discusión (a pesar del texto del mensaje de error, que hace parecer que éste solamente se produce en una sección Var): procedure TForm2.Button1Click(Sender: TObject); const ThisIsThis: Boolean = True; . . . 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 No asigne un tipo de datos a una constante en la sección Const de un procedimiento o función. Para inicializar la variable ThisIsThis con el valor True (como se intenta en el procedimiento de arriba), proceda de la siguiente forma: procedure TForm2.Button1Click(Sender: TObject); var ThisIsThis: Boolean; begin ThisIsThis := True; . . . O de esta forma, si es que el valor nunca cambiará: procedure TForm2.Button1Click(Sender: TObject); const ThisIsThis = True; . . . 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 valores 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 Cannot initialize multiple variables Posible causa de error Puede estar intentando declarar más de una variable inicializada (o constante con tipo) utilizando una asignación. Por ejemplo, lo siguiente generará el mensaje de error bajo discusión: interface const QueSeraSera, WhateverWillBeWillBe: Boolean = True; . . . 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 convirtiéramos en constantes con tipo. Cannot initialize thread local variables Posible causa de error Puede estar intentando asignar un valor inicial a una variable local de hilo (declarada mediante la palabra reservada Threadvar). Por ejemplo, lo siguiente generará este mensaje de error: threadvar Threadbare: Byte = 7; 98 Los Tomos de Delphi: Delphi sin problemas 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 objetos TThread pueden hacer referencia a ellas como si hubiesen sido declaradas localmente. Alternativamente, puede declarar un campo o un par campo/propiedad 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; Cannot Load IDAPI Service Library Posible causa de error 1. Si está utilizando el controlador del BDE para MS Access, y Access 95 o Microsoft Office 95 no fueron utilizados para instalar el motor DAO, es posible que falte una entrada necesaria en el Registro. 2. Puede que IDPROV32.DLL no esté situado en la localización esperada. 3. Si obtiene este mensaje de error en una aplicación de múltiples capas, es posible que STDVCL[32,40].DLL y/o DBCLIENT.DLL no estén registradas en el servidor. 4. El Registro del sistema puede estar configurado como de sólo lectura. 5. Puede estar intentando acceder a tablas de Access, pero el motor DAO de Microsoft no está instalado en el sistema (o está instalada una versión antigua de él). 6. Una DLL requerida por el BDE puede estar ausente o dañada. 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 2. 3. 4. 5. 6. 99 b. Introduzca regedit en el cuadro de combinación Abrir y pulse el botón Aceptar. c. Navegue hasta HKEY_LOCAL_MACHINE\Software\Microsoft\Shared Tools\DAO. d. Pulse con el botón derecho sobre la entrada Path, seleccione Modificar en el menú de contexto, y luego asigne en el cuadro de edición que aparece la localización de DAO3032.DLL. Localice el archivo IDPROV32.DLL, y muévalo al directorio del BDE en el servidor. La localización por defecto es: C:\Archivos de programa\Borland\Common files\BDE. Verifique que IDPROV32.DLL está situada en el directorio de DLLs del BDE (como está especificado en WIN.INI o el Registro del sistema, según el sistema operativo de que se trate). Adicionalmente, DBCLIENT.DLL y STDVCL[32,40].DLL deben estar instalados en el directorio de sistema de Windows y registrados. Modifique el estado general del Registro del sistema a lectura/escritura, o al menos la entrada correspondiente para la .DLL en cuestión. Instale el motor DAO, y luego añada la entrada para el controlador de Access incluido en su versión de DAO, utilizando la utilidad de Configuración del BDE (Configuration | Drivers | Native | MSAccess | DLL32), por ejemplo, IDDA3532.DLL. Si no está utilizando la última versión del BDE, descárguela del sitio www.borland.com. Ejecute la utilidad de Configuración del BDE y modifique la entrada correspondiente al controlador de Access de IDDAO32.DLL a IDDA3532.DLL (o cualquiera que sea la versión más reciente del controlador de Access). Verifique que ha realizado una instalación completa del BDE y de todo el software cliente que sea necesario para conectarse a la base de datos que esté utilizando. 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 Cannot load IDAPI[32].DLL Posible causa de error 1. Pueden faltar uno o más archivos del BDE. O puede que el BDE no haya sido instalado en absoluto. 2. El BDE puede no estar correctamente configurado. Uno de los posibles problemas es que haya una entrada incorrecta en WIN.INI (Delphi 1) o en el Registro del sistema (Delphi de 32 bits) para la clave CONFIGFILE01. 3. Puede haber realizado sólo una instalación parcial del BDE. 4. Puede haber utilizado InstallShield Express para instalar una aplicación que utiliza el BDE, y no haber añadido la entrada correspondiente al camino de las .DLLs del BDE en el Registro del sistema. 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 distribuir 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 Si el camino de la DLL en WIN.INI corresponde al valor C:\IDAPI, pero IDAPI.DLL está situada en otro sitio, mueva IDAPI.DLL al lugar asignado en WIN.INI, o modifique la configuración en WIN.INI para que apunte al camino donde reside IDAPI.DLL. 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 IDAPI32.DLL está en otro sitio, mueva IDAPI32.DLL al lugar configurado en el Registro o cambie la configuración del Registro para que indique el camino donde reside IDAPI32.DLL. 3. Reinstale el BDE, seleccionando Full install. 4. Edite el Registro del sistema, como se indica en Información adicional. Introduzca el camino de acceso a IDAPI32.DLL en el parámetro DLLPATH (por defecto C:\Archivos de programa\Borland\Common files\BDE). 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 directorio del programa que utiliza el BDE. Cannot load language driver Posible causa de error Su controlador de lenguaje podría estar ausente, o la entrada del Registro podría ser incorrecta. 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 configurada 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 Si el controlador de lenguaje apropiado (.BLL) está ausente, cópielo desde el CD-ROM de Delphi al lugar indicado arriba. Información adicional Nota: Este es el error de inicialización del BDE $3E06. Cannot load package <>. It contains unit <> which is also contained in package <> Posible causa de error 1. Puede estar intentando cargar un paquete que contiene una unidad que ya está presente en su biblioteca. 2. Puede estar intentando recompilar un paquete existente después de instalar en él un componente que ya está contenido en la VCL. Solución rápida 1. Si el paquete no contiene unidades adicionales que usted necesite, simplemente 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. Cannot locate IDAPI[01,32].DLL Posible causa de error Puede haber optado por una instalación parcial cuando instaló Delphi. 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 relacionada 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. Busque 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 parecerse un poco a esto: [IDAPI] DLLPATH=C:\IDAPI CONFIGFILE01=C:\IDAPI\IDAPI.CFG Si no hay una entrada [IDAPI], o están ausentes los valores de configuración para DLLPATH y/o CONFIGFILE01, añádalos para que apunten a las ubicaciones de las DLLs de IDAPI (IDAPI01.DLL, etc.) y al archivo IDAPI.CFG, respectivamente. 104 Los Tomos de Delphi: Delphi sin problemas 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 ubicació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. Como crear un Alias utilizando la herramienta de configuración de BDE En Delphi 1, la herramienta de configuración del BDE es BDECFG.EXE. En Delphi 2, es BDECFG32.EXE. A partir de Delphi 3 es BDEADMIN.EXE. En cualquier versión, debe estar disponible seleccionando Inicio | Programas | Borland Delphi X | BDE [Configuration, Administrator]. Alternativamente, usted puede añadirlo al menú Tools de Delphi para acceder rápidamente a él mientras trabaja en Delphi (Tools | Configure Tools | Add). Para crear un alias con la herramienta de Configuración del BDE, siga estos pasos: 1. Seleccione Inicio | Programas | Borland Delphi X | BDE [Configuration, Administrator]. 2. Teniendo activa la etiqueta Databases y el elemento Databases seleccionado en la vista jerárquica, seleccione Object | New. . . . 3. Compruebe que el parámetro Type corresponda al tipo de la base de datos que haya creado o creará (’Standard’ para Paradox, dBASE, y ASCII; ‘Access’ para MS Access, etc.). 4. Si seleccionó el controlador Standard (para crear una base de datos Paradox, por ejemplo), asigne la ubicación de la base de datos al parámetro Path (ServerName para InterBase y Oracle; Database Name para MS SQL Server, MS Access, Sybase, e Informix; DB2 DS2 para DB2). Si utiliza Path, puede introducir un camino DOS, como: K:\HallOfFame\Baseball o, en Delphi de 32 bits, puede utilizar el formato UNC (Convenio Universal de Nombres), con el formato: \\ServerName\ShareName\ShareDir Mensajes de error 105 Cannot make a visible window modal Posible causa de error Puede haber llamado al método ShowModal de un formulario que ya estaba desplegado. 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 abiertos 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 formulario 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 Cannot modify a read-only dataset Posible causa de error Puede estar intentando editar un componente TTable cuya propiedad ReadOnly tiene el valor True. 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á primero 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; Cannot modify SessionName while AutoSessionName is enabled Posible causa de error Puede estar intentando asignar un nuevo valor a la propiedad SessionName de un componente TSession cuando su propiedad AutoSessionName tiene el valor True. Solución rápida Absténgase de editar el nombre generado automáticamente para un componente 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. Cannot open component library <Path>\Complib.dcl Posible causa de error Puede haber instalado un componente que se enlaza estáticamente a una .DLL que no puede ser encontrada. 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 funciones 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. Cannot open file <> Posible causa de error 1. Puede estar intentando abrir un archivo cuyo contenido no está en el formato adecuado. Por ejemplo, si intenta cargar un archivo que se espera que contenga un gráfico, y en realidad es un archivo de texto, obtendrá este mensaje de error. 2. Puede estar intentando abrir un archivo que no existe, utilizando el método LoadFromFile (o al menos, el fichero no existe en la ubicación que ha especificado). 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 componente 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. Cannot open module because it is a dependent of <>, which is open as text Posible causa de error Mientras está intentando compilar un proyecto, puede tener un archivo de formulario abierto (.DFM) como texto. 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. Cannot optimize. Not an .exe Posible causa de error Puede estar escaso de espacio de disco o memoria RAM. Mensajes de error 109 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. Desmarque 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. Cannot override a static method Posible causa de error Puede haber añadido la directiva Override a un método que no ha sido declarado como Virtual en la clase ancestro. 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 procedure procedure procedure procedure WorkHard; virtual; PlayHard; dynamic; StudyHard; virtual; abstract; RunHard; dynamic; abstract; Leotard; 110 Los Tomos de Delphi: Delphi sin problemas end; Se puede redefinir los métodos WorkHard, PlayHard, StudyHard y RunHard, pero no el método Leotard, ya que es un método estático (por defecto). Podrá crear un método con ese mismo nombre en la clase descendiente, pero tendrá que abstenerse de asociarle la directiva Override, y el nuevo método no heredará la funcionalidad del método de igual nombre en la clase ancestro. De esta manera, lo siguiente es permitido en la clase descendiente: type AA = class(A) procedure WorkHard; override; procedure PlayHard; override; procedure StudyHard; override; procedure RunHard; override; procedure Leotard; {Sin ninguna relación con el método de la clase A} end; Cannot perform operation - DB is not open Posible causa de error Puede haber intentado asignar True a la propiedad Active de un componente TIBTransaction (o haber llamado a su método StartTransaction) mientras el componente TIBDatabase al cual está conectada la transacción no está activo. 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. Cannot perform this operation on a closed connection Posible causa de error Puede haber intentado activar un conjunto de datos de DBExpress antes de que su objeto TSQLConnection asociado esté abierto. Mensajes de error 111 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 formulario 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. Cannot perform this operation on a closed database Posible causa de error Puede haber intentado llamar al método StartTransaction de un componente TDataBase sin primero asignar True a la propiedad Connected o llamar a su método Open. Por ejemplo, puede haber hecho algo así: with Database1 do begin StartTransaction; Table1.FieldByName('Mister').Value := 'Magoo'; 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 StartTransaction. 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 with Database1 do begin Open; StartTransaction; try try Table1.FieldByName('Mister').Value := 'Coffee(Joe DiMaggio)'; . . . finally Commit; end; except Rollback end; 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. Cannot perform this operation on a closed dataset Posible causa de error 1. Puede haber intentado refrescar, editar, vaciar, borrar o buscar en un componente TDataSet que no estaba abierto o activo. Por ejemplo, se producirá este mensaje de error si trata de hacer lo siguiente: Table1.Close; Table1.Refresh; -OTable1.Active := False; Table1.Edit; 2. Un conjunto de datos auxiliar que es requerido por otro conjunto de datos puede estar inactivo o cerrado. Por ejemplo, puede haber una tabla de búsqueda que deberá estar abierta para que sus valores puedan ser accedidos. 3. Puede haber llamado a Open o asignado True a la propiedad Active de un TClientDataSet que es utilizado en una aplicación multi-capa, y no ha asignado un componente TDataSetProvider válido a la propiedad Provider del TClientDataSet. 4. Puede haber llamado a Open o asignado True a la propiedad Active de un TClientDataSet que es utilizado en una aplicación de una sola capa, y no ha abierto todavía el archivo que contiene los datos. Mensajes de error 113 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 superiores, 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; with dm.cdsStudents do begin if FileExists('Students.cds') then LoadFromFile('Students.cds') else LoadFromFile('Students.xml'); (donde dm es un módulo de datos, y cdsStudents es un componente TClientDataSet). 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 componentes 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 referencia 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 permite 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. Cannot perform this operation on an active session Posible causa de error Puede estar intentando asignar True a la propiedad AutoSessionName de un componente TSession, o modificando su propiedad SessionName mientras su propiedad Active tiene el valor True. Solución rápida Asigne primero False a la propiedad Active antes de intentar cambiar la propiedad 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 database sessions”, “managing multiple sessions”, “naming a session”, “working with a session component”, “using the default session” y “using a session component in data modules” en la ayuda de Delphi. Cannot perform this operation on an empty dataset Posible causa de error Puede haber intentado llamar al método Delete de un objeto TTable cuando la tabla no contenía registros. 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; -Oif 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} Cannot perform this operation on an open database Posible causa de error 1. Puede haber intentado asignar el valor True a la propiedad Exclusive de un objeto TTable mientras su propiedad Active tenía el valor True. 2. Puede haber intentado asignar un valor a la propiedad TableName de un TTable mientras su propiedad Active tenía el valor True. 3. Puede haber intentado asignar un valor a una de las propiedades Alias o DatabaseName de un TDatabase mientras su propiedad Connected tenía el valor True. 4. Puede haber intentado asignar un valor a una de las propiedades Active o AutoSessionName de un componente TSession mientras la propiedad Connected de un componente TDatabase asociado tenía el valor True. 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”. Cannot perform this operation on an open dataset Posible causa de error 1. Puede haber intentado modificar una de las propiedades Exclusive, ReadOnly, DatabaseName, TableName, TableType o SessionName de un objeto TTable mientras la tabla estaba abierta. 2. Puede haber llamado al método Unprepare para un objeto TQuery mientras la consulta estaba activa. 3. Puede haber modificado la propiedad SQL de un objeto TQuery mientras la consulta estaba activa. Solución rápida 1. Cierre el TTable antes de modificar cualquiera de las propiedades mencionadas 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; -OQuery1.Active := False; o llamando a su método Close: Table1.Close; -OQuery1.Close; Es necesario asignar True a la propiedad Exclusive de un objeto TTable antes de ejecutar ciertas tareas, tales como añadir índices con el método AddIndex. Por lo tanto, debe primero cerrar el TTable, añadir los índices, y luego abrir la tabla de nuevo. Mensajes de error 117 Cannot perform this operation with table open Posible causa de error Puede haber intentado borrar una tabla en el Database Desktop mientras la tabla estaba abierta. 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. Cannot perform utility while table is in use Posible causa de error Puede estar intentando ejecutar cierta acción, como por ejemplo editar o modificar la estructura de una tabla en el Database Desktop, mientras la tabla está abierta. Solución rápida Cierre la tabla, asignando False a la propiedad Active del TTable y a la propiedad 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. Cannot read a write-only property Posible causa de error Puede estar intentando acceder al valor de una propiedad que es de sólo escritura. 118 Los Tomos de Delphi: Delphi sin problemas 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} Pero no puede asignarle un valor, porque es de sólo lectura. Información adicional Si una propiedad es de sólo lectura, es declarada así: property Required: Boolean read FRequired; y es declarada normalmente en la sección Public o Published de una clase. Si una propiedad es tanto de lectura como escritura, se declara así: property NetFileDir: string read GetNetFileDir write SetNetFileDir; 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; Esta es la definición del método SetDatabaseName: procedure TDatabase.SetDatabaseName(const Value: string); begin if csReading in ComponentState then FDatabaseName := Value else if FDatabaseName <> Value then Mensajes de error 119 begin CheckInactive; ValidateName(Value); FDatabaseName := Value; end; end; Como puede verse, cuando un usuario accede a la propiedad DatabaseName, el valor es leído del campo privado interno FDatabaseName. Cuando un usuario asigna un valor a la propiedad DatabaseName, al método SetDatabaseName se le pasa el valor que el usuario está intentando asignar a DatabaseName. Cannot Run a Unit or DLL Posible causa de error 1. Puede estar intentando ejecutar una aplicación desde el entorno integrado de Delphi sin tener el proyecto (.DPR) abierto. Por ejemplo, puede haber abierto una o más unidades que son parte de un proyecto, pero no abrió el proyecto en sí. 2. Puede haber intentado ejecutar una .DLL. Solución rápida 1. Abra el archivo fuente del proyecto (archivo .DPR) del cual es parte la unidad 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 proyecto 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 proyectos, 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 Cannot update, <> is not owned by <> Posible causa de error Puede haber llamado a ApplyUpdates y haber suministrado el nombre de un componente TDataSet que no hace referencia al componente TDatabase cuyo método ApplyUpdates usted ha llamado. Por ejemplo, si llamó a ApplyUpdates así: Database1.ApplyUpdates([Backgammon, Pool]); y Pool hacía referencia a Database2 en lugar de Database1 en su propiedad DatabaseName, obtendrá este mensaje de error. Solución rápida Verifique que todos los objetos TDataSet pasados a ApplyUpdates hagan referencia al mismo componente TDatabase. Información adicional Los descendientes de TDataSet incluyen a TTable, TQuery, TStoredProc y TClientDataSet. Cannot use array of Field values with Expression Indices Posible causa de error Puede haber intentado añadir un índice a una tabla dBASE utilizando corchetes en lugar de paréntesis, así: Table1.AddIndex([<NombreIndice>],[<NombreCampo>],[ixExpression]); 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 Cannot use reserved unit name <> Posible causa de error Puede haber utilizado un nombre de unidad que el compilador de Delphi tiene reservado. Por ejemplo, puede haber nombrado una unidad como System o SysInit. 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. Cannot write EXE or DLL to disk Posible causa de error Puede haber ejecutado el módulo (.EXE o .DLL) y luego intentó compilar el proyecto mientras el módulo estaba todavía residente en memoria. Solución rápida Cierre la instancia del programa antes de intentar recompilarlo. Si es necesario, 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 ejecutado desde el entorno integrado. Cierre Delphi y reinícielo, y luego intente compilar el proyecto/programa de nuevo. Cannot Write to Engine Configuration File Posible causa de error IDAPI.CFG (Windows 3.x) o IDAPI32.CFG (Windows/Delphi de 32 bits) puede no estar situado donde debería. 122 Los Tomos de Delphi: Delphi sin problemas 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. Delphi de 32 bits /Windows 95 Asegúrese de que la localización real de IDAPI32.CFG (C:\Archivos de programa\Borland\Common files\BDE por defecto) coincide con el valor indicado en el Registro del sistema. Si es necesario, mueva el archivo al lugar indicado por el Registro, o modifique la entrada del Registro para que refleje la localización real del archivo. Información adicional Este es el error $8453 del BDE. Capability Not Supported Posible causa de error 1. Puede tener un error de sintaxis en una sentencia SQL. Puede estar intentando realizar sobre una base de datos local o de escritorio una acción que sólo puede llevarse a cabo sobre una base de datos cliente/servidor. Por ejemplo, puede estar intentando utilizar una sentencia SELECT anidada sobre tablas Paradox. 2. Puede estar utilizando una sintaxis SELECT de SQL que no permite producir un conjunto de resultados actualizable (”vivo”) mientras la propiedad RequestLive del componente TQuery tiene asignado el valor True. 3. Puede haber intentado modificar la propiedad StoredProcName de un componente TStoredProc mientras la propiedad DatabaseName hacía referencia a una base de datos local o de escritorio. 4. Puede haber omitido el nombre de la tabla en una sentencia SELECT (proporcionando solamente el nombre de la columna). Por ejemplo, puede tener una sentencia SELECT similar a: SELECT Candy FROM Sees WHERE Chocolate = ‘DarkRaspberry’ 5. Puede haber intentando utilizar las actualizaciones en caché sobre una tabla que contiene campos BLOb. Mensajes de error 123 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 documentació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 nombres 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/servidor 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 servidores 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áusula 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 5. Si está utilizando la versión Cliente/Servidor (Enterprise) de Delphi 3 ó superior, consulte en la ayuda de Delphi “TClientDataSet” para una alternativa a las actualizaciones en caché. Case label outside of range of case expression Posible causa de error Puede estar intentando evaluar en una sentencia Case una etiqueta que no está en el rango de la variable de control de la sentencia Case. Por ejemplo, lo siguiente generará este mensaje de error, debido a que DallasCowboys no es parte de NFCCentralDivision: type SomeFootballTeams = (GreenBayPackers, MinnesotaVikings, ChicagoBears, DetroitLions, TampaBayBuccaneers, TennesseeTitans, StLouisRams, DallasCowboys); NFCCentralDivision = GreenBayPackers..TampaBayBuccaneers; 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; También es una optimización evaluar las etiquetas en orden ascendente. Por ejemplo, dadas estas declaraciones: const Favre = 1; Culpepper = 2; Batch = 3; King = 4; McNown = 5; var QBRating: Integer; este código: case QBRating of Favre: s := Culpepper: s := Batch: s := King: s := McNown: s := end; ‘Lock him ‘Give him ‘Bake him ‘Give him ‘He might up (to a long-term contract)’; a raise’; some cookies’; a crown’; get better’; es preferible a este código: case QBRating of Favre: s := Culpepper: s := King: s := McNown: s := Batch: s := end; ‘Lock him ‘Give him ‘Give him ‘He might ‘Bake him up (to a long-term contract)’; a raise’; a crown’; get better’; some cookies’; 126 Los Tomos de Delphi: Delphi sin problemas Circular datalinks are not allowed Posible causa de error Puede estar intentando utilizar un componente TTable como su propia tabla de búsqueda, configurando la propiedad MasterSource del componente TTable para que apunte a un componente TDataSource que hace referencia al propio componente TTable. Solución rápida Asigne a la propiedad MasterSource una fuente de datos (de la lista desplegable que aparece en la propiedad MasterSource) que esté asociada a otro componente 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 propio 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. Circular Unit Reference [to <>] Posible causa de error Puede haber colocado referencias mutuas en las cláusulas Uses de la sección Interface de dos unidades. 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 secciones 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 Modifíquela de forma que quede así: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; {eliminada Unit2} type TForm1 = class(TForm) private { Private declarations } public { Public declarations } end; var Form1: TForm1; 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 unidades (debe mover al menos una; o puede mover ambas). Las únicas unidades que necesitan ser incluidas en la cláusula Uses de la secció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 Delphi. Tendrá que añadir manualmente la cláusula Uses de la parte Implementation. 128 Los Tomos de Delphi: Delphi sin problemas Class <> not found. [Ignore the error and continue?] Posible causa de error 1. Puede haber modificado el archivo .DFM de un formulario y cambiado el tipo de un objeto por otro (por ejemplo, un TButton a TBitBtn), y Delphi no puede reconciliar las diferencias. 2. Puede haber utilizado en el proyecto una unidad o componente que posteriormente ha sacado del camino de búsqueda de Delphi, desinstalado o borrado. 3. Puede estar cargando un proyecto en una versión de Delphi anterior a la versión utilizada la última vez que lo compiló. 4. Puede haber modificado directamente la declaración de un campo de un componente en un archivo .PAS (es decir, no a través del Inspector de Objetos, cambiando el valor de la propiedad Name del componente), y luego haber respondido Yes al mensaje “Field <> does not have a corresponding component. Remove the declaration?” 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 dependencia 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 Delphi. Si este es el caso, cargue el proyecto en la versión más nueva para mantener el uso de la clase a la que se refiere el mensaje de error. 4. Pulse el botón OK. En modo de diseño, elimine el componente que no fue encontrado, y luego añádalo de nuevo. 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á eliminada 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 declaration?”. 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 utilice 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?”. Class already has a default property Posible causa de error Puede haber intentado asignar una propiedad por defecto a una clase que ya tiene una propiedad por defecto definida. 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 valores 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 asignar un valor así: Circus[i] := Bozo; En otras palabras, ya que es la propiedad por defecto, no es necesario escribir el nombre de la propiedad cuando se le asigna algo, así: Circus.Clowns[i] := Bozo; Sin embargo, si trata de hacer lo siguiente, obtendría este mensaje de error: type TCircus = class . . . property Clowns[Index: integer]: String read Fbozo write SetBozo; default; property Animals[Index: integer]: String read FAnimals write SetAnimals; default; {No se puede añadir una segunda propiedad por defecto} . . . end; Class does not have a default property Posible causa de error Puede haber intentado asignar un valor a una variable de clase utilizando una expresión de array, cuando el tipo de la clase no tiene una propiedad por defecto. Por ejemplo, puede haber escrito algo como esto: TCollection[i] := BostonHarbor; -OBeatlesParaphernalia := 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”. Class, interface and object types only allowed in type section Posible causa de error Puede haber intentado declarar una variable de un tipo de clase fuera de la sección Type. Por ejemplo, puede haber intentado algo así: var ts: class(TFont); 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) Obtendrá el mensaje de error “, or : expected but = found”. Si intentar declarar un tipo de clase en una sección Const, así: const TForm1 = class(TForm) Obtendrá el mensaje de error “Expression expected but CLASS found”. Si intenta declarar un tipo de clase en un procedimiento o método local, así: procedure TryToDeclareALocalFormClass; type TForm1 = class(TForm) 132 Los Tomos de Delphi: Delphi sin problemas Obtendrá el mensaje de error “Local class, interface, or object types not allowed”. Class methods not allowed as property getters and setters Posible causa de error Puede haber especificado un método de clase como “getter” (método de acceso de lectura) o “setter” (método de acceso de escritura o transformación). Por ejemplo, lo siguiente generará este mensaje de error: Type No = class private Ffffft: String; class procedure AskTheCat(AResponse: String); public property fffft :String read Ffffft write AskTheCat; end; 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 “constructores” 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; //Observe que no hay variables de formulario como: //var // frmTMSExpressMaterial: TfrmTMSExpressMaterial; implementation {$R *.DFM} class procedure TfrmTMSExpressMaterial.Cre8Thyself; begin Mensajes de error 133 with Self.Create(nil) do try ShowModal; finally Free; end; end; Class not registered Posible causa de error 1. Puede que esté intentando ejecutar una aplicación que contiene un control ActiveX (.OCX) que no ha sido instalado o registrado en el sistema. 2. Puede haber intentado asignar el valor True a la propiedad Connected de un componente TOLEEnterpriseConnection, TRemoteServerConnection o TDCOMConnection cuyo servidor (que se indica mediante la propiedad ServerName o ServerGUID) no ha sido registrado en el sistema. 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 (identificador 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 (En Delphi 4, el archivo correspondiente es STDVCL40.DLL, y por ello el comando necesario sería Regsvr32 STDVCL40.) En Delphi 3-6 es posible registrar y borrar del Registro controles ActiveX a través de elementos del menú, específicamente Run | Register ActiveX Server y Run | Unregister ActiveX Server. Estos ítems están disponibles cuando un proyecto de control de ActiveX o Biblioteca ActiveX está abierto en el entorno integrado. Consulte “DAX Error: Class not registered”. Class or object types only allowed in type section Posible causa de error Puede haber intentado declarar un tipo de clase en una sección Var, así: var TStudentCommand = (scAdd, scEdit, scActivate, scInactivate, scRemove); TMaterialCommand = (mcAdd, mcEdit, mcDelete, mcImport); TScheduleCommand = (scSchedule, scPrint); 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ísticas 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; Class type required Posible causa de error 1. Puede haber hecho una referencia a un tipo que no es una clase como el argumento de una sentencia Raise de un bloque de excepción. Por ejemplo, puede haber hecho algo así: var b : Byte; aRuckus: String; begin try b := StrToInt(Edit1.Text); except on Cain do raise aRuckus('¡Vaca sagrada!'); end; end; 2. Puede haber utilizado dos tipos de interfaces en la declaración de un tipo de clase ActiveForm, así: type TActiveFormX = class(IActiveFormX, IActiveFormX) 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 Result := Pieces div Recipients; except on EDivByZero do Result := 0; end; end; Este es un ejemplo de declaración y utilización de un objeto de excepción definido por el usuario (ESoMuchTrouble): type ESoMuchTrouble = class(Exception); . . . if Problems > BreakingPoint then raise ESoMuchTrouble.Create('La gota que colmó el vaso'); Para más informacion sobre las excepciones, consulte “exception declarations”, “predefined exceptions” y “exception” en la ayuda de Delphi. 2. Consulte “Interface type required”. Clipboard does not support Icons Posible causa de error Puede haber intentado colocar un icono en el portapapeles. Por ejemplo, puede haber tratado de hacerlo cuando un control de imagen se refería a un archivo .ICO: Clipboard.Assign(Image1.Picture); 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). Close error on <Filename> Posible causa de error Puede tener el disco lleno o dañado. Mensajes de error 137 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 utilizar la herramienta de defragmentación provista con Windows para verificar los errores del disco duro. Para localizarla, vaya a Inicio | Programas | Accesorios | 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). Code Insight features are disabled while debugging Posible causa de error Está intentando utilizar características de Code Insight mientras el programa está ejecutándose dentro del entorno integrado de Delphi. Por ejemplo, puede haber intentado hacer uso de las características de completamiento de código, pulsando Ctrl+espacio mientras depura el código línea a línea. 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, consulte “Code Insight” en la ayuda de Delphi. Code Segment Too Large Posible causa de error Puede haber colocado demasiado código en una misma unidad del proyecto. Solución rápida Mueva algo de código a otra unidad, y añada directamente después de la palabra reservada Implementation una sección Uses que haga referencia a la 138 Los Tomos de Delphi: Delphi sin problemas segunda unidad. Por ejemplo, si el nombre de la segunda unidad es SecondCU, deberá hacer referencia a ella desde la unidad original así: implementation uses SecondCU; {$R *.DFM} 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. COINITIALIZE has not been called Posible causa de error Puede estar utilizando múltiples hilos en una aplicación COM, pero no ha llamado a CoInitialize para cada hilo. 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. Column not a BLOb Consulte “Unknown SQL Error”. 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 procedimiento o función propio), revise su declaración para determinar esa información. Información adicional En realidad, Delphi probablemente no sólo está esperando una coma, sino también como mínimo el parámetro que sigue a la coma. Como la coma es lo primero que no aparece, se indica como el problema. Compilation terminated; too many errors Posible causa de error Hay muchos errores en el proyecto actual. 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ódicamente 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. Component already installed Posible causa de error El componente que está intentando instalar ya es parte de su VCL. 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 biblioteca 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 \Windows\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 programa\Borland\Delphi [5,6]\Lib. Connection error—no server available Posible causa de error Puede estar intentando utilizar Delphi Connection de ReportSmith sin proporcionar un componente TReport y un componente TTable o TQuery (con el valor True asignado a su propiedad Active). 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 3. Desplácese a la parte inferior y localice el componente TReport. 4. Seleccione el componente TReport. 5. Pulse el botón Add. El componente TReport será añadido a la página Data Access de la Paleta de Componentes. Connection in use by another statement Posible causa de error 1. Puede estar intentando abrir o ejecutar una consulta mientras el conjunto resultado de una consulta anterior está todavía pendiente. En otras palabras, todo el conjunto resultado no ha sido devuelto todavía. 2. Puede estar intentando ejecutar un procedimiento almacenado después de que anteriormente haya fallado otro procedimiento almacenado. 3. Puede haber llamado al método Unprepare de un objeto TQuery antes de que todo el conjunto resultado haya sido devuelto. 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; with StoredProc1 do begin StoredProcName := 'SafewayMosaic'; Prepare; try ExecProc; finally Close; Unprepare; end; end; 3. Añada una llamada a Last antes de llamar a Unprepare: with Query1 do begin Last; Close; Unprepare; 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. Connection name missing Posible causa de error Puede haber tratado de asignar valor a una de las propiedades CommandText o SortFieldNames de un componente SQLDataSet (DBExpress) sin especificar primero el correspondiente componente TConnection. 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 asigná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 basadas en el BDE, TIBDatabase en las aplicaciones InterBase Express, y ADOConnection en las aplicaciones ADO Express. DBExpress apareció con Delphi 6. Constant expression expected Posible causa de error Puede haber intentado asignar la dirección de una variable local (de pila) o dinámica (en el heap) a una constante de tipo puntero. Por ejemplo, lo siguiente generará este mensaje de error: procedure TForm1.Button1Click(Sender: TObject); var i: integer; const ptr: Pointer = @i; 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. Constant expression violates subrange bounds Posible causa de error 1. Puede estar intentando hacer una asignación a un elemento de un array que no existe. Por ejemplo, lo siguiente producirá este mensaje de error, ya que se está intentando acceder a un elemento que está fuera de los límites declarados para el array: 144 Los Tomos de Delphi: Delphi sin problemas type Rays = array[0..6] of end; ... procedure Radiation; var FamousRays: Rays; begin FamousRays[0] := 'Ray FamousRays[1] := 'Ray FamousRays[2] := 'Ray FamousRays[3] := 'Ray FamousRays[4] := 'Ray FamousRays[5] := 'Ray FamousRays[6] := 'Ray FamousRays[7] := 'Ray {Esta línea provoca end; string; Bolger'; Deaton'; Konopka'; Krok'; Lischner'; Pierce'; Rogers'; [O-Hope, O-Light, O-Vac] West'; el error, pues no hay elemento 7} 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 negativo 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. Constant object cannot be passed as var parameter Posible causa de error 1. Puede haber intentado pasar un parámetro constante a un procedimiento o función que espera un parámetro variable. Por ejemplo, lo siguiente generará este mensaje de error: procedure GiveMeAPointer(var malleable: string); var owwhoooWerewolvesOfLondon: Integer; begin owwhoooWerewolvesOfLondon := Form1.InstanceSize; malleable := malleable + ' ' + IntToStr(owwhoooWerewolvesOfLondon); end; Mensajes de error 145 procedure BigShovel(const Immutable: string); begin GiveMeAPointer(Immutable); end; procedure RoyalMountainKingMineOrangeMonster; begin BigShovel('Hitachi'); end; debido a que el parámetro Immutable es un parámetro constante, pero el parámetro Malleable es un parámetro variable. 2. Puede haber intentado pasar una propiedad de una clase a un procedimiento o función que espera una variable. Por ejemplo, puede haber intentado hacer algo como lo siguiente: type TTime = class private FWound: string; public . . . published property Wound: string read FWound write SetWound; end; . . . procedure TForm1.HealAll(Sender: TObject); var Sage: TTime; begin Sage := TTime.Create; Wound := 'Bury My Heart at Wounded Knee'; Delete(Sage.Wound, 1, Length(Sage.Wound)); 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 procedimiento 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 procedimiento o función. Constant or type identifier expected Posible causa de error Puede haber declarado una variable local de un tipo desconocido para el compilador. En otras palabras, el compilador conoce el símbolo que se ha utilizado como tipo, pero no es aplicable en este contexto (no es un tipo válido). Por ejemplo, lo siguiente generará este mensaje de error: var f: Text; Solución rápida Asegúrese de que los tipos que utilice para las variables sean tipos predefinidos 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; Como se ha indicado arriba, lo siguiente producirá el mensaje de error “Constant or Type Identifier Expected”: f: Text; Puede también utilizar el tipo Text anteponiéndole System así: f: System.Text; Mensajes de error 147 Por último, también puede utilizar: f: Textfile; Constant out of range Posible causa de error 1. Puede haber asignado a una variable de un tipo subrango un valor más grande o más pequeño que sus límites. Para ser más específico, puede haber declarado una variable de tipo subrango y luego haber intentado una asignación, así: var OctoberRoster: 1..25; begin OctoberRoster := 0; 2. Puede haber asignado a un tipo de Object Pascal un valor más grande o más pequeño de lo que puede almacenar. Por ejemplo, el tipo de datos Byte puede almacenar valores entre 0 y 255. Obtendrá este mensaje de error si trata de almacenar algo menor que 0 o mayor que 255 en una variable Byte, así: const Under, Over: Byte; begin Under: -1; Over := 256; 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 evitar 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); Alternativamente, en lugar de verificar explícitamente el problema, puede codificar de manera defensiva y reaccionar (lo contrario de proactivo) manejando el error cuando se produzca, así: 148 Los Tomos de Delphi: Delphi sin problemas const Under, Over: Byte; begin try Under := StrToInt(Edit1.Text); except on Exception do {atrapar y manejar el error}; end; end; Constants cannot be used as open array arguments Posible causa de error Puede tener un error de sintaxis en una llamada a un método, como podría ser el método InsertRecord de TDataSet. Por ejemplo, lo siguiente generará este mensaje de error: Table1.InsertRecord('Jenny Lind', 'Calaveras', 'California', 50, 1200); 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; De nuevo, simplemente añada corchetes a la llamada del procedimiento: Busywork([12,24,36,48]); Mensajes de error 149 Constructing Instance of <> containing abstract methods Posible causa de error 1. Puede estar intentando crear una instancia de una clase que contiene métodos abstractos. Un ejemplo de cuándo podría ocurrir esto es si crea una variable TStrings así: var CoffeeStrings: TStrings; . . . CoffeeStrings := TStrings.Create; 2. Puede estar intentando crear un objeto que hereda uno o más métodos virtuales abstractos que no están redefinidos (override) en las clases descendientes. 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 definició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 funcionalidad 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á sustituyendo 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 unidad, 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). Constructors and Destructors must have register calling convention Posible causa de error Puede haber añadido una palabra reservada de convenio de llamada diferente de Register en la declaración de un constructor o destructor. Por ejemplo, cualquiera de los siguientes ejemplos producirá este mensaje de error: constructor Create(AOwner: TComponent); override; pascal; destructor Destroy; override; stdcall; constructor Create(AOwner: TComponent); override; safecall; destructor Destroy; override; cdecl; 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ícitamente la palabra reservada Register. Para más información sobre este tema, consulte “calling conventions”, “constructors and destructors” y “method calling conventions” en la ayuda de Delphi. Mensajes de error 151 Constructors and Destructors not allowed in OLE automation section Posible causa de error Puede haber declarado un constructor o destructor en la sección Automated de la declaración de una clase. 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 especificadores de visibilidad: Private, Protected, Public, Published y Automated. La sección Automated se conserva en Delphi 3 y superiores para compatibilidad hacia atrás con Delphi 2. Para más información, consulte “automated components” en la ayuda de Delphi. CONTAINS clause is incorrect Posible causa de error La cláusula Contains en el Package Editor puede tener un error de sintaxis. Lo siguiente no es permitido y podría ocasionar este mensaje de error: 1. Añadir unidades inválidas a la cláusula Contains. 2. Incluir extensiones de nombres de archivos (por ejemplo, .PAS) en la cláusula Contains. 3. Omitir el punto y coma detrás del último archivo listado en la cláusula Contains. Solución rápida 1. Asegúrese de que todas las unidades que añada sean válidas. Para ser válidas, deben existir, estar correctamente escritas, y estar en la ruta de búsqueda de Delphi. Para verificar la ruta de búsqueda de Delphi, seleccione 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 unidades 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 Control <> has no parent window Posible causa de error 1. Puede estar intentando mostrar o realizar alguna otra acción sobre un componente que no tiene asignado un padre (parent). Por ejemplo, lo siguiente producirá este mensaje de error, ya que ningún control padre ha sido asignado a la variable TBitBtn: procedure TForm1.OrphanBitBtn(Sender: TObject); var Oliver: TBitBtn; begin Oliver := TBitBtn.Create(Self); Oliver.SetFocus; {No se puede asignar el foco a un control sin padre} end; 2. Puede estar intentando acceder a un control cuya ventana padre no tiene aún asignado un menjador (handle). Por ejemplo, el formulario sobre el que reside el control puede no haber sido creado todavía. 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 formulario) 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 componentes 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 visualmente 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. Controls cannot be added to a data module Posible causa de error Puede estar intentado añadir un componente visual (un control) a un módulo de datos. 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 componentes 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 Corrupt table/index header Posible causa de error 1. Puede estar intentando asignar una valor a la propiedad IndexName o IndexFieldNames de un componente TTable que tiene un índice dañado. 2. Puede estar intentando instanciar los campos de una tabla en tiempo de diseño (utilizando el editor de campos - Fields Editor), pero la tabla tiene un índice dañado. 3. Puede estar intentando asignar True a la propiedad Active de un TTable, pero la tabla tiene un índice dañado. 4. Puede estar intentando abrir en el Database Desktop una tabla que tiene un índice dañado. 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 probablemente 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) contienen información de índices secundarios. <NombreTabla>.Ynn Los archivos con la extensión .Ynn (donde nn es un número hexadecimal) contienen información de índices secundarios. <NombreTabla>.VAL Los archivos con la extensión .VAL contienen información que se ha proporcionado 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). Could not create output file <> Posible causa de error 1. Puede haber especificado un directorio que no existe para almacenar archivos de salida. 2. Puede haber especificado un directorio que está protegido contra escritura para almacenar archivos de salida. 3. Puede estar tratando de ejecutar un archivo que está todavía en ejecución o que ya está ejecutándose en otra instancia de Delphi. 4. Si la extensión del archivo de salida mencionado en el mensaje de error es .OCX, puede estar intentando modificar un ActiveForm que ya está instalado en Delphi. Solución rápida 1. Asegúrese de que existe el directorio en el que el archivo de salida supuestamente 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 directorio, 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 directorio del archivo de proyecto (.DPR). Ejemplos de archivos de salida son los Mensajes de error 157 ejecutables (.EXE), las unidades compiladas (.DCU), y los archivos de mapas de carga (.MAP). Si desea almacenar los archivos de salida en algún lugar distinto del directorio del proyecto para un proyecto en particular, siga estos pasos: 1. Cree, si es necesario, el directorio que almacenará los archivos de salida. 2. Asegúrese de que el directorio no está protegido contra escritura. 3. Seleccione Project | Options. 4. Seleccione la página Directories/Conditionals. 5. Introduzca la ruta completa del directorio en el cuadro de combinación Output Directory, por ejemplo, I:\Separate\Output. 6. Pulse el botón OK para cerrar el cuadro de diálogo Project Options. Could not find IDataBroker in type library Posible causa de error Puede haber borrado un archivo necesario, más concretamente STDVCL[32,40].DLL, que debería estar en el directorio \Windows\System. 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 introducir 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\Borland\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 Para instrucciones específicas sobre cómo utilizar TRegSvr, consulte “Cannot Load IDAPI Service Library”, solución número 3. Could not find interface <> in type library Posible causa de error La biblioteca de tipos a la que se hace referencia por su nombre en este mensaje de error no ha sido registrada. 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 programa\Borland\Delphi X\BIN. STDVCL[32,40].DLL contiene las declaraciones de interfaz para la VCL estándar de Borland. Could not find interface IDataBroker in type library Posible causa de error Puede que la biblioteca de tipos que define IDataBroker no haya sido correctamente registrada durante la instalación de Delphi. 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 Could not find language driver ($220B) Posible causa de error Puede haber seleccionado un controlador de lenguaje utilizando la utilidad BDE Configuration (o editando directamente WIN.INI o el Registro de Windows) cuyo archivo correspondiente está ausente o no está en el lugar esperado, o está ausente la línea que hace referencia a él en WIN.INI. 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. Ejecute 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 componente 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 2. En SQL Explorer/Database Explorer, seleccione Object | New. . . . 3. Seleccione el tipo de controlador adecuado en el cuadro de combinación (seleccione Standard si está trabajando con tablas Paradox o dBASE) y pulse el botón OK. El nuevo alias se mostrará en la página Database del panel izquierdo con el nombre por defecto Standard1. 4. Pulse con el botón derecho sobre el nuevo alias, seleccione Rename del menú de contexto, e introduzca el nombre que quiera darle al alias. 5. En la página Definition del panel derecho, seleccione el controlador apropiado en el cuadro de combinación Default Driver. 6. Introduzca la ruta de la base de datos en el cuadro de edición Path. 7. Seleccione Object | Exit, y luego Yes para grabar los cambios realizados. Could not initialize IDAPI Posible causa de error 1. Las .DLLs del BDE pueden haber sido movidas o borradas. 2. El archivo WIN.INI o el Registro del sistema pueden haber sido modificados. Solución rápida 1,2. Compruebe que las .DLLs del BDE existen y están en la localización especificada 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 sistema, cópielas desde el CD Delphi. Información adicional Cada PC que utilice el BDE necesita las .DLLs del BDE y un archivo de configuració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 En Delphi de 32 bits, la ubicación de las .DLLs y el archivo de configuración es mantenido en el Registro del sistema. La configuración del Registro puede ser encontrada ejecutando Regedit y navegando hasta HKEY_LOCAL_MACHINE\Software\Borland\Database Engine. Mensajes de error 161 Las entradas por defecto son C:\Archivos de programa\Borland\Common files\BDE\IDAPI32.CFG como camino de las DLL, y C:\Archivos de programa\Borland\Common files\BDE\IDAPI32.CFG para CONFIGFILE01 (el archivo de configuración). 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”. Could not load RLINK32.DLL Posible causa de error El archivo RLINK32.DLL puede no estar ubicado en la ruta de búsqueda de Delphi. Solución rápida Localice RLINK32.DLL. Su ubicación por defecto es C:\Archivos de programa\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 sistema, para Delphi, y/o para su propio bienestar. Consulte “Error 0: RLINK32 Error opening file <>.tlb”. Could not load StdOle version 1.0 type library Posible causa de error STDOLE.TLB o STDOLE2.TLB pueden haber sido movidos o borrados. 162 Los Tomos de Delphi: Delphi sin problemas 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. Could not load Type Library Posible causa de error Puede haber borrado un archivo de biblioteca de tipos (Type Library). 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 Reciclaje), 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 actualizaciones 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á directamente 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áticamente 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 “TransIsolation” en la ayuda de Delphi. Data Base Error: Database access resulted in error Posible causa de error Puede haber intentado acceder al constructor de consultas SQL (Query Builder) de Delphi pulsando el botón derecho del ratón sobre un componente TQuery y seleccionando Query Builder. . . del menú de contexto, pero después de proporcionar el nombre del alias no proporcionó una contraseña válida y pulsó el botón OK. 164 Los Tomos de Delphi: Delphi sin problemas Solución rápida Proporcione una contraseña válida en el cuadro de edición Password e inténtelo de nuevo. Información adicional El Query Builder solamente está disponible en la versión Cliente/Servidor (Enterprise) de Delphi. Data Segment Too Large Posible causa de error 1. Puede haber declarado demasiadas variables globales (es decir, variables globales a la unidad). Estas se almacenan en el segmento de datos. 2. Puede estar utilizando estructuras de datos que consumen gran cantidad del espacio en el segmento de datos, por ejemplo, cadenas en Delphi 1 (las cadenas consumen 256 bytes en Delphi 1, a menos que se declaren explícitamente más pequeñas), arrays grandes, o registros que contienen numerosos campos o campos grandes (como cadenas). Por ejemplo, puede estar declarando un registro como: TRecording = record Number: Integer; Hits: Integer; Title: String; Artist: String; end; var Platter, Album, Disc, CD, Music, Tunes, Toons: TRecording; 3. Puede haber declarado demasiadas constantes con tipo. 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 -OPuede 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 asignada 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 cantidad 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 grandes (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 Initialization y un procedimiento de salida. En Delphi de 32 bits, puede utilizar las secciones Initialization y Finalization. A continuación se muestra un ejemplo 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 derreferenciá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 problema 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. Utilice variables locales siempre que sea posible. Si necesita compartir variables globales entre múltiples unidades, utilice una unidad global especí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 inicializada. Sustituya las constantes con tipo por variables inicializadas para compatibilidad con versiones futuras de Delphi. Data Structure Corruption Posible causa de error 1. Puede estar intentando realizar más de 255 cambios en una sola transacción de base de datos. 2. Puede estar utilizando la versión 3.00 o 3.10 del BDE. Mensajes de error 167 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 relacionada con las limitaciones del BDE y dBASE, consulte en la Web de Borland http://www.borland.com. 127 Tablas abiertas por el sistema 254 Tablas abiertas por el sistema (BDE 4.01 y posteriores) 64 Bloqueos de registros en una tabla (16 bits) por sesión 255 Bloqueos de registros en una tabla (32 bits) por sesión 255 Registros en transacción sobre una tabla (32 bits) 512 Archivos físicos abiertos (DB, PX, MB, X??, Y??, VAL, TV) 1024 Archivos físicos abiertos (BDE 4.01 y posteriores) 300 Usuarios en un archivo de red PDOXUSRS.NET 255 Número de campos por tabla 255 Tamaño de los campos de caracteres 2.000 Millones de registros en una tabla 2.000 Millones de bytes en un archivo .DB (tabla) 10.800 Bytes por registro para tablas indizadas 32.750 Bytes por registro para tablas no indizadas 127 Número de índices secundarios por tabla 16 Número de campos en un índice 255 Usuarios concurrentes por tabla 256 Megabytes de datos por campo BLOb 100 Contraseñas por sesión 15 Longitud máxima de contraseña 63 Contraseñas por tabla 159 Campos con chequeos de validación (32 bits) 63 Campos con chequeos de validación (16 bits) 168 Los Tomos de Delphi: Delphi sin problemas Data Type too large: exceeds 2 GB Posible causa de error Puede haber intentado declarar un tipo de datos definido por el usuario que es excesivamente grande. Por ejemplo, la siguiente declaración de tipo produce este mensaje de error: TDeviantVariants = array[0..135000000] of variant; como también lo hace ésta: TSoMuchTrouble = array[0..1333333333] of integer; Solución rápida Debe disminuir el tamaño del tipo. Por ejemplo, lo siguiente compilará: TTexasSizedArray = array[0..100000000] of variant; Como también esto: TAlaskaSizedArray = array[0..200000000] of integer; 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; (Declarar un array con el tamaño combinado de los dos anteriores ocasiona este mensaje de error). Database name missing Posible causa de error Puede haber intentado asignar True a la propiedad Connected de un componente TDatabase sin haber asignado primero un valor a la propiedad DatabaseName. 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 asignadas 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 propiedad KeepConnected del componente TDatabase, evitando muchas inicializaciones de conexión que consumen tiempo durante la ejecución del programa. Un componente TDatabase permite también utilizar procesamiento de transacciones 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; Para más información sobre las transacciones de base de datos, consulte “handling transactions” en la ayuda de Delphi. Database not Assigned Posible causa de error Puede haber ejecutado una sentencia SQL sin asignar una base de datos al componente de consulta. Por ejemplo, lo siguiente generará este mensaje de error: IBQry := TIBQuery.Create(nil); try with IBQry do begin SQL.Add('SELECT COUNT(DelphiConverts) FROM Redmond'); SQL.Add('WHERE Job_Status = FormerMSEmployees'); Open; 170 Los Tomos de Delphi: Delphi sin problemas 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 consulta, 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. Dataset is not a query Posible causa de error Puede haber intentado asignar el valor True a la propiedad Active de un componente TQueryClientDataSet, pero el conjunto de datos al que hace referencia el componente TProvider (indicado mediante la propiedad Provider del objeto TQueryClientDataset) no es un objeto TQuery. Por ejemplo, puede que se trate de un componente TTable o TStoredProc. Solución rápida Proporcione un componente TQuery como valor de la propiedad Dataset del componente TProvider. Información adicional Nota: Los componentes MIDAS solamente son proporcionados con Delphi 3 Cliente/Servidor y versiones posteriores de Delphi. TQueryClientDataSet apareció con Delphi 4 y desapareció en Delphi 5. Mensajes de error 171 Dataset not configured for network access Posible causa de error Puede haber asignado el parámetro NetDir del BDE a una unidad local. 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 directorio 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). Dataset [is] not in edit or insert mode Posible causa de error Puede estar intentando editar un valor en una tabla o intentando insertar un nuevo registro mientras el conjunto de datos está en un modo distinto a dsEdit o dsInsert. Por ejemplo, puede haber intentado hacer algo así: with qryUpdateMaterial do begin SQL.Add('UPDATE Material'); SQL.Add('SET Student = :Student'); SQL.Add('WHERE WeekBegin = :WeekBegin'); SQL.Add('AND TalkIndicator = :TalkIndicator'); if Householder then Params.ParamByName('Student').AsString := Format(‘%s HH: %s',[Existing,AstudentToSchedule]) else Params.ParamByName('Student').AsString := AStudentToSchedule; Params.ParamByName('WeekBegin').AsDateTime := dtpWeekToSchedule.Date; Params.ParamByName('TalkIndicator').AsString := ATalkIndicator; ExecSQL; Post; end; 172 Los Tomos de Delphi: Delphi sin problemas 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; En el ejemplo de arriba, borre la llamada a Post, ya que ExecSQL ya la hace. 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 campos (Fields Editor). De otro modo, necesitará asignar un valor al campo utilizando 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. DAX Error: Class not registered Posible causa de error Puede no tener un archivo necesario, por ejemplo DBCLIENT.DLL, instalado y registrado en la máquina cliente. 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 DAX Error: Name not unique in this context Consulte “Name not unique in this context”. DAX Error: Unexpected failure Posible causa de error El servidor de aplicaciones ha disparado una excepción durante la inicialización. 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 naturaleza específica del problema que está experimentando. DCOM not installed Posible causa de error Puede haber intentado asignar el valor True a la propiedad Connected de un componente TMIDASConnection mientras su propiedad ConnectType estaba asignada a ctDCOM y su propiedad UseBroker era False sin instalar primero DCOM. 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. Debug process is already running Posible causa de error 1. Puede tener una ventana de visualización de variables abierta y estar trazando la ejecución del código más rápidamente de lo que la ventana es capaz de actualizarse. 174 Los Tomos de Delphi: Delphi sin problemas 2. Puede haber intentado compilar o ejecutar dentro del entorno integrado de Delphi sin haber terminado la ejecución de un programa que generó una excepción mediante Run | Program Reset. 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 | Program Reset. Información adicional 2. Al seleccionar Run | Program Reset después de experimentar excepciones, 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. Debug session in progress. Terminate? Posible causa de error Puede haber seleccionado Project | Build All, Project | Compile, o Project | Syntax Check mientras su proyecto estaba en ejecución o suspendido. 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 problemas, cierre todo y reinicie Windows. Mensajes de error 175 Debugger kernel error. Error code: <> Posible causa de error 1. Su programa puede estar intentando cargar una DLL (puede ser una DLL regular o un paquete, que no es más que una DLL específica de Delphi con extensión .DPL) que no puede encontrar. Puede que no exista en el sistema o no esté en el directorio actual de la ruta de búsqueda. 2. Puede ser que un procedimiento o función de una DLL a la que está intentando acceder no esté disponible debido a una mala escritura del nombre. 3. Puede ser que un procedimiento o función de una DLL a la que está intentando acceder no esté disponible debido a la utilización de una signatura incorrecta (un error en la cantidad de parámetros, sus tipos u orden). 4. Puede estar trazando la ejecución del código demasiado rápidamente mientras muchas variables complejas se están monitorizando en la ventana de visualización. 5. Si el código de error es 25, puede haber intentado depurar remotamente en Delphi 4 o superiores y haber especificado un camino remoto o nombre de equipo inválido. 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 Recuerde además que no es posible mezclar y combinar DLLs de 16 bits y de 32 bits. 5. Consulte “remote debugging” en la ayuda de Delphi para detalles específicos. Declaration expected but <> found Posible causa de error 1. Puede haber introducido algo distinto a una declaración de Object Pascal válida en una posición donde el compilador espera encontrar una declaración. Para ser más específicos, puede obtener este mensaje de error si utiliza una palabra reservada de Object Pascal o inicia una declaración con algo distinto a un guión bajo o un caracter alfabético (a..z, A..Z). Los dígitos se permiten después del primer caracter; otros caracteres no son permitidos. Por ejemplo, estas declaraciones no son permitidas: string: string; {palabra reservada de Object Pascal} 1string: string; {empieza con un dígito} +1string: string {el caracter ‘+’ no puede ser utilizado} 2. Puede haber borrado u omitido algo que es necesario. Por ejemplo, borrar la sección Begin … End de una DLL producirá este mensaje de error. 3. Puede haber añadido una sección Finalization a una unidad sin haber proporcionado una sección Initialization. Solución rápida 1. Utilice un nombre válido de Object Pascal para la declaración. Estas declaraciones 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 Initialization. Puede inicializar variables, asignar memoria, etc., en la sección Initialization. La sección Finalization es un buen lugar para liberar memoria y otros recursos. Mensajes de error 177 Declaration of <> differs from declaration in interface <> Posible causa de error Puede haber declarado una clase que implementa una interfaz, y la signatura de uno (o más) de los métodos que está implementando difiere de la signatura de la implementación. Por ejemplo, lo siguiente generará este mensaje de error: type ITomJonesTheSingerNotTheProtagonistOfTheClassicBook = interface procedure RaveUp(var ItsNotUnusual: WideString); end; type TTomJonesImplementor = class(TInterfacedObject, ITomJonesTheSingerNotTheProtagonistOfTheClassicBook) procedure RaveUp(var WhatsNewPussycat: Integer); end; Debido a que las signaturas de los dos métodos RaveUp no concuerdan. 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étodos 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. Declaration of <> differs from previous declaration Posible causa de error 1. Una declaración de un procedimiento o función en la parte Implementation difiere de la declaración anterior. 2. Un método que está intentando redefinir puede tener una signatura diferente (en cuanto a número, tipo u orden de los parámetros) del original. 3. Puede estar intentando redefinir un método virtual, pero está utilizando un convenio de llamada distinto del utilizado por el método redefinido. 178 Los Tomos de Delphi: Delphi sin problemas 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. Declaration of class <> is missing or incorrect Posible causa de error 1. Puede haber modificado o borrado el nombre de la clase (descendiente) de la sección Interface de una unidad. Por ejemplo, modificando una declaración de tipo del formulario de: TForm1 = class(TForm) 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 Objetos (Object Inspector). Información adicional Puede declarar un nuevo tipo sin especificar un ancestro, así: TBill = class Mensajes de error 179 Si lo hace, su ancestro será el ancestro último de todas las clases, TObject. No puede, sin embargo, como se muestra arriba, cambiar implícitamente el ancestro de un formulario de, por ejemplo, TForm a TObject. DEFAULT clause not allowed in OLE automation section Posible causa de error Puede haber utilizado la cláusula Default en una sección Automated de OLE. Solución rápida La cláusula Default no está permitida en las secciones Automated de OLE. Elimine la cláusula. Información adicional Delphi 2 y posteriores ofrecen cinco especificadores de visibilidad: Private, Protected, Public, Published y Automated. Una propiedad de una clase puede especificar características de almacenamiento mediante las palabras reservadas 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. Default parameter ‘<>’ must be by-value or const Posible causa de error Puede haber creado un método que asocia un valor por defecto a un parámetro que es un parámetro Var (que se pasa por referencia). Por ejemplo, lo siguiente generará este mensaje de error: procedure ThatAintWorkin(var iYiYi: Integer = 86); 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); 3. Elimine el valor por defecto: procedure ThatAintWorkin(var iYiYi: Integer); 180 Los Tomos de Delphi: Delphi sin problemas Por supuesto, puede también hacer esto: procedure ThatAintWorkin(const iYiYi: Integer); Información adicional En Pascal, hay tres formas de pasar parámetros: por referencia (Var), constante (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 utilice 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. Default property must be an array property Posible causa de error Puede haber declarado una propiedad que no es de tipo array como la propiedad por defecto de la clase. Por ejemplo, la siguiente declaración de propiedad generará este mensaje de error: property Twiggy: String read FTwiggy write FTwiggy; default; Solución rápida Borre la directiva Default de la declaración de la propiedad. Solamente es posible 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 especificar el nombre de la propiedad. Por ejemplo, a la propiedad declarada arriba se le podría asignar un valor así: var PC: TComputer; . . . PC[i] := Compaq; En otras palabras, como es la propiedad por defecto, no es necesario escribir el nombre de la propiedad cuando se hace una asignación, así: PC.Clones[i] := PackardBell; Default value required for <> Posible causa de error Puede haber proporcionado un parámetro con un valor por defecto, pero luego añadió otro parámetro que no tiene un valor por defecto. Por ejemplo, lo siguiente provocará este mensaje de error: procedure BiDefault(i: Integer = 76; s: String); 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'); o colocar el parámetro con valor por defecto en último lugar, así: procedure BiDefault(s: String; i: Integer = 76); 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. Default values must be of ordinal, pointer, or small set type Posible causa de error Puede haber declarado una propiedad que contenga una directiva de almacenamiento por defecto cuyo tipo de datos es incompatible con los aceptables como valores por defecto. Por ejemplo, lo siguiente produce este mensaje de error, ya que el tipo de datos String no puede tener un valor por defecto asociado: property Nanook: string read FZappa write FZappa default 'great oogly moogly'; 182 Los Tomos de Delphi: Delphi sin problemas 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érminos 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; Delphi ofrece tres directivas de almacenamiento. Además de Default, también están Nodefault y Stored. Normalmente, todos los valores de propiedades se almacenan, y no hay valores por defecto para una propiedad dada. La única manera de especificar un valor por defecto es utilizando la directiva de almacenamiento Default. La única manera de evitar que un valor sea almacenado es utilizar la directiva de almacenamiento Stored, seguida por una función booleana cuyo valor devuelto determina si la propiedad es almacenada o no. He aquí otro fragmento de la unidad Buttons de Delphi que muestra la directiva Stored en uso: TBitBtn = class(TButton) . . . private function IsCustom: Boolean; function IsCustomCaption: Boolean; . . . published Mensajes de error 183 . . . 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; Para más información, consulte “storage specifiers” en la ayuda de Delphi. Destination must be indexed Posible causa de error Puede estar intentando añadir, actualizar o borrar registros de un tabla indizada desde una tabla no indizada mediante el componente TBatchMove. Por ejemplo, si la tabla Source contiene una clave primaria, y la tabla Destination no, y llama al método Execute del componente TBatchMove (en tiempo de ejecución o en tiempo de diseño desde el entorno integrado de Delphi; vea la sección de Información Adicional) mientras la propiedad Mode del componente TBatchMove tiene asignado el valor batAppendUpdate, batDelete o batUpdate, obtendrá este mensaje de error. 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 correspondientes, 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 componente TTable. 184 Los Tomos de Delphi: Delphi sin problemas 3. Asigne a la propiedad Mode del componente TBatchMove la operación deseada (batAppend, batAppendUpdate, batCopy, batDelete o batUpdate). 4. Pulse el botón derecho del ratón sobre el componente TBatchMove. 5. Seleccione Execute desde el menú de contexto. Para más información, consulte “TBatchMove” en la ayuda de Delphi. Directory Is Busy Posible causa de error Múltiples aplicaciones (o múltiples instancias de una misma aplicación) pueden 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 directorio 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 ejecutan 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 utilizar 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). Directory is controlled by other .NET file Posible causa de error 1. Puede estar intentando acceder a una tabla que está siendo actualmente utilizada por alguien cuya configuración del parámetro NetDir de Paradox difiere del suyo. Todos los usuarios deben compartir el mismo archivo de control de red (PDOXUSRS.NET) para habilitar el acceso concurrente a la tabla. 2. Pueden haber archivos de control de red (PDOXUSRS.NET) o archivos de bloqueos (*.LCK) inválidos en su sistema. Estos archivos se quedan algunas veces después de una terminación anormal del programa (una caída del sistema). 3. Puede no tener configurado a True el parámetro Local Share mientras accede a un directorio en una red local punto a punto. 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 Si es necesario, mueva el archivo al directorio indicado en WIN.INI, o modifique la entrada de WIN.INI para que coincida con la ubicación del archivo. 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/Administration, puede consultar el Registro del sistema para asegurarse de que la ubicació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 ubicació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 configuració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 establecer como su directorio privado un directorio de su propio disco duro, asigná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 asociado (.DCR) está dañado. Solución rápida Borre el archivo .DCR (tiene el mismo nombre del componente, pero su extensió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 visualmente 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 componente. 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 ejemplo, 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 Objetos mostrará SoftBatchMove1: TSoftBatchMove cuando el componente descendiente tenga el foco. Disk read error Posible causa de error Puede haber intentado leer más allá del final de un archivo. Por ejemplo, si está leyendo un archivo de 50 líneas, lo siguiente generará este mensaje de error: var s: String; I: Integer; begin AssignFile(states,'50states.txt'); Reset(states); i := 0; while i < 232 do begin readln(states, s); inc(i); end; . . . 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. Disk write error Posible causa de error Puede haber llamado a uno de los siguientes procedimientos cuando el disco en el que está intentando escribir está lleno o ha quedado lleno como resultado de la operación: CloseFile 190 Los Tomos de Delphi: Delphi sin problemas 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 parezcan tener sentido, verifique el espacio disponible en disco. Dispid <> already used by <> Posible causa de error Puede estar intentando utilizar un identificador dispid que ya ha sido asignado a otro procedimiento de la clase. Por ejemplo, lo siguiente produciría este mensaje de error: automated procedure OnClick; dispid 1; procedure OnKeyPress(var Key: Smallint); dispid 1; 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 directiva Dispid, ésta debe ir seguida por una constante entera. Si no se especifica explícitamente una directiva Dispid con su correspondiente número, el compilador generará automáticamente un identificador único. Para más información, consulte “automated components” en la ayuda de Delphi. Mensajes de error 191 Dispid clause only allowed in OLE automation section Posible causa de error Una directiva Dispid ha sido añadida a una propiedad que no está situada en la sección Automated de la clase. Por ejemplo, lo siguiente generará este mensaje de error: Public . . . property rillest8: integer read getF14 dispid 3; 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. Dispose not supported (nor necessary) for dynamic arrays Posible causa de error Puede haber intentado aplicar el procedimiento Dispose a un array dinámico. Por ejemplo, lo siguiente generará este mensaje de error: procedure BusyWork; var argh : array of integer; begin SetLength(argh, 12); . . . Dispose(argh); . . . 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 operació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. Duplicate case label Posible causa de error Este mensaje de error se produce cuando hay más de una etiqueta de opción con el mismo valor en una sentencia Case. Solución rápida Asegúrese de que haya solamente una ocurrencia de cada valor en una sentencia 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 ejemplo, 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; Puede especificar múltiples constantes en una línea, pero ninguna de ellas puede ser utilizada más de una vez en la misma sentencia Case. Por ejemplo, las dos siguientes sentencias son válidas: function GetFirstInitial(shagger: outfielders): string; var FirstInitial: char; 194 Los Tomos de Delphi: Delphi sin problemas 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; Duplicate database name <> Posible causa de error Puede haber asignado a la propiedad DatabaseName de un componente TDatabase un nombre ya asignado a otro componente TDatabase existente en el formulario. 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. Delphi 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 mantenimiento del código. Mensajes de error 195 Duplicate dynamic method index Posible causa de error Puede haber asignado el mismo código de mensaje a dos procedimientos que responden a un mensaje de ventana específico. Por ejemplo, lo siguiente generará este mensaje de error: const GOTTA_GETTA_MESSAGE_TO_YOU = WM_User + 160; MESSAGE_IN_A_BOTTLE = WM_User + 160; type TTooMuchMonkeyBusiness = class(TComponent) procedure HereComesTheNewBoss(var Msg: TMessage); message GOTTA_GETTA_MESSAGE_TO_YOU; procedure SameAsTheOldBoss(var Msg: TMessage); message MESSAGE_IN_A_BOTTLE; end; 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 correspondiente se dispare. Para más información, consulte “PostMessage” y “SendMessage” 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 Windows. Para más información, consulte “message dispatching” en la ayuda de Delphi. Para información similar, consulte “duplicate message method index”. Duplicate field name <> Posible causa de error Puede estar intentando utilizar el mismo nombre para varios campos de base de datos. Por ejemplo, puede estar creando campos así: 196 Los Tomos de Delphi: Delphi sin problemas with Table1 do begin . . . with FieldDefs do begin Clear; Add('Outstanding', ftBoolean, 0, True); Add('Outstanding', ftString, 30, False); end; 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. Duplicate implements clause for interface <> Posible causa de error Puede haber declarado dos propiedades delegadas para la misma interfaz. Por ejemplo, lo siguiente generará este mensaje de error: property SomeInterface: ISomeInterface read ReadItAndWeep implements ISomeInterface; property SomeOtherInterface: ISomeInterface read ReadItAndRejoice implements ISomeInterface; 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 propiedades para implementar interfaces, consulte “Implements getter must be register calling convention” y “Read or Write clause expected, but identifier <> found”. Duplicate message method index Posible causa de error Puede haber utilizado el mismo índice de mensaje para más de un método de gestión de mensaje. Por ejemplo, lo siguiente ocasionará este mensaje de error, ya que intenta asignar el procesamiento del mensaje WM_CHAR a dos métodos: type TForm1 = class(TForm) private { Private declarations } public procedure WMChar(var Message: TWMChar); message WM_CHAR; procedure WMKeyDown(var Message: TWMChar); message WM_CHAR; end; 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 programa. 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 3. Puede haber intentado añadir manualmente un recurso al archivo .RES del proyecto. 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 Duplicate session name <> Posible causa de error Puede haber asignado el mismo valor a la propiedad SessionName de dos componentes TSession. 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 aplicaciones 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. Duplicate Tag Value Posible causa de error Puede haber declarado un registro variante que se refiere al mismo valor en la sección Case más de una vez. Por ejemplo, lo siguiente generará este mensaje de error, ya que True ha sido especificado dos veces: Type TProgrammer = record FirstName, LastName: string[40]; DateOfFirstHelloWorldProgram: TDateTime; case BorlandTools: Boolean of True: (BorlandConferencesAttended: Integer); True: (FrontalLobotomiesUndergone: Integer); end; 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 Dynamic method or message handler not allowed here Posible causa de error Puede haber especificado un método de gestión de mensaje o un método dinámico como método de acceso de lectura o escritura de una propiedad. Por ejemplo, cualquiera de las declaraciones siguientes generará este mensaje de error: private function Dynamo: Integer; dynamic; procedure wmuserchanged(var Message: TMessage); message WM_USERCHANGED; . . . published property propwash: integer read dynamo; property improper: integer write wmuserchanged; type IMPei = interface function Accessor: IMPei; dynamic; property IMPei: IMPei read Accessor implements IWhatFlavor; end; 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ámicos 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; -OElimine 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 Dynamic method or message handlers not allowed in OLE automation sections Posible causa de error Puede haber declarado un método dinámico o de gestión de mensaje en una sección Automated de una clase. Por ejemplo, cualquiera de las siguientes declaraciones generará este mensaje de error: automated procedure dynamo; dynamic; procedure wmvscrollclipboard(var Message: integer); message WM_VSCROLLCLIPBOARD; 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 normalmente (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 automation 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 formulario 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 unidad 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 Componentes (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 problema durante el intento de convertir de un tipo de datos a otro. Puede utilizar la clase de excepción EConvertError como herramienta de validació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 necesiten. 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 funcionalidad, 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 ignorado. Diferentes clases con un mismo nombre, sin embargo, provocan error. Mensajes de error 205 Este error es la clase base de los siguientes descendientes: EClassNotFound, EInvalidImage, EMethodNotFound y EReadError. 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); . . . -Ovar sT: System.Text; {o tF: TextFile} begin AssignFile(sT,'SoTrue.txt'); try System.Append(sT) except on EInOutError do Rewrite(sT); end; . . . Puede también protegerse contra excepciones EInOutError al cerrar los archivos (que no se puedan grabar) así: procedure TForm1.CloseButtonClick(Sender: TObject); begin . . . try 206 Los Tomos de Delphi: Delphi sin problemas 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 compilació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”. EInvalidOperation: Cannot create form. No MDI forms are currently active Consulte “Cannot create form. No MDI forms are currently active”. EInvalidOperation: Cannot make a visible window modal Consulte “Cannot make a visible window modal”. 208 Los Tomos de Delphi: Delphi sin problemas EInvalidPointer Consulte “Invalid pointer operation”. Element 0 Inaccessible—use Length or SetLength Posible causa de error Puede estar intentando acceder al elemento 0 de una variable de tipo String en Delphi de 32 bits. Por ejemplo, el siguiente intento de almacenar el elemento de índice 0 en la variable de tipo Byte LengthByteContents generará este mensaje de error: procedure Bight; var s : String; LengthByteContents : Byte; begin s := 'Cheese'; LengthByteContents := s[0]; end; El siguiente intento de asignar un valor al elemento 0 también generará este mensaje de error: program Produce; var s: String; LengthByteSize: Integer; begin LengthByteSize := 25; s[0] := LengthByteSize; end; 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; Para asignar la longitud de la cadena, haga esto: Mensajes de error 209 procedure SetStringLength(s: String; ANumber: Integer); begin SetLength(s, ANumber); 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; END expected but <> found Posible causa de error Puede haber añadido algo sobrante a una sentencia, como un paréntesis derecho donde no es necesario. 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 innecesario (aunque inofensivo); por lo tanto, el compilador no lo espera. END expected but implementation found Posible causa de error Puede haber omitido el End que era necesario para terminar una declaración de tipo en la parte Interface de una unidad. 210 Los Tomos de Delphi: Delphi sin problemas 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!} END. missing at end of module Posible causa de error 1. Puede que no haya concordancia entre los pares Begin y End. 2. Puede haber olvidado añadir la palabra reservada End al final de una sentencia Case, un bloque Try. . . Finally o un bloque Try. . . Except. 3. Puede haber en realidad un End final, pero el compilador no puede verlo por alguna razón. Por ejemplo, puede haber dejado una llave abierta ({ ) en el código en algún lugar, que está causando que todo lo que está después de él sea considerado como un comentario, ya que no existe una llave derecha ( }) correspondiente para cerrar la sección de comentario. 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 sentencia 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 A partir de Delphi 3 están disponibles las plantillas de código (code templates). Consulte “code templates” en la ayuda de Delphi para más detalles, o seleccione Tools | Environment Options, y la página Code Insight. La sección Code Templates muestra una lista de plantillas predefinidas y una ventana que las despliega. Por ejemplo, la plantilla de código predefinida tryf es la siguiente: try | finally end; La barra vertical muestra dónde se ubicará el cursor después de utilizar esta plantilla de código — exactamente en donde debe empezar a codificar el bloque Try. . . Finally. Para utilizar una plantilla de código, siga estos pasos: 1. En la ventana de código, pulse Ctrl + J. 2. Seleccione de la lista la plantilla de código que desee. 3. Pulse la tecla Intro. EOLEError Consulte “Class not registered”. EOLEException Consulte “OLE error 800A03EC”. EOleSysClass not Registered Consulte “Class not registered”. 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 global 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 manejador (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 indirectamente 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 documentació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 Nota: Para conservar los recursos: Mueva tantos formularios como sea posible de la lista Auto-Create a la lista Available. Siempre que sea posible, utilice componentes gráficos en lugar de componentes de ventana. Los componentes gráficos no necesitan un controlador de ventana. Por ejemplo, si desea mostrar una cadena de texto de sólo lectura, utilice un TLabel en lugar de un control TEdit. 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 reference?” Si selecciona No, obtendrá este error. Al seleccionar Yes, el método Button1Click (o cualquier método o propiedad que haya borrado) será eliminado 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. Si todo lo anterior falla, compare el archivo de formulario (.DFM) con el archivo de unidad (.PAS) y asegúrese de que todos los componentes, propiedades y métodos declarados estén presentes en ambos. Para ver el archivo de formulario .DFM como un texto, pulse con el botón derecho del ratón sobre el formulario en tiempo de diseño y seleccione la opción View as Text del menú de contexto. Cuando haya finalizado de ver el archivo .DFM, realice el proceso inverso (pulse con el botón derecho del ratón sobre la ventana de código y seleccione View as Form del menú de contexto). Error 0: RLINK32 Error opening file <TypeLibrary>.tlb Posible causa de error Puede estar intentando crear un servidor de automatización, ActiveForm o control ActiveX y sus DLLs de OLE son antiguas. Solución rápida Instale el Internet Explorer desde el CD de Delphi, o copie las DLLs directamente desde \RunImage\Delphi X\Windows\System32. Información adicional Consulte “Could not load RLINK32.DLL”. Error 2—File not found Consulte “File <> not found”. Error 4—Too many open files Consulte “Too many open files”. Mensajes de error Error 68—Circular Unit Reference Consulte “Circular Unit Reference”. Error 76—Constant out of range Consulte “Constant out of range”. Error 94—“.” Expected Consulte “ “.” Expected”. Error 101—Disk write error Consulte “Disk write error”. Error 102—File not assigned Consulte “File not assigned”. Error 103—File not open Consulte “File not open”. Error 104—File not open for input Consulte “File not open for input”. Error 105—File not open for output Consulte “File not open for output”. Error 200—Division by zero Consulte “Division by zero”. 217 218 Los Tomos de Delphi: Delphi sin problemas Error 201—Range check error Consulte “Range check error”. Error 202—Stack overflow error Consulte “Stack overflow”. Error 203—Heap overflow error Consulte “EOutOfMemory”. Error 204—Invalid pointer operation Consulte “Invalid pointer operation”. Error 207—Invalid floating point operation Consulte “Invalid floating point operation”. Error 210—Abstract Method Error Consulte “Abstract Method Error”. Error 215—Arithmetic overflow error Consulte “Arithmetic Overflow Error”. Error 216—Access Violation Consulte “Access Violation”. Error 219—Invalid Typecast Consulte “Invalid typecast”. Mensajes de error 219 Error 220—Invalid Variant Typecast Consulte “Invalid variant type conversion”. Error 227—Assertion failed Consulte “Assertion failed”. Error Creating Cursor Handle Posible causa de error Este error normalmente ocurre cuando Delphi no recibe un conjunto resultado cuando lo está esperando. 1. Puede haber intentado asignar el valor True a la propiedad Active de un componente TQuery o llamar a su método Open mientras la propiedad SQL del TQuery contenía una sentencia SQL que no devuelve un conjunto resultado (en otras palabras, no una sentencia SELECT, sino una sentencia INSERT, UPDATE o DELETE). 2. Puede haber intentado asignar el valor True a la propiedad Active de un componente TStoredProc o llamar a su método Open mientras no tenía un valor asignado a la propiedad StoredProcName. 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 DataBaseName debe estar asignada a un alias que describa una base de datos de servidor SQL, como InterBase, Oracle, MS SQL Server, Sybase, Informix, 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). Error creating form: access violation at. . . vcl[30,40,50,60] Posible causa de error Puede haber cambiado el nombre del formulario en el código, así: procedure ChChChChChanges; begin Form1.Name := 'whatever'; end; 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? Error creating form: Ancestor for “<>” not found Posible causa de error Puede estar utilizando herencia visual de formularios y no haber incluido todos los formularios ancestros en su proyecto. 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 Error Creating Form: Cannot inherit from form <>. Contains a component <> that does not support inheritance Posible causa de error Utilizando la herencia visual de formularios en Delphi de 32 bits, puede haber intentado heredar de un formulario que contiene un componente TTabbedNotebook. 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. Error Creating Form: Cannot inherit from form <>. It contains a component with a blank name property Posible causa de error Puede haber intentado heredar de un formulario del proyecto actual que contiene un componente con la propiedad Name en blanco. 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 2. 3. 4. 5. 6. 7. 8. Si sólo quiere que el formulario esté disponible para el proyecto actual, no necesita hacer nada más. El formulario ancestro está disponible automáticamente para ser heredado. Si quiere que el formulario esté disponible para otros proyectos (y no solamente para el proyecto actual), siga estos pasos adicionales: Pulse el botón derecho del ratón sobre el formulario y seleccione Add To Repository. Proporcione un título para el formulario en el cuadro de edición Title. Opcionalmente, proporcione una descripción en el cuadro de edición. Seleccione o introduzca la página del Almacén de Objetos (Object Repository) en la que quiere que aparezca el formulario en el cuadro de combinación Page. Opcionalmente, introduzca su nombre en el cuadro de edición Author. Opcionalmente, seleccione un icono para representar el formulario. Pulse el botón OK. Para heredar de un formulario, siga estos pasos: 1. Seleccione File | New. 2. Seleccione el formulario del que desea heredar en la página del Almacén donde se encuentre. Si hereda de un formulario que tiene un botón llamado Button1, el botón en el formulario heredado será exactamente el mismo botón ancestro (el único que está en el formulario del que está heredando). Todas las propiedades, incluyendo los gestores de eventos, serán heredados. Por ejemplo, si el formulario ancestro tiene un botón con la propiedad Caption asignada a ‘Belly’, la propiedad Tag asignada a 7, y el siguente gestor del evento OnClick: procedure TForm1.Button1Click(Sender: TObject); begin Close; end; El botón del formulario heredado también tendrá la propiedad Caption igual a ‘Belly’, la propiedad Tag igual a 7, y su gestor del evento OnClick heredará del gestor del ancestro: procedure TForm2.Button1Click(Sender: TObject); begin inherited; end; Mensajes de error 223 Error creating form: Cannot open file <>.DFM Posible causa de error Puede estar intentando abrir un archivo .PAS, y su correspondiente archivo de formulario (.DFM) contiene errores, se ha dañado o no está en el mismo lugar que el archivo .PAS que está intentando abrir. 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. Error Creating Form: Duplicate resource [Type:,Name:] Posible causa de error Puede estar cargando un proyecto en una versión de Delphi anterior a la que se utilizó para compilarlo. Por ejemplo, puede estar abriendo un proyecto creado con Delphi 2 en Delphi 1. 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 En Delphi 4 o superior, Project | Build <Proyecto>. Todas las unidades serán recompiladas para la versión actual de Delphi que esté ejecutando. Alternativamente, puede borrar el archivo .RES del proyecto (el archivo con el nombre del proyecto y extensión .RES). La próxima vez que compile, el archivo .RES apropiado será recreado para la versión de Delphi que esté utilizando. Información adicional Los recursos de 16 bits y de 32 bits son como el agua y el aceite — no se mezclan. 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”. Error Creating Form: Invalid Stream Format Posible causa de error Puede estar intentando portar una aplicación a una versión de Delphi anterior a la utilizada cuando se compiló la aplicación por última vez. Solución rápida Utilice la utilidad de conversión de Delphi para convertir los archivos de formulario (.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 compilar 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 formulario contiene referencias a propiedades que no existen en la versión anterior de Delphi, elimínelas. Mensajes de error 225 6. Convierta los archivos .TXT a .DFM utilizando el mismo comando, reemplazando “dfm” por “txt”: convert C:\ConvertMe\*.txt. Ahora tendrá una versión binaria (*.DFM) de los archivos de formulario en el formato esperado por la versión anterior de Delphi. 7. Copie los archivos de formulario a una ubicación separada y añada sus correspondientes archivos .PAS (y el .DPR). Ahora deberá poder abrir el proyecto y ejecutarlo en la versión anterior de Delphi. 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 reading <>. 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”. Error creating Process Posible causa de error Puede estar haciendo referencia a DLLs en Windows NT especificando la extensión (.DLL). Por ejemplo, lo siguiente generará este mensaje de error en NT: procedure HawaiianPunch; external ‘pineappl.DLL'; Aunque es la forma apropiada de hacerlo en otras versiones de Windows. 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 Error Creating Variant Array Posible causa de error Puede haber intentado crear un array variante de cadenas utilizando el tipo de datos varString. Por ejemplo, lo siguiente generará este mensaje de error: procedure TForm1.Button1Click(Sender: TObject); var Roster: Variant; begin Roster := VarArrayCreate([0,40], varString); . . . 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. Error Creating Window Posible causa de error Puede tener simultáneamente demasiados manejadores de ventanas. 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 que reciben el foco de entrada — en otras palabras, clases descendientes de TWinControl) es un ventana y requiere un manejador de ventana. Utilice controles gráficos (descendientes de TGraphicControl) siempre que sea posible. Por ejemplo, utilice componentes TLabel para mostrar texto en lugar de TEdit, y componentes TBevel en lugar de TPanel si todo lo que necesita es proveer una separación visual entre diferentes áreas del formulario. Exceptuando al formulario principal, cree tantos formularios como sea posible dinámicamente; particularmente aquellos que no necesariamente estarán abiertos durante toda la ejecución de la aplicación — por ejemplo, un cuadro de diálogo ‘Acerca de’. Error debug setting hook Posible causa de error Puede haber terminado la ejecución de su aplicación de un modo anormal, por ejemplo pulsando Ctrl+F2. 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. Error in CREATE INDEX statement Posible causa de error Probablemente tiene un error de sintaxis en una sentencia CREATE INDEX de SQL. Por ejemplo, lo siguiente generará este mensaje de error: with TADOQuery.Create(nil) do try Connection := ADOConnection1; SQL.Add('CREATE INDEX ORD_SEQ (ORDER_SEQUENCE) ON SCRIPTURES'); ExecSQL; finally Free; end; 228 Los Tomos de Delphi: Delphi sin problemas 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; En otras palabras, la sintaxis correcta en este caso es: CREATE INDEX <NombreIndice> ON <NombreTabla> (<NombreCampo>) 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”. Error in module <>: Call to Application.CreateForm is missing or incorrect Consulte “Call to Application.CreateForm is missing or incorrect”. Error in module <>: CONTAINS clause is incorrect Consulte “CONTAINS clause is incorrect”. Error in module <>: Declaration of class <> is missing or incorrect Consulte “Declaration of class <> is missing or incorrect”. Error in module <>: END. missing at end of module Consulte “END. missing at end of module”. Mensajes de error 229 Error in module <>: Implementation part USES clause incorrect Consulte “Implementation part USES clause incorrect”. Error in module <>: Incorrect field declaration: class <> Consulte “Incorrect field declaration: class <>”. Error in module <>: REQUIRES clause is incorrect Consulte “REQUIRES clause is incorrect”. Error in module <>: USES clause is missing or incorrect Consulte “USES clause is missing or incorrect”. Error initializing BDE ($2B05) Posible causa de error Puede estar intentando ejecutar una aplicación que necesita el BDE en una máquina que no tiene el BDE instalado. 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 funcionará bien en la máquina donde la ha instalado. Sin embargo, como la Solución Rápida indica, esto no es suficiente. Error loading type library/dll Posible causa de error El archivo STDVCL[32,40].DLL no se encuentra, está en el lugar equivocado o no está registrado. 230 Los Tomos de Delphi: Delphi sin problemas 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) Error Opening Component Library Posible causa de error Puede haber instalado un componente que se enlaza estáticamente (es decir, a través de sentencias External) a una .DLL que no puede ser encontrada. 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. Error reading <>.<>: <> Posible causa de error 1. Puede ser que los componentes a los que se hace referencia en el archivo de formulario (.DFM) no estén disponibles. Puede haber desinstalado esos componentes después de utilizarlos en un proyecto. Esto ocurre más frecuentemente con componentes de terceros. 2. Puede haber abierto un proyecto en una versión de Delphi anterior a la que utilizó para compilar el proyecto. En este caso, podrán aparecer uno o más mensajes que indiquen que cierta propiedad no existe. 3. Puede manualmente haber editado el archivo de formulario (.DFM) independientemente del archivo .PAS, tal vez cambiando un tipo de objeto por otro. Si es así, habrá propiedades que un objeto tiene y el otro no, ocasionando este problema. 4. Puede ser que Delphi no pueda encontrar un archivo de configuración necesario, como IDAPI32.CFG. 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 a. Seleccione Inicio | Ejecutar. b. Introduzca regedit en el cuadro de combinación Abrir... y pulse el botón OK (o presione la tecla Intro). c. Navegue hasta HKEY_LOCAL_MACHINE\Software\Borland\Database Engine. El valor para CONFIGFILE01 mostrará el camino donde está situado el archivo de configuración. Si difiere de la ubicación de su copia de IDAPI32.CFG, mueva el archivo a la ubicación apuntada por la clave anterior del Registro (recomendado), o cambie el valor de la clave para adecuarlo a la ubicación actual del archivo. Información adicional Consulte “Stream Read Error”. Error reading <ComponentName or FormName>.<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. Posible causa de error 1. Puede haber intentado cambiar un componente por otro que no es compatible editando el archivo .DFM. Por ejemplo, puede haber cambiado TDateTimePicker por TEdit, en cuyo caso la parte <PropertyName> del mensaje sería <CalAlignment> (el primer mensaje de error de este tipo que se obtendría en esta ocasión). 2. Puede haber abierto un proyecto en una versión de Delphi anterior a la utilizada para crear el proyecto. Por ejemplo, ha creado el proyecto con Delphi 4, y luego intentado abrirlo en Delphi 3. En ese caso, el mensaje puede contener <NombreFormulario>.OldCreateOrder. 3. Puede haber eliminado un paquete de su sistema y luego intentado abrir un proyecto que utiliza componentes contenidos en dicho paquete. 4. Puede haber eliminado algunos paquetes que pensó que nunca utilizaría (como FastNet o QuickReports) y luego haber abierto un proyecto de demostración que utiliza uno de esos paquetes. 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 recomendado. Sin embargo, puede seleccionar Yes para ignorar el error, y las Mensajes de error 233 propiedades ya no estarán en ocasiones posteriores en que abra el proyecto. Lo contrario (es decir, abrir un proyecto creado en Delphi 3 con Delphi 4) normalmente funciona bien. 3, 4Cargue el paquete que contiene el componente al que se hace referencia en el mensaje de error (Component | Install Packages) para resolver los posibles errores mencionados en el punto 3 y 4. 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 formulario específico o solamente para los controles que seleccione en el editor de formularios de Delphi. Consulte “Error Creating Form: Invalid Stream Format”. Error reading <Database>.SessionName. Duplicate database name <> Posible causa de error Puede tener asignada a False la propiedad HandleShared de un componente TDatabase. 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. Error reading <Session>.SessionName. Duplicate session name <> Posible causa de error Puede tener asignada a False la propiedad AutoSessionName del componente TSession. 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. Error reading symbol file Posible causa de error 1. El archivo de símbolos del proyecto (.DSM) puede estar dañado o no sincronizado con el proyecto. 2. Puede estar abriendo en Delphi de 32 bits un proyecto que ha compilado con Delphi 1, y el proyecto contiene un archivo de símbolos (.DSM) de 16 bits. 3. Puede haber movido un proyecto a un directorio o máquina diferente. 4. Puede estar ejecutando un programa creado en otra máquina que hace referencia en el archivo .DSK a un directorio que no es válido. 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 mensaje (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 volver 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 Error saving I(Interface): The parameter is incorrect Posible causa de error Puede estar intentando crear un servidor de automatización, ActiveForm o control ActiveX y las .DLLs de OLE no están actualizadas. 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 opening file <TypeLibrary>.tlb”. Error setting debug exception hook Posible causa de error 1. Puede estar experimentando un fallo menor en Delphi. 2. Uno o más archivos de unidades compiladas (.DCU) pueden estar dañados. 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 formulario). La mayoría de los demás archivos serán regenerados automáticamente 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 Error starting Program. The <>.DLL file appears to be corrupt. Reinstall the file, and then try again. Posible causa de error Puede haber intentado ejecutar en Delphi de 32 bits un programa que utiliza una .DLL de 16 bits. 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; FieldValues es la propiedad por defecto de TDataset; por esa razón no es necesario hacer la referencia explícitamente. En otras palabras, las siguientes dos asignaciones ejecutan la misma acción: i := Query1['ExpendableIncome']; i := Query1.FieldValues(['ExpendableIncome']); Para más información, consulte “TDataset.FieldValues” en la ayuda de Delphi. Except or Finally expected Posible causa de error 1. Ha omitido la palabra reservada Finally o Except después de utilizar la palabra reservada Try. Por ejemplo, lo siguiente generará este mensaje de error: procedure TForm1.SiskoAndEbertClick(Sender: TObject); var 238 Los Tomos de Delphi: Delphi sin problemas 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; Los bloques Try. . . Except se utilizan generalmente para proveer respuestas a errores específicos. Un ejemplo de utilización del bloque Try. . . Except es: try Dividend := StrToInt(Edit1.Text); Divisor := StrToInt(Edit2.Text); Quotient := Dividend div Divisor; except on EDivByZero do ShowMessage('Introduzca un valor más grande que 0 ' Mensajes de error 239 +#13#10+ ' en el cuadro de edición Divisor’); Edit2.SetFocus; end; end; Exception <> in module <> at <>.<> Posible causa de error Este es el mensaje de error por defecto que se obtiene si una excepción hace todo el recorrido “hacia arriba” (la excepción no ha sido atrapada por su código o el código de la VCL). 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. Expected an identifier but function found Posible causa de error Puede haber olvidado añadir el paréntesis final a la signatura de un procedimiento o función. Por ejemplo, lo siguiente generará este mensaje de error: procedure CalculateDueDate(AAgencyID, AEmployerID: Integer; APayrollDate: TDate; 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 Expecting a column separator in table [header] Posible causa de error La tabla indicada en el mensaje de error es probablemente una tabla Paradox que se ha dañado de algún modo. 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). Exports allowed only at global scope Posible causa de error Puede haber añadido la cláusula Exports a un procedimiento o función local. 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. Expression expected but <> found Posible causa de error 1. Puede haber omitido algo. Por ejemplo, la siguiente sentencia (en la que falta el segundo operando, que debería aparecer después del signo más) genera este mensaje de error: LblIntegerAddition.Caption := IntToStr(1+); 2. Puede estar intentando asignar una fracción a un número real/punto flotante (o una hora en una variable TDateTime), pero ha olvidado anteponer Mensajes de error 241 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 mensaje 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; External error C0000006 Posible causa de error Puede haber instalado un componente inestable de un tercero. 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 invirtiendo el proceso: 1. Seleccione Component | Install Packages. 2. Pulse el botón Add. 3. Abra el archivo .BPL apropiado. External error C0000012 Posible causa de error Ya que es un error “externo”, no es un fallo de Delphi. Puede ser una excepción no manejada en una .DLL o cualquier otra cosa. Solución rápida No estoy seguro de por qué, pero en una ocasión resolví este problema cambiando 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. External exception C0000008 Posible causa de error Puede estar utilizando el cliente de SQL Net versión 2.3.3. 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 servidores AS/400. Para más información, visite www.danysoft.com. Failed to get data for <> Posible causa de error Puede haber intentado obtener datos del Registro del sistema a una variable de un tipo de datos que difiere del tipo de datos del valor obtenido. Por ejemplo, lo siguiente generará este mensaje de error si el valor ThirdBase almacenado en el Registro es un entero (o de hecho cualquier otra cosa distinta a un String): function GoSeeCal: String; var ReggiesTree: TRegistry; begin ReggiesTree := TRegistry.Create; try ReggiesTree.RootKey := HKEY_CURRENT_USER; ReggiesTree.OpenKey('\drmtmale\Baltimore Orioles', False); Result := ReggiesTree.ReadString('ThirdBase'); finally ReggiesTree.Free; end; end; 244 Los Tomos de Delphi: Delphi sin problemas 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 utilizaban 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. Failed to load stream Consulte “BLOb has been modified”, número 2. Fatal Error: <>: Required Package <> not found Consulte “Required package <> not found”. Mensajes de error 245 Field <> cannot be modified Posible causa de error 1. Puede estar intentando modificar la propiedad Params de un objeto TClientDataSet después que ha sido asignada, sin primero borrar el contenido original de Params. 2. Puede estar intentando hacer una búsqueda utilizando un índice distinto al índice actual. 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 modificar esta propiedad en tiempo de ejecución utilizando el componente TClientDataSet. Field <> cannot be used in a filter expression Posible causa de error 1. Puede estar intentando filtrar por un campo calculado. 2. Puede estar intentando filtrar por un campo cuyo tipo de datos no permite utilizarlo en filtros (como un gráfico). Solución rápida 1,2. Utilice solamente campos de datos estáticos cuyos valores puedan ser cuantificados 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 permitido 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 2. Un filtro que compare cadenas o valores numéricos no trabajará con ciertos tipos de datos (como TGraphicField y TMemoField), y por lo tanto los campos de estos tipos de datos provocarán este mensaje de error si los utiliza en una expresión de filtro. Un ejemplo podría ser el siguiente filtro aplicado a la tabla Biolife de Paradox que viene con Delphi: Graphic > 8 Field <>.<> does not have a corresponding component. Remove the declaration? Posible causa de error 1. Tiene una referencia en el archivo .PAS que no tiene una referencia correspondiente en el archivo .DFM. 2. Puede obtener este mensaje de error si después de recibir el mensaje de error “Class <> not found. Ignore the error and continue?” continúa con la carga del proyecto (después de ignorar el mensaje de error anterior). 3. Puede haber borrado manualmente la referencia al campo en el archivo .DFM. 4. Puede haber modificado la declaración del campo en el archivo .PAS. Por ejemplo, puede haber cambiado: type TForm3 = class(TForm) Label1: TLabel; a: type TForm3 = class(TForm) abel1: TLabel; {borró la L de Label1} 5. Puede haber intentado añadir manualmente un tipo de clase en la parte Published del archivo de unidad, así: type TForm1 = class(TForm) Image1: TImage; Chloro: Form; {esta línea ocasiona el error} private { Declaraciones Private } public { Declaraciones Public } end; Solución rápida 1. Seleccione Yes para borrar la declaración. Mensajes de error 247 2. Si quiere luego volver a insertar la referencia en el archivo .DFM, es más fácil añadir el componente de nuevo al formulario, lo que automáticamente reinsertará la referencia en el archivo .DFM. 3. Vuelva a insertar la referencia que haya borrado en el archivo .DFM. 4. Restaure la declaración del campo para que esté acorde con el nombre del componente en el Inspector de Objetos. 5. Cuando añada campos de tipos de clase, no los añada a la parte Published de un archivo de unidad de formulario (.PAS). Lo siguiente es aceptable: type TForm1 = class(TForm) Image1: Timage; private Concrete: Form; public { Public declarations } end; 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 <>”. Field <> is not indexed and cannot be modified Posible causa de error Puede estar intentando buscar por un campo de una tabla local (Paradox o dBASE) que (a) no está indizado o (b) está indizado, pero la propiedad IndexFieldNames del objeto TTable no tiene asignada una clave primaria (simple o compuesta), o la propiedad IndexField no tiene asignada una clave secundaria. Por ejemplo, lo siguiente generará este mensaje de error si se da alguna de esas posibilidades: with Table1 do begin SetRangeStart; FieldByName('Ballyard').AsString := 'Camden'; SetRangeEnd; FieldByName('Ballyard').AsString := 'Wrigley'; ApplyRange; end; 248 Los Tomos de Delphi: Delphi sin problemas Solución rápida Cuando acceda a tablas locales (Paradox o dBASE), asegúrese de que los campos 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 nombre del campo a la propiedad IndexFieldNames. Si es una clave primaria compuesta, 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'; Si quiere buscar por una clave secundaria, utilice la propiedad IndexField. Puede hacerlo en el entorno integrado o desde código, así: IndexName := 'SecondaryIndx'; 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 cualquier 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 IndexFieldNames del objeto TTable. Field <> is not of the expected type Posible causa de error Después de crear instancias de los campos en tiempo de diseño, puede haber modificado la estructura de la tabla borrando un campo (o campos) o modificando el nombre de un campo, su tipo de datos o tamaño. 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 propiedades 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 seleccionando 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 Si los valores de las propiedades no se corresponden con las propiedades actuales del campo, borre o modifique esta entrada si es necesario. Field <> is of an unknown type Posible causa de error 1. Puede haber intentando ejecutar una consulta parametrizada en el editor SQL de Delphi. Por ejemplo, puede tener una consulta de estructura similar a ésta: select SCRIPT_ID, SCRIPT_DESC, BUILD_NO, SCRIPT_TYPE from SCRIPTMAIN where SCRIPT_TYPE = :SCRIPT_TYPE 2. Puede estar consultando tablas de Access que contienen valores Date y TimeStamp y tiene asignado el valor True a la propiedad RequestLive del TQuery. 3. Puede estar utilizando un componente TUpdateSQL con una tabla que contiene un nombre de campo al que se le ha añadido el prefijo OLD_. 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. Field <> is of an unsupported type Posible causa de error Puede estar utilizando una versión antigua de algún software de capa intermedia, por ejemplo un versión vieja del BDE. 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 Field <> must have a value Posible causa de error Puede haber intentado grabar un registro a la base de datos, pero la tabla tiene un campo obligatorio (o NOT NULL si es una base de datos de servidor SQL) al que no se ha asignado un valor. 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 obligatorio cuando se creó la tabla local (Paradox, dBASE, etc.) utilizando el Database 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 definirlo 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 propiedad 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, consulte “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 proporcionar un valor por defecto para los descendientes de TField a través de la propiedad 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); Para más información sobre la validación de datos (a nivel de tabla, registro, campo y carácter) consulte “A value must be specified for <>”. 252 Los Tomos de Delphi: Delphi sin problemas Field <> not found Posible causa de error 1. Puede haber hecho referencia, posiblemente en la propiedad Filter de un TDataset, a un campo que no existe en el conjunto de datos (un campo calculado, por ejemplo). 2. Puede haber cambiado la propiedad TableName de un componente TTable, y la propiedad Filter aún hace referencia a un campo de la tabla anterior. 3. Después de crear los campos persistentes utilizando el editor de campos (Fields Editor), puede haber cambiado la propiedad TableName de un componente TTable. 4. Puede haber especificado en una llamada a AddIndex el nombre de un campo que no existe en el conjunto de datos subyacente. Por ejemplo, lo siguiente generará este mensaje de error si no hay un campo llamado City en Table1: Table1.AddIndex('City', 'City', []); 5. Puede haber borrado algunos campos de un TTable que anteriormente había añadido explícitamente utilizando el editor de campos (Fields Editor). 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 componente 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 propiedad Table del componente TTable o modificar la tabla. 5. Borre las declaraciones de descendientes de TField en el archivo de formulario (.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 campo llamado CurrentAddress en una tabla de búsqueda, sería erróneo intentar asignar lo siguiente a la propiedad Filter de KnightsOfTheRound: CurrentAddress = ‘Tower of London’ 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 <ComponentName>.<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 components 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 components to be deleted or property values to be lost”. 2. Consulte “Class <> not found”. Field declarations not allowed in interface type Posible causa de error Puede haber declarado un campo en un tipo de interfaz. Por ejemplo, lo siguiente generará este mensaje de error: IYamWhatIYam = interface(IInterface) ['{360C6A60-6EE0-11D4-A238-705350C10000}'] FSpinachBrand: String; //esto no tiene sentido; provoca el error function SmoochOliveOil(const unkOuter: Iunknown; const iid: TIID; out obj): HResult; stdcall; Mensajes de error 255 function BashBrutus(fLock: BOOL): HResult; stdcall; end; 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; Pero no obstante, es simplemente un nombre, después de todo. Field definition not allowed after methods or properties Posible causa de error 1. Puede estar intentando añadir un campo (o campos) a una declaración de clase después de declarar un método o propiedad. 2. Puede haber añadido las directivas Index, Stored, Default o Nodefault después de una función en una sección Automated. Por ejemplo: automated function yowza: string; index; 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 Field in group by must be in result set Posible causa de error Puede tener una sentencia SQL que hace referencia en una cláusula GROUP BY a un campo que no está incluido en la cláusula SELECT. Por ejemplo, puede tener algo así: SELECT Title, Protagonist, Rating, Count(*) FROM Movies WHERE Protagonist = 'Bogart' OR Protagonist = 'Brando' GROUP BY Rating 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). Field in order by must be in result set Posible causa de error Puede estar intentado ordenar por un campo que no existe o no ha sido especificado en la cláusula SELECT de la sentencia SQL. Solución rápida Verifique que el campo por el que está intentando ordenar (utilizando la cláusula 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 SELECT de la sentencia SQL, y que el nombre del campo esté correctamente escrito. 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 El campo por el que esta sentencia intenta ordenar no aparece en la cláusula SELECT. Puede rectificar esto añadiendo explícita o implícitamente el campo Bananas a la cláusula SELECT de la sentencia SQL. Para añadir explícitamente el campo Bananas a la cláusula SELECT de la sentencia SQL, haga esto: SELECT Peaches, Strawberries, Bananas 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 No tiene que limitar su criterio de selección a una única tabla, siempre y cuando las tablas que seleccione estén relacionadas unas con otras por un campo común. Por ejemplo, si quiere encontrar en qué año los equipos de una misma ciudad ganaron el campeonato de rugby (SuperBowl) y de béisbol (World Series), podría hacer esto: SELECT B.ThatChampionshipSeason FROM Baseball B, Football F WHERE B.City = F.City AND B.ThatChampionshipSeason = F.ThatChampionshipSeason ORDER BY B.ThatChampionshipSeason Field index out of range Posible causa de error 1. Puede estar intentando acceder al índice de una tabla utilizando un valor de índice mayor que el índice más alto definido en la tabla. Por ejemplo, lo siguiente generará este mensaje de error: 258 Los Tomos de Delphi: Delphi sin problemas 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 propiedad 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 indizan 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. Field name already exists. Rename one of the fields Posible causa de error Puede haber asignado el mismo nombre a dos campos en el Database Desktop. Por ejemplo, puede tener dos campos con el nombre Address. 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 primero 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 iguales, este mensaje de error se generará. Field not found in table Posible causa de error 1. Puede estar intentando añadir un índice a una tabla, pero ha especificado un campo que no existe en el método AddIndex de TTable. Por ejemplo, lo siguiente generará este mensaje de error si ha escrito mal el campo Geeko como Gecko: with Table1 AddIndex('Chipheads', 'Gecko', []); 2. Puede estar intentando añadir un índice de expresión a una tabla dBASE, pero no ha especificado ixExpression en el parámetro Options de AddIndex. Por ejemplo, lo siguiente generará este mensaje de error: with Table1 AddIndex('CityState',' city+state', []); 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. Field or method identifier expected Posible causa de error 1. Puede haber especificado un identificador que no es un campo o método como identificador de acceso de escritura o lectura de una propiedad. Por 260 Los Tomos de Delphi: Delphi sin problemas ejemplo, lo siguiente generará este mensaje de error (a menos que fajdlskdfajlsk sea un campo o nombre de método): property Rates: string read fajdlskdfajlsk write FRates; 2. Puede haber declarado un método de escritura o lectura para una propiedad sin haber declarado el método. Por ejemplo, lo siguiente generará este mensaje de error si no ha declarado GetStartDate: property StartDate: String read GetStartDate; 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 especificar 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 lectura 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 property RealEstate: Currency read GetRealEstate write SetRealEstate; 2. Recuerde que también hay que definir el método en la sección Implementation. Field out of range Posible causa de error Puede estar intentando ordenar por un campo calculado que no es del tipo fkInternalCalc. 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. Field types do not match Posible causa de error Puede haber seleccionado Table Lookup (Búsqueda en Tabla) en el Database Desktop y haber intentado enlazar dos campos que no son del mismo tamaño. Solución rápida Para poder enlazar dos tablas con capacidad de búsqueda (lookup), debe seleccionar 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 cualquier 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 solamente deben ser campos Alpha sino que deben tener asignado el mismo tamaño. Por ejemplo, dos campos Alpha con una longitud de 12 caracteres pueden 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. Field value required Posible causa de error Puede haber fallado la asignación de un valor a un campo obligatorio. Por ejemplo, si el primer campo en una tabla es obligatorio, lo siguiente generará este mensaje de error: Table1.InsertRecord([Null, Now, 'Filet Mignon', 'Medium', 'Italian', 'Zinfandel', 'Cheesecake', 'Kenya AA']); No proporcionar valores obligatorios cuando se introducen datos manualmente en tiempo de ejecución produce también este 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écnicas para asegurarse de que toda la información necesaria sea proporcionada. File <> not found Posible causa de error Puede haber introducido el nombre de un archivo no existente en un cuadro de diálogo que pregunta por el nombre de un archivo. 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 Puede ser conveniente utilizar botones de búsqueda, cuando estén disponibles, para hacer posible navegar hasta el archivo que se quiera utilizar. De esta manera solamente se seleccionarán archivos válidos, eliminando la necesidad de adivinación, los nombres mal escritos, etc. File access denied Posible causa de error 1. El archivo al que está intentando acceder puede haber sido configurado como de sólo lectura a través del Explorador de Windows u otro programa. 2. Puede estar intentando abrir para escritura un archivo cuya propiedad FileMode es igual a 0 (sólo lectura). 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 necesario, 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. File extension <> is not valid. Expecting <> Posible causa de error Está intentando utilizar un archivo para algo para lo que (se supone) no está destinado (o la extensión del archivo ha sido modificada inadvertidamente de forma tal que el archivo parece inadecuado para la acción actual). 264 Los Tomos de Delphi: Delphi sin problemas 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. File is Locked. Table: <> User: <> Posible causa de error Puede estar intentando abrir una tabla que otro usuario ha abierto en modo exclusivo. 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 ejecutar 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. File not assigned Posible causa de error Puede haber olvidado llamar a AssignFile antes de llamar a Rewrite, Reset, Append, Rename o Erase. Por ejemplo, lo siguiente generará este mensaje de error: Mensajes de error 265 var tex: TextFile; begin Rewrite(tex); Writeln(tex, 'I think I forgot something'); CloseFile(tex); end; 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. File not found <> Posible causa de error 1. Puede tener una unidad en la sección Uses cuyo nombre no coincide con el de la verdadera unidad, la unidad no existe en su sistema o no puede ser encontrada debido a que no está ubicada en la ruta de búsqueda de Delphi (o a su vez hace referencia a una unidad que cumple lo anterior). 2. Puede estar intentando instalar un componente dentro de un paquete, y una unidad a la que se hace referencia en la unidad del componente no se encuentra en la ruta. Esto puede pasar con una unidad de registro (una unidad que contiene el procedimiento Register para varios componentes que se listan en la cláusula Uses) cuando una de las unidades a la que hace referencia no está en la ruta de búsqueda de Delphi. 3. En Delphi 3, puede estar intentando utilizar un componente TReport (ReportSmith), pero no ha añadido todavía el camino de Report.DCU en la ruta de búsqueda de Delphi. 4. Un archivo de recursos puede estar ausente. 5. Puede estar intentando abrir un archivo de texto que no existe, utilizando el procedimiento Append o Reset. 266 Los Tomos de Delphi: Delphi sin problemas 6. Puede estar intentando instalar un componente utilizando el archivo .DCU en lugar del archivo .PAS. 7. Puede haber incluido un archivo .DPK en la sección Contains de otro archivo .DPK (archivo de paquete). 8. Puede estar intentando utilizar el enlace temprano de controles ActiveX sin importar primero el archivo apropiado en Delphi. 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úsqueda 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, seleccionando 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. c. d. e. 4. 5. 6. 7. 8. Seleccione Data Access de la lista Pages. Navegue hasta localizar el componente TReport. Seleccione el componente TReport. Pulse el botón Add. El componente TReport será añadido a la página Data Access de la Paleta de Componentes. Localice los recursos y muévalos al directorio del proyecto. No utilice el procedimiento Reset sobre archivos que no existan en el momento de la llamada. La utilización de un archivo .DCU para instalar un componente normalmente funciona bien, pero si el archivo .DCU fue compilado utilizando una versión anterior de Delphi, usted necesitará instalarlo utilizando el archivo .PAS. Si ha incluido el nombre de una unidad de paquete (.DPK) en la sección Contains de otro archivo de paquete, elimínelo. 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 ocasionados 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 extensiones: OLB, TLB, OCX, DLL y EXE. File not open Posible causa de error 1. Puede estar intentando ejecutar alguna operación de lectura o de escritura sobre un archivo que no está abierto. Por ejemplo, el siguiente código ocasionará este mensaje de error: var Textilefile: TextFile; begin AssignFile(Textilefile, 'bellbottoms.txt'); Writeln(Textilefile, 'The hippies in the sixties’); CloseFile(Textilefile); end; 2. Puede estar intentando escribir en un archivo que no existe o que existe pero es de sólo lectura. Por ejemplo, utilizar el procedimiento Append para escribir en un archivo que no existe, o intentar escribir en un archivo de texto abierto con el procedimiento Reset generará este mensaje de error. A modo de ejemplo, el siguiente código generará este error cuando intente escribir en un archivo de sólo lectura (debido a que ha sido abierto con el procedimiento Reset): 268 Los Tomos de Delphi: Delphi sin problemas 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; 3. Si ha creado algún procedimiento que directamente intercepta mensajes de Windows (métodos de manejo de mensajes), puede que esté intentando acceder a un archivo de texto dentro de un mensaje de Windows que es despachado antes de que el archivo de texto pueda ser creado (por ejemplo WM_CREATE) o después que el archivo de texto haya sido cerrado (por ejemplo WM_DESTROY). Para ilustrar esto, podríamos redefinir el gestor del mensaje de Windows WM_KEYDOWN declarando un procedimiento utilizando esta sintaxis: procedure wmkeydown(var Message: TMessage); message WM_KEYDOWN; Luego debemos definir el procedimiento en la parte Implementation de la unidad así: procedure TForm1.wmkeydown(var Message: TMessage); begin inherited; { para ejecutar la funcionalidad predefinida } {Cualquier cosa que queramos hacer cuando el mensaje WM_KEYDOWN sea despachado} end; Por ejemplo, para seguir la pista a los eventos que se están produciendo, podríamos hacer algo así: Writeln(tf, ‘Enviado mensaje KeyDown’); end; Intentar escribir en un archivo de texto durante ciertos eventos (como WM_CREATE y WM_DESTROY, entre otros) produciría este mensaje de error. 4. Puede haber intentado escribir una línea en blanco en un archivo de texto del sistema que ha sido asignado a la impresora. Por ejemplo, lo siguiente generará este error: procedure TBadIdea.SetTheStage; begin Screen.Cursor := crHourglass; AssignPrn(PrintText); Rewrite(PrintText); Printer.Canvas.Font.Name := 'Arial'; Mensajes de error 269 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á suficiente para añadir una línea en blanco. File not open for input Posible causa de error 1. Puede estar intentando leer de un archivo de texto que no ha sido abierto para lectura. Por ejemplo, el siguiente código generará este error, ya que el procedimiento Reset no ha sido llamado: var cookie: TextFile; s : String; i : Integer; begin i:=0; AssignFile(cookie,'history.txt'); try while not eof(cookie) do begin readln(cookie, s); cbxSitesVisited.items[i]:= s; inc(i); end; finally CloseFile(cookie); end; end; 2. Puede haber utilizado una sentencia Read o Readln sin proporcionar el nombre de la variable del archivo de texto para leer. Por ejemplo, lo siguiente generará este mensaje de error: Mensajes de error 271 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. File not open for output Posible causa de error 1. Puede estar utilizando Delphi 1 y el procedimiento Writeln sin haber añadido la unidad WinCRT a la cláusula Uses. 2. Puede estar intentando escribir en un archivo de texto que ha sido abierto con el procedimiento Reset. 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. File or directory does not exist Posible causa de error Puede haber especificado una tabla que no existe en una sentencia SQL. Por ejemplo, con la propiedad DatabaseName de un TQuery asignada a DBDEMOS, la siguiente sentencia SQL generará este mensaje de error: SELECT * FROM ANIMULES 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 solucionado 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 Paradox, luego dBASE y por último un archivo ASCII (texto). File type not allowed here Posible causa de error 1. Puede haber intentado declarar una variable de tipo File of File, File of Text, o File of TextFile. 2. Puede haber intentado pasar un tipo de archivo como parámetro por valor. Por ejemplo, lo siguiente generará este error: procedure LegoMania(Technik: file); Mensajes de error 273 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 información, consulte “parameters” en la ayuda de Delphi. Por defecto, los parámetros son pasados por valor. Fixed column count must be less than column count Posible causa de error Puede haber asignado a la propiedad FixedCols de un control TStringGrid o TDrawGrid un número mayor que la cantidad de columnas de la rejilla. 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 ejemplo, 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 Fixed row count must be less than row count Posible causa de error Puede haber asignado a la propiedad FixedRows de un control TStringGrid o TDrawGrid un número mayor que la cantidad de filas de la rejilla. 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. For Loop control variable must be simple local variable Posible causa de error Puede haber utilizado un campo de un registro o de una clase como variable de control en un bucle For. Por ejemplo, lo siguiente generará este mensaje de error: type TDateRec = record Year: Integer; Month: 1..12; Day: 1..31; end; Mensajes de error 275 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. For Loop control variable must have ordinal type Posible causa de error Puede haber intentado utilizar como variable de control de un bucle For una variable de un tipo de datos que no es un tipo ordinal (Boolean, Char, WideChar, Integer, enumeración, subrango). Por ejemplo, lo siguiente generará este mensaje de error: var flcv, WinnieThePooh: String; begin WinnieThePooh := ''; for flcv := 'a' to 'z' do WinnieThePooh := WinnieThePooh+flcv; 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. For-Loop variable <> cannot be passed as var parameter Posible causa de error Puede haber intentado pasar una variable de control de un bucle For a un procedimiento o función como parámetro Var (por referencia). Por ejemplo, lo siguiente generará este mensaje de error: procedure FruitLoops; const CaliforniaCounties = 58; var i : Integer; // procedure ColoredMarshmallows(var LuckyStars: Integer); begin . . . end; begin for i := 1 to CaliforniaCounties do ColoredMarshmallows(i); end; 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); o utilice un bucle While en lugar de un bucle For: while i <= CaliforniaCounties do ColoredMarshmallows (i); Mensajes de error 277 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 formulario 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 primer formulario (TDatabase, TTable, TQuery, TStoredProc, TDataSource, etc.). 2. Puede haber intentado guardar un formulario que está enlazado a un formulario 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/redirect 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?” Format “<>” invalid or incompatible with argument Posible causa de error Puede haber utilizado una opción de formato que no está en correspondencia con su argumento correspondiente. Por ejemplo, lo siguiente generará este mensaje de error: Add(Format('ThouSeparator = %c', [SysUtils.ThousandSeparator])); 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. Function needs result type Posible causa de error Puede haber omitido el tipo del resultado (o los dos puntos entre el nombre de la función y el tipo del resultado) en una declaración de función. Por ejemplo, lo siguiente generará este mensaje de error: function junction(s: string); 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 normalmente 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). General SQL Error—connection does not exist Posible causa de error Puede estar intentando ejecutar un operación de base de datos en un hilo al que no ha asignado un componente TSession. 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”. General SQL Error—FROM keyword not found where expected Posible causa de error Puede haber olvidado añadir una o más comas como separadores entre los nombres de campos en una lista SELECT. Por ejemplo, lo siguiente generará este mensaje de error: SELECT First, Second, Third Fourth FROM ORDINALS 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”. General SQL Error: Missing Left Parenthesis Posible causa de error Puede haber olvidado incluir entre paréntesis los campos a los que se asignarán los valores o el grupo de valores que serán insertados. Por ejemplo, lo siguiente generará este mensaje de error: 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'); . . . 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). General SQL Error: SQL Command not properly ended Posible causa de error Puede haber olvidado borrar el contenido de la propiedad SQL antes de añadirle una sentencia SQL, y como consecuencia se han mezclado varias sentencias, resultando en algo que no puede ser interpretado correctamente en la próxima ejecución de la sentencia SQL. Por ejemplo, la siguiente sentencia SQL: SQL.Add('Select * from FortKnox'); funcionará bien la primera vez, pero la segunda vez será doble: 'Select * from FortKnoxSelect * from FortKnox' Mensajes de error 281 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. General SQL Error: SQL is too complex Consulte “SQL is too complex”. General SQL error. The [Commit,Rollback] Transaction request has no corresponding begin transaction Posible causa de error 1. Puede estar llamando a Commit o Rollback, pero no ha iniciado explícitamente una transacción mediante una llamada a StartTransaction. Por ejemplo, podría estar haciendo esto: begin with Database1 do begin Connected := True; try Query1.Active := True; Commit; except Rollback; end; end; end; 2. Puede estar trabajando con MS SQL Server y estar experimentando un interbloqueo (deadlock). 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. GOTO <> leads into or out of TRY statement Posible causa de error Puede tener una sentencia GoTo que está contenida o salta dentro de un bloque de código protegido (un bloque Try. . . Finally o Try. . . Except). 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. Grid Index Out of Range Posible causa de error 1. Puede estar iterando a través de un conjunto de datos y está alcanzando el final del archivo (EOF) mientras está mostrando el conjunto de datos en un control TDBGrid. Mensajes de error 283 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é iterando 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 ejemplo, 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. GROUP BY is required when both aggregate and non-aggregate fields are used in result set Posible causa de error Puede estar intentando utilizar una o más funciones de agregación en una sentencia SQL, pero ha olvidado añadir una sección GROUP BY. Por ejemplo, lo siguiente generará este mensaje de error: SELECT DIM, SUM(TSINGTAO) 284 Los Tomos de Delphi: Delphi sin problemas 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 ejemplo, 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). Heap Overflow Error Posible causa de error Este error es informado por New o GetMem cuando no hay suficiente espacio disponible en el heap para reservar un bloque del tamaño requerido. 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. High cannot be applied to a long string Posible causa de error Puede estar portando de Delphi 1 a Delphi de 32 bits una aplicación que utiliza la función High sobre una cadena. Por ejemplo, lo siguiente generará este mensaje de error en Delphi de 32 bits: var i: integer; s: string; begin Mensajes de error 285 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 longitud 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; Alternativamente, si quiere dejar su código como está, puede desactivar la utilización de cadenas largas como tipo de cadenas por defecto en Delphi de 32 bits seleccionando Project | Options | Compiler | Syntax Options, y desmarcando la casilla de verificación Huge Strings. Otra manera de hacer lo mismo es incluyendo la directiva de compilador {$H-} en la parte superior de la unidad. Información adicional Para más información, consulte “open string parameters” y “High function” en la ayuda de Delphi. Higher table level required Posible causa de error Está intentando añadir o utilizar alguna funcionalidad disponible solamente con tablas Paradox de nivel superior. Una o más de las siguientes posibilidades siguientes puede cumplirse: 1. Puede haber intentado añadir un índice único en el código a una tabla Paradox de nivel inferior a 7. Por ejemplo, la siguiente línea produce este mensaje de error con una tabla Paradox de nivel 4 ó 5: Table1.AddIndex('NewIndex','Name_Last',[ixUnique]); 2. Puede haber intentado añadir un índice descendiente en el código a una tabla Paradox de nivel inferior a 7. Por ejemplo, la siguiente línea produce este mensaje de error con una tabla Paradox de nivel 4 ó 5: Table1.AddIndex('Wf','Waterfall',[ixDescending]); 3. Puede estar haciendo referencia a una tabla Paradox cuya ruta contiene nombres de archivo largos. 286 Los Tomos de Delphi: Delphi sin problemas 4. Puede estar intentando añadir un campo Long Integer, BCD, Time, Timestamp, Logical, Autoincrement o Bytes a una tabla Paradox de nivel inferior a 7. Estos tipos de datos son nuevos para Paradox 7. Por ejemplo, si es una tabla anterior al nivel 7, lo siguiente generará este mensaje de error: FieldDefs.Add('OttoInque', ftAutoInc, 0, True); 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 reestructurar 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. f. Seleccione Paradox o dBASE, según sea apropiado. 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 descendentes 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 l. Pulse el botón Save en la ventana Restructure. m. Seleccione File | Close. Ahora podrá activar el índice que agregó en el código: Table1.Exclusive := True; Table1.IndexName := 'Sub7Index'; También podrá crear nuevos índices en el código a la tabla de Paradox 7: Table1.Exclusive := True; Table1.AddIndex('Paradox7Index', 'City', [ixUnique]); 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,[]); Los índices que asigne en código de esta manera son persistentes. I/O Error 102 Consulte “File not assigned”. I/O Error 103 Consulte “File not open”. I/O Error 104 Consulte “File not open for input”. I/O Error 105 Consulte “File not open for output”. Mensajes de error 289 I/O error found for file “<Current directory>\Database.GDB”. Error while trying to open file. The system cannot find the file specified. Posible causa de error Puede haber intentado seleccionar un valor para la propiedad TableName de un componente TSQLTable de DBExpress sin primero asignar un valor válido a la propiedad Params del componente TSQLConnection relacionado. Solución rápida Asigne el nombre de la base de datos a la que se desea conectar en la propiedad Params.Database de TSQLConnection. Información adicional DBExpress apareció por primera vez en Delphi 6. Identifier expected but <> found Posible causa de error 1. Puede haber codificado una sección Type, Var o Const sin declarar nada en ella. 2. Puede haber intentado utilizar una palabra reservada como identificador. 3. Puede haber antepuesto el operador de ámbito ‘punto’ (.) al nombre de una propiedad de tipo array (antes de los corchetes). Por ejemplo: Label1.Caption := ListBox1.Items.[0]; 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, constantes, 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 Identifier expected but array found Posible causa de error Puede haber declarado un array como valor de retorno de una función. Por ejemplo, lo siguiente generará este mensaje de error: function Three41(i: integer): array[0..3] of char; 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 problema 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. Identifier expected but number found Posible causa de error Puede haber utilizado un paréntesis mientras intentaba declarar un tipo subrango. Por ejemplo, lo siguiente generará este mensaje de error: type TSillySubrange = (4 * 8)..255; 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 aceptable para el compilador: Mensajes de error 291 type TSeriousSubrange = 32..255; type TSuaveSubrange = 32..((32 * 8) -1); Identifier redeclared: <> Posible causa de error 1. Puede estar intentando utilizar un nombre que ya está siendo utilizado en el mismo ámbito. Puede ser una variable, constante, tipo, campo (miembro de una clase), método, o una unidad redundante en una sección Uses. Por ejemplo, lo siguiente generará este mensaje de error, debido a que la variable Thirty está declarada dos veces: function BrickHouse(Thirty, Ten, Thirty: integer): integer; 2. Puede haber añadido la unidad System dentro de la sección Uses de una unidad. En este caso, el mensaje de error será “Identifier redeclared: System”. 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). Illegal character in input file: <> (<>) Posible causa de error 1. Puede haber iniciado una declaración con uno de los símbolos &, /, \, tilde, etc. Por ejemplo, lo siguiente generará este mensaje de error: type Proto = & 292 Los Tomos de Delphi: Delphi sin problemas 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 constantes de cadena y los comentarios. Illegal message method index Posible causa de error Puede haber declarado un método de mensaje con un valor menor que 1. Por ejemplo, lo siguiente generará este mensaje de error: procedure WMChar(var Message: TWMChar); message -34; 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 correspondiente, 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; o por su valor decimal: procedure WMChar(var Message: TWMChar); message 34; Para más información, consulte “message handlers” en la ayuda de Delphi y la unidad MESSAGES.PAS. Mensajes de error 293 Illegal type in OLE automation section: <> Posible causa de error Puede haber añadido algo a la sección Automated de una clase que contiene un tipo que no está permitido en una sección Automated. Por ejemplo, el siguiente código genera este mensaje de error: automated procedure WMVScrollClipboard(var Message: TMessage); message WM_VSCROLLCLIPBOARD; Solución rápida Utilice solamente tipos válidos para la sección Automated. Consulte “automatable 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. Illegal type in Read/Readln statement Posible causa de error Este error ocurre cuando se intenta escribir una variable de un tipo que no es válido en una llamada a Read o Readln. Por ejemplo, lo siguiente generará este mensaje de error: var f: TextFile; sl: TStrings; begin sl := TStringList.Create; try AssignFile(f, 'gonzo'); Reset(f); Readln(f, sl); 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 for i := 0 to Pred(sl.Count) do begin s := sl[i]; Readln(f,s); end; Illegal type in Write/Writeln statement Posible causa de error Este error ocurre cuando trata imprimir una variable de un tipo que no es válido en una llamada a Write o Writeln. Por ejemplo, este código generará este mensaje de error: var f: TextFile; sl: TStrings; begin sl := TStringList.Create; try AssignFile(f, 'FisherLGattling'); Reset(f); Writeln(f, sl); 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. IMPLEMENTATION part is missing or incorrect Posible causa de error Puede haber alterado, borrado o puesto entre comentarios la palabra reservada Implementation de la unidad. 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. Implementation part USES clause incorrect Posible causa de error Puede tener un error de sintaxis en la cláusula Uses de la parte Implementation. Solución rápida Verifique que hay una coma entre todas las unidades a las que se hace referencia 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) . . . Puede también tener una cláusula Uses en la sección Implementation de la unidad: . . . implementation uses EdArabEm; {$R *.DFM} . . . Implements clause only allowed for properties of class or interface type Posible causa de error Puede haber utilizado un tipo que no es una clase o una interfaz en la cláusula Implements. Por ejemplo, lo siguiente generará este mensaje de error: 296 Los Tomos de Delphi: Delphi sin problemas 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. Implements clause only allowed for readable property Posible causa de error Puede haber utilizado una propiedad que es de sólo escritura en una cláusula Implements. Por ejemplo, lo siguiente generará este mensaje de error: TItalianStallion = class(TInterfacedObject, IOfTheTiger) FRockyRead: IOfTheTiger; property MyInterface: IOfTheTiger implements IOfTheTiger; end; 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 Implements clause only allowed within class types Posible causa de error Puede haber utilizado la cláusula Implements en una declaración de interfaz. Por ejemplo, lo siguiente generará este mensaje de error: type IMPei = interface function Accessor: IMPei; property IMPei: IMPei read Accessor implements IWhatFlavor; end; 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 implementació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. Implements getter must be register calling convention Posible causa de error Puede haber especificado un convenio de llamada distinto del convenio por defecto Register para el método de acceso (getter) de una propiedad de interfaz delegada. Por ejemplo, lo siguiente generará este mensaje de error: type ISomeInterface = interface procedure RollOver; function FetchMySlippers: Boolean; end; TSomeClass = class(TObject, ISomeInterface) FSomeInterface: ISomeInterface; function ReadItAndWeep: ISomeInterface; stdcall; property SomeInterface: ISomeInterface read ReadItAndWeep implements ISomeInterface; end; 298 Los Tomos de Delphi: Delphi sin problemas 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. Improper GUID syntax Posible causa de error Puede haber modificado el formato de un GUID añadiéndole o borrándole caracteres o reorganizando sus grupos. 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ígitos o caracteres). Incompatible Record Structures Posible causa de error Puede haber utilizado un componente TBatchMove para mover los registros de un conjunto de datos a una tabla, pero los campos del conjunto de datos fuente no coinciden con los campos de la tabla de destino, o puede incluso que las tablas sean de tipos diferentes (por ejemplo, una tabla es de dBASE y la otra de Paradox). Solución rápida Compruebe que el conjunto de datos fuente y la tabla de destino tengan estructuras compatibles. Información adicional Los conjuntos fuente y destino no tienen que coincidir exactamente. Por ejemplo, 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 llamaría a Inherited, así: procedure DoPopup(Sender: TObject); override; . . . procedure TForTheTillermanPopupMenu.DoPopup(Sender:TObject); begin inherited; . . . Se puede sobrecargar un método añadiendo la directiva Overload a la declaración del método, lo cual le permite tener múltiples métodos con un mismo nombre (pero diferentes signaturas). Por ejemplo: procedure GetAWife(Bait: Currency); overload; procedure GetAWife(Bait: String); overload; procedure GetAWife(Bait: TDateTime); overload; Incompatible types: <> and <> Posible causa de error 1. Puede estar intentando asignar a una propiedad o variable de un tipo un valor de un tipo incompatible. Por ejemplo, podría estar intentando asignar una cadena a una variable entera o un mapa de bits a una variable de tipo Boolean. 2. Puede estar intentando asignar un descendiente de TField (como TStringField, TFloatField, etc., que Delphi crea cuando se crean los campos persistentes de un conjunto de datos) a una variable de un tipo de datos diferente. No se puede (directamente) asignar un TStringField a una variable de tipo String. A modo de ilustración, ninguna de las siguientes asignaciones es permitida (aquí Capital es un TStringField y Area es un 300 Los Tomos de Delphi: Delphi sin problemas TFloatField. Ambos pertenecen a la tabla Country de Paradox que viene con Delphi): {Esto generará "Incompatible types: String and TStringField"} StringGrid1.Cells[0,0] := Table1Capital; {Esto generará "Incompatible types: Extended and TFloatField"} StringGrid1.Cells[0,0] := FloatToStr(Table1Area); 3. Puede estar pasando a un procedimiento o función un valor que no es compatible con el parámetro declarado en el procedimiento o función. Por ejemplo, lo siguiente generará este mensaje de error: procedure TypeConfusion(i: integer); . . . procedure SendString; var s: string; begin TypeConfusion(s); {¡pase un entero, no un string!} 4. Puede haber declarado que una función devuelve un tipo de resultado y estar intentando devolver un resultado de un tipo de datos diferente. Por ejemplo, lo siguiente generará este mensaje de error: function mpd(var i: integer): boolean; begin i := i+1; Result := IntToStr(i); {¡El resultado debe ser boolean!} end; 5. Puede haber utilizado un operador que produce un resultado de un tipo de datos que no es adecuado en un contexto dado. Por ejemplo, lo siguiente generará este mensaje de error, ya que el operador / produce un número real (punto flotante), no un entero: i := 3 / 2; 6. Puede haber intentado asignar un control gráfico (un descendiente de TGraphicControl) a una propiedad que requiere un control de ventana (un control que tiene un manejador de ventana y puede recibir el foco; un descendiente de TWinControl). Por ejemplo, lo siguiente producirá este error (”Incompatible types: TWinControl and TLabel”): ActiveControl := Label1; 7. Puede ser también que una cláusula Write o Read de una propiedad haga referencia a un campo o método cuyo tipo difiere del de la propiedad. Por ejemplo, lo siguiente generará el mensaje de error “Incompatible Types”, ya que para escribir el valor de una propiedad Boolean se ha intentado utilizar un procedimiento que recibe una cadena: private FEmUpJoe: boolean; procedure SetEmUpJoe(s: string); public { Declaraciones públicas } Mensajes de error 301 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 mensaje 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 conjunto 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 dependencia 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 asignació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 procedimiento 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 resultado 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 procedure TForm1.Button2Click(Sender: TObject); begin Button1.OnClick := HandCodedMethod; end; 10. Asigne el valor de tipo enumerado al conjunto dentro de corchetes, así: case radgrpSalesReps.ItemIndex of 0: FrozenCustardObj.Flavors := [fcfHeath]; 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 campos 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: Tipo de datos Paradox Descendiente TField de Delphi Alpha TStringField Autoincrement TAutoIncField BCD TBCDField Binary TBlobField Byte TBytesField Date TDateField Formatted Memo TBlobField Graphic TGraphicField Logical TBooleanField 304 Los Tomos de Delphi: Delphi sin problemas Long Integer TIntegerField Memo TMemoField Money TCurrencyField Number TFloatField OLE TBlobField Short TSmallIntField Time TTimeField Timestamp TDateTimeField 9. El mensaje de error específico en este caso será “Incompatible types: method pointer and regular procedure”. 10. Otra manera de llevar a cabo esto sería: TFrozenCustardFlavors = (fcfHeath, fcfSnickers, fcfCaramel); Si opta por hacerlo de esta manera, no obtendría este mensaje de error. En otra palabras, está asignación compilaría: case radgrpFrozenCustard.ItemIndex of 0: FrozenCustardObj.Flavors := fcfHeath; 1: FrozenCustardObj.Flavors := fcfSnickers; 2: FrozenCustardObj.Flavors := fcfCaramel; else ; //Añada aquí código de protección contra errores end; Incompatible types: Parameter lists differ Posible causa de error 1. Puede haber asignado una función a un tipo función (o un procedimiento a un tipo procedimiento) y sus signaturas no son iguales. Por ejemplo, lo siguiente generará este mensaje de error: procedure Cream(Clapton, Bruce, Baker: integer); type TYearsAfter = procedure(Lee, Alvin: integer); const DesertRoseBand: TYearsAfter = Cream; 2. Puede haber asignado a un gestor de eventos de un componente un método personalizado que no tiene una signatura idéntica. Por ejemplo, podría haber hecho algo así: TCombobox(Components[I]).OnKeyPress := LowerCase; donde el método personalizado LowerCase está declarado así: Mensajes de error 305 procedure LowerCase; Solución rápida 1. Para asignar una función o procedimiento a un tipo función o procedimiento, 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. Incorrect field declaration: class <> Posible causa de error Puede haber modificado la declaración de la clase de un campo por un identificador de Pascal inválido. Por ejemplo, en una unidad que originalmente contenía: type TForm1 = class(TForm) Button1: TButton; puede haber modificado la declaración de la clase (la parte correspondiente a TButton) de tal forma que ha quedado algo como: type TForm1 = class(TForm) Button1: TZip^per; 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 declared as <>. Correct the declaration?” Consulte la entrada correspondiente a este mensaje de error para más información. Incorrect method declaration in class <> Posible causa de error Puede haber añadido una directiva de almacenamiento a un método. Por ejemplo, lo siguiente generará este mensaje de error: procedure Button607Click(Sender: TObject); stored; 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 almacenamiento 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áticamente, 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. Incorrect syntax near ':' Posible causa de error Puede haber intentado ejecutar una consulta parametrizada en SQL Explorer. Por ejemplo, puede tener una consulta de estructura similar a esta: select SCRIPT_ID, SCRIPT_DESC, BUILD_NO, SCRIPT_TYPE from SCRIPTMAIN Mensajes de error 307 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. Index already exists Posible causa de error Puede estar intentando añadir en el código un índice a una tabla que ya tiene un índice con ese nombre. Solución rápida Compruebe que el índice que desea crear no exista. Por ejemplo, podría proceder 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 Database 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 INDEX clause not allowed in OLE automation section Posible causa de error Puede haber utilizado la cláusula Index en una sección Automated. 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. Index does not exist Posible causa de error 1. Puede haber intentado activar un índice (en tiempo de diseño, editando la propiedad IndexName de un objeto TTable, o en tiempo de ejecución mediante código) que no ha sido creado para la tabla. Por ejemplo, el siguiente código: Table1.IndexName := 'CustomerCredit'; provocará este mensaje de error si no se ha definido un índice de nombre CustomerCredit para la tabla. 2. Puede haber cambiado la propiedad TableName de un componente TTable, y la propiedad IndexName todavía se refiere a un índice de la tabla anterior. 3. Puede estar utilizando una tabla de Oracle y se ha olvidado de anteponer el nombre de la tabla a la propiedad IndexName del componente TQuery. Por ejemplo, podría haber proporcionado el valor siguiente: Molehill Solución rápida 1. Cree el índice antes de intentar activarlo. Puede llevar a cabo esto utilizando 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 3. Puede necesitar especificar un nombre completamente cualificado para el índice en la propiedad IndexName del componente TQuery. Por ejemplo, si tiene una tabla denominada Mountain y un índice llamado Molehill, asigne a la propiedad el valor: Mountain.Molehill Información adicional El código que ocasiona este error compilará, debido a que hasta donde el compilador 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. Index is out of date Posible causa de error Probablemente tendrá una inconsistencia entre una tabla de Paradox (.DB) y uno de sus archivos de índice. Uno o más archivos de índice están dañado o fuera de sincronización con su correspondiente tabla. Un usuario puede haber cerrado la aplicación inapropiamente o haber experimentado una caída del sistema con el programa activo. El archivo de índice primario de una tabla Paradox tiene el nombre del archivo y una extensión .PX . Los archivos de índice secundarios tienen el mismo nombre de la tabla, seguido por la extensión .Xnn y .Ynn (donde nn es un número hexadecimal). Esto puede haber ocurrido debido a una de las siguientes razones: 1. Modificó la tabla (añadió o editó registros) mientra la tabla en sí (*.DB) estaba situada en un directorio diferente que los archivos de índice. 2. Modificó el contenido de la tabla utilizando otra aplicación. 3. Su sistema se cayó mientras estaba añadiendo o editando un registro. 4. Puede haber accedido a tablas de Paradox sobre una red desde una máquina cliente que ejecuta Windows 95 y tiene una versión del archivo VREDIR.VXD (Virtual Network Redirector) de Microsoft entre 4.00.1111 y 4.00.1114. 5. Puede haber intentado editar o insertar un registro en una tabla cuyo índice no es mantenido automáticamente. 6. Puede estar experimentando problemas de red. 7. Puede estar utilizando Windows NT y bloqueos oportunistas. 310 Los Tomos de Delphi: Delphi sin problemas 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 directorio 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. b. c. d. Seleccione Tools | BDE Administrator. Seleccione la pestaña Configuration. Expanda el nodo Drivers en la vista de árbol. 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 actualizada del archivo desde el sitio web de Microsoft. 5. Si va a editar o insertar registros en una tabla, no utilice índices no mantenidos. 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 c. Seleccione Tools | Utilities | Restructure (o pulse sobre el icono Restructure). d. Seleccione Secondary Indexes en la lista desplegable Properties de la tabla. e. Pulse el botón Define. Aparecerá el cuadro de diálogo Define Secondary Index. f. Seleccione el índice que se desea convertir en mantenido. g. Marque la casilla de verificación Maintained en la sección Index Options del diálogo. h. Seleccione OK para grabar las modificaciones. 6. Consulte a su administrador de red. 7. Necesita editar (o crear, si es necesario) dos entradas del Registro del sistema siguiendo estos pasos: a. Seleccione Inicio | Ejecutar en el escritorio. b. Introduzca regedit en el cuadro de combinación Abrir y pulse el botón Aceptar. c. Navegue hasta HKEY_LOCAL_MACHINE\System\ CurrentControlSet\Services\LanmanServer\Parameters. d. Edite o añada la clave EnableOplock y asígnele el valor 0. e. Edite o añada la clave UseOpportunisticLocking y asígnele el valor 0. f. Reinicie el sistema para que la configuración surta efecto. 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) contienen información de un índice secundario. <NombreTabla>.Ynn 312 Los Tomos de Delphi: Delphi sin problemas Los archivos con extensión .Ynn (donde nn es un número hexadecimal) contienen información de un índice secundario. 5. Los índices no-mantenidos están obsoletos— son una reminescencia de Paradox 1.0 para DOS. Para más información, consulte http://www.borland.com/devsupport/bde/ti_list/ TI3342.html. Index is out of range Posible causa de error Puede haber utilizado un elemento de un TListBox cuya propiedad MultiSelect tiene el valor False. Por ejemplo, lo siguiente generará este mensaje de error: ListBox1.Items.Add('Peter, Bugs, and Roger'); ListBox1.Selected[0] := True; 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ñadida al cuadro de lista, a menos que llame a Application.ProcessMessages. Index is read only Posible causa de error Puede estar intentando editar una tabla que tiene uno o mas índices secundarios, pero esos índices secundarios son no-mantenidos. 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 e. f. 313 Pulse el botón Define. Aparecerá el cuadro de diálogo Define Secondary Index. Seleccione el índice que se desea convertir en mantenido. g. Marque la casilla de verificación Maintained en la sección Index Options del diálogo. h. Seleccione OK para grabar las modificaciones. 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. Index not found Posible causa de error Puede estar intentando abrir una tabla dBASE, y su archivo de índices de producción (.MDX) no está presente. 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). Index or Primary Key cannot contain a Null value Posible causa de error Puede estar grabando un registro en una tabla, pero ha olvidado proporcionar un valor para la clave primaria, una columna indizada, o una de las columnas de una clave primaria compuesta. Solución rápida Asigne valores a todos los campos de la clave primaria y a los campos indizados 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. INDEX, READ, OR WRITE clause expected but ‘;’ found Posible causa de error Puede estar intentando declarar una propiedad, pero ha omitido los métodos de escritura y lectura (o la palabra reservada opcional Index). 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; La sintaxis correcta cuando se utiliza la directiva Index es: property Zeitgeist: Longint index 0 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. INSERT and UPDATE operations are not supported on autoincrement field type Posible causa de error Puede estar intentando asignar un valor a un campo de tipo Autoincrement utilizando las operaciones Insert o Update de SQL. Por ejemplo, puede haber tratado de hacer algo así: update "MACABRE.DB" set OttoIncrease = :SomeNum, DrOctopus = :Villain, EightHead = :DistinguishingFeature where Name = :OLD_Name Mensajes de error 315 -Oinsert 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 siempre 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. Installation error –113 Posible causa de error Puede estar intentando instalar Delphi sobre un ordenador que tiene instalado un controlador de CD-ROM de 16 bits. Solución rápida Contacte con el vendedor o el fabricante del ordenador para obtener un controlador 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 Instance variable <> inaccessible here Posible causa de error 1. Puede estar intentando hacer referencia a una variable de instancia desde un procedimiento de clase. 2. Puede haber intentado hacer referencia a una clase miembro de un formulario (por ejemplo, un componente) en un método de clase sin anteponer el nombre de la variable del formulario al componente. Por ejemplo, lo siguiente generaría este mensaje de error: if Mode = psSingle then begin frmSingle.Caption := SEnterOrdNum; GroupBox1.Caption := SPrintSingleInvoice //aquí! end; Solución rápida 1. Evite hacer referencia a variables de instancia en el método de clase, o convierta el método de clase en un método normal. 2. Anteponga el nombre de la variable del formulario al nombre del componente, 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; Consulte “Property <> inaccessible here” en este libro. Insufficient disk space Posible causa de error 1. Puede no tener suficiente espacio en el disco duro para que Delphi cree archivos. Mensajes de error 317 2. Puede estar utilizando el BDE en una red punto-a-punto sin asignar el valor True al parámetro Local Share del BDE. 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. Insufficient memory for this operation Posible causa de error Puede haber ejecutado varias operaciones de consulta, especialmente con la propiedad RequestLive asignada a True, pero puede haber olvidado liberar la memoria que éstas requieren llamando al método Unprepare. 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 {Lo que haya que hacer} finally Unprepare; end; end; 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 cuadriplicarlo, 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 (especialmente 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”. Insufficient SQL rights for operation Posible causa de error Puede estar intentando ejecutar una acción sobre una tabla que reside en un servidor SQL para la cual no han sido otorgados los correspondientes derechos. Por ejemplo, puede estar intentando editar un registro de una tabla para la que solamente tiene permiso de lectura (no de escritura). Solución rápida Consulte al administrador del servidor SQL para obtener los derechos necesarios. 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 Insufficient table rights for operation Posible causa de error Puede estar intentando asignar True a la propiedad Active de una tabla con protección de contraseña, sin primero haber proporcionado la contraseña. Solución rápida Proporcione la contraseña antes de intentar asignar el valor True a la propiedad 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 información no será legible. Por ejemplo, si antes de proteger con contraseña o encriptar una tabla, puede abrirla y ver la información que contiene en este formato: DE White QB Favre después de encriptarla, la misma información aparecerá de esta manera: __(c_.jy*+8f_VG|_L::5!Ya_R2M_9=,]x_&k*-_$A__S<cT@`c~ Para evitar que el cuadro de diálogo de solicitud de contraseña aparezca en tiempo de ejecución, puede proporcionar la contraseña mediante código (por supuesto, alguien con acceso a su código fuente podrá ver la contraseña, pero puede hacer esto durante el desarrollo para ahorrar tiempo, y luego borrar el código antes de distribuir). Puede proporcionar la contraseña mediante código así: Session.AddPassword('Kennwort58'); Table1.Active := True; 320 Los Tomos de Delphi: Delphi sin problemas Integer constant too large Posible causa de error 1. Puede haber especificado una constante entera que requiere más de 32 bits para ser representada (en otras palabras, un número mayor que 2.147.483.647) en Delphi 1, 2 ó 3. Por ejemplo, lo siguiente generará este error: procedure OnKeyPress(var Key: Smallint); dispid 2147483648; De manera similar, lo siguiente también ocasionará este error en una .DLL (unidad de biblioteca): procedure JerryJeffWalker; begin { Whatever } end; exports JerryJeffWalker index 2800000000; 2. Puede haber asignado un valor entero a un tipo de datos real o de punto flotante (Double, Extended, Comp, etc.) Por ejemplo, lo siguiente generará este error: var r: double; . . . r := 2222222222; 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 InterBase install DLL ibinstall.dll not found in path. Please install InterBase 6 to use this functionality. Posible causa de error Puede haber intentado soltar sobre un formulario un componente TIBInstall o TIBUninstall, de la etiqueta InterBase Admin de la Paleta de Componentes, y no tiene InterBase 6 instalado o necesita mover IBINSTALL.DLL a un lugar donde Delphi puede encontrarlo. 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). Interface <> already implemented by <> Posible causa de error Puede haber intentado implementar la misma interfaz más de una vez. Por ejemplo, lo siguiente generará este mensaje de error: TPassiveClass = class(TInterfacedObject, IWatched, IWaited, IPined, IWatched) . . . 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) . . . Y luego implementar las funciones y procedimientos miembros de la interfaz IWalk de manera diferente en cada clase. 322 Los Tomos de Delphi: Delphi sin problemas Interface <> has no interface identification Posible causa de error Ha intentado asignar una interfaz a un tipo GUID, pero la interfaz no fue definida con un GUID. Por ejemplo, lo siguiente generará este mensaje de error: IPotato = interface(IUnknown) function IdahoSpud(Chips: BOOL): HResult; stdcall; function WisconsinWhite(Chips: BOOL): HResult; stdcall; function MaineRusset(Chips: BOOL): HResult; stdcall; end; procedure TForm1.Button1Click(Sender: TObject); var sguid: TGUID; begin sguid := IPotato; 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. Interface <> not mentioned in interface list Posible causa de error Puede haber intentado implementar una interfaz en una clase que no tiene especificado a través de su signatura que implementará la interfaz en cuestión. Por ejemplo, lo siguiente generará este mensaje de error: TOopsadaisacal = class(TInterfacedObject, IMPei) function Accessor: IMPei; property Oopsy: IMPei read Accessor implements IMCake; end; 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. Interface mismatch. Engine version different Posible causa de error Puede estar intentando ejecutar un programa de base de datos creado con una versión de Delphi (y por lo tanto, del BDE) más reciente que la versión instalada en el sistema en el que se está produciendo este mensaje de error. Solución rápida Cuando distribuya una aplicación de base de datos de Delphi, incluya la versió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. Interface type required Posible causa de error Puede haber utilizado dos tipos de clase en la declaración de un tipo de clase ActiveForm, así: TActiveFormX = class(TActiveForm, TActiveForm) 324 Los Tomos de Delphi: Delphi sin problemas 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). Internal error: <> Posible causa de error Estos tipos de errores son extremadamente raros en Delphi. Son normalmente ocasionados por errores en la programación del compilador mismo. 1. Si el código de error es L1317, es específico de Delphi 3. Este error puede estar relacionado con las características de Code Insight de Delphi 3. 2. Si el código de error es URW337 con Delphi 2 o L1086 con Delphi 3, puede obtenerlo mientras compila. Si intenta compilar de nuevo, podrá recibir el mensaje “Fatal Error: Unit SysUtils was compiled with a different version of System”. 3. Si el código de error es C3254, es aparentemente específico de Delphi 2. Puede haber hecho una asignación a una variable Result implícita en el código Asm. 4. Si el código de error es L721, esto es aparentemente específico de Delphi 5. 5. Si el código de error es R938, puede estar generando archivos .MAP detallados. 6. Puede haber cambiado el código de un paquete, y luego haber ejecutado un programa que utiliza el paquete sin primero recompilarlo. Solución rápida 1. Haga una construcción completa (Project | Build All) en vez de una simple 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 problema, 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 5. Elimine la opción de obtener archivos .MAP detallados, desmarcando la casilla Project | Options | Linker | Map File | Detailed. La opción de línea de comandos correspondiente es -GD. 6. Recompile el paquete, después de hacer los cambios a cualquier unidad que contenga. 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 codificación estándar. Es usualmente el código “extraño” el que provoca esos mensajes 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 determinar 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 seleccionando 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 compilador {$IMPLICITBUILD ON} habilitada. Internal Error; Near: query shellmgr Posible causa de error Puede estar utilizando el servidor Local de InterBase, y tiene un equipo Dell Pentium Pro con Windows NT 4 preinstalado. 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 ‘Explorer.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). Internal Error 500. Interface not supported Posible causa de error Puede estar haciendo referencia a un método de la interfaz Weblib, pero la biblioteca de tipos de esta interfaz no ha sido registrada. 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. Internal Server Error 500 Consulte “COINITIALIZE has not been called”. Invalid address value. Must be a hexadecimal value in the range 00000000-FFFFFFFF Posible causa de error Puede haber introducido en el cuadro de diálogo Find Error un valor de dirección que no está dentro de los límites aceptados. 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 Invalid argument to date encode Posible causa de error Puede haber proporcionado a la función EncodeDate un conjunto de valores que no conforman una fecha válida. Por ejemplo, lo siguiente generará este mensaje de error, ya que Febrero 29 de 2100 no es una fecha válida (2100 no es un año bisiesto): var MyDate: TDateTime; begin MyDate := EncodeDate(2100, 2, 29); Label1.Caption := DateToStr(MyDate); 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 asignació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 dependencia de los valores del mes y el año. Invalid argument to time encode Posible causa de error Puede haber pasado a la función EncodeTime un conjunto de valores que tiene fuera del rango de valores válidos al menos uno de sus cuatro parámetros. 328 Los Tomos de Delphi: Delphi sin problemas 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ámetros Min y Sec va de 0 a 59. El rango de valores válidos para el parámetro MSec es de 0 hasta 999. Invalid Batch Move Parameters Posible causa de error Puede haber utilizado la misma tabla en las propiedades Source y Destination de un componente TBatchMove, y luego haber intentado ejecutar el método Execute en tiempo de diseño (pulsando con el botón derecho sobre el componente TBatchMove y seleccionando Execute del menú de contexto) o en el código. Por ejemplo, asumiendo que el componente BatchMove se denomina BatchMove1, el siguiente código generaría este mensaje de error: BatchMove1.Execute; 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 Invalid Bind Type Consulte “Unknown SQL Error”. Invalid BLOb handle [in record buffer] Posible causa de error Puede estar accediendo a una gran cantidad de campos BLOb, y el valor del parámetro BLOB SIZE del BDE es muy pequeño. 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 Nota: Si está utilizando conjuntos de resultados vivos, los parámetros BLOBS TO CACHE y BLOB SIZE del BDE no tendrán efecto. Este es el error del BDE número 10030. Invalid BLOb Size Posible causa de error A pesar de lo que dice el mensaje de error, el problema puede ser que la tabla no tenga un índice único en cluster. 330 Los Tomos de Delphi: Delphi sin problemas 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. Invalid class string Posible causa de error 1. Puede haber introducido en la propiedad ServerGUID de un componente TDCOMConnection, TMIDASConnection, TOLEEnterpriseConnection o TRemoteServer un valor que no se ajusta al formato esperado. 2. Puede haber introducido un valor para la propiedad ServerName de un componente TRemoteServer, pero olvidó especificar el ServerGUID. 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. Invalid class typecast Posible causa de error Puede estar intentando convertir una variable a un tipo de objeto con el cual no es compatible. 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; Invalid compiler directive: <> Posible causa de error 1. Puede tener una directiva de compilación $ELSE o $ENDIF que no está precedida por una directiva $IFDEF, $IFNDEF o $IFOPT. Por ejemplo, lo siguiente generará este mensaje de error: uses Windows, Messages, SysUtils, Classes, Graphics, Registry, {$ELSE} IniFiles, {$ENDIF} Controls; Lo siguiente también ocasionará el mismo error, ya que hay un espacio entre la llave ( { ) y el signo de dólar ( $ ), lo que convierte el texto en un comentario en lugar de una directiva de compilación: uses Windows, Messages, SysUtils, Classes, Graphics, { $IFDEF WIN32} Registry, {$ELSE} IniFiles, {$ENDIF} Controls; 2. Puede haber especificado una directiva de compilador $IFOPT sin una opción de compilación posterior; o sin un signo mas (+) o menos (–) posterior para indicar si se está comprobando si la opción del compilador está activa o inactiva; o ha utilizado la forma larga de la directiva de compilación. Por ejemplo, lo siguiente generará este mensaje de error: {$IFOPT} //falta la opción del compilador {$IFOPT I} //falta el + o – Y también lo siguiente: {$IFOPT IOCHECKSON} //no se puede utilizar la forma larga de las opciones //de compilación con la directiva IFOPT 332 Los Tomos de Delphi: Delphi sin problemas 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 contiene 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. Invalid field name Posible causa de error 1. Puede haber especificado en la propiedad SQL de un TQuery un nombre de campo que no existe en la tabla. Por ejemplo, lo siguiente generará este error si no existe un campo Films en la tabla Documentaries: SELECT Films FROM Documentaries Mensajes de error 333 WHERE Director = 'Sayles' OR 'Morris' 2. Puede no haber especificado la sentencia SQL de la forma precisa (sintácticamente) en la que Delphi espera verla. Por ejemplo, la siguiente sentencia puede generar este mensaje de error: SELECT * FROM Customers WHERE State = 'ID' 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). Invalid field size Posible causa de error Puede haber intentado crear un campo de cadena de caracteres en el código, pero olvidó asignarle un tamaño. Por ejemplo, lo siguiente generará este mensaje de error: Add('DIVISIONNAME', ftString, 0, False); 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 Memo o Graphic, el parámetro Size determina la cantidad de bytes que son realmente almacenados en la propia tabla de base de datos (los demás son almacenados en un archivo .MB). Invalid field type Posible causa de error Puede estar intentando seleccionar un campo Autoincrement de una tabla utilizando la propiedad SQL de un componente TQuery mientras está utilizando actualizaciones en caché. Solución rápida Aunque es cierto que no se puede editar un campo Autoincrement, puede seleccionarlo 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 actualizados, ya que son normalmente utilizados como claves primarias generadas automáticamente. Invalid file name Posible causa de error 1. Puede estar utilizando la versión 3.5 del BDE y Windows 95B (4.00.950b, también conocida como Win95 OSR2) mientras accede a tablas cuya ruta contiene nombres de archivos largos y/o espacios en los nombres de directorio o de archivo. 2. Puede estar excediendo la máxima longitud de una ruta, si su sistema operativo de red es Novell. 3. Puede tener un apóstrofe en un nombre de directorio al que ha asignado un alias. Por ejemplo, si crea un directorio denominado What’sUpDoc, y luego crea un alias como BugsBunny que apunta a él, obtendrá este mensaje de error. 4. Puede estar intentando acceder a un archivo al que no tiene acceso. Por ejemplo, puede estar intentando abrir un archivo de esta forma: AssignFile(NoRouteFile, SpoolPath+FileName); Rewrite(NoRouteFile); Mensajes de error 335 y el archivo es inaccesible debido a que Spoolpath = 'G:\data\spool\' y la máquina en la que el programa está ejecutándose no tiene mapeada la unidad G. Solución rápida 1. Si está utilizando la versión 3.5 del BDE (que viene con Delphi 2) y Windows 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 Propiedades 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. Invalid floating point operation Posible causa de error 1. Puede haber intentado asignar un número demasiado grande a un tipo de datos de punto flotante. Por ejemplo, lo siguiente generará este error: var Gates, Turner, McCartney: Currency; begin 336 Los Tomos de Delphi: Delphi sin problemas 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 ejecuta 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 2. En los ejemplos dados arriba, el mensaje de error específico que acompaña a EInvalidOp es “Invalid floating point operation”. Consulte “Integer constant too large”. Invalid function result type Posible causa de error Puede haber declarado una función con un resultado de tipo File. Por ejemplo, lo siguiente generará este mensaje de error: function GetFromCabinet: file; 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. Invalid GUID format Posible causa de error Puede haber modificado manualmente un GUID. Por ejemplo, puede haber eliminado uno de los dígitos de un GUID en una biblioteca de tipos. 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. Invalid index descriptor Posible causa de error Puede haber intentado crear un índice en una tabla dBASE utilizando el método AddIndex e indicó una opción de índice inválida. Por ejemplo, la opción 338 Los Tomos de Delphi: Delphi sin problemas ixCaseInsensitive no es válida para tablas dBASE, por eso el siguiente código genera este mensaje de error: Table1.AddIndex('Area','Area',[ixCaseInSensitive]); 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. Invalid index expression Posible causa de error Puede estar intentando crear un índice compuesto sobre una tabla dBASE, pero no ha pasado la constante de opción de índice ixExpression al método AddIndex. Por ejemplo, lo siguiente generará este mensaje de error: Table1.AddIndex('ndxCityState','City+State', []); 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. Invalid index/tag name Posible causa de error 1. Puede estar intentando añadir un nombre de índice que ya está siendo utilizado. Por ejemplo, lo siguiente generará este mensaje de error, ya que el mismo nombre está siendo utilizado por los dos índices: AddIndex('Verzeichnis', 'Stadt', []); AddIndex('Verzeichnis', 'Land', []); 2. Puede estar intentando asignar a un índice compuesto por un único campo un nombre distinto del campo al que hace referencia y no ha proporcionado la opción de índice ixCaseInsensitive. Por ejemplo, lo siguiente generará Mensajes de error 339 este mensaje de error, ya que el nombre proporcionado para el índice no coincide con el nombre del campo: AddIndex('ndxStadt', 'Stadt', []); 3. Puede estar intentando pasar en el parámetro TIndexOptions del método AddIndex un valor que no es apropiado para el tipo de la tabla. Por ejemplo, puede estar proporcionando para una tabla Paradox el valor ixExpression, que sólo puede ser utilizado con tablas dBASE. 4. Puede estar intentando crear más de un índice primario (clave primaria). Por ejemplo, si ya tiene un índice primario sobre un campo, lo siguiente generará este mensaje de error: AddIndex('Stadt', 'Stadt', [ixPrimary]); 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 Invalid message parameter list Posible causa de error 1. Puede haber declarado un método de gestión de mensajes y proporcionó más de un parámetro. Por ejemplo, lo siguiente generará este mensaje de error: procedure WMChar(var Message: TWMChar; n: Word); message WM_CHAR; 2. Puede haber eliminado, o le faltó añadir, la palabra reservada Var en la declaración del manejador de mensaje: procedure WMChar(Message: TWMChar); message WM_CHAR; 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ámetro. 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; Para más información, consulte “message handlers” en la ayuda de Delphi. Invalid package file <> Posible causa de error 1. Probablemente intenta cargar un archivo que tiene una extensión distinta de .DPL o .DPC en la página Packages del cuadro de diálogo Project Options, después de haber seleccionado Install Packages del menú Component, haber pulsado el botón Add, y luego seleccionar un archivo en el cuadro de diálogo Add Design Package. 2. Si el archivo tiene una de las extensiones apropiadas, no es realmente un archivo de paquete o se ha dañado. Solución rápida 1. Seleccione un archivo con extensión .DPL (biblioteca de paquetes de Delphi) 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 Componentes) 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 componente TBatchMove. Información adicional Para más información, consulte “TBatchMove” en la ayuda de Delphi. Invalid parameter type: <> Posible causa de error Puede haber introducido un tipo no permitido en una biblioteca de tipos, como cuando se añade un miembro a una interfaz. Por ejemplo, añadir la siguiente propiedad generará este mensaje de error: property FFroggy: String; Solución rápida Utilice WideString como el tipo de la propiedad; String no es un tipo de automatización OLE. Información adicional Todos los tipos de automatización OLE deben ser compatibles con las variantes. Los siguientes tipos de Delphi pueden ser utilizados en proyectos de automatización: Byte, Currency, Double, IDispatch, Integer, IUnknown, 342 Los Tomos de Delphi: Delphi sin problemas OLEVariant, SmallInt, Single, TDateTime, WideString, WordBool, SCode, TColor y TSafeArray. Invalid path Consulte “Invalid file name”. Invalid pointer operation Posible causa de error Puede estar intentando liberar memoria que ya ha sido liberada. Por ejemplo, pasar a Dispose o FreeMem un puntero con valor Nil genera este mensaje de error. El siguiente código potencialmente produce el mensaje de error bajo discusión. La razón es que la memoria siempre es liberada en la parte Finally, pero en el caso de una excepción, es liberada primero en la parte Except. Esto ocasiona que la ejecución posterior de la parte Finally (que siempre se ejecuta, con o sin excepción) intente liberar la memoria de nuevo, produciendo el error: procedure FinallyFree; var Homework: Pointer; begin GetMem(Homework, 32); try try {Acciones...} except FreeMem(Homework, 32); end; //except finally {Lo siguiente funciona bien, a menos que haya ocurrido una excepción, en cuyo caso se intentará liberar la memoria por segunda vez} FreeMem(Homework, 32); end; //finally end; 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. Invalid property path Posible causa de error Puede estar escribiendo un componente e intentando almacenar sus propiedades Published manualmente utilizando el método DefineProperties (y posiblemente otros métodos relacionados, como ReadData y WriteData). 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áticamente por Delphi. En ocasiones puede que necesite utilizar el método DefineProperties, como cuando quiera almacenar el estado de propiedades no publicadas. Invalid property value Posible causa de error 1. Puede haber asignado un valor que no es válido a una propiedad. Por ejemplo, introducir el nombre de un componente no existente en la propiedad ActiveControl de un formulario, o “Maybe” dentro de la propiedad Enabled 344 Los Tomos de Delphi: Delphi sin problemas (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 control 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 discusión no será generado. Invalid property value on line <> Posible causa de error Puede tener un error de sintaxis en un archivo .DFM. 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 describen qué objetos están sobre el formulario, dónde son mostrados sobre el formulario 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 ubicació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 Invalid resource format Posible causa de error Puede estar intentando cargar un recurso de 16 bits en Delphi de 32 bits. 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. Invalid Stream Format Posible causa de error Un archivo que Delphi está tratando de cargar, quizás un archivo de formulario o paquete, puede estar dañado. 346 Los Tomos de Delphi: Delphi sin problemas 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 integrado 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 principal 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 adaptará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 Type Conversion Consulte “Unknown SQL Error”. 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 ejemplo, 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 verificaciones/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 Lo siguiente (ordinal a ordinal) funciona: Chicago := Boolean(0); Pero esto (cadena a ordinal) no: Memphis := Boolean('False'); Invalid use of keyword Posible causa de error 1. Puede haber un error de sintaxis en la sentencia SQL asociada a un componente TQuery. Por ejemplo, puede estar intentando utilizar un parámetro en la cláusula FROM, o puede haber obviado la cláusula FROM completamente. Por ejemplo, esto generará el mensaje de error bajo discusión: SELECT * FROM :Rebel Y también esto: SELECT * WHERE Rebel = 'Without a clause' 2. Puede que no tenga ningún nombre de columna en la cláusula SELECT y/o ningún nombre de tabla en la cláusula FROM. 3. Puede haber utilizado la palabra reservada GROUP BY sin haber utilizado alguna función de agregación en la cláusula SELECT (como COUNT, SUM, MIN, MAX, AVG, etc.). 4. Puede estar utilizando Oracle y no haber utilizado mayúsculas en la sentencia SQL. 5. Puede tener un nombre de campo con espacios en la parte SELECT de su sentencia SQL y no haberle antepuesto el nombre de la tabla o el alias al campo. 6. Puede haber olvidado añadir un “AND” en una sentencia SQL. Por ejemplo, lo siguiente generará este mensaje de error: SQL.Add('SELECT Material.WeekBegin, Material.TalkIndicator'); SQL.Add('FROM Material, Week WHERE'); SQL.Add('Material.WeekBegin >= :FirstDate'); SQL.Add('AND Material.WeekBegin <= :LastDate'); SQL.Add('AND Material.WeekBegin = Week.WeekBegin'); SQL.Add('Week.WeekType = "Reg"'); 7. Puede haber utilizado una sentencia SQL que hace referencia a un campo que utiliza una palabra reservada de SQL, y no ha antepuesto al nombre de campo el nombre de la tabla, ni encerrado el nombre de campo entre comillas. Por ejemplo, lo siguiente generará este mensaje de error: Mensajes de error 349 with qryActiveStudents do begin SQL.Clear; SQL.Add('SELECT *'); SQL.Add('FROM Students'); SQL.Add('WHERE Active = True'); // Aquí el error SQL.Add('ORDER BY DateOfLastTalk'); Open; First; end; 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 utilizando 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 nombre 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 SQL.Add('AND Material.WeekBegin <= :LastDate'); SQL.Add('AND Material.WeekBegin = Week.WeekBegin'); SQL.Add('AND Week.WeekType = "Reg" '); //aquí 7. Anteponga el nombre de la tabla al nombre de campo “problemático”, y encierre el nombre de campo entre comillas, así: with qryActiveStudents do begin SQL.Clear; SQL.Add('SELECT *'); SQL.Add('FROM Students'); SQL.Add('WHERE Students."Active" = True'); //todo OK SQL.Add('ORDER BY DateOfLastTalk'); Open; First; end; Información adicional Las sentencias SQL que devuelven un conjunto resultado requieren una cláusula 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. Invalid variable reference Posible causa de error Puede estar pasando una propiedad a un procedimiento o función que espera recibir un parámetro variable. Por ejemplo, lo siguiente generará el mensaje de error bajo discusión (EyeColor es una propiedad de tipo String de la clase Woman): Insert(Source, Woman.EyeColor, 3); 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 propiedades (un “envoltorio” alrededor de los campos) no pueden ser modificadas. Invalid variant type conversion Posible causa de error 1. Puede haber intentado convertir de un tipo de datos a otro en una operación que no parece lógica (al menos para el compilador). Por ejemplo, los dos siguientes fragmentos de código generarán este mensaje de error: 352 Los Tomos de Delphi: Delphi sin problemas 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 columnas (í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 primaria 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 definitivamente una de las áreas en donde los mensajes de error son sus amigos. 354 Los Tomos de Delphi: Delphi sin problemas Label <> is not declared in current procedure Posible causa de error Puede estar intentando utilizar la sentencia GoTo para saltar a una etiqueta que no está declarada en el mismo procedimiento que sentencia GoTo. 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 fronteras de procedimiento, aunque Pascal estándar si. Las etiquetas y sus correspondientes 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 ;-) Label already defined: <> Posible causa de error Puede haber definido una etiqueta más de una vez. Por ejemplo, lo siguiente generará este mensaje de error: procedure Etikett; label 1; begin 1: if (Jordache or Nike) then goto 1; 1: end; Solución rápida Defina las etiquetas una y solamente una vez. Información adicional Las etiquetas y sus correspondientes sentencias GoTo son normalmente utilizadas para el manejo de errores, y Delphi proporciona un mecanismo mucho Mensajes de error 355 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 declaration not allowed in interface part Posible causa de error Puede haber intentado declarar una etiqueta en la parte Interface de una unidad. Por ejemplo, lo siguiente generará este mensaje de error: 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 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 ;-) Label declared and referenced, but not set Posible causa de error Puede haber declarado y hecho referencia a una etiqueta (en una sentencia GoTo), pero la etiqueta no está definida. Por ejemplo, lo siguiente generará este mensaje de error: procedure Alamo; label SpursThatJingleJangleJingle; begin goto SpursThatJingleJangleJingle; end; 356 Los Tomos de Delphi: Delphi sin problemas 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 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 ;-) 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 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 ;-) Left side cannot be assigned to Posible causa de error 1. Puede estar intentando asignar una valor a una constante. Por ejemplo, el siguiente código produce el mensaje de error bajo discusión: const crlf = #13#10; . . . crlf := #8#8#8#8#8#8#8#8; 2. Puede estar intentando asignar un valor a un parámetro constante (un parámetro formal que está antecedido por la palabra reservada Const). Por ejemplo, lo siguiente produce el mensaje de error bajo discusión: procedure Popeye(const IYamWhatIYam: string); var s: string; begin s := IYamWhatIYam; {ningún problema aquí} IYamWhatIYam := 'et 2, Brutus?'; {no permitido} end; ya que está intentando asignar un valor al parámetro constante IYamWhatIYam. 3. Puede estar intentando asignar un valor al valor de retorno de una función fuera de la función. Por ejemplo, lo siguiente produce el mensaje de error bajo discusión: function GiveMeAnH: char; begin Result := 'H' { Asignar a 'Result' es lo mismo que asignar a GiveMeAnH } end; begin GiveMeAnH := 'H'; { esto no } end. 358 Los Tomos de Delphi: Delphi sin problemas 4. Puede estar intentando incrementar o disminuir un valor no ordinal utilizando la función Inc o Dec. Por ejemplo, lo siguiente generará este mensaje de error: inc('orporated'); dec('10.0'); 5. Puede haber intentado asignar un valor a un puntero utilizando una sintaxis incorrecta (tipo “puntero a puntero”). Por ejemplo, lo siguiente generará este mensaje de error: procedure DysfunctionalPoynter; type iptr = ^Integer; var i:integer; q:iptr; begin ^q := @i; end; 6. Puede haber intentado ejecutar la función Inc sobre una propiedad de una clase. Por ejemplo, lo siguiente generará este mensaje de error: inc(ZipObj.CurrentDisketteNumber); 7. Puede haber olvidado añadir una conversión de tipos a un campo. Por ejemplo, lo siguiente generará este mensaje de error: with nvcmod.cds do begin FieldByName('ID') := edtAddFName.Text; Solución rápida 1. No haga asignaciones a constantes. Borre la sentencia de asignación o cambie la constante por una variable inicializada. 2. No haga asignaciones a parámetros constantes. Borre la sentencia de asignació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^:= 5; // q apunta a la variable i // 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 7. Añada la función de conversión AsX al nombre de campo: with nvcmod.cds do begin FieldByName('ID').AsString := edtAddFName.Text; 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”. Line number must be between 1 and <> Posible causa de error En el editor de Delphi está intentando ir a una línea que no existe en la unidad actual. 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 cuadro de diálogo Go To Line Number y pulsando OK. Line too long [more than 255 characters] Consulte “String [literal]s may have at most 255 elements”. List capacity out of bounds (<>) Posible causa de error Puede haber asignado a la propiedad Capacity de una lista un valor mayor que MaxListSize. En Delphi 1, MaxListSize es 16.380. En Delphi de 32 bits, es 134.217.727. Por ejemplo, lo siguiente generará este mensaje de error (Liszt es una variable TList): Liszt.Capacity := 2222222222; 360 Los Tomos de Delphi: Delphi sin problemas 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. List index out of bounds (<>) Posible causa de error 1. (A) Puede haber intentado hacer referencia a un elemento de una lista que no existe. Por ejemplo, lo siguiente producirá este mensaje de error, ya que el elemento 1 no ha sido asignado (ya que los índices de una lista comienzan en cero): procedure var sl: TStringList; s: String; begin sl := TStringList.Create; sl.Add('Samuel Langhorne Clemens'); s := sl.Strings[1]; {no se puede acceder a algo situado más allá de Strings[0], ya que no existe} end; 1. (B) Una de las mucha maneras de provocar este mensaje de error es llamar al método Move de TString, proporcionando un parámetro inválido para uno o los dos argumentos: var NoneAttached: TStrings; begin NoneAttached := TStringList.Create; NoneAttached.Move(0, 1); 2. Puede también obtener este error al eliminar los elementos de una lista dentro de un bucle For. . . To que utiliza la cantidad de elementos de la lista como valor final, ya que ésta irá disminuyendo dinámicamente (pero el bucle For intentará continuar hasta el valor Count-1). Por ejemplo, lo siguiente ocasionará este error: var i: integer; begin with ListBox1 do begin Items := ListBox2.Items; Mensajes de error 361 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 ejemplo 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 resultados (como las sentencias SELECT). Utilice ExecSQL con las sentencias INSERT, DELETE y UPDATE. Mensajes de error 363 Local class, interface or object types not allowed Posible causa de error Puede haber intentado declarar una clase local. Por ejemplo, lo siguiente generará este mensaje de error: procedure TForm1.Button8Click(Sender: TObject); type ELOCALError = class(Exception); . . . Solución rápida Declare todos los tipos de clases como globales, y no locales (dentro de una función o procedimiento). Información adicional Para más información, consulte “class types” en la ayuda de Delphi. Local class or object types not allowed Consulte más arriba “Local class, interface or object types not allowed”. Local procedure/function <> assigned to procedure variable Posible causa de error 1. Puede haber intentado asignar un procedimiento o función local a una variable de tipo procedimiento. 2. Puede haber intentado pasar como parámetro un procedimiento o función local. Solución rápida 1,2. No asigne procedimientos o funciones locales a variables de tipo procedimiento 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 Lock file [has grown] too large Posible causa de error Puede estar utilizando tablas de Paradox y presentarse una de las siguientes situaciones: 1. Múltiples usuarios están accediendo al mismo directorio privado. 2. El ejecutable y las tablas están en el mismo directorio. 3. El valor del parámetro Local Share del BDE es True. 4. Está ejecutando múltiples operaciones de consulta simultáneas contra un mismo TTable. 5. Puede estar utilizando actualizaciones en caché y llamando al método ApplyUpdates de un objeto TDataset, pero se ha olvidado de llamar después a CommitUpdates. Si este es el caso, puede que no se haya dado cuenta de que está utilizando tablas Paradox — realmente puede estar utilizando Oracle o MS SQL Server o alguna otra gran base de datos SQL (al utilizar actualizaciones en caché, las tablas Paradox son creadas de forma transparente por el BDE). 6. El directorio privado ha sido asignado a un directorio raíz. 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 mismas 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 red punto-a-punto están accediendo a las tablas a través de su propia copia del ejecutable. 5. Llame siempre a CommitUpdates después de ApplyUpdates. 6. Asigne el Directorio Privado a un subdirectorio, nunca al directorio raíz de una unidad. 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 bloqueos (.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. Lock time out Posible causa de error Puede ser que una aplicación que está intentando acceder a una tabla haya colocado un bloqueo de escritura sobre el archivo de bloqueos (.LCK) mientras hace una búsqueda para asegurarse de que no hay ningún bloqueo exclusivo sobre la tabla (que le impediría el acceso a la tabla). Al mismo tiempo, otra aplicación que ya tiene un bloqueo sobre la tabla está intentando acceder al archivo de bloqueos para liberarlo, pero no puede debido al bloqueo de escritura que la otra aplicación ha aplicado. La aplicación que ha colocado el bloqueo de escritura (y que quiere acceder a la tabla) localiza el bloqueo que la otra aplicación asignó, y continúa comprobando el archivo de bloqueos. Esto no 366 Los Tomos de Delphi: Delphi sin problemas 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 permite 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). -OMover 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: Deshabilitar la nueva semántica de bloqueos 1. En la máquina Windows 95, seleccione Inicio | Configuración | Panel de Control. 2. Haga doble clic sobre el icono Sistema. 3. Seleccione la página Rendimiento. 4. Pulse el botón Sistema de Archivos. 5. Seleccione la página Solución de Problemas. 6. Seleccione Deshabilitar la nueva semántica de bloqueos y uso compartido de archivos. Deshabilitar la caché de escritura en segundo plano 1. Siga los pasos 1-6 de arriba. 2. Seleccione Deshabilitar la caché de escritura en segundo plano para todas las unidades. Lookup information for field <> is incomplete Posible causa de error Puede estar intentando hacer referencia a un campo de búsqueda (lookup) cuya tabla ha sido eliminada del formulario o proyecto. Por ejemplo, puede haber creado un campo calculado basado en un campo de una tabla relacionada y posteriormente haber borrado la tabla (eliminando por lo tanto la referencia a ella). Si posteriormente hace referencia al campo, obtendrá este mensaje de error. 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 informació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 Low bound exceeds High bound Posible causa de error Puede haber declarado un subrango cuyo límite inferior es mayor que el límite superior. Por ejemplo, las dos siguientes declaraciones producen este mensaje de error: type YellowSubmarange = 12..1; HomeHomeOnTheRange = 'w'..'c'; -oPuede haber declarado un rango de valores en una sentencia Case donde el elemento 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. Master has detail records. Cannot delete or modify Posible causa de error El registro maestro que está intentando borrar tiene registros de detalle que hacen referencia a él. 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 procedure TForm1.Table1BeforeDelete(DataSet: TDataSet); begin with Query1 do begin SQL.Clear; SQL.Add('DELETE FROM STATS'); SQL.Add('WHERE STATS."NO" = 32'); Prepare; try ExecSQL; finally Unprepare; end; end; end; Colocar este tipo de código en el evento BeforeDelete permite que el registro maestro (que no tendrá más hijos en la tabla de detalles una vez que la sentencia SQL sea ejecutada) sea borrado. 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 configuración Prohibit impide que se modifiquen o borren los valores primarios en la tabla maestra si existen hijos en la tabla de detalle. Master has detail records. Cannot empty it Posible causa de error Puede estar intentando borrar todo el contenido de una tabla maestra para la que se cumplen las siguientes dos condiciones: Update tiene asignado Prohibit. La tabla contiene registros que tienen registros hijos en una tabla de detalle. 370 Los Tomos de Delphi: Delphi sin problemas 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”. Master record missing Posible causa de error Puede haber introducido un valor en un campo de clave foránea de una tabla de detalle para el que no existe un valor en la clave primaria de la tabla maestra. 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 representa 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. Maximum Validity Check Failed Posible causa de error Puede haber intentado asignar a un campo de tipo TBCDField, TFloatField, TCurrencyField o TIntegerField un valor que es mayor que el valor del Mensajes de error 371 parámetro MaxValue que se le ha asignado al campo en el Database Desktop. Por ejemplo, puede haber asignado un valor de 1.000.000 a MaxValue para el campo Salary de tipo TCurrencyField y luego haber intentado asignar un valor mayor que éste al campo: TblEmployeesSalary.Value := 112000; 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 ocasionará un mensaje más informativo si posteriormente asigna un valor demasiado 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. Memo too large Posible causa de error Puede estar ejecutando Delphi 2/BDE 3.5/MS SQL Server 6.5 bajo Windows NT 4, y utilizando una tabla con un índice único. 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). Metafile is not valid Posible causa de error Puede estar cargando un archivo en la propiedad Picture de TImage que, aunque tenga una extensión .WMF o .EMF, no es realmente un metaarchivo. 372 Los Tomos de Delphi: Delphi sin problemas 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: <>”. Method <> hides virtual method of base class <> Posible causa de error 1. Puede haber intentado redeclarar un método virtual heredado con la directiva Virtual. Por ejemplo, la clase ancestro puede parecerse a esto: type TBass = class procedure WalkAndRock; virtual; end; Y la clase descendiente: type TGuitar = class procedure WalkAndRock; virtual; end; 2. Puede haber declarado un método que tiene el mismo nombre que el método virtual en la clase base, pero olvidó (o deliberadamente no lo hizo) utilizar la directiva Override. Por ejemplo, lo siguiente producirá este mensaje de error: type TAndCrumpets(TComponent) . . . public constructor Create(AOwner: TComponent); 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 funcionalidad 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; Method <> not found in base class Posible causa de error Puede haber añadido la directiva Override a un método, pero el método no existe en la clase ancestro. 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. Method “<>” not supported by automation object Posible causa de error Puede haber intentado llamar a un método no existente para un objeto de Automatización OLE. Por ejemplo, lo siguiente generará este mensaje de error: var ExcelObj: Variant; begin 374 Los Tomos de Delphi: Delphi sin problemas ExcelObj := CreateOLEObject('Excel.Application'); . . . ExcelObj.SaveAll; //error: method SaveAll not supported by automation object Ya que Excel no expone un método “SaveAll”. 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 temprano). 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. Method <> with identical parameters exists already Posible causa de error Puede haber declarado dos métodos con la misma signatura (nombre, cantidad, tipos y orden de los parámetros). Por ejemplo, lo siguiente generará este mensaje de error: constructor Create(AOwner: TComponent); overload; override; constructor Create(AOwner: TComponent); overload; 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 constructor Create(AOwner: TComponent); overload; override; constructor Create(AOwner: TComponent; i:integer); overload; 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”. Method identifier expected Posible causa de error 1. Puede haber recibido primero el error “Undeclared Identifier:<>” dentro de un procedimiento o función que no es miembro de la declaración de tipos de la unidad, y luego intentó rectificar este error anteponiendo el nombre de la clase (por ejemplo TForm1) al identificador. Por ejemplo, si tiene un procedimiento parecido a éste: procedure loopdeloop; begin Label1.Caption := IntToStr(SizeOf(Byte)); end; Obtendrá el error “Undeclared Identifier:<>”. Si luego añade el nombre del tipo de la clase así: procedure loopdeloop; begin TForm1.Label1.Caption := IntToStr(SizeOf(Byte)); end; recibirá el mensaje de error bajo discusión. 2. Puede haber declarado un campo privado en una cláusula Read o Write de una propiedad en la sección Automated de un tipo. 3. Puede haber utilizado la palabra reservada Inherited en Delphi 1 sin especificar el método o propiedad que está siendo heredado. Por ejemplo, lo siguiente ocasionará este error en Delphi 1: procedure TascY2KDBComboBox.DoExit; begin try if length(Self.Text)<10 then begin SelectAll; SetFocus; raise EFullDateNotSupplied.Create(SEnterAFourDigitYear); end; 376 Los Tomos de Delphi: Delphi sin problemas 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 (asumiendo 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. Microsoft Transaction Server is not installed Posible causa de error Puede haber incluido una directiva en un tipo de disp-interfaz. Por ejemplo, lo siguiente generará este mensaje de error: Mensajes de error 377 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á deshabilitado, a menos que haya añadido un Módulo de Datos MTS a su proyecto. Presumiblemente, usted no seleccionará el elemento de menú Run | Install MTS Objects. . . a menos que haya instalado MTS. En otras palabras, probablemente sólo obtendrá este mensaje de error si está haciendo experimentos. Minimum Validity Check failed Posible causa de error Puede haber tratado de asignar a un campo de tipo TBCDField, TFloatField, TCurrencyField o TIntegerField un valor que es menor que el valor asignado al parámetro MinValue para el campo en el Database Desktop. Por ejemplo, puede haber asignado un valor de 20.000 al parámetro MinValue para el campo Salary de tipo TCurrencyField, y luego haber intentado asignar un valor más pequeño que ese al campo: TblEmployeesSalary.Value := 19000; 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. Alternativamente, 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 inicio 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. Missing Connection or Connection String Posible causa de error 1. Puede haber desplegado el Editor de Campos (Fields Editor) para un componente TADODataSet, TADOTable o TADOQuery (seleccionando Fields Editor del menú de contexto o haciendo doble clic sobre él), y luego seleccionó Add Fields o Add All Fields del menú de contexto del Editor de Campos sin tener una entrada válida en la propiedad Connection o ConnectionString. 2. Puede haber intentado ejecutar una sentencia SQL sin especificar un componente TADOConnection para un componente TADOQuery o TADODataset. Por ejemplo, lo siguiente generará este mensaje de error: with TADOQuery.Create(nil) do begin try SQL.Add('ALTER TABLE SCRIPTURES'); SQL.Add('ADD ORDER_SEQUENCE VARCHAR(3)'); ExecSQL; finally Free; end; end; 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 componente TADOQuery o TADODataSet. Si lo hace, pulse sobre el botón … a la derecha de la propiedad ConnectionString para desplegar su editor de propiedades. Es preferible utilizar un componente TADOConnection para toda la 380 Los Tomos de Delphi: Delphi sin problemas aplicación, asignando su propiedad ConnectionString, y tener todos los conjuntos de datos asociados al componente TADOConnection. TADOConnection es similar a TDatabase en las aplicaciones de BDE, y a TIBDatabase en las aplicaciones InterBase Express. Los componentes ADO aparecieron en Delphi 5. Missing Data Provider or Data Packet Posible causa de error 1. Puede haber intentado asignar True a la propiedad Active de un componente TClientDataSet sin haber especificado un componente TProvider en la propiedad ProviderName (el proveedor de datos no se encuentra). 2. El proveedor puede no haber devuelto registros (el paquete de datos se ha perdido). 3. Puede estar utilizando un TClientDataSet en una aplicación de una capa y haber olvidado asignar un valor a la propiedad FileName. 4. Puede estar intentando utilizar sentencias SQL contra un conjunto de datos local (una capa). Por ejemplo, lo siguiente generará este error si cdsDinnerGuests es un conjunto de datos de una sola capa (la propiedad ProviderName no está asignada a un TDataSetProvider que apunte a datos SQL o a otra capa lógica o lógica y física): cdsDinnerGuests.CommandText := 'DELETE FROM cdsDinnerGuests WHERE FName = ''Jeffrey'' AND‘ + ‘ LName = ''Dahmer'''; cdsStudents.Execute; 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 componente 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, actualizar y borrar datos, puede utilizar los métodos InsertRecord y Delete de Mensajes de error 381 TClientDataSet. Por ejemplo, para borrar un registro, puede primero localizar el registro, y luego llamar al método Delete, así: CdsDinnerGuests.Locate(’FName;LName’, VarArrayOf(['Jeffrey', 'Dahmer']), [loPartialKey]); cdsStudents.Delete; 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 dfBinary, dfXML o dfXMLUTF8. Missing ENDIF directive Posible causa de error Puede tener una directiva de compilación $IFDEF, $IFNDEF o $IFOPT sin la correspondiente directiva $ENDIF. Por ejemplo, lo siguiente generará este mensaje de error: uses Windows, Messages, SysUtils, Classes, Graphics, Registry, {$IFDEF Leppard} IniFiles, {$IFNDEF DumbAndBlindKid} Controls; Solución rápida Asegúrese de que cada sentencia {$IFDEF} tenga un sentencia {$ENDIF} correspondiente. Información adicional Consulte “Invalid compiler directive: <>”. Missing operator or semicolon Posible causa de error 1. Puede haber olvidado poner un punto y coma al final de una línea. 2. Puede haber omitido un operador o palabra reservada entre los operandos. Por ejemplo, en una sentencia With... Do, puede haber olvidado el Do: with Table1 begin 382 Los Tomos de Delphi: Delphi sin problemas 3. Puede haber omitido el operador de concatenación (+) entre cadenas definidas una detrás de otra. 4. Puede haber tenido un único apóstrofe (') en su propia línea y luego haber intentado compilar. Entonces habrá obtenido el mensaje de error “Unterminated string”, seguido por el mensaje de error bajo discusión. 5. Puede estar llamando a un procedimiento o función que no está en ámbito, pero otro procedimiento o función que tiene el mismo nombre pero una signatura diferente sí lo está. Por ejemplo, puede estar intentando llamar al procedimiento estándar Delete declarado en la unidad System, pero está llamando en su lugar (inadvertidamente) al método Delete de TStringList. 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 utilizando 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 resolver 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 procedimiento 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 literales. Por ejemplo, para mostrar un mensaje partiéndolo en varias líneas en un cuadro de diálogo (en una línea de código), puede hacer esto: ShowMessage('I remember you used to pick the git-fiddle’ + #13#10 + ‘fairly tolerable, Andy!'); También puede incorporar y concatenar variables, valores de propiedades, y literales de cadena en una simple línea de texto, así: ShowMessage('Listen: ' + Edit1.Text + ' ' + s + '!') 5. Consulte “Constant or type identifier expected” y “Undeclared Identifier: <>”. Si identificadores idénticos aparecen en múltiples unidades, la declaración situada en la unidad que aparece en último lugar en la cláusula Uses es la que recordará el compilador. Missing or invalid conditional symbol in <$> directive Posible causa de error Puede haber añadido las directivas $IFDEF, $IFNDEF, $DEFINE o $UNDEF sin especificar qué símbolo condicional pretende verificar, definir o indefinir. Por ejemplo, lo siguiente generará este mensaje de error: uses Windows, Messages, SysUtils, Classes, Graphics, {$IFDEF} Registry, { ... } 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. Missing parameter type Posible causa de error Puede haber declarado un procedimiento o función que recibe uno o más parámetros por valor cuyos tipos no se han especificado. Por ejemplo, lo siguiente generará este mensaje de error: procedure fudgsicle(a); 384 Los Tomos de Delphi: Delphi sin problemas 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); Missing right quote Posible causa de error Puede tener un apóstrofe sin emparejar en una sentencia SQL. Solución rápida Borre el apóstrofe solitario o añádale su pareja. Información adicional Consulte “QuotedStr” en la ayuda de Delphi. Missing TableName property Posible causa de error 1. Puede haber intentado ejecutar una acción sobre una tabla para la cual no se ha proporcionado un valor a la propiedad DatabaseName. 2. Puede haber intentado crear los campos persistentes de una tabla en tiempo de diseño pulsando dos veces sobre el componente TTable y luego seleccionando Add Fields del menú de contexto sin haber asignado a la propiedad TableName del objeto TTable una tabla válida. 3. Puede haber intentado asignar True a la propiedad Active de un componente TTable sin haberle asignado valor a su propiedad TableName. Mensajes de error 385 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\Borland\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 combinació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ícitamente. No es tan rígido como una ruta fija, ni tan flexible como un alias. Module <>s time/date changed. Reload? Posible causa de error 1. Puede haber (inadvertidamente) iniciado varias instancias de Delphi. 2. Puede haber marcado para guardar (check-out) mediante un sistema de control de versiones (como PVCS) una versión de un archivo que es anterior o posterior a la del archivo cargado en el proyecto (es una versión diferente del archivo, en otras palabras). 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 seleccionados, 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”. Module header is missing or incorrect Posible causa de error 1. Puede haber cambiado el nombre del archivo fuente fuera del entorno integrado (por ejemplo, en el Explorador de Windows). 2. Puede haber omitido la cláusula Uses de la sección Interface de una unidad. 3. Puede haber copiado los archivos .DSK y/o .DOF junto con los archivos fuente de un proyecto de un directorio a otro. 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 archivos 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 contenga 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 3. En las primeras versiones de Delphi, los archivos .DOF tenían la extensión .OPT. Multiple Net Files found Posible causa de error 1. Dos o más usuarios pueden estar intentando acceder a la misma tabla de la base de datos, pero no comparten la misma configuración de NET DIR. 2. Si todos los usuarios tienen la misma configuración de NET DIR, puede ser que haya un archivo .LCK viejo que apunte a una ruta distinta del directorio al que apunta NetDir. 3. Puede tener un archivo PDOXUSRS.NET o PDOXUSRS.LCK dañado. 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 Paradox. Para hacer esto, siga estos pasos: 388 Los Tomos de Delphi: Delphi sin problemas a. Abra la utilidad de configuración del BDE (BDECFG32.EXE) seleccionando Inicio | Programas | Delphi | BDE Config. b. Con la entrada de 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. Consulte “Delphi de 32 bits” más abajo. 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 Paradox. 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/Administration, puede consultar su configuración del Registro de Windows para asegurarse 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 indicada 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últiples 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 normalmente 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”. Multiple Paradox Net files found/in use Para más información, consulte “Directory is controlled by other .NET file” y “Multiple Net Files found”. Must apply updates before refreshing data Posible causa de error Puede haber llamado al método Refresh de un TClientDataSet, o ha pulsado el botón Refresh de un TDBNavigator asociado a él mientras hay actualizaciones pendientes. 390 Los Tomos de Delphi: Delphi sin problemas 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 utilizando 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. Name not unique in this context Posible causa de error Puede estar utilizando un objeto TDatabase cuya propiedad HandleShared tiene asignado el valor False. 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 Nota: Si está utilizando un servidor de aplicación multi-hilos, asegúrese de colocar un objeto TSession en el Módulo de Datos Remoto, y de asignar True a su propiedad AutoSessionName. Need to specify at least one dimension for SetLength of dynamic array Posible causa de error Puede haber llamado a SetLength sobre un array, pero olvidó especificar un valor para la longitud del array. Por ejemplo, lo siguiente generará este mensaje de error: procedure ShortestProcedureNameKnownToWesternCivilization; var ABunchOfIntegers: array of integer; begin SetLength(ABunchOfIntegers); end. 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. Never-build package <> must be recompiled Posible causa de error Puede haber hecho modificaciones a otro paquete que es requerido por el paquete al que se hace referencia en el mensaje de error. 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. Never-build package <> requires always-build package <> Posible causa de error Puede estar intentando crear un paquete de “no construir” (never-build) que requiere un paquete “construir siempre” (always-build). 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 cualquier 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é marcado como “no construir”. Para más información, consulte “weak packaging” y “implicit build” en la ayuda de Delphi. New not supported for dynamic arrays—use SetLength Posible causa de error Puede estar intentado especificar el tamaño de un array dinámico utilizando el procedimiento New. Por ejemplo, lo siguiente generará este mensaje de error: procedure Newby; var ArrayOfScores: array of integer; begin New(ArrayOfScores, StrToInt(edtNumberOfGames)); end. 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 Internet (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 proporcionar el nombre del servidor en la propiedad Host. Esto, sin embargo, es más lento que configurar directamente la propiedad Address, ya que la dirección del servidor deberá ser buscada. No argument for format <> Posible causa de error Puede no haber proporcionado la misma cantidad de argumentos que los especificadores de formato indicados en una llamada a la función Format. Por ejemplo, lo siguiente generará este mensaje de error, debido a que hay tres especificadores de formato, pero solamente dos argumentos han sido proporcionados: Label1.Caption := Format('Los %s de %s ganarán la %s’, ['Baltimore', ‘Serie Mundial']); 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 Label1.Caption := Format('Los %s de %s ganarán la %s’, [' Orioles', 'Baltimore', ‘Serie Mundial']); Información adicional Para más información, consulte “Format function”, “format specifier”, y “format strings” en la ayuda de Delphi. No code was generated for the current line Posible causa de error 1. Puede estar intentando ejecutar hasta la ubicación del cursor, pero seleccionó Run | Run To Cursor o pulsó F4 sobre una línea para la que no se generó código. Por ejemplo, puede ser un encabezamiento de un procedimiento (en lugar de una sentencia de asignación). 2. La línea en cuestión puede no haber generado código debido a que no estaba enlazada al proyecto. Si el código no es llamado, el enlazador inteligente de Delphi lo dejará fuera para reducir el tamaño del ejecutable. Por ejemplo, si incluye el siguiente procedimiento en la unidad: procedure TForm1.DontCallUs; . . . pero éste nunca es llamado por otro procedimiento o función, no será enlazado al ejecutable, y ningún código será generado para él. 3. Puede estar situado sobre una línea que de hecho genera código, pero la unidad no es parte del proyecto actual. Puede ser que la unidad en cuestión no se encuentre en la cláusula Uses de ninguna de las unidades que son parte del proyecto. 4. Puede ser que tenga una copia de una unidad que está almacenada en una ubicación diferente que la copia de la unidad que es parte del proyecto. Por ejemplo, puede tener una unidad nombrada Usee que está almacenada en el directorio del proyecto (por ejemplo, C:\User), pero ha abierto una copia de la unidad Usee que está almacenada en un directorio diferente (por ejemplo, C:\UserBkup). 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 sentencia 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 ubicació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 4. Cierre la unidad que está almacenada en una ubicación distinta de la que se ha designado en el Gestor de Proyectos (Project Manager), y abra la copia de la unidad que reside en el directorio/localización correcto. Seleccione View | Project Manager para ver las unidades incluidas en el proyecto y su ubicación. 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. No Databases Are Listed In Transaction Component Posible causa de error Puede haber llamado al método StartTransaction de un componente TIBTransaction sin primero haber configurado su propiedad DefaultDatabase. 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 aplicaciones 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. No definition for abstract method <> allowed Posible causa de error Puede haber definido un método que fue declarado anteriormente como abstracto en la misma unidad. Por ejemplo, lo siguiente generará este mensaje de error: 396 Los Tomos de Delphi: Delphi sin problemas procedure VAndA; virtual; abstract; . . . procedure TForm1.VAndA; var SpudLovers: string; begin SpudLovers := 'Bendocchi, Christy, Rogers, Shannon'; end; 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 definido. 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. No fields defined—cannot create dataset Posible causa de error Puede haber intentado llamar al método CreateDataSet de TClientDataSet sin primero proporcionar el conjunto de datos que debe crear — es decir, no ha asignado valores a las propiedades FieldDefs o Fields del TClientDataSet. 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 indudablemente (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. No index currently active Posible causa de error Puede haber intentado llamar a uno de los métodos FindKey o Locate de un conjunto de datos sin especificar un índice por el que buscar. 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. No MDI forms are currently active Consulte “Cannot create form. No MDI forms are currently active”. No MDI Parent Active Posible causa de error 1. Puede haber olvidado designar al formulario principal de la aplicación MDI como el formulario padre MDI. 2. Puede estar creando dinámicamente el formulario MDI principal. 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. No overloaded method of <> with this parameter list exists Posible causa de error Puede haber intentado llamar a un método sobrecargado con un parámetro o conjunto de parámetros para los cuales no hay un método sobrecargado compatible. Por ejemplo, lo siguiente generará este mensaje de error: function BTOSong(AName: String): Integer; overload; function BTOSong (ALengthInSeconds: Integer): String; overload; . . . s := BTOSong(3.36); Mensajes de error 399 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 actualización y/o parche para una funcionalidad plena y un mejor rendimiento. En particular 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 No SQL statement available Posible causa de error 1. Puede haber llamado al método Prepare de un TQuery, pero la propiedad SQL no tenía asignada ninguna sentencia. 2. Puede haber intentado añadir campos a un componente TQuery utilizando el Editor de Campos sin primero haber asignado una sentencia SQL a la propiedad SQL del componente TQuery. 3. Puede haber llamado al método Open o ExecSQL de un TQuery cuando la propiedad SQL estaba vacía. 4. Puede haber intentado asignar el valor True a la propiedad Active de un componente TDecisionQuery sin haber especificado primero una sentencia SQL para la propiedad SQL. 5. Puede haber llamado a Open o haber asignado True a Active para un componente TSQLQuery (DBExpress) que no tenía una sentencia SQL asignada en su propiedad SQL. 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 componente 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 recomendable 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 (incluyendo 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. No user transaction is currently in progress Posible causa de error Puede haber llamado al método Commit de un componente TDatabase sin haber primero iniciado una transacción mediante una llamada a StartTransaction. 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 descartar 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; Para más información sobre las transacciones de bases de datos, consulte “handling transactions” en la ayuda de Delphi. No Web browser could be located Posible causa de error Ha intentado entrar a un sitio web o ver un documento .HTML, pero Delphi no puede localizar un navegador en el sistema. Por ejemplo, puede haber seleccionado Borland Home Page, Delphi Home Page o Borland Programs & Services del menú Help de Delphi. 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 disponibles otros navegadores, tanto comerciales como freeware. Además, usted podría crear su propio navegador utilizando Delphi. NODEFAULT clause not allowed in OLE automation section Posible causa de error Puede haber utilizado la cláusula Nodefault en una sección Automated. 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 Stored, Default o Nodefault como directivas de almacenamiento. Estas directivas de almacenamiento no están permitidas en la sección Automated. Not enough actual parameters Posible causa de error 1. Puede haber llamado a un procedimiento o función sin proporcionar todos los parámetros necesarios. Por ejemplo, puede haber intentado algo así: MessageDlg('Eat at Joe''s', mtCustom, [mbOK]); { Olvidó añadir el cuarto parámetro (HelpCtx) } 2. Puede estar intentando redefinir un método de la clase ancestro, pero no ha proporcionado todos los parámetros declarados en el ancestro. Por ejemplo, lo siguiente generará este mensaje de error, ya que el constructor que está siendo redefinido declara un parámetro como de tipo TComponent: type TYoopdl = class(TComponent) private FOutstanding: string; public constructor Create; override; end; . . . constructor TYoopdl.Create; begin inherited Create; {esta línea ocasiona el error} FOutstanding := 'yowza-bop'; end; 3. Puede estar intentando revisar si un gestor de eventos está asignado a una propiedad de evento comprobando si su valor es Nil, así: if TrueIdentity.OnValidate = nil then 4. Puede haber utilizado un punto y coma en una llamada a un procedimiento o función. Por ejemplo: rptModule.PrintReport(ProgramMode, sOutFileName; sStartDate, sEndDate, sDaysPrevious, iUpdateOption); Solución rápida 1. Proporcione los parámetros que faltan. Por ejemplo, para solucionar el problema 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 MessageDlg('Eat at Joe''s’, mtCustom, [mbOK, mbHelp], 11); 2. Borre la llamada a Inherited de la definición del constructor si lo que desea es crear un nuevo constructor, en lugar de redefinir el constructor de TComponent. Para redefinir el constructor de TComponent, añada el parámetro a la declaración, definición y llamada, así: constructor Create(AOwner: TComponent); . . . constructor TCmpntDescendent.Create(AOwner: TComponent); begin inherited Create(AOwner); . . . 3. Utilice la función Assigned para hacer la comprobación, así: if not Assigned(TrueIdentity.OnValidate) then 4. Sustituya el punto y coma por una coma: rptModule.PrintReport(ProgramMode, sOutFileName, sStartDate, sEndDate, sDaysPrevious, iUpdateOption); 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ámetros 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. Not enough file handles Posible causa de error Puede tener más aplicaciones/archivos abiertos de los que el sistema es capaz de manejar. 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 utilidad 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áneamente, y cada uno necesita su propio manejador. Not exact read/write in <>.mb and <>.mb Posible causa de error Puede tener una tabla dañada. 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 Not in cached update mode Posible causa de error Puede estar intentando acceder a la propiedad OldValue de un registro, pero la propiedad CachedUpdates del DataSet tiene asignado el valor False. 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; Podría también si lo desea verificar que el registro no es nuevo, en cuyo caso no tendría un valor anterior: if (Table1.CachedUpdates = True) and (Table1.State <> dsInserting) then LegacyVal := OldValue; 406 Los Tomos de Delphi: Delphi sin problemas Consulte “At End of Table” para más información. Not initialized for accessing network files Posible causa de error 1. Puede tener una configuración inválida en el archivo IDAPI.CFG en relación con la ubicación del directorio del archivo de control de red. 2. Puede tener una configuración inválida en WIN.INI o en el Registro del sistema en relación con la ubicación del archivo de configuración del BDE (IDAPI.CFG). 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 configuración del BDE IDAPI.CFG está ubicado en C:\IDAPI (el valor por defecto), la sección se leería: [IDAPI] ConfigFile01=C:\IDAPI Si es necesario, mueva el archivo para que su ubicación coincida con lo indicado por la entrada en WIN.INI, o modifique la entrada de WIN.INI para que apunte a la ubicación actual del archivo. Delphi de 32 bits Verifique que la ubicación de IDAPI32.CFG (por defecto C:\Archivos de programa\Borland\Common files\BDE) coincida con la que se indica en el Registro del sistema. Si es necesario, mueva el archivo para que su ubicación coincida con lo indicado 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 Para asignar un valor a NET DIR con la utilidad BDE Configuration/Administration, siga estos pasos: 1. Cree un directorio sobre una unidad de red compartida al que todos los usuarios que accederán a las tablas de bases de datos tengan derechos de lectura, escritura y creación. 2. Asigne el directorio creado en el paso 1 como valor del parámetro NetDir en cada archivo de configuración del BDE de los usuarios, mediante la utilidad BDE Configuration o directamente en el Registro del sistema). Cómo crear un Alias utilizando la herramienta de Configuración del BDE En Delphi 1, la herramienta de configuración de BDE es BDECFG.EXE. En Delphi 2, es BDECFG32.EXE. En Delphi 3 y 4 es BDEADMIN.EXE. En Delphi 5 y 6 es DBEXPLOR.EXE. En Windows 95 y posteriores, está disponible seleccionando Inicio | Programas | Borland Delphi X | BDE Administrator. Para crear un alias con la herramienta BDE Configuration/Administration, siga estos pasos: 1. Seleccione Inicio | Programas | Borland Delphi X | BDE [Configuration, Administration]. 2. Con la pestaña Databases activa, seleccione Object | New. . . y luego indique el tipo de alias que desea crear (por ejemplo, Standard para una base de datos Paradox). 3. Verifique que el parámetro Type se corresponda con el tipo de base de datos que quiere crear o creará (Standard para Paradox, dBASE, y ASCII, Access para MS Access, etc.). 4. Si selecciona el controlador Standard (para crear una base de datos Paradox, por ejemplo), asigne al parámetro Path la ubicación de la base de datos (ServerName para InterBase y Oracle; DatabaseName para MS SQL Server y MS Access, Sybase, e Informix; DB2 DS2 para DB2). Si utiliza Path, puede introducir una ruta DOS, así: I:\LessTaken\Diff 5. Asigne a Path la ubicación de la base de datos. Puede introducir una ruta DOS, así: K:\HallOfFame\Baseball o, en Delphi de 32 bits, puede utilizar el convenio de nombres UNC (Universal Naming Convention), que tiene este formato: \\Servidor\Recurso\Directorio 408 Los Tomos de Delphi: Delphi sin problemas Number is out of range Posible causa de error 1. Puede haber intentado añadir un índice primario a una tabla que ya tiene una clave primaria definida. 2. Puede estar intentando crear un índice primario sobre un campo que no es el primer campo de la tabla. 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 primeros 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 primaria (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]); Si no está utilizando una tabla de Paradox 7 y prueba lo anterior, obtendrá el mensaje de error “Higher table level required”. Consulte esta entrada para más información. Las opciones de índice que puede asignar en el parámetro final son ixPrimary, ixUnique, ixDescending, ixCaseInsensitive y ixExpression. No puede utilizar ixPrimary o ixCaseInsensitive en el caso de una tabla dBASE. No puede utilizar ixExpression para una tabla Paradox. Number of elements differs from declaration Posible causa de error Puede haber declarado un array de constantes con tipo, pero ha proporcionado una cantidad de elementos diferente de los declarados. Por ejemplo, las siguientes dos declaraciones generarán este mensaje de error: {No se proporcionan suficientes elementos} Mensajes de error 409 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. Object Factory for TwebResponse Missing Posible causa de error Puede estar haciendo referencia a un método de la interfaz Webbrokerscript, pero su biblioteca de tipos no ha sido registrada. 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. Object or class type required Posible causa de error Puede estar intentando llamar a un método de un tipo que no es un objeto o clase. Por ejemplo, lo siguiente generará este mensaje de error: type TNumberWithoutDecimalPoints = Integer; . . . procedure TForm1.WhateverDude(Sender: TObject); 410 Los Tomos de Delphi: Delphi sin problemas 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. OLE error 800A03EC Posible causa de error Puede estar utilizando Microsoft Excel y ha intentado asignar un valor a las celdas de una hoja de Excel antes de añadir una hoja de trabajo. Por ejemplo, lo siguiente generará este mensaje de error: 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'); SetColumnTitles; xl.Workbooks.Add; end; 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. Only one of a set of overloaded methods can be published Posible causa de error Puede haber declarado varios métodos sobrecargados en una sección Published. Por ejemplo, lo siguiente generará este mensaje de error: . . . published procedure yoopdl(tl: TThreadList); overload; procedure yoopdl(tl: TList; ol: TObjectList); overload; 412 Los Tomos de Delphi: Delphi sin problemas 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 particulares: 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; Only one TIDAntiFreeze can exist per application Posible causa de error Puede haber añadido múltiples componentes TIDAntiFreeze a una aplicación, o puede haber colocado uno sobre un formulario y haber creado una segunda instancia del formulario en tiempo de ejecución. 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), conocido 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 (distribuido por Danysoft) es que, como su nombre implica, AsyncPro trabaja asíncroncamente (sin bloqueo), mientras Internet Direct es síncrono (con bloqueo). 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 propósito de TIDAntiFreeze es resolver ese problema — que su aplicación no se “congele”. Los programadores de Internet Direct se llaman a sí mismos “la tripulación de Indy”, y por lo tanto el término “Anticongelante” se ajusta bien al tema general del producto. Only register calling convention allowed in OLE automation section Posible causa de error Puede haber especificado un convenio de llamada distinto de Register en la sección Automated de la clase. Por ejemplo, lo siguiente generará este mensaje de error: automated procedure Blip; stdcall; 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. Operation not allowed on a unidirectional dataset Posible causa de error 1. Puede haber conectado un conjunto de datos de DBExpress directamente a un DBGrid a través de la propiedad DataSource del DBGrid, y luego intentó desplazarse hacia atrás por el conjunto resultado en la rejilla. 2. Puede haber intentado moverse hacia atrás por un conjunto de datos cuya propiedad Unidirectional tiene asignado True. 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. Operation not allowed on sorted string list Posible causa de error 1. Puede haber intentado un operación de filtro inválida sobre un campo de tipo String. Por ejemplo, puede haber asignado a la propiedad Filter de un TDataset algo así: common_name > graphic 2. Puede haber intentado asignar un valor a una lista de cadenas ordenada. Por ejemplo, lo siguiente generará este mensaje de error: slTemp := TStringList.Create; try TStringList(slTemp).Sorted := True; { Crear una lista delimitada por puntos y comas (campos) y tildes (registros)} i := 0; while i < Pred(sl.Count) do begin slTemp.Add(Format('%s;%s;%s;%s;%s;%s~', [sl[i],sl[i+1],sl[i+2],sl[i+3],sl[i+4],sl[i+5]])); inc(i,NUM_COLUMNS); end; { El contenido de sl ha sido movido a slTemp. Vaciar sl para que pueda recibir de nuevo el contenido ordenado. } sl.Clear; { Analizar las líneas ordenadas de slTemp y devolverlas a sl } for j := 0 to Pred(slTemp.Count) do while (Pos('~',slTemp[j]) > Pos(';',slTemp[j])) do if Pos(';',slTemp[j]) > 0 then begin sl.Add(Copy(slTemp[j],1,Pred(Pos(';',slTemp[j])))); slTemp[j] := Copy(slTemp[j],Pos(';',slTemp[j])+1, length(slTemp[j])); end else sl.Add(Copy(slTemp[j],1,Pos('~',slTemp[j]))); Mensajes de error 415 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 ;-) Operation not applicable Posible causa de error 1. Puede estar desarrollando una aplicación multicapa y está utilizando una copia antigua de DBClient.DLL. 2. Puede estar intentando acceder a la propiedad RecordCount sin haber primero llamado al procedimiento Last del TQuery. 3. Puede haber incluido un campo memo en una consulta, por ejemplo: SELECT STRINGFIELD, INTEGERFIELD, AMEMOFIELD FROM SIMTABLE 4. Puede haber construido una aplicación CGI que utiliza el BDE y hay demasiados usuarios concurrentes. 5. Puede haber asignado una cadena nula a un parámetro de consulta. Por ejemplo, si la variable HungryFor en el código siguiente contiene una cadena vacía, podría obtener este error en la línea Open: Params.ParamByName('Food').AsString := HungryFor; Open; 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 condició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. Operation not supported Posible causa de error 1. Si obtiene este mensaje de error en relación con una consulta, eso normalmente indica algún error en la sintaxis de la sentencia SQL. 2. Puede estar utilizando paréntesis en lugar de corchetes al indizar un array. Por ejemplo, lo siguiente generará este error si ha declarado un array llamado Synergy: i := Synergy(0); 3. Puede haber añadido un nuevo alias al SQL Explorer y ha intentado expandirlo antes de grabar los cambios. Mensajes de error 417 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). Operator not applicable to this operand type Posible causa de error 1. Puede haber intentado utilizar un operador aplicable solamente a enteros sobre operandos de punto flotante, o viceversa. Por ejemplo, lo siguiente generará este mensaje de error: procedure TForm1.Table1CalcFields(DataSet: TDataSet); { los campos son campos TFloat; Percentage es un campo calculado} begin Table1Percentage.Value := Table1MySalary DIV Table1AllTheMoneyInTheWorld; end; 2. Puede haber realizado al revés la comprobación de pertenencia de un elemento a un conjunto. Por ejemplo, obtendrá este mensaje de error si codifica lo siguiente: if [dsEdit, dsInsert] in State then . . . 3. Puede haber inadvertidamente utilizado dos signos más (+) para concatenar cadenas. Por ejemplo, lo siguiente generará este mensaje de error: var s:string; . . . s := 's'++'t'; 4. Puede haber intentado hacer una asignación a través de un puntero sin tipo, así: . . . 418 Los Tomos de Delphi: Delphi sin problemas var p: pointer; begin p^ := 5; -Otype 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 procedimiento denominado ValidateState así: if not ValidateState then 6. Puede haber intentado utilizar los operadores Is o As sobre uno o más operandos 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; -Otype 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 programació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. ORA-1001 invalid cursor Posible causa de error Lo siguiente podría ser cierto: Está utilizando Delphi 4. Está intentando ejecutar un procedimiento almacenado en un paquete situado en un servidor de Oracle 7.3.x. Tiene un procedimiento con más de un parámetro. 420 Los Tomos de Delphi: Delphi sin problemas Uno de los parámetros es un REF CURSOR. 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. Order of fields in record constant differs from declaration Posible causa de error Puede haber declarado una constante con tipo (variable inicializada) que inicializa a los miembros de un registro en un orden distinto del de la declaración del registro. Por ejemplo, lo siguiente generará este mensaje de error. Type TTresHombres = record Z: String; Zee: String; Top: String; end; var TresHombres : TTresHombres = (Zee: 'Billy'; Z: 'Dusty'; Top: 'Frank'); 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 inicializadas, aunque sean declaradas en secciones Const. Mensajes de error 421 Ordinal type required Posible causa de error Puede haber utilizado un tipo no ordinal en un lugar o situación donde un tipo ordinal es requerido. Cualquiera de los siguientes ejemplos generará este mensaje de error: { a } type GilligansIsland = 'Ginger'..'MaryAnne'; { b } var i: Integer; s: String; begin for i := 0 to ColCount-1 do strgrd.Cells[i,s]; { c } Type GoodViewing = set of string; { d } var SixPack: string; begin case SixPack of 'Pilsner Urquell':'Czech Republic'; 'Lambic':'Belgium'; 'Becks':'Germany'; 'Guinness Stout':'Ireland'; 'Sprechers': 'USA'; 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 controladores 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 (preferido). 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 Experimentar con la intensidad/resolución de color; 1024x768 en colores de 16 bits parece ser lo peor. Obtener la última versión de los controladores de DirectX (probablemente no los necesite para sistemas Win98). No utilizar fondos de escritorio o utilizar un fondo que consuma poca memoria. 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 iconos 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. Out of system resources Posible causa de error Puede tener muchas ventanas abiertas. 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 manejador (handle) son considerados ventanas por Windows. Podría obtener este mensaje de error por tener un montón de botones, etc. activos al mismo tiempo. 424 Los Tomos de Delphi: Delphi sin problemas Overflow in conversion or arithmetic operation Posible causa de error Puede tener un archivo .DCU dañado. 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. Overloaded procedure <> must be marked with the overload directive Posible causa de error Puede haber intentado sobrecargar un método, pero olvidó proporcionar la directiva Overload a uno o ambos métodos. Por ejemplo, lo siguiente generará este mensaje de error: constructor Create(AOwner: TComponent); overload; override; constructor Create(AOwner: TComponent; i:integer); 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 Overriding automated virtual method <> cannot specify a dispid Posible causa de error Puede estar intentando declarar un nuevo disp-id para un procedimiento de tipo Automated que está redefiniendo. 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. Package <> already contains unit <> Posible causa de error Puede estar intentando compilar un paquete que requiere (a través de la cláusula Requires o de la lista de paquetes) otro paquete, y ambos paquetes (el que está intentando compilar y el requerido, que se menciona en el mensaje de error) contienen la unidad especificada en el mensaje. 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. Package <> can’t be installed because another package with the same base name is already loaded (<>) Posible causa de error 1. Puede haber intentado reinstalar un paquete que ya ha sido instalado en su sistema. 2. Puede haber intentado instalar un componente dentro de un paquete siguiendo estos pasos: 426 Los Tomos de Delphi: Delphi sin problemas a. Seleccionó Component | Install Component. b. Seleccionó la página New Package. c. En el cuadro de combinación Package File Name, proporcionó el nombre de un paquete existente dentro del cual instalar el componente. 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. Package <> can’t be installed because it is not a design time package Posible causa de error Puede haber intentado instalar un paquete de tiempo de ejecución en la Paleta de Componentes. 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 distribuyan 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). Package <> is recursively required Posible causa de error Puede haber colocado un paquete en su propia sección Required. 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 unidad de registro, los recursos de iconos de componentes, y requieren el paquete de tiempo de ejecución. Package unit <> cannot appear in contains or uses clauses Posible causa de error Puede haber intentado añadir un paquete a la cláusula Contains o Uses de un paquete. 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 compilador 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 Packages <> and <> both contain unit <> Posible causa de error Puede estar intentando compilar un proyecto que utiliza los dos paquetes mencionados en el mensaje de error, y cada uno contiene una unidad del mismo nombre (quizás la misma unidad, quizás dos unidades que por coincidencia tienen el mismo nombre). 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 unidades, para evitar que este error se produzca. PACKED not allowed here Posible causa de error Puede estar intentando aplicar la palabra reservada Packed a un tipo que no es un conjunto (set), array, registro (record), clase (class) o archivo (file). Por ejemplo, lo siguiente generará este mensaje de error: type House = Extended; CamdenYards = packed House; 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 Page Fault in module <> at <> Posible causa de error Puede estar intentando mostrar un formulario que ya ha sido liberado. Cualquiera de los dos ejemplos siguientes generará este mensaje de error si el formulario ha sido creado y luego liberado: Form1.Show; Form1.ShowModal; 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”. Page name cannot be blank Posible causa de error Puede estar intentando utilizar el Asistente de Componentes (Component Wizard) para crear un nuevo componente, pero borró el texto del cuadro de combinación Palette Page. 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 componente será instalado. Param <> not found Posible causa de error Puede haber borrado un parámetro de una lista, pero olvidó actualizar el código que hace referencia al parámetro. Por ejemplo, puede haber tenido una sentencia SQL como: INSERT INTO ABC.Alphabet (SQU_ID, LetterCode, ReportedOn, EffectiveDate) VALUES (:squid, :ltrcode, :sysDate, :effDate) Y luego eliminó el campo ReportedOn y el parámetro :sysDate, quedando la sentencia como: INSERT INTO ABC.Alphabet (SQU_ID, LetterCode, EffectiveDate) VALUES (:squid, :ltrcode, :effDate) 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') Parameter <> not allowed here due to default value Posible causa de error Puede haber intentando combinar dos variables con un mismo valor por defecto en la declaración de un método, así: procedure PTBoat(i: Integer; j, k: Integer = 0); Mensajes de error 431 Solución rápida Coloque la segunda variable (k, en el caso de arriba) en su propia sección delimitada, 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. Parameter <> not found Posible causa de error Puede haber llamado al método Params.ParamByName de un componente TSQLQuery (DBExpress) sin haber configurado antes su propiedad SQLConnection. 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. Parameters of this type cannot have default values Posible causa de error Puede haber intentado proporcionar un valor o valores por defecto a un parámetro de un método, pero esta característica no está soportada para el tipo de datos del parámetro para el que está proporcionando el valor por defecto. type AI2 = array [0..2] of integer; . . . procedure BraveAttempt(a: AI2 = [1, 2, 3]); 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. Parent Interface must be Dispatchable for dual interface Posible causa de error Puede estar intentando cargar una biblioteca de tipos con Delphi 3. 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/opinion/1998/04/di199804ft_o/di199804ft_o.asp, o visite http://www.danyshop.com para conocer las razones por las que es conveniente actualizarse. Passthrough SQL connection must be shared Posible causa de error Puede estar utilizando Microsoft Access e intentó actualizar los resultados de una consulta. 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. Path not found. File <> Posible causa de error Puede estar intentando abrir o activar un componente TTable cuya propiedad DatabaseName apunta a una ubicación de la tabla indicada en la propiedad Mensajes de error 433 TableName que difiere de la ubicación real de la tabla. La tabla puede haber sido movida o borrada, o el alias no ha sido configurado apropiadamente. 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 herramienta 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. Path too long Posible causa de error Puede estar utilizando tablas Paradox anteriores al nivel 7. 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”. Pointer type required Posible causa de error Puede estar intentando aplicar un operador de derreferenciación (^) a un identificador que no es un puntero. Los dos ejemplos siguientes generarán este mensaje de error: { Ejemplo A } procedure ItsNotPoliteTo; var i, j: Integer; p: Pointer; begin p := @i; 434 Los Tomos de Delphi: Delphi sin problemas i^ := j; //esto provoca el error, ya que i no es un puntero //y no puede aplicársele el operador ^ { 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. Preparation of default expression failed with error “Type mismatch in expression” Posible causa de error Puede haber asignado a la propiedad DefaultExpression de un TField un valor que no es un entero o no está encerrado entre apóstrofes. Por ejemplo, si asigna True o False como DefaultExpression para un campo TBooleanField, obtendrá este mensaje de error. Mensajes de error 435 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. Previous declaration of <> was not marked with the ‘overload’ directive Posible causa de error 1. Puede estar intentando crear una segunda versión de un método con una lista de parámetros diferente del primero (esto es lo que el mensaje de error indica). 2. Puede tener listas de parámetros diferentes en la sección Implementation y en la sección Interface para un mismo método, procedimiento o función. Por ejemplo, puede tener en la interfaz una declaración similar a ésta: procedure BelowZeroError(Sender: TObject); y en la implementación una definición como ésta: procedure BelowZeroError(PercentageType: String; Sender: TObject); 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. Procedure cannot have a result type Posible causa de error Puede haber declarado un procedimiento, pero le asoció un tipo de resultado. Por ejemplo, lo siguiente generará este mensaje de error: procedure FetchMySlippersFido: TSlippers; 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 procedimiento devuelva un valor, puede pasar un parámetro Var al procedimiento: Mensajes de error 437 procedure HotEnoughForYa(var globalWarming: Boolean); var Centigrade: integer; begin Centigrade := StrToInt(Edit1.Text); if Centigrade > 77 then globalWarming := True; end; Procedure FAIL only allowed in constructor Posible causa de error Puede haber llamado a Fail en algún lugar que no es un constructor. Por ejemplo, lo siguiente generará este mensaje de error: if Grade in ['D','F'] then Fail; 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. Procedure, function or property expected Posible causa de error Puede haber seleccionado Edit | Add to Interface en un proyecto que tiene una biblioteca de tipos, pero olvidó especificar el tipo del elemento que quiere añadir a la interfaz. Por ejemplo, si escribe “Condemned” en el cuadro de edición, obtendrá este mensaje de error. 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 de resultado: function <nombre>: <tipo_resultado>. Si añade una propiedad, debe especificar un tipo: property <nombre>: <tipo>. Procedure or Function expected Posible causa de error Puede estar intentando crear un método de clase, pero olvidó añadir la palabra reservada Function o Procedure. Por ejemplo, lo siguiente generará este mensaje de error: public function BillyCanYouLendMeA: Currency; class a; 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 instancia 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; Los constructores y destructores son tipos especiales de métodos de clase. Mensajes de error 439 Procedure or Function name expected Posible causa de error Puede haber especificado un identificador que no es un procedimiento o función en una cláusula Exports. Por ejemplo, si Yoopdl es el nombre de una variable de tipo Integer, lo siguiente en un archivo de biblioteca (.DLL) generará este mensaje de error: exports yoopdl; 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 funció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. Program or unit <> recursively uses itself Posible causa de error Puede haber añadido el nombre de la unidad actual a su propia cláusula Uses (en la sección Interface o Implementation). Por ejemplo, lo siguiente generará este mensaje de error: unit TheGooch; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, TheGooch; 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á bastante general, como ERangeError, EInvalidCast, EInvalidPointer, EStringListError) 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 producido 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 estuviera activada)*. Para volver al entorno de tiempo de diseño para trabajar con el problema: Pulse Ctrl+F2. -OPulse Alt+R, E. -OSeleccione 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 3. En la sección Debugging, marque la casilla de verificación Break on Exceptions. Property <> does not exist in base class Posible causa de error Puede haber declarado una propiedad sin declarar su tipo. Por ejemplo, puede haber hecho algo así: published property ValuesKeepSkyrocketing; Solución rápida Si la propiedad es nueva para la clase, debe añadir el tipo de datos de la propiedad, 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 propiedad 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 continuació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; Property <> inaccessible here Posible causa de error Puede haber intentado acceder a una propiedad dentro de un procedimiento o función. Por ejemplo, lo siguiente generará este mensaje de error: class procedure TWhatever.Cre8Yourself; begin with TWhatever.Create(Application) do Show; SomeProperty := 1; end; 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 concretas de la clase. Información adicional Consulte “Instance variable <> inaccessible here” en este libro. Mensajes de error 443 Property does not exist Posible causa de error Puede estar abriendo un proyecto creado en Delphi 4 o superior con Delphi 3 o una versión inferior. Solución rápida Abra el proyecto con la versión más nueva de Delphi, pulse con el botón derecho 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. Property getters and setters cannot be overloaded Posible causa de error Puede haber añadido métodos de acceso de lectura (getters) o de escritura (setters) sobrecargados a una declaración de la clase. Por ejemplo, lo siguiente generará este mensaje de error: type TGoIrish = class function GoGetter: Integer; overload; function GoGetter: String; overload; procedure IrishSetter(Value: Integer); overload; procedure IrishSetter(Value: String); overload; Solución rápida Borre la directiva Overload de todos los métodos de acceso y elimine una versió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 modificació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 Property overrides not allowed in interface type Posible causa de error Puede haber derivado un tipo de interfaz de otro, y utilizó la misma propiedad en la interfaz derivada. Por ejemplo, lo siguiente generará este mensaje de error: type BigDog = interface function Fetch: Integer; procedure Dig(ADepth : Integer); property PapersAndHoles: Integer read Fetch write Dig; end; Puppy = interface (BigDog) function FetchQuicker: Integer; property PapersAndHoles: Integer read FetchQuicker; end; 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. Provider name was not recognized by the server Posible causa de error Puede haber hecho cambios a la aplicación servidora sin reconstruir todo el proyecto. 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 Published field <> not a class nor interface type Posible causa de error 1. Puede haber intentado declarar un campo que no es de un tipo de clase en una sección Published. Por ejemplo, lo siguiente generará este mensaje de error: type TScantyClass = class published eye : Integer; end; 2. Puede haber olvidado especificar la visibilidad para un campo que declaró en una clase. Por ejemplo, lo siguiente generará este mensaje de error: type TMyClass = class(TComponent) FInteger: Integer; . . . end; 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 Published property <> cannot be of type <> Posible causa de error Puede haber declarado una propiedad de un tipo que no es ordinal, Single, Double, Extended, Comp, String, Set (hasta 16 elementos en Delphi 1; hasta 32 elementos en Delphi de 32 bits), o puntero a método. 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. Published real[48] property <> must be Single, Double, or Extended Posible causa de error Puede haber intentado publicar una propiedad de tipo Real en Delphi 1, 2 ó 3. Por ejemplo, lo siguiente generará este mensaje de error: . . . private FElCamino: Real; public { Public declarations } published property ElCamino: real read FElCamino write SetElCamino; Solución rápida Cambie la declaración de Real a Single, Double o Extended. Por ejemplo, cambiar 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. PutObject to undefined item Posible causa de error Puede estar intentando insertar en una lista de cadenas un objeto que no tiene una cadena correspondiente. 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. Query Is Too Complex Posible causa de error Puede que la propiedad UpdateMode de un TQuery tenga el valor UpWhereAll. 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ó grabar 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 Todos los campos (si UpdateMode es igual a UpWhereAll). Comparar todos los campos puede resultar en un duro golpe para el rendimiento; en consecuencia, el mensaje de error. Query makes no sense Posible causa de error Puede estar intentando una inserción, pero ha especificado nombres de columnas en lugar de los valores a insertar. Por ejemplo, lo siguiente generará este mensaje de error: INSERT INTO TEAM VALUES(Catcher, Pitcher, Shortstop, Centerfield) 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; Para especificar valores literales, sustituya la línea SQL.Add por: SQL.Add('INSERT INTO TEAM VALUES(’ + QuotedStr(‘Hoiles’) + QuotedStr(‘Mussina') + QuotedStr('Bordick') + QuotedStr('Anderson') + ‘)’); 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 Query may take a long time to process Posible causa de error Puede estar utilizando una sentencia SQL que devuelve un conjunto de resultados muy grande, por ejemplo SELECT * FROM TEXAS WHERE FAVORITE_EXPRESSION = 'YEE-HAH!' 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!' Range check error Posible causa de error 1. Puede haber intentado acceder mediante un índice a un elemento de un array proporcionando un número que es mayor que el tamaño del array. Por ejemplo, lo siguiente produciría este mensaje de error: procedure TForm1.Button2Click(Sender: TObject); var i: integer; a: array[1..16] of integer; begin i := 17; a[i] := 1; {se intenta asignar al elemento 17, que no existe} end; 2. Puede haber intentado asignar a una variable un valor muy grande para el tipo de datos de la variable. Por ejemplo, un intento de asignar un número negativo o un número positivo mayor que 255 a una variable Byte generaría este mensaje de error. 450 Los Tomos de Delphi: Delphi sin problemas 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 valores que la variable puede necesitar manejar. Información adicional Para más información, consulte “range checking” en la ayuda de Delphi. Read failure. File: <>.val Posible causa de error Puede haber intentado asignar True a la propiedad Active de un componente TTable que representa una tabla Paradox, y la tabla contiene un archivo .VAL dañado. 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 Database 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. Read or Write clause expected but identifier <> found Posible causa de error Puede haber olvidado proporcionar un especificador Read o Write en la declaración de una propiedad que lo requiere . Por ejemplo, debido a que las propiedades que son utilizadas para implementar interfaces por delegación requieren un especificador Read, lo siguiente generará este mensaje de error: Mensajes de error 451 property SomeInterface: ISomeInterface implements ISomeInterface; 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. Record already locked by this session Posible causa de error 1. Puede estar utilizando Paradox y tener un archivo .LCK o .NET dañado. 2. Puede haber asignado True a la propiedad Active de un conjunto de datos en tiempo de diseño. 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). Record changed by another user Posible causa de error Puede estar utilizando MS SQL Server, y el registro en cuestión contiene una columna DateTime. 452 Los Tomos de Delphi: Delphi sin problemas 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. Record Key deleted Posible causa de error Puede estar utilizando MS Access y un controlador ODBC. 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 Record Locked by another User Posible causa de error Puede estar intentando editar un registro mientras otro usuario lo tiene bloqueado. 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). Record, object or class type required Posible causa de error Puede haber intentado utilizar la palabra reservada With sobre una variable. Por ejemplo, lo siguiente generará este mensaje de error: var JAndJWentUpTheVerticallyChallengedMountain: Boolean; . . . with JAndJWentUpTheVerticallyChallengedMountain do if True then False; 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 mencionados en el mensaje de error, como componentes TQuery, etc. 454 Los Tomos de Delphi: Delphi sin problemas Recursive include file <> Posible causa de error Puede haber utilizado la directiva de compilador {$I <archivo>}, y el archivo que incluyó también contiene la misma directiva {$I <archivo>} (es decir, el archivo incluido está tratando de incluirse a sí mismo). Por ejemplo, si añadió: {$I Murder.inc} a una unidad, y el archivo contenía esta línea: {$I Murder.inc} obtendrá este mensaje de error. 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} a una unidad, y el archivo Murder.inc incluyó esto: { El idioma francés, con su gran cantidad de letras mudas, ha ocasionado el desperdicio de muchos galones de tinta. ¿no es cierto, Phydeaux? } Este comentario será añadido al código fuente. Redeclaration of <> hides a member in the base class Posible causa de error 1. Puede haber creado un descendiente de una clase y declaró un método que tiene el mismo nombre de alguno situado en la clase de la cual heredó, pero no ha utilizado la directiva Override. 2. Puede haber sido instalada una nueva versión de una clase base, a la que se han añadido nuevas propiedades y/o métodos que tienen el mismo nombre que otras propiedades y/o métodos en la clase descendiente. Mensajes de error 455 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 <>”. Redeclaration of property not allowed in OLE automation section Posible causa de error Puede haber intentado promover una propiedad heredada a la sección Automated de una clase descendiente. 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. Required package <> not found Posible causa de error Puede estar intentando compilar un paquete que contiene en su cláusula Requires una unidad (explícitamente por su nombre o implícitamente a través de una unidad utilizada por la unidad nombrada) que no existe o no está en la ruta de búsqueda de Delphi. 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 directorio \Windows\System. REQUIRES clause is incorrect Posible causa de error Puede haber omitido el punto y coma final en la cláusula Requires del archivo fuente de paquete, o añadió alguna extensión de archivo a la declaración. 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; Re-raising an exception only allowed in exception handler Posible causa de error 1. Puede haber intentado relanzar una excepción fuera de un bloque de excepción. 2. Puede haber reasignado el gestor de eventos OnException del objeto Application así: Application.OnException := FilterExceptions; y luego utilizó la palabra reservada Raise en el gestor de excepción personalizado, así: Mensajes de error 457 if ReportObj.ProgramMode = pmBatch then begin ReportObj.WriteToLogFile( SReportName, SDelphiErrorMessage+E.Message, SWindowsErrorCode+IntToStr(GetLastError), DateToStr(Now), TimeToStr(Now)); Abort; end else raise; 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 Exception, 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 desarrolladores. 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 excepciones que lleguen a ese punto. Sin embargo, no liberará los recursos por sí mismo — eso es responsabilidad del desarrollador. Resource <> not found Posible causa de error Puede haber añadido su propio recurso a un proyecto, pero éste no puede ser encontrado por el compilador debido a que está mal escrito el nombre del recurso o no está en el mismo directorio que el archivo de proyecto (.DPR). 458 Los Tomos de Delphi: Delphi sin problemas 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. Segment/Offset pairs not supported in Borland 32-bit Pascal Posible causa de error Puede estar utilizando una versión de Delphi diferente de Delphi 1 y haber especificado una dirección de memoria con un segmento y un desplazamiento. Por ejemplo, la siguiente declaración de variable generará este mensaje de error en Delphi de 32 bits: type Vodka = Integer; var Absolut: Vodka absolute $00:40; Solución rápida Si realmente necesita especificar una dirección, utilice una dirección de memoria “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. Selection contains a component introduced in an ancestor form which cannot be deleted Posible causa de error Puede haber intentado borrar un componente heredado de un formulario descendiente. Mensajes de error 459 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 formulario 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. Como se puede ver, el único objeto que ha sido añadido al formulario es un TButton, declarado como Button1: TButton. Cuando se hereda de este formulario (seleccionando File | New, y luego seleccionando el formulario de la página que tiene el mismo nombre del proyecto), el código fuente es: unit Unit2; interface uses Windows, Messages, SysUtils, Classes, 460 Los Tomos de Delphi: Delphi sin problemas Graphics, Controls, Forms, Dialogs; type TForm2 = class(TForm1) private { Declaraciones Private } public { Declaraciones Public } end; var Form2: TForm2; implementation {$R *.DFM} end. Como se puede ver, no hay una declaración explícita de un objeto TButton en la clase descendiente. Sin embargo, esto está implícito en la declaración TForm2 = class (TForm1), que dice, en efecto, que TForm2 hereda todo de TForm1 (incluyendo el botón). Si se permitiera borrar cualquier cosa de TForm2 que fuera heredada de TForm1, la declaración de arriba no sería válida, y el enlace de herencia quedaría roto. Server Execution Failed Posible causa de error Puede haber intentado asignar True a la propiedad Connect de un componente TDCOMConnection, TOLEEnterprise o TRemoteServer sin haber especificado una valor válido para la propiedad ServerName o ServerGUID. Solución rápida Proporcione en la propiedad ServerName o ServerGUID un valor correspondiente 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. Session name missing Posible causa de error Puede estar intentando asignar True a la propiedad Active de un componente TSession sin primero proveer un valor para su propiedad SessionName. Mensajes de error 461 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 nombre 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 contener 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 proporciona 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. Sets may have at most 256 elements Posible causa de error Puede haber intentado declarar un tipo conjunto (set) utilizando un tipo base que contiene más de 255 elementos. Por ejemplo, los siguientes tipos generarán este mensaje de error: type sow = set of Word; sos = set of String; 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 normalmente 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]; Recuerde, sin embargo, que no puede exceder el límite inferior de 0 ni el límite superior de 255. Ninguna de las declaraciones siguientes compilará: type TAWholeMessOfIntegers = -2..243; TAWholeMessOfIntegers = 23..263; Share not loaded. It is required to share local files Posible causa de error Al archivo SYSTEM.INI o AUTOEXEC.BAT le puede faltar una línea que es requerida por el BDE (el módulo Share no está cargado). 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 estos 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 estar 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 Para editar AUTOEXEC.BAT en una ventana DOS, siga estos pasos: 1. Teclee Edit autoexec.bat y pulse la tecla Enter. 2. Añada SET SHARE=C:\dos\share /F:4096 /L:40 al final del archivo. 3. Guarde el archivo, seleccionando File | Exit y luego Yes para grabar los cambios. 4. Escriba autoexec y pulse la tecla Enter. Size mismatch error Consulte “Record Key deleted”. Size of published set <> is greater than [4 bytes, 32 bits] Posible causa de error Puede haber intentado declarar un propiedad de un tipo conjunto que tiene más de 32 elementos. Por ejemplo, lo siguiente generará este mensaje de error: TGridIronMen = set of (TQuarterback, THalfback, TFullback, TTailback, TFlanker, TLWideReceiver, TRWideReceiver, TTightEnd, TLTackle, TRTackle, TRGuard, TLGuard, TCenter, TMiddleLinebacker, TNoseguard, TLDefensiveTackle, TRDefensiveTackle, TLDefensiveEnd, TRDefensiveEnd, TLLinebacker, TRLinebacker, TLSafety, TLCornerback, TRCornerback, TRSafety, TKicker, TPunter, TPuntReturner, TKickReturner, TSpecialTeamsDemon, TGeneralManager, TCoach, TWaterboy); type private FGridIronMen: TGridIronMen; public {} published property GridIronMen: TGridIronMen read FGridIronMen write FGridIronMen; Solución rápida Reduzca el tamaño del conjunto a una cantidad menor o igual que 32 elementos. 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 TFontStyle = (fsBold, fsItalic, fsUnderline, fsStrikeOut); TFontStyles = set of TFontStyle; La clase TFont luego declara una propiedad Style: property Style: TFontStyles read GetStyle write SetStyle; Puede luego asignar valores a la propiedad así: Font.Style := [fsBold, fsItalic]; Puede borrar todos los estilos asignándole a la propiedad el conjunto vacío: Font.Style := []; Para más información, consulte “sets (set types)” en la ayuda de Delphi. Slice standard function is only allowed as open array argument Posible causa de error Puede haber llamado a la función Slice, pero no está enviando el resultado a un procedimiento o función que espera un argumento de array abierto. Por ejemplo, lo siguiente generará este mensaje de error: procedure Chop; begin Slice(Dice,2); 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. Socket Error # 10061 – Connection Refused Posible causa de error 1. Puede estar intentando conectarse a un socket (representado por un componente TIdTCPServer) con un componente TIdTCPClient, y el servidor no está en ejecución. 2. Puede haber especificado un socket inválido o inexistente al intentar conectarse a un socket con un componente TIdTCPClient. 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. Socket Error # 10065 – No route to host Posible causa de error Puede estar intentando conectarse a un componente TIdTCPServer con un componente TIdTCPClient, pero ha introducido un valor erróneo en la propiedad Host de TIdTCPClient. 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. Socket Error # 11001 – Host not found Posible causa de error Puede estar intentando conectarse a un componente TIdTCPServer, pero no es posible establecer una conexión con la máquina a la cual está intentando conectarse. Por ejemplo, puede estar intentando conectarse a un servidor HTTP, pero no tiene una conexión a Internet activa. 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. SQL Connection timed out Posible causa de error 1. Puede estar experimentando un bajo rendimiento de la red. 2. Puede estar intentando obtener un conjunto resultado muy grande. 3. Puede que necesite cambiar el valor de un parámetro del controlador del BDE o de su sistema de base de datos. 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 datos. Si no es tan obvio, trate de preguntar en los grupos de noticias relaconados con su base de datos. 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. SQL Dialect Invalid Posible causa de error Puede haber cambiado el valor de la propiedad SQLDialect de un componente TIBDatabase a algo diferente de 1 mientras utilizaba una versión de InterBase anterior a InterBase 6. 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 anteriores. 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). SQL is too complex Posible causa de error Puede haber intentado grabar registros mientras la propiedad UpdateMode del objeto TTable o TQuery tiene asignado el valor UpWhereAll. 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 valor UpWhereAll en el parámetro UpdateMode, algunos controladores de bases de datos no son lo suficientemente robustos para manejarlo. Para más información, consulte “UpdateMode” en la ayuda de Delphi. 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 unidad 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 recursió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 inicial 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} 2. Reduzca el tamaño y cantidad de las variables globales. 3. Si no está utilizando deliberadamente la recursión, verifique el código de gestores de eventos como OnChange, donde puede estar provocando un cambio que dispara el evento de nuevo, que provoca el cambio de nuevo, que dispara el evento de nuevo, etc. 4. Pase punteros a registros en lugar de pasar los propios registros. 5. Divida los procedimientos y/o funciones grandes en otros más pequeños. 6. Pase las variables grandes como parámetros variables o constantes. Mensajes de error 469 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 infinita (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. Statement expected, but expression of type <> found Posible causa de error Puede estar intentando llamar al procedimiento Abort de la unidad SysUtils, pero también tiene la unidad DbiProcs o BDE en la sección Uses. 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) contienen 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. Statements not allowed in interface part Posible causa de error Puede haber añadido una sentencia a la parte Interface de una unidad. Por ejemplo, lo siguiente generará este mensaje de error: unit Unit4; interface procedure ColorFormWhite(Sender: TObject); begin TForm(Sender).Color := clWhite; 470 Los Tomos de Delphi: Delphi sin problemas 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. STORED clause not allowed in OLE automation section Posible causa de error Puede estar intentando utilizar la cláusula Stored en la sección Automated. 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 almacenamiento Stored, Default o Nodefault. No obstante, estas directivas de almacenamiento no están permitidas en la sección Automated. Stream Read Error Posible causa de error Puede estar intentando cargar un formulario creado en Delphi de 32 bits en Delphi 1. 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 Delphi de 32 bits no puedan ser utilizados en Delphi 1 son las cadenas largas, el tipo TCollection, y la herencia de formularios. String constant truncated to fit STRING[ ] Posible causa de error Puede haber asignado una cadena a una variable cuyo tamaño es menor que el de la cadena que está intentando asignar. Por ejemplo, lo siguiente generará este mensaje de error: var s: String[3]; begin s := ’string’; Solución rápida Modifique el tamaño de la cadena, o asigne una cadena que quepa en la variable. Por ejemplo, cualquier de las siguientes soluciones funcionará: var s: String[6]; begin s := ’string’; -Ovar s: String[3]; begin s := ’str’; Información adicional Para más información, consulte “strings” en la ayuda de Delphi. String [literal]s may have at most 255 elements Posible causa de error 1. Puede haber declarado una cadena corta de más de 255 caracteres. Por ejemplo, la siguiente declaración generará este mensaje de error: var s: string[256]; 472 Los Tomos de Delphi: Delphi sin problemas 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. Syntax Error in Field Definition Posible causa de error Probablemente tiene un error de sintaxis en una sentencia SQL. Por ejemplo, lo siguiente generará este mensaje de error: with TADOQuery.Create(nil) do begin try Connection := ADOConnection1; SQL.Add(’ALTER TABLE SCRIPTURES’); SQL.Add(’ADD INDEX ORD_SEQ ON ORDER_SEQUENCE’); Mensajes de error 473 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; En otras palabras, la sintaxis SQL correcta en este caso es: CREATE INDEX <NombreIndice> ON <NombreTabla>(<NombreCampo>) Información adicional Utilice la referencia de SQL de la base de datos que esté utilizando para determinar 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”. Syntax error in query. Incomplete query clause Posible causa de error Puede estar intentando acceder a una tabla de Access que tiene espacios en su nombre, pero ha olvidado encerrar el nombre de la tabla entre corchetes. Por ejemplo, puede haber hecho algo así: SELECT * FROM "ROUND TABLE" 474 Los Tomos de Delphi: Delphi sin problemas 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. Syntax error in real number Posible causa de error Puede haber añadido un factor de escala a un número de punto flotante sin seguidamente haber escrito el exponente. Por ejemplo, lo siguiente generará este mensaje de error: var Mint: Double; begin Mint := 123.E; 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”. System unit out of date or corrupted Posible causa de error La ruta de búsqueda de bibliotecas puede estar apuntando a una versión obsoleta de SYSTEM.DCU, o SYSTEM.DCU puede haberse dañado. Mensajes de error 475 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úsqueda de archivos y carpetas del Explorador de Windows. Si no encuentra ninguna 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 convenio 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 unidades nombres como DRISStrUtils, DRISConsts, DRISGlobal, etc. Table cannot be opened for exclusive use Posible causa de error Puede estar intentando llevar a cabo sobre una tabla abierta una acción que requiere que la tabla esté cerrada para poder ser llevada a cabo. Por ejemplo, no puede vaciar una tabla (llamando al método EmptyTable de TTable) o añadir índices a una tabla que esté abierta. 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; Active es una propiedad de TTable, que puede ser asignada así: Table1.Active := True; 476 Los Tomos de Delphi: Delphi sin problemas Si trata de añadir un segundo índice por un mismo campo mediante código, también se generará este mensaje de error. Por ejemplo, la segunda línea en el siguiente fragmento de código produce este error: Table1.AddIndex('LastNameAsc', 'LastName', []); Table1.AddIndex('LastNameDesc', 'LastName', [ixDescending]); Table corrupt—other than header Posible causa de error Puede estar utilizando tablas de Paradox sobre una red Windows NT y no ha asignado True a Local Share en cada uno de los clientes y/o tiene habilitados los bloqueos oportunistas. 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 necesario) 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. Table does not exist Posible causa de error 1. Puede tener un error en la sentencia SQL. Verifique la ortografía en la propiedad SQL del objeto TQuery, ya que puede faltar el nombre de la tabla. 2. Puede haber intentado asignar True a la propiedad Active de un objeto TTable sin proporcionar un valor válido a la propiedad DatabaseName. Mensajes de error 477 3. Puede estar intentando utilizar un componente TBatchMove, habiendo asignado a su propiedad UpdateMode un valor distinto de batCopy, y la tabla de destino no corresponde a una tabla existente en la ubicación especificada por la propiedad DatabaseName. 4. Puede estar intentando acceder a tablas Oracle a través de una sentencia SQL utilizando un objeto TQuery con la propiedad RequestLive asignada a True, pero ha olvidado escribir en mayúsculas los nombres de las tablas. 5. Puede estar intentando acceder a tablas de MS SQL Server, y ha olvidado anteponer dbo. al nombre de la tabla. Por ejemplo, puede estar utilizando el siguiente tipo de sentencia SQL: SELECT * FROM Cooper 6. Puede estar intentando acceder a una tabla que está activa en otro hilo o conexión. 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). Table does not support this operation Posible causa de error 1. Puede estar utilizando SQL Anywhere y llamando al método RecordCount de un objeto TTable asociado a una tabla que contiene campos memo. 478 Los Tomos de Delphi: Delphi sin problemas 2. Puede estar accediendo a tablas de MS SQL Server y olvidó anteponer dbo. al nombre de la tabla. Por ejemplo, puede tener un sentencia SQL como: SEECT * FROM UHF 3. Puede estar intentando llamar a Refresh sobre un TQuery asociado a una base de datos SQL Server (Oracle, MS SQL Server, InterBase, etc.) que tiene asociada una consulta compleja o que involucra productos cartesianos. Solución rápida 1. Si está llamando a RecordCount para determinar si la cantidad de registros 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 sentencia 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 particularidades 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 propiedad Active del componente. 3. Encierre la sentencia que asigna True a la propiedad Exclusive en un bloque 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 propiedad 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 Configuration/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, modifique 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 configuració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 configuración del parámetro Block Size en la configuración del BDE: Tamaño bloque Tamaño máximo de tabla 2 KB 128 MB 4 KB 256 MB 8 KB 512 MB 16 KB 1.024 MB 32 KB 2.048 MB Table is not indexed Posible causa de error Puede estar intentando crear un índice secundario sobre una tabla Paradox que no tiene un índice primario. 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 primera 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]); Para más información, consulte “secondary indexes” en la ayuda de Delphi. Table is read only Posible causa de error 1. Puede haber intentado llamar al método Edit o Delete de un objeto TTable cuya propiedad ReadOnly tiene asignado el valor True. 2. Puede estar intentando editar el resultado de una consulta que conecta varias tablas. 3. Puede estar intentando editar el resultado de una consulta sobre una única tabla, y el parámetro RequestLive del objeto TQuery tiene asignado False. 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 Table or View does not exist Posible causa de error 1. Puede no tener derechos para ver la tabla o vista a la que está intentando acceder. 2. Puede estar utilizando una consulta “viva” (con valor True en su propiedad RequestLive) y no haber utilizado las mayúsculas para especificar el nombre de la tabla. Por ejemplo, lo siguiente generará este mensaje de error: SELECT * FROM Round 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 administrador de la base de datos. 2. Si asigna True a la propiedad RequestLive de un componente TQuery, utilice 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. TActiveFormX declaration missing or incorrect Posible causa de error Puede haber cambiado el nombre de una CoClass antes de cambiar el nombre del formulario. 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 y modifíquela para que contenga el nombre su variable de instancia y su tipo de clase, por ejemplo: object Whatever: TWhatever Mensajes de error 483 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. Text after final END Posible causa de error Puede tener algún texto después del End final. (El End final va seguido de un punto en lugar de un punto y coma). 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á después del End final, pero no impide la compilación. En este caso, la frase “ignored by compiler” se añade al mensaje de error. The <>.EXE file is linked to missing export <>.DPL:<> Posible causa de error Puede haber creado una aplicación que utiliza paquetes, y actualizó uno o más de los paquetes que usa sin actualizar el .EXE. 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 buscará la versión antigua del paquete. El nuevo paquete solamente será encontrado 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 declaración Published explícita. Todos los métodos que usted añade son automáticamente 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. Después de crear un botón y asociarle un gestor de eventos, el archivo .PAS tendrá la siguiente apariencia: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) {ésta es la sección Published} Button1: Tbutton; {Los componentes que coloque sobre el formulario serán colocados en la sección Published} procedure Button1Click(Sender: TObject); {Los gestores de eventos que cree serán colocados en la sección Published} private { Declaraciones Private } public { Declaraciones Public } end; var Form1: TForm1; implementation {$R *.DFM} end. Esto es diferente a lo que ocurre en el caso de un archivo de componente .PAS, que contiene explícitamente secciones Private, Protected, Public y Published. El siguiente código es del que usted deberá partir si utiliza el Asistente de Componentes (Component Wizard) para crear un nuevo componente basado en el componente TStringGrid: unit StringGrid1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids; type TStringGrid1 = class(TStringGrid) private { Declaraciones Private } protected 486 Los Tomos de Delphi: Delphi sin problemas { Declaraciones Protected } public { Declaraciones Public } published { Declaraciones Published } end; procedure Register; implementation procedure Register; begin RegisterComponents('Samples', [TStringGrid1]); end; end. The <> method referenced by <>.<> has an incompatible parameter list. Remove the reference? Posible causa de error Puede haber cambiado la lista de parámetros original del método (la que está en la parte Interface). 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). The application or DLL <> is not a valid Windows image. Please check this against your installation diskette. Posible causa de error Puede haber intentado registrar un servidor de automatización de Delphi antes de compilarlo. Por ejemplo, si escribe <Proyecto>.DPR /regserver en la línea de comandos, obtendrá este mensaje de error. 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 avisará 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. The Edit Buffer of <> is marked read-only Posible causa de error Puede estar intentando editar un archivo bloqueado. Por ejemplo, puede estar intentando hacer cambios a un archivo que ha sido marcado como de sólo lectura desde un sistema de control de versiones como PVCS. 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. The Master Source property of <> must be linked to a DataSource Posible causa de error Puede haber intentado asignar la propiedad MasterFields de un componente TTable sin primero haber asignado la propiedad MasterSource. 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 The package already contains unit named <> Posible causa de error Está intentando instalar un componente dentro de un paquete que ya contiene un componente con el mismo nombre. 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 instalarla 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. Primero las malas noticias: los paquetes añaden complejidad al proceso de desarrollo 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 aplicaciones escritas en Delphi. En lugar de tener el núcleo de la funcionalidad de Delphi embebida cada ejecutable, los paquetes permiten distribuir un ejecutable reducido que llama a los paquetes (.DLLs específicas de Delphi) cuando necesita cierta funcionalidad. The package already requires a package named <> Posible causa de error Puede haber intentado añadir un paquete a la sección Required de otro paquete que ya ha sido especificado en la sección Required del primer paquete. 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. The page cannot be displayed Posible causa de error Puede haber especificado incorrectamente el puerto en el URL, o ningún puerto, o está escuchando por el puerto equivocado en su aplicación Site Express. 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. The path entered does not exist Posible causa de error Puede haber seleccionado el botón Finish en el Asistente de Aplicaciones (Application Wizard) sin haber especificado una ruta válida en el cuadro de edición donde se debe indicar dónde la aplicación se almacena. 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. The project already contains a form or module named <> Posible causa de error Puede estar intentando darle a un formulario o unidad el mismo nombre de otro ya existente en el proyecto. Puede ser que esté tratando de asignarle a un formulario el mismo nombre de archivo que el nombre de componente que le ha asignado en el Inspector de Objetos (o el nombre que Delphi asigna por defecto) — por ejemplo, Form1. 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 nombre 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. The Resource DLL Wizard requires a project to be open Posible causa de error Puede haber seleccionado el Asistente de .DLLs (File | New | DLL Wizard) sin tener un proyecto abierto. 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ísticas 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. The search string cannot be blank Posible causa de error Puede haber intentado buscar una cadena en el entorno integrado de Delphi utilizando Search | Find, pero olvidó introducir una cadena para buscar en el cuadro de combinación correspondiente. 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. The selected bitmap is larger than 24x24 Posible causa de error Mientras creaba una plantilla de componente, puede haber intentado grabar un mapa de bits para el icono del componente que es demasiado grande para ser mostrado en el espacio reservado para ello en la página correspondiente de la Paleta de Componentes. 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 componente seleccionado, si seleccionó los componentes utilizando el ratón y la 494 Los Tomos de Delphi: Delphi sin problemas tecla May, o b) el del componente situado más a la izquierda o más arriba, si seleccionó los componentes marcando un área con el ratón. Si no desea utilizar el icono por defecto, puede crear uno (recuerde que no debe ser mayor de 24 x 24 píxeles) con el Image Editor o cualquier otro programa de edición de mapas de bits, como Microsoft Paint. Para crear un icono con el Image Editor, siga estos pasos: 1. Seleccione Tools | Image Editor. 2. Seleccione File | New. . . | Bitmap file (OJO: no Icon file, aunque el cuadro de diálogo Component Template Information lo llama ‘Palette Icon’). 3. Asigne 24 a Width (ancho) y Height (altura). 4. Seleccione View | Zoom In hasta cuatro veces (dependiendo de su preferencia). 5. Cree el mapa de bits que desee utilizar como su icono de la paleta. 6. Guarde el archivo de mapa de bits. The server returned an invalid response Posible causa de error Puede estar haciendo referencia a un método de la interfaz Webbrokerscript, pero su biblioteca de tipos no ha sido registrada. 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 soportan 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. The type library has syntax errors Posible causa de error Probablemente ha omitido algo necesario de la biblioteca de tipos, como una interfaz para una CoClass. 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”. Consulte la discusión sobre este mensaje de error para detalles más específicos. 496 Los Tomos de Delphi: Delphi sin problemas There is currently no active project Posible causa de error Puede haber seleccionado File | New | Control Panel Applet sin tener activo un proyecto de aplicación del Panel de Control. Solución rápida Abra primero una aplicación del Panel de Control, seleccionando File | New | Control Panel Application. Posible causa de error Las aplicaciones del Panel de Control pueden ser creadas con la versiones Professional y Enterprise de Delphi. There is no default printer currently selected Posible causa de error Puede estar ejecutando Citrix Winframe sobre Windows NT y no ha establecido una impresora por defecto. 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. There is no overloaded version of <> that can be called with these arguments Posible causa de error 1. Puede estar llamando a una función de conversión inapropiada. Por ejemplo, lo siguiente generará este mensaje de error: HollywoodSquare := IntToStr(Sqr(StrToInt(edtNum2Square.Text))); Mensajes de error 497 2. Puede estar pasando un parámetro de un tipo diferente al indicado en la signatura del método al que está llamando. Por ejemplo, el siguiente código generará este mensaje de error: if SelectDirectory(TaxSolver.FileLocation, [sdAllowCreate, sdPerformCreate, sdPrompt], 0) then debido a que TaxSolver.FileLocation es una propiedad, y SelectDirectory espera un parámetro Var como primer argumento. 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. This form of method call only allowed for class methods Posible causa de error 1. Puede haber estado intentando llamar a un método normal utilizando el tipo de clase en lugar de una instancia (variable) del tipo. Esto es solamente permitido para los métodos de clase — no para métodos normales. 2. Puede haber olvidado anteponer el tipo de la clase al nombre del método. 3. Puede estar intentando llamar a un método abstracto desde la unidad en la que éste ha sido declarado. 498 Los Tomos de Delphi: Delphi sin problemas 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 procedure Rock; virtual; abstract; procedure Thump; dynamic; abstract; end; sus métodos puede ser redefinidos en una clase descendiente así: type TGarryTallent = class(TBassist) procedure Walk; override; procedure Rock; override; procedure Thump; override; end; This form of method call only allowed in methods of derived types Posible causa de error Este mensaje de error se produce si se intenta hacer una llamada a un método de un tipo ancestro, pero no se hace desde un método. Puede simplemente haber olvidado anteponer el nombre del tipo al nombre del método. Por ejemplo, lo siguiente generará este mensaje de error: procedure KeyPress(var Key: Char); var TextLength, i: Integer; begin inherited KeyPress; 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 This package already contains unit named <> Posible causa de error Está intentando instalar una unidad dentro de un paquete que ya contiene una unidad con el mismo nombre. 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). This type cannot be initialized Posible causa de error Puede estar intentando declarar una constante con tipo (variable inicializada) del tipo File, Text, Textfile o Variant. Por ejemplo, lo siguiente generará este mensaje de error: argyle: array[0..1] of variant = ('zig','zag'); El mensaje de error también será generado si en lugar de Variant se hubiera utilizado Text, File o Textfile. 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 Thread local variables cannot be ABSOLUTE Posible causa de error Puede haber aplicado la palabra reservada Absolute a una variable local de un hilo (Threadvar). 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 utilizació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. Thread local variables cannot be local to a function Posible causa de error Puede haber intentado declarar una variable local de hilo, mediante la palabra reservada Threadvar, en un método de un objeto TThread o descendiente. Por ejemplo, lo siguiente generará este mensaje de error: procedure TFancyThread.Execute; threadvar ILostTheThread: Integer; begin { Coloque el código del hilo aquí} end; 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 Token not found Posible causa de error Puede haber omitido una parte necesaria de una sentencia SQL. Por ejemplo, puede haber introducido: FROM Customer WHERE AmountOwed > 0 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 * { FROM Customer { WHERE { AmountOwed lista de campos } lista de tablas } cláusula where opcional} > 0 Token not found. Token :dbo. line number:1 Posible causa de error Puede estar utilizando un componente TQuery con su propiedad RequestLive asignada a True y no ha encerrado el propietario/nombre de la tabla entre dobles comillas. Por ejemplo, la sentencia SQL podría ser similar a ésta: SELECT * FROM dbo.COOPER 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 Too many actual parameters Posible causa de error 1. Puede haber proporcionado más parámetros a un procedimiento o función que la cantidad de parámetros con la que éste ha sido declarado. 2. Puede estar intentando pasar más de 255 parámetros individuales a un procedimiento o función de automatización OLE. 3. Puede estar llamando a un procedimiento o función del que hay dos versiones, y el compilador piensa que está intentando llamar a una versión distinta de la que usted tiene en mente. 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 automatizació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. Too many connections Posible causa de error Puede estar utilizando demasiadas conexiones a bases de datos asociando directamente cada componente TTable, TQuery y TStoredProc a un alias del BDE a través de su propiedad DatabaseName. 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 Name del componente TDatabase a la propiedad DatabaseName de todos los componentes TTable, TQuery y TStoredProc. 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. Too many files open Posible causa de error 1. 2. 3. 4. Puede Puede Puede Puede estar intentando escribir en un CD-ROM. estar olvidando cerrar los archivos después de abrirlos. tener un valor muy pequeño en el parámetro Files en CONFIG.SYS. tener su proyecto en un directorio con un nombre de ruta muy largo. Solución rápida 1. CD-ROM significa Compact Disc-Read Only Memory (Memoria de sólo lectura 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 3. Cuando mueva un proyecto de un directorio a otro, no mueva el archivo .DSM del proyecto, ya que contiene información de directorio (y por lo tanto apuntará al directorio anterior). Too many locks on table Posible causa de error Puede haber modificado más de 255 registros de una tabla Paradox durante una transacción sobre una base de datos local. 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. Too many open cursors Posible causa de error Puede tener muchas tablas abiertas. Solución rápida Cierre las tablas cuando termine de utilizarlas. Si utiliza una cantidad relativamente pequeña de tablas (hasta varias docenas), probablemente podrá esperar 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 configurado a un valor independiente, distinto del configurado para el BDE. Consulte la documentación de su base de datos para más detalles. Too many open files Posible causa de error 1. Puede tener más archivos abiertos de los que Windows puede manejar. 2. Puede tener más archivos abiertos que el límite impuesto por el parámetro MAXFILEHANDLES del BDE. 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”. Too many parameters Posible causa de error 1. Puede estar proporcionando a un procedimiento o función más parámetros de los especificados en su declaración. Por ejemplo, si llama al procedimiento estándar Release (que no tiene parámetros) y le pasa un parámetro, recibirá este mensaje de error: Release(MeLetMeGo); 2. Puede estar intentando llamar en una clase descendiente a un método estático que tiene el mismo nombre que un método de una clase ancestro, pero el tipo de la variable es del tipo ancestro (aunque se haya instanciado el tipo descendiente). Por ejemplo, lo siguiente generará este mensaje de error, ya que los métodos estáticos son resueltos de acuerdo al tipo de la variable (TGramps en este caso), y no al tipo de la instancia (que en este caso es TYoungWhipperSnapper): type TGramps = class procedure NoteOrTriad(note: string); . . . TYoungWhipperSnapper = class(TGramps) procedure NoteOrTriad(note1, note2, note3: string); Mensajes de error 507 . . . 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; Transaction not Assigned Posible causa de error Puede tener algunos conjuntos de datos abiertos en tiempo de diseño o que se han dejado abiertos al salir del programa en una aplicación de InterBase Express. 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. Translate error, value out of bounds Posible causa de error 1. Puede estar copiando datos de una máquina a otra (por ejemplo, de un cliente a un servidor) donde los formatos de fecha son diferentes. Mensajes de error 509 2. Puede estar copiando datos de un tipo de base de datos a otro, y los formatos de fechas no son iguales. 3. Puede estar trabajando con una tabla dBASE y estar utilizando un controlador 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 compatibilidad con la automatización OLE. Tried to search marked block but it is invalid Posible causa de error Puede tener el entorno integrado configurado para buscar en el bloque marcado (en lugar de ejecutar un búsqueda global), pero no hay un bloque marcado. Solución rápida Marque un bloque para buscar, o cambie la opción de búsqueda a global, marcando 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. Type <> has no type info Posible causa de error Puede estar intentando obtener un puntero a la información de tipos para un tipo que no puede ser utilizado en una propiedad Published y por lo tanto no 510 Los Tomos de Delphi: Delphi sin problemas tiene información de tipos en tiempo de ejecución asociada a él. Por ejemplo, lo siguiente generará este mensaje de error: var BirdDog: Pointer; begin BirdDog := TypeInfo(file); 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. Type <> is not yet completely defined Posible causa de error Puede tener asignada como clase ancestro a la misma clase descendiente en una sección Type. Por ejemplo, lo siguiente generará este mensaje de error: type TForm3 = class(TForm3) 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 <> must be a class to have a PUBLISHED section Posible causa de error Puede haber declarado un objeto utilizando el viejo estilo (Turbo Pascal con Objetos) y haber intentado proporcionarle una sección Published. Por ejemplo, lo siguiente generará este mensaje de error: Mensajes de error 511 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. Type <> must be a class to have OLE automation Posible causa de error Puede haber declarado un objeto utilizando el viejo estilo (Turbo Pascal con Objetos) y haber intentado proporcionarle una sección Automated. Por ejemplo, lo siguiente generará este mensaje de error: type TModel = object Black: TColor; automated AssemblyLines: Integer; 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 Type <> needs finalization—not allowed in file type Posible causa de error Puede estar declarando cadenas largas en un tipo File of Record. Por ejemplo, lo siguiente generará este mensaje de error: type TDateRec = File of record FlowSnakes, Snirt: Integer; Bouldershades: String; end; 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 registros, y en este caso el tamaño del registro no podría ser determinado por adelantado. Type expected but <> found Posible causa de error Puede haber introducido un carácter ilegal en un identificador de tipo. Por ejemplo, lo siguiente generará este mensaje de error: type ShesNotMy = @ 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. Type expected but real constant found Posible causa de error Puede haber omitido uno de los dos puntos requeridos en la declaración de un tipo array. Por ejemplo, lo siguiente producirá el mensaje de error bajo discusión: type gross = array[0.143] of integer; 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; Type mismatch for field <FieldName>, expecting: <Field type>, actual: <Field type> Posible causa de error Puede estar utilizando un TClientDataSet para almacenar datos, y ha grabado datos para una columna en particular en un formato (por ejemplo, AsMemo); luego ha creado un descendiente de TFieldType de otro tipo de datos (como TStringField), e intentado asignar los datos en el archivo actual al campo del ClientDataSet. 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. Type mismatch [in expression] Posible causa de error Puede haber intentado ejecutar una operación de agregación sobre un campo no numérico en una sentencia SQL. Por ejemplo, lo siguiente generará este mensaje de error si el campo State no es numérico: SELECT AVG(State) FROM CUSTOMER 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. Type not allowed in OLE Automation call Posible causa de error Puede haber utilizado en una llamada de automatización OLE un tipo que no puede ser convertido en un Variant. Por ejemplo, lo siguiente generará esta excepción, ya que el argumento aquí es una clase (TThread), y las clases no pueden ser convertidas a variantes: procedure TFancyThread.Execute; var v: Variant; begin v.WontWork(Self); end; Solución rápida Utilice únicamente tipos de automatización cuando haga llamadas de automatizació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. Type of expression must be BOOLEAN Posible causa de error 1. Puede haber utilizado en una sentencia condicional If o un bucle While una expresión que no produce un resultado de tipo Boolean (no puede ser evaluada como True o False). Por ejemplo, lo siguiente generará este mensaje de error: if Form1.Name then 2. Algunas veces este mensaje de error es ocasionado por un error de sintaxis cuando se intenta convertir a otro tipo el parámetro Sender. Por ejemplo, lo siguiente producirá el mensaje de error bajo discusión: if (Sender as TDBEdit)Tag = 8 then 516 Los Tomos de Delphi: Delphi sin problemas 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). Type of expression must be INTEGER Posible causa de error Puede haber especificado la longitud de una cadena como algo distinto de un valor entero. Por ejemplo, lo siguiente generará este mensaje de error: Wisconsin: String['cheese']; 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. TYPEINFO standard function expects a type identifier Posible causa de error Puede haber intentado llamar a la función TypeInfo, pero proporcionó un argumento que no es un tipo. Por ejemplo, lo siguiente generará este mensaje de error: var BirdDog: pointer; . . . Mensajes de error 517 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. TYPEOF can only be applied to object types with a VMT Posible causa de error Puede haber llamado a TypeOf sobre un objeto que no tiene una Tabla de Métodos Virtuales (VMT). Por ejemplo, lo siguiente generará este mensaje de error: type TSimple = class procedure Einfach; end; . . . var pWhatYouBe: Pointer; begin pWhatYouBe := TypeOf(TSimple); . . . end. 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 Types of actual and formal var parameters must be identical Posible causa de error 1. Puede estar intentando pasar un parámetro real que difiere en el tipo del parámetro formal definido para el procedimiento o función. Por ejemplo, lo siguiente generará este mensaje de error: procedure TForm1.Button1Click(Sender: TObject); procedure Snowblind(var nish: Variant); begin nish := 'nash, I was takin'' a bash'; end; begin Snowblind(Query1); end; 2. Puede estar intentando compilar un proyecto que contiene una llamada a la API de Windows y estaba originalmente desarrollado utilizando una versión anterior de Windows. Por ejemplo, puede tener un procedimiento como éste: function WinExecAndWait32(FileName: String; Visibility: Integer; DoWait : Boolean): Integer; cuyo resultado es pasado así: Result := WinExecAndWait32('OPECDonuts.txt', 2, True); GetExitCodeProcess(ProcessInfo.hProcess, Result); 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 Unable to Execute a Query Posible causa de error Puede haber llamado a Open o asignado True a la propiedad Active de un componente TSQLQuery (DBExpress) que no tiene una sentencia SQL asignada en su propiedad SQL. 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. Unable to find both a form and a source file Posible causa de error Puede haber movido o borrado al archivo .PAS y/o el archivo .DFM de un proyecto en el Almacén de Objetos. 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. Unable to insert a line Posible causa de error Puede estar intentando insertar una línea en una lista de cadenas utilizando un índice que todavía no contiene un valor. Por ejemplo, si hay solamente tres líneas en ListBox1 (en los índices 0, 1 y 2), lo siguiente generará este mensaje de error: ListBox1.Items.Insert(3, 'DreiTresTrey'); 520 Los Tomos de Delphi: Delphi sin problemas 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. Unable to load GDS[32].DLL Posible causa de error Puede haber intentado arrastrar un componente IBEventAlerter sobre un formulario, pero la .DLL correspondiente de InterBase no está instalada en su sistema. Puede haber elegido no instalar InterBase cuando instaló Delphi. Solución rápida Si no instaló InterBase cuando instaló Delphi, instale la versión local de InterBase 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. Unable to load RPTSMITH.EXE Posible causa de error La sección [ReportSmith] de DELPHI.INI puede haber sido borrada o no refleja la ubicación actual de ReportSmith. 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á limitado 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. Undeclared Identifier: <> Posible causa de error Hay muchas causas posibles a este mensaje de error. 1. Puede haber asignado un valor a una variable que no está declarada en el ámbito del programa (en cuyo caso el error fue causado por la parte izquierda de la sentencia de asignación). 2. Puede haber asignado a una propiedad un valor que no es apropiado para ella (en cuyo caso el error fue causado por la parte izquierda de la sentencia de asignación genera el error). 3. Puede haber antepuesto el nombre de la clase a un método en la parte Interface de una unidad (esto es necesario en la parte Implementation, pero innecesario y no permitido en la parte Interface). 4. Puede haber escrito mal un identificador en el punto de la declaración o en el de la implementación. 5. Puede ser que esté refiriéndose a un objeto, procedimiento, tipo o función que reside en una unidad que no está incluida en la sección Uses. Por ejemplo, puede estar llamando la función ShowMessage o MessageDlg sin tener incluida la unidad Dialogs en la sección Uses, o puede haber hecho referencia al objeto Clipboard sin haber incluido la unidad Clipbrd en la sección Uses. 6. Puede haber alterado el ancestro en la declaración de tipo del formulario. Por ejemplo, si cambia el tipo del formulario base de Form a Application, así: { debería ser TForm1 = class(TForm) } TForm1 = class(TApplication) obtendrá el mensaje de error bajo discusión. 7. Puede estar intentando acceder a un identificador que está declarado en la sección Private de otra unidad. 8. Puede estar intentando liberar una instancia de una interfaz mediante una llamada a Free. Por ejemplo, lo siguiente generará este mensaje de error: type ILittleDog = interface(IUnknown) 522 Los Tomos de Delphi: Delphi sin problemas ['{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 procedimiento. 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 expresamente 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 asignado 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éndolo 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 9. Borre el punto y coma. 10. Mueva los elementos Resourcestring a la sección Interface, así: unit NGCDialogMessages; interface 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.'; implementation 11. Borre la asignación a Result, o cambie el procedimiento a una función (no olvide añadir un tipo de resultado, por ejemplo Boolean). 12. Añada la unidad en la que está definido el tipo Set o enumerado a la cláusula Uses: implementation uses SysUtils, fmOKOpts, nvcmod, AbArcTyp, // necesaria para utilizar soStripPath fmDCmprs, fmZipstr FileCtrl; // necesaria para hacer referencia al tipo // TFileAttr (ftArchive, etc.) 13. Convierta el método en un procedimiento o función, o mueva el código a la sección Initialization o Finalization. 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 dependencia 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áusula 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 7. 8. 9. 12. 525 En Delphi 6, CurrToBCD y BCDToCurr han sido movidos de DB.PAS a la nueva unidad FMTBCD.PAS. Cuando porte una aplicación de una versión anterior de Delphi a Delphi 6 o superior, puede necesitar añadir FMTBCD a la cláusula Uses (preferiblemente a la cláusula Uses de la sección Implementation) si recibe este mensaje de error debido a una llamada a una de aquellas funciones que no puede ser resuelta. Puede acceder a los métodos y propiedades Public y Published de otra clase siempre y cuando esté utilizando la unidad en la que esa clase está declarada. Puede tener también acceso a la sección Protected si está creando una clase descendiente de la clase en cuestión. Sin embargo, nunca tendrá acceso a una sección Private en otra unidad. Las instancias de interfaces son liberadas automáticamente en las siguientes situaciones: La variable de interfaz sale de ámbito. Usted asigna a la variable de interfaz un objeto de una interfaz diferente. Usted asigna Nil a la variable de interfaz. Consulte “<> is not a valid component name”. El compilador no espera un punto y coma hasta el final de la declaración de la primera clase. Un control puede tener una propiedad de tipo conjunto cuyos posibles valores están definidos en otra unidad, en la que se implementa una clase situada más arriba en el árbol de herencia. Por ejemplo, en el ejemplo, en el que se accede a la propiedad FileType de TFileListBox, el tipo conjunto y su tipo enumerado asociado están definidos en la unidad FileCtrl: type TFileAttr = (ftReadOnly, ftHidden, ftSystem, ftVolumeID, ftDirectory, ftArchive, ftNormal); TFileType = set of TFileAttr; Undeclared Identifier: 'EmptyParam' Posible causa de error Puede haber olvidado añadir Variants a la cláusula Uses. 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 aplicación que compila correctamente en versiones anteriores de Delphi. La declaración de EmptyParam ha sido movida a la unidad Variants (Variants ha experimentado extraordinarias mejoras, no solamente relacionadas con COM). Undeclared Identifier: 'Result' Posible causa de error Puede haber deshabilitado la sintaxis extendida y ha hecho una asignación a la variable local Result que está declarada implícitamente en las funciones. Solución rápida Rehabilite la sintaxis extendida (está habilitada por defecto) marcando la casilla 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. Undeclared Identifier: 'Unassigned' Consulte “Undeclared Identifier: ‘EmptyParam’”. Undeclared Identifier: 'VarToStr' Consulte “Undeclared Identifier: ‘EmptyParam’”. Unexpected end of command Posible causa de error Puede no haber escrito parte de una sentencia SQL; por ejemplo, en la siguiente sentencia SQL no se especifica la columna que va a ser utilizada como clave primaria: ALTER TABLE Placemats ADD CONSTRAINT pkSlogan PRIMARY KEY Mensajes de error 527 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. Unit <> was compiled with a different version of <> Posible causa de error 1. Puede haber asignado a una unidad el mismo nombre que una unidad que ya existe en la ruta de búsqueda de las bibliotecas de Delphi. 2. Usted (o el autor de la unidad en cuestión) puede haber cambiado la declaración de un símbolo en la parte Interface de una unidad, y otra unidad que hacía referencia a esta unidad (modificada) en su cláusula Uses no puede ser recompilada debido a que el archivo fuente (.PAS) no está disponible. 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 colisiones 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 riesgo. Los cambios tienden a afectar imperceptiblemente a otras cosas aparentemente no relacionadas. Unit File Format Error Posible causa de error Puede haber abierto un proyecto en una versión de Delphi anterior a la última con la que lo compiló. 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). Unit name mismatch: <> Posible causa de error Puede haber alterado manualmente el nombre de una unidad sin actualizar las referencias a ella en otras unidades. 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, tendrá que actualizar éstas. Unit version mismatch: <> Posible causa de error 1. Puede haber dado a una unidad un nombre que ya existe en la VCL o RTL, como Buttons, SysUtils, etc. Mensajes de error 529 2. Puede haber alterado el código fuente de la VCL. 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 2. Proporcione un valor para la propiedad AliasName antes de asignar True a la propiedad Connected. 3. Asegúrese de que la clave del Registro del sistema que apunta a la ubicación de IDAPI32.CFG se corresponda con la ubicación actual del archivo. 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 Si no tiene un archivo IDAPI32.CFG en el sistema, cópielo a la ubicación apropiada del CD de Delphi. Si va a distribuir una aplicación de base de datos en otras máquinas, deberá asegurarse de que las máquinas de destino tengan configurados los alias que vaya a utilizar para acceder a bases de datos. Puede hacer esto tanto con InstallShield como mediante código. Consulte “AddAlias” en la ayuda de Delphi para ver un ejemplo de cómo crear un alias en el código. Consulte la documentación de InstallShield para instrucciones sobre cómo proporcionar un alias durante la instalación. Si está utilizando una ruta (en lugar de un alias), un método que puede utilizar para garantizar que la base de datos siempre será encontrada es seguir uno de estos pasos: Indicar a los usuarios que mantengan todos los archivos en el mismo directorio que la aplicación. -O Asignar /. a la propiedad DatabaseName. Unknown directive: <> Posible causa de error 1. Puede estar utilizando una sintaxis incorrecta en una declaración de procedimiento o función. El problema puede ser simplemente algo mal escrito, o la falta de un punto y coma. 2. Puede estar intentando declarar un método como Virtual, Dynamic, Abstract u Overload fuera de la declaración de una clase. 3. Puede estar intentando interceptar un mensaje de Windows, pero olvidó colocar un punto y coma antes de la directiva Message. Esta no es reconocida por el compilador, que espera un punto y coma. Por ejemplo, esto ocasionará el error: procedure wmcommand(var Message: TMessage) message WM_COMMAND; 4. Puede haber añadido la directiva Stored a un procedimiento en una sección Private, Protected o Public de una clase. Por ejemplo, lo siguiente generará el mensaje de error bajo discusión procedure Setuuuu(b: string) stored; 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 3. Cuando intercepte mensajes de Windows, recuerde incluir el punto y coma antes de la directiva Message. procedure wmcommand(var Message: TMessage); message WM_COMMAND; 4. No utilice la directiva Stored en una sección Private, Protected o Public de una clase. 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; Unknown directive (already exists) Posible causa de error Puede haber añadido la directiva Override a un método redefinido en la sección Implementation. 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 compilador 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á declarado. 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 identificador 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. Unknown picture file extension: <> Posible causa de error 1. Puede estar intentando cargar un archivo con una extensión distinta a .BMP, .ICO, .EMF o .WMF en la propiedad Picture de un objeto TImage. Por ejemplo, la siguiente línea producirá el mensaje de error bajo discusión: Image1.Picture.LoadFromFile('Sunflowers.txt'); 2. Puede haber omitido la extensión del archivo al hacer referencia al archivo. 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'); Unknown SQL Error Posible causa de error Puede estar accediendo a una base de datos de servidor SQL y ha añadido o borrado una columna o índice, o modificado una descripción de campo nulo o no nulo mientras el parámetro del BDE ENABLE SCHEMA CACHE tenía asignado True. Mensajes de error 535 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. Además de la opción ENABLE SCHEMA CACHE, para las bases de datos de servidor 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. Unknown user name or password Posible causa de error Puede haber introducido una contraseña inválida en el cuadro de diálogo de conexión a base de datos (Database Login) después de lo siguiente: a. Intentó asignar True a la propiedad Connected de un componente TDatabase, en tiempo de diseño o en tiempo de ejecución (en el código). b. Llamó al método Open de un componente TDatabase o TTable. c. Intentó asignar True a la propiedad Active de un objeto TTable, en tiempo de diseño o en tiempo de ejecución (en el código). 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'); Para asignar la contraseña utilizando la sección Parameter Overrides del componente TDatabase, siga estos pasos: 1. Haga doble clic sobre el componente TDatabase. 2. Verifique que se muestren el nombre y alias correctos. 3. Quite la selección de la casilla de verificación Login Prompt. 4. Pulse el botón Defaults. 5. Añada la contraseña a la línea Password= en el cuadro de lista Parameter Overrides. Alternativamente, puede proporcionar un gestor de eventos para el evento OnLogin. Unnamed arguments must precede named arguments in OLE Automation call Posible causa de error Puede haber nombrado un argumento en una llamada OLE, y luego haber escrito un valor para un argumento sin nombre. Por ejemplo, el siguiente código generará este mensaje de error si se intenta activar la base de datos: procedure BackwardsCoding; var v: Variant; begin v.Tail(Bonanza := 'Cartwrights', 'Beech'); Solución rápida Elimine el argumento con nombre: procedure BackwardsCoding; var v: Variant; begin v.Tail('Cartwrights', 'Beech'); O nombre también el argumento que le sigue: procedure BackwardsCoding; var v: Variant; begin v.Tail(Bonanza := 'Cartwrights', HarrietStower := 'Beech'); O invierta el orden de los argumentos: procedure BackwardsCoding; Mensajes de error 537 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. Unrecognized database parameter block Posible causa de error Puede haber añadido una sentencia inválida a la propiedad Params de un componente IBDatabase. Por ejemplo, la siguiente entrada generará este mensaje de error si intenta activar la base de datos: username=SYSDBA password=masterkey 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. Unsatisfied forward or external declaration: <> Posible causa de error 1. Este mensaje de error aparece cuando tiene una declaración adelantada o externa de un procedimiento o función, o una declaración de un método en una clase o tipo de objeto, y no define el método, procedimiento o función en algún lugar. De hecho, puede ser que la definición haya sido omitida o 538 Los Tomos de Delphi: Delphi sin problemas 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 equivalente a una declaración adelantada — usted deberá proporcionar su implementación en la parte Implementation. De forma similar, la declaració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 proporcionará el resto de la información más adelante (en la sección Implementation que sigue). Debe cumplir su promesa haciéndolo. Unsupported 16bit resource Posible causa de error Puede estar intentando instalar en Delphi de 32 bits un componente que tiene asociado un archivo .DCR (recurso de icono de mapa de bits) que fue creado con una herramienta de 16 bits (como el Image Editor de Delphi 1). 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 instalar 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?'; USES clause is missing or incorrect Posible causa de error Puede tener un error de sintaxis en la cláusula Uses de la parte Interface. 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áusula Uses en un archivo de biblioteca (.DLL). Validation error for column <Column Name>, value <***Null***> Posible causa de error Puede haber intentado insertar una fila en una tabla sin proporcionar un valor para una columna no nula de esa tabla. Por ejemplo, puede tener un código 540 Los Tomos de Delphi: Delphi sin problemas 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 Variable <> inaccessible here due to optimization Posible causa de error El valor de la variable o propiedad que está intentando ver o examinar ha sido optimizado en este punto de la vida del programa. 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. Variable name expected Posible causa de error Puede haber intentado utilizar una dirección absoluta al declarar una variable en una versión de Delphi (Delphi 6 y superiores) que incluye la Biblioteca de Componentes de Borland (conocida como CLX, que significa “Component Library X-Platform” o “Class Library X-Platform”). Por ejemplo, lo siguiente generará este mensaje de error: var x: Integer absolute $1234; 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. Variant does not reference an automation object Posible causa de error Puede haber olvidado crear un objeto OLE antes de acceder a la variable de tipo Variant utilizada para hacer referencia a él. Por ejemplo, lo siguiente generará este mensaje de error: 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; 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. Variant does not reference an OLE object Posible causa de error Puede haber intentado acceder a un objeto OLE asignado a una variable de tipo Variant que no ha sido registrado en su sistema. 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. Variant is not an array Posible causa de error Puede haber intentado acceder a un elemento de una variable de tipo Variant, como si fuera una cadena. Por ejemplo, puede haber intentado algo así: var CoderCandy: Variant; begin CoderCandy := 'Melts In Your Mug, Not In Your Mitt'; {La siguiente línea generará el error} Label1.Caption := CoderCandy[1] + '&' + CoderCandy[1]; {Lo mismo esta línea} CoderCandy[4] := 'u'; end; 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 Vendor initialization failure: ORA[NT]7[1,2,3].DLL Posible causa de error El BDE podría no estar encontrando la .DLL de Oracle que se ha especificado en el parámetro Vendor Init de la utilidad de Administración/Configuración del BDE. 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. Windows socket error: <> on API <> Posible causa de error 1. Si el primer parámetro de este mensaje de error es 10014, 10022 ó 10049, puede que esté utilizando Delphi 4 Update Pack 2. 2. Si el primer parámetro en este mensaje de error es 10049, puede haber intentado asignar True a la propiedad Active de un componente TClientSocket mientras el valor de su propiedad Address contenía un valor erróneo. 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 Windows Socket Error: (10060), on API connect Posible causa de error Puede haber intentado asignar True a la propiedad Connected de un objeto TRemoteServer mientras la propiedad ConnectType tenía asignado el valor ctSockets, pero el servidor de aplicación no ha sido configurado. 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. Write error on <> Posible causa de error El disco en el que el compilador está intentando grabar un archivo puede estar lleno. 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. You cannot add a <> to the current project because it is not an ActiveX library. Click OK to start a new ActiveX library project Posible causa de error Puede haber seleccionado File | New... | ActiveX | ActiveForm o ActiveX Control mientras estaba abierto un proyecto convencional (no ActiveX). Mensajes de error 547 Si está utilizando Delphi 4, puede haber seleccionado File | New... | ActiveX | MTS Automation object mientras estaba abierto un proyecto convencional (no ActiveX). 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. You cannot specify a size for a field of this type Posible causa de error Puede estar intentando cambiar el tipo de datos de un campo en el Database Desktop, por ejemplo de ‘A’ (Alpha) a ‘N’ (Number), pero el valor anterior del tamaño (Size) está todavía especificado, y no es aplicable al tipo de datos al que se desea cambiar el campo. 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 automatización seleccionando File | New. . . , pulsando la pestaña ActiveX, y entonces pulsando dos veces sobre el icono Automation object. You must select a VCL class Posible causa de error Puede estar intentando crear un control ActiveX utilizando el Asistente de Controles ActiveX, pero no ha proporcionado la clase VCL en la que se basa el control ActiveX en el cuadro de combinación ‘VCL Class Name’. 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. Your application is not enabled for use with this driver Posible causa de error 1. Puede estar intentando utilizar SQL Links con una versión de Delphi que no es la Cliente/Servidor (Enterprise). 2. Puede estar intentando utilizar un controlador ODBC con una versión de Delphi estándar o de evaluación. 3. Puede que originalmente tuviera una versión inferior de Delphi en su sistema, y luego instaló Delphi Cliente/Servidor sin desinstalar antes la versión previa. 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 3. Desinstale la versión anterior de Delphi, y luego instale Delphi Cliente/Servidor. 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 suministre 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, despué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 Si está buscando un mensaje de error específico, consulte la Tabla de Contenido. Allí se listan los mensajes de error alfabéticamente, y por esa razón no son reproducidos aquí. ! Readln, 293 $2108, 51 $2109, 51 $220B, 159 $2501, 62 $2B05, 229 $2C08, 51 $2C09, 51 $3E06, 102 $DENYPACKAGEUNIT, 2 $DESIGNONLY, 2 $ENDIF, 381 $IFDEF, 381 $IFNDEF, 381 $IFOPT, 381 $L, 60 $LINK, 60 $R *.DFM, 215 $RUNONLY, 2 $WEAKPACKAGEUNIT, 4 .BMP, 63 .BPL, 38 ,74 .DCR, 80 ,188 .DCU, 61 ,235 ,266 ,424 .DFM, 11 ,34 ,108 ,128 ,201 ,214 ,215 ,223 ,225 ,231 ,234 ,344 ,443 ,470 .DLL, 33 ,37 ,75 ,89 ,119 ,225 ,439 ,491 ,492 ,538 ,539 ,545 .DOF, 386 .DPK, 264 .DPL, 74 .DPR, 26 ,109 ,457 .DSK, 234 ,386 .DSM, 234 .EMF, 64 .ICO, 64 .INI, 244 .LCK, 365 .mb, 405 .MB, 156 .MDX, 313 .OBJ, 27 ,60 .OPT, 387 .PAS, 25 ,34 ,119 ,201 ,214 ,234 ,254 .PX, 155 ,309 ,311 ,405 .RES, 198 ,215 ,227 ,458 .VAL , 155 ,450 .WMF, 534 10014, 545 10022, 545 10049, 545 25, 175 800A03EC, 410 A Abort, 469 Absolute, 458 ,501 abstractas, clases, 149 abstractos, métodos, 44 ,149 ,498 Access, (Microsoft Access), 250 Active, 106 ,110 ActiveControl, 93 ActiveForms, 89 ,216 ,235 ActiveX Asistente, 13 ,37 ,548 biblioteca, 88 ,134 ,547 controles, 29 ,37 ,89 ,133 ,162 ,216 ,235 ,548 Add, 41 i AddIndex, 9 ,252 AddIndexDef, 398 address, 393 ADO, 473 ADO Express, 143 Alias, 104 alias del BDE, 159 ,503 ,530 Apache, 416 API, xxxiv Append, 264 ,503 ApplyUpdates, 120 ,364 arrays, 392 ,446 ,524 Assert, 55 AssignFile, 264 AsyncPro, 412 AUTOEXEC.BAT, 462 Autoincrement, campos, 314 ,315 automatización, 341 AutoSessionName, 78 ,89 ,90 ,106 ,114 ,199 ,233 ,279 ,391 ,461 Available Forms, 48 B BDE, 1 BDE Administración/configuración, 186 BDEProv, 399 BLOB SIZE, 329 Boolean, 9 ,516 Break, 67 Break on Exceptions, 239 ,440 C C++ Builder, 89 ,541 C0000006, 241 C0000008, 242 C0000012, 242 C3254, 324 CachedUpdates, 58 Campos calculado, 252 calculados, 258 obligatorios, 251 capacity, 359 case, 124 ,193 CGI, 415 Chr , 276 Citrix Winframe, 496 clases abstractas, 149 class , 497 Close, 115 ii CLX, 541 CoClass, 28 ,482 Code Insight, 137 CoInitialize, 138 COM, xxxiv ,29 ,138 CommandText, 142 Commit, 401 CommitUpdates, 364 compilación condicional, 381 Componentes eliminación, 36 ,51 ,231 instalación, 28 ,231 CONFIG.SYS, 404 ConfigFile01, 100 CONFIGFILE01, 91 ,161 connect, 83 Connect, 460 Connected, 111 ,112 ,133 ,168 ,173 ,393 Connection, 379 ConnectionString, 22 ,379 ConnectType, 173 Const, 241 ConstraintErrorMessage, 42 constructores, 150 Contains, 151 Continue, 67 contraseña, 83 ,164 ,167 ,319 ,535 conversiones, 347 convert (utilidad), 224 CoUninitialize, 138 CREATE INDEX, 227 CreateDataSet, 396 CreateOLEObject, 212 ,543 CustomConstraint, 42 D Database Desktop, 287 DatabaseName, 115 ,168 ,194 ,384 ,504 ,529 DateTime, 451 Datos de Automatización, 341 del Registro, 243 en Paradox, 298 dBASE, 167 ,337 ,338 ,494 ,509 DBClient.DLL, 415 ,416 DBCLIENT.DLL, 98 DBExpress, 38 ,110 ,142 ,395 ,400 ,413 ,519 DCOM, 173 ,393 Dec, 359 Default, 179 ,255 DefaultExpression, 251 ,434 DefineProperties, 343 Delete, 114 DeleteTable, 115 Delphi 3, 422 Delphi 4, 419 ,431 Delphi 5, 75 Delphi 6, 26 ,27 ,33 ,75 ,93 ,111 ,113 ,140 ,143 ,289 ,326 ,346 ,381 ,395 ,409 ,412 ,427 ,431 ,437 ,490 ,494 ,519 ,524 Delphi/400, 243 destructores, 150 dfBinary, 113 ,381 dfXML, 113 ,381 dfXMLUTF8, 381 DisableControls, 283 dispid, 190 ,425 dispinterface, 33 Dispose, 191 DLLPATH, 100 ,103 duplicados nombres, 196 ,198 ,258 propiedades, 199 ,200 recursos, 197 valores, 196 ,199 E EditMask, 40 EmptyTable, 115 ENABLE SCHEMA CACHE, 535 EncodeDate, 327 EncodeTime, 327 End, 209 ,483 Entrada/Salida, error 100, 189 Entrada/Salida, error 101, 190 Entrada/Salida, error 102, 265 Entrada/Salida, error 105, 272 Erase, 264 error, 205 ,272 Error, 204 Error de Protección General, 45 Excel, 374 ,410 excepciones, 457 Except, 210 Exclusive, 264 ExecSQL, 85 ,219 ,362 ,544 Exit, 68 Exports, 240 ,439 F Fail, 437 FetchAll, 141 ficheros conversión, 224 localización, 85 nombrado, 60 FieldDefs, 396 FieldKind, 258 ,261 Fields Editor, 172 ,379 File of Record, 512 FillChar, 49 filtros, 415 ,452 Finalization, 176 Finally, 237 FindKey, 258 ,361 ,397 FindNearest, 258 FixedCols, 273 FixedRows, 274 For , 56 format, 58 ,60 ,393 formularios creación, 45 ,71 ,78 ,105 herencia, 220 visualización, 221 G General Protection Fault GPF, 45 GetLastError, 59 ,457 GetMem, 49 ,284 ,342 GetProcAddress, 230 ,240 GExperts, 233 GoTo, 282 ,354 gráfico, API, xxxiv gráficos, formatos, 63 GROUP BY, 256 ,283 ,348 GUID, 34 H Halt, 67 HandleShared, 233 ,390 High, 284 Host, 393 I ibinstall.dll, 321 IBX, 170 ,395 icono, 493 iconos, 80 IDAPI.CFG, 91 ,121 ,160 IDAPI.DLL, 100 iii IDAPI01.DLL, 102 IDAPI32.CFG, 91 ,121 ,160 ,186 IDAPI32.DLL, 2 ,51 ,101 ,103 IDataBroker, 157 ,158 identificadores, 289 IDPROV32.DLL, 98 Image Editor, 494 Implementation, 294 Implements, 295 ImportedConstraint, 42 Inc , 358 Index, 227 ,257 ,282 ,307 IndexField, 247 IndexFieldNames, 9 ,155 ,247 ,397 IndexName, 9 ,155 ,245 ,248 ,308 ,309 ,397 índices, 475 crear por código, 310 mantenidos, 310 ,312 primarios, 408 secundarios, 408 Indy, 412 ,465 Initialization, 11 ,15 ,62 ,176 ,523 InstallShield Express, 1 ,38 ,100 ,323 InterBase, 73 ,104 ,169 ,170 ,321 ,520 InterBase 6, 73 ,321 ,467 InterBase Express, 110 ,143 ,380 ,508 Interface, 7 ,235 ,321 interfaces, 7 Internet Direct -Indy, 412 Is, 347 IsValidDateMonthWeek, 26 IUnknown, 177 K KeepConnection, 112 KeyPress, 19 ,21 ,499 Kylix, 412 ,541 L L1086, 324 L1317, 324 L721, 324 Label, 354 Last, 141 Length, 208 Library Path, 60 ,151 ,456 LoadFromFile, 86 LoadLibrary, 230 ,240 Local Share, 317 ,364 Locate, 397 iv M MasterFields, 488 MasterSource, 126 ,488 MAXQUERYTIME, 467 MaxValue, 23 ,371 MDI, 87 formularios, 398 hijos, 398 memoria, 77 liberación, 342 limitaciones, 422 metaarchivos, 136 ,207 ,371 métodos abstractos, 44 ,149 ,498 Microsoft Access, 250 Microsoft Excel, 374 ,410 MIDAS, 113 ,170 ,173 ,399 ,414 ,460 MIDAS.DLL, 416 MinValue, 23 ,377 Miser, Dan, 250 ,432 MTS, 377 multi-hilos, 106 ,199 ,236 ,391 ,461 ,477 MultiSelect, 312 N Name , 460 NetDir, 171 configuración, 185 New, 392 Nodefault, 255 ,402 NOT NULL, 540 Null, 237 O Object Pascal directivas, 11 palabras reservadas, 11 tipos ordinales, 421 ODBC, 361 ,365 ,452 ,548 OldCreateOrder, 232 ,242 ,443 OldValue, 58 ,405 OLEVariant, 543 OnActivate, 80 OnHide, 81 OnShow, 81 OnValidate, 42 open, 107 optimización, 109 ,541 Oracle .DLL, 545 ORDER BY, 123 ,256 ,350 ordinal, 275 overload, 299 ,374 ,411 ,412 ,424 ,435 override, 109 ,149 ,372 ,375 ,444 ,533 P Packed, 428 PageIndex, 13 paquetes, 7 ,75 ,422 ,425 ,456 ,483 borrado, 341 recompilación, 61 Paradox, 240 ,479 compartición, 171 integridad referencial, 369 limitaciones, 167 Tipos de datos, 65 ,66 ,303 parámetros, 171 ,420 ,486 Params, 245 ,289 ,537 PDOXUSRS.LCK, 387 PDOXUSRS.NET, 387 Prepare, 142 ,317 propiedades, 343 declaración, 434 tipos, 437 Published, 509 puertos, 57 ,465 punteros, 45 ,143 ,164 ,165 ,180 ,301 ,342 ,347 ,358 ,434 ,446 ,509 ,512 Q Query Builder, 163 QuickReports, 232 ,521 R R938, 324 Raise, 135 ,456 Read, 11 ,79 ,450 ReadBinaryData, 214 Readln, 270 ReadOnly, 106 ,116 Real, 446 recursión, 439 ,468 recursos conservación, 214 DLLs, 492 renombrar, 197 REF CURSOR, 420 Referencial, integridad, 10 Refresh, 389 Register, 202 ,413 RegisterClass, 72 ,204 RegisterComponents, 28 ,72 ,202 ,486 Rename, 258 ReportSmith, 140 ,265 ,520 RequestLive, 249 ,317 ,477 ,481 ,502 Required, 203 ,244 ,262 Requires, 425 ,455 Reset, 264 ,265 resourcestring, 11 Resourcestring, 165 ,522 Rewrite, 264 ,265 RLINK32.DLL, 161 Round, 336 RTTI, 484 Run-time error 202, 469 Runtime Error 215, 54 S SaveToFile, 85 SDI, 87 SELECT, 256 ,257 ,348 ServerGUID, 83 ,330 ,460 ServerName, 460 SessionName, 90 ,106 ,116 ,199 ,233 ,460 SetDatabaseName, 118 SetFocus, 93 SetLength, 208 ,391 ,393 SHAREDMEMSIZE, 62 ,318 ,329 ShortDateTime, 452 ShowModal, 105 Site Express, 32 ,92 ,326 ,490 ,494 Slice, 464 sockets, 466 SortFieldNames, 142 SQL, 115 ,219 SQLDialect, 467 SQLPASSTHRU MODE, 432 StartTransaction, 38 ,110 ,169 ,281 ,395 ,401 ,505 ,507 STDOLE.TLB, 161 STDOLE2.TLB, 161 Stored, 255 ,470 StoredProcName, 219 Synchronize, 236 SYSTEM.DCU, 474 SYSTEM.INI, 422 T TableName, 9 ,115 ,252 ,308 ,384 TableType, 116 TADOConnection, 22 TBatchMove, 183 ,184 ,298 v TBits, 64 TClientDataSet, 514 TClientDataSetGrid, 113 TClientSocket, 57 ,72 ,545 TDatabase, 168 TDataSet, 112 TDateTime, 16 ,22 TDateTimePicker, 17 Terminate, 67 TextOut, 301 TField, descendientes para los tipos de Paradox, 66 ,299 TFileAttr, 525 TFrame, 397 Threadvar, 97 ,501 TIBDatabase, 110 TIBInstall, 321 TIBTransaction, 110 ,395 TIBUninstall, 321 TIDAntiFreeze, 412 tiDirtyRead, 495 TModalResult, 524 TObject, 179 TObjectList, 411 TPageControl, 221 TQuery, 400 ,447 TQueryClientDataSet, 170 TransIsolation, 494 TRegSvr, 157 ,158 ,230 ,326 ,409 ,487 ,494 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 V validación, 40 ,251 Var, 131 parámetros, 497 variables declaración, 146 inicialización, 95 variantes, 515 ,524 VARIANTS.PAS, 524 VBX, 488 VCL, 30 ,139 virtual, 372 VMT, 517 W WaitFor, 236 Webbrokerscript, 409 ,494 Weblib, 326 WideString, 7 ,98 ,177 ,341 ,347 ,515 WIN.INI, 91 WinCRT, 271 Windows, 1 ,47 ,62 ,65 ,76 ,87 ,91 ,121 ,138 ,225 ,309 ,325 ,334 ,366 ,371 ,407 ,426 ,476 ,496 With , 453 Write, 77 ,450 Writeln, 269 ,294 X XML, 113 ,380 ,514