Anda di halaman 1dari 701

MODULO

PROGRAMACION DE COMPUTADORES

CARLOS GUTIERREZ RODAS


CONTENIDO

1 Ficha programación de computadores…………………………………… .5


2 Presentación…………………………………………………………………. .6
3 Contextualización…………………………………………………………......9
3.1 Situación problémica………………………………………………. .9
3.2 Planteamiento………………………………………………………..9
3.3 Conocimientos previos……………………………………………...9
4 Competencias………………………………………………………………... .10
5 Ideograma – Mapa Conceptual……………………………………………..13
6. Unidades de aprendizaje………………………………………………….... 14
6.1 Componentes Hardware………….………………………………...14
6.1.1 Tabla de saberes……………………….………………………....14
6.1.2 Resumen………………………………………………………….. 15
6.1.3 Desglose general de contenidos………………………………...15
6.1.4 Lecturas requeridas…….………………………………...............16
6.1.5 Lecturas complementarias……………………………………….16
6.1.6 Actividades de aprendizaje………………………………………17
6.1.6.1 Actividades autónomas…………………………………….......17
6.1.6.2 Actividades colaborativas……………………………………...17
6.1.6.3 Acompañamiento tutorial…………………………………........18
6.1.7 Resultados de aprendizaje……………………………………… 19
6.1.8 Valoración de evidencias…………………………………………20
6.1.9 Propósitos de formación………………………………………….20
6.1.10 Criterios de evaluación………………………………………….20

6.2 Software - Sistemas operativos……………………………………22


6.2.1 Tabla de saberes – Parte I…………….………………………....22
6.2.2 Resumen………………………………………………………….. 23
6.2.3 Desglose general de contenidos………………………………...23
6.2.4 Lecturas requeridas…….………………………………...............23
6.2.5 Lecturas complementarias……………………………………….24
6.2.6 Actividades de aprendizaje………………………………………25
6.2.6.1 Actividades autónomas…………………………………….......25
6.2.6.2 Actividades colaborativas……………………………………...26
6.2.6.3 Acompañamiento tutorial…………………………………........26
6.2.7 Resultados de aprendizaje……………………………………… 27
6.2.8 Valoración de evidencias…………………………………………28
6.2.9 Propósitos de formación………………………………………….28
6.2.10 Criterios de evaluación………………………………………….28

6.2.11 Tabla de saberes – Parte II…..……….………………………..30


6.2.12 Resumen…………………………………………………………30
6.2.13 Desglose general de contenidos………………………………31
6.2.14 Lecturas requeridas…….………………………………............31
6.2.15 Lecturas complementarias……………………………………..32
6.2.16 Actividades de aprendizaje…………………………………….32
6.2.16.1 Actividades autónomas……………………………………....32
6.2.16.2 Actividades colaborativas…………………………………….33
6.2.16.3 Acompañamiento tutorial…………………………………......33
6.2.17 Resultados de aprendizaje……………………………………..34
6.2.18 Valoración de evidencias…………………………………….…35
6.2.19 Propósitos de formación………………………………………..35
6.2.20 Criterios de evaluación…………………………………………36

6.3 Software – utilitarios y recursos….………………………………..38


6.3.1 Tabla de saberes……………………….………………………....39
6.3.2 Resumen………………………………………………………….. 39
6.3.3 Desglose general de contenidos………………………………...39
6.3.4 Lecturas requeridas…….………………………………...............40
6.3.5 Lecturas complementarias………………………………………..40
6.3.6 Actividades de aprendizaje……………………………………….40
6.3.6.1 Actividades autónomas……………………………………........40
6.3.6.2 Actividades colaborativas……………………………………....41
6.3.6.3 Acompañamiento tutorial………………………………….........41
6.3.7 Resultados de aprendizaje……………………………………….42
6.3.8 Valoración de evidencias…………………………………………43
6.3.9 Propósitos de formación………………………………………….43
6.3.10 Criterios de evaluación………………………………………….43

6.4 Seguridad informática…………………..………………………….45


6.4.1 Tabla de saberes – Parte I…………….………………………....45
6.4.2 Resumen…………………………………………………………..46
6.4.3 Desglose general de contenidos………………………………..46
6.4.4 Lecturas requeridas…….………………………………..............47
6.4.5 Lecturas complementarias………………………………………47
6.4.6 Actividades de aprendizaje………………………………………48
6.4.6.1 Actividades autónomas…………………………………….......48
6.4.6.2 Actividades colaborativas……………………………………...48
6.4.6.3 Acompañamiento tutorial…………………………………........49
6.4.7 Resultados de aprendizaje……………………………………… 50
6.4.8 Valoración de evidencias………………………………………...50
6.4.9 Propósitos de formación…………………………………………51
6.4.10 Criterios de evaluación…………………………………………51

6.4.11 Tabla de saberes – Parte II…………….………………………..52


6.4.12 Resumen………………………………………………………….53
6.4.13 Desglose general de contenidos……………………………….53
6.4.14 Lecturas requeridas…….……………………………….............53
6.4.15 Lecturas complementarias………………………………………54
6.4.16 Actividades de aprendizaje……………………………………...55
6.4.16.1 Actividades autónomas……………………………………......55
6.4.16.2 Actividades colaborativas……………………………………..55
6.4.16.3 Acompañamiento tutorial………………………………….......56
6.4.17 Resultados de aprendizaje……………………………………...56
6.4.18 Valoración de evidencias………………………………………..57
6.4.19 Propósitos de formación………………………………………...58
6.4.20 Criterios de evaluación……………………………………….…58

7. Glosario………………………………………………………………………..60
8. Bibliografía……………………………………………………………………62
1. PROGRAMACION DE COMPUTADORES

TIEMPO EN HORAS CREDITOS

HORAS DE HORAS DE
TRABAJO ACOMPAÑAMIENTO
AUTONOMO TUTORIAL

Construido Por Carlos Gutiérrez Rodas

Implementar soluciones informáticas


manejando lenguajes de programación
adecuados ,de acuerdo a las
Competencia General del Módulo necesidades y ambientes web
orientadas hacia la empresa u
organización de una manera confiable y
oportuna,respetando las normas de
seguridad e impacto ambiental.
2. PRESENTACION

Los computadores en su inicio fueron creados para realizar cálculos matemáticos de una manera más rápida. La
forma de darle ordenes al computador era conectando y desconectando cables, los tubos de vacio, con los que
funcionaban los computadores, se fundían frecuentemente. El funcionamiento de un computador se basa en el
sistema binario, y es lo único que entiende un PC. Cuando se programaba entonces un computador las
instrucciones eran representadas por números binarios ejemplo: 1110110101000111 esto podría significar darle un
valor a una variable, sumar dos números, o cualquier otra instrucción. Luego para hacer la programación mas
entendible y fácil se creó el asembler, el cual usa unas instrucciones básicas para desarrollar programas en
ambiente DOS (sistema operativo no grafico). Aunque este lenguaje era más sencillo que teclear dígitos binarios,
algunos programadores crearon compiladores mucho más fáciles de entender, lo que facilitaba realizar programas
más complejos. Es así como hoy en día conocemos lenguajes de programación dinámicos, tales como: PHP, ASP,
JAVA, ACTIVEX, JSCRIPT, GRAFICADORES, Programacion interactiva, Programación online que automatizan el
trabajo del programador. Compiladores que convierten el programa a su nivel más bajo (conjunto de unos y cero).

La mayor parte de los computadores que existen en la actualidad están diseñados de forma que puedan ejecutar
diversas tareas o programas. Estos programas pueden ir desde un procesador de textos, a un programa para la
animación de gráficos tridimensionales o distintos tipos de juegos.
Para su correcto funcionamiento deben ser además capaces de acceder a los recursos de que dispone el
computador, como por ejemplo escribir o leer datos en un disco duro, mostrar un gráfico por pantalla, etc. Es
evidente, que si cada programa actúa de una forma independiente, existirían graves problemas y conflictos, puesto
que, por ejemplo, tendrían libertad para escribir sus datos sobre los de otro, etc.

Para solucionar este tipo de problemas se desarrollaron los Sistemas Operativos, los cuales aportan unos
mecanismos y reglas básicas de funcionamiento, de forma que los programas puedan acceder a los recursos del
ordenador de una forma adecuada. Aunque ésta fue la funcionalidad inicial de los sistemas operativos, con el tiempo
se han añadido otras muchas, como la ejecución de programas, el control de la memoria del ordenador, la creación
y control de interfaces gráficas de usuario, etc.

La elaboración del presente módulo está basada en la norma de competencia 220501007 denominada ¨desarrollar
el sistema que cumpla con los requerimientos de la solución informática¨, donde se tienen en cuenta los aspectos
definidos por la universidad.

El módulo aborda temas de gran importancia para la formación del futuro técnico como son:
Evolución de los lenguajes de computación, generaciones de los lenguajes de programación, algoritmia, diagrama
de flujo y pseudocódigo.
La segunda unidad aborda los temas de lenguajes de progrmacion, divido el lenguajes orientdos a objetos(java,
visual basic) y lenguajes dinaicos ( a nivel del servidor: ASP y PHP; a nivel del cliente: JavaScript y
visualBasicScript).

En este curso el estudiante aprenderá como darle instrucciones al computador, y así crear aplicativos que cumplan
con los requerimientos identificados para una solución especifica. El estudiante aprenderá la lógica de la
programación, entendiendo que programar no es aprender un lenguaje, programar es resolver problemas y
comunicar la solución al computador a través de un lenguaje de programación, por esto queridos participantes los
invito que se motiven a aprender a programar, a desarrollar la lógica para resolver problemas, a no pensar en el
lenguaje sino en la solución.

Con este curso el estudiante estará en capacidad de dar soluciones informáticas efectivas, crear aplicaciones de
calidad en ambientes web y con un enfoque orientado a objetos, exhortando a las empresas a ser más
competitivas ya sean estas del sector privado o público, Siendo el desarrollador de aplicaciones Web quien genere
la toma de decisiones en todos los niveles de la empresa.
3. CONTEXTUALIZACION

Las organizaciones desde el punto de vista de la teoría de los sistemas, puede ser considerara como un sistema
abierto y por esta razón , la organización estará expuesta a los diversos cambios que se producen el medio
ambiente que la rodea.
El éxito o fracaso de una organización, cualquiera sea su rubro, dependerá de la capacidad que tenga la misma
para adaptarse a tales cambios.
Teniendo en cuenta el concepto anterior, podemos afirmar que existen diversas empresas que ante la necesidad de
un cambio o adaptación en el área de informática (manejo de tecnología e información), han implementado un
nuevo encuadre para el líder de la tecnología de información, es decir un cambio en la visión y misión que traen
durante una larga trayectoria los profesionales de sistemas (en particular los directores/gerentes del centro de
cómputo).

Por mucho tiempo el área de sistemas fue considerada como un gasto innecesario para la mayoría de las
compañías, eran un tanto más operativos: pues se les llamaba cuando los equipos de cómputo sufrían algún
desperfecto, y más que considerárseles como estrategas, siempre se les relegaba en la toma de decisiones...

Hoy por hoy esta situación ha cambiado y para bien, pues la dirección general ha tenido a bien reconocer la
importancia que la labor de los gerentes y directivos de sistemas tienen para lograr el éxito de una empresa
mediante la aplicación de las TIC de una forma innovadora para lograr la reducción de gastos operativos,
automatización de tareas, ahorro de tiempo y eficiencia de los procesos.

Asimismo, y a medida que ha aumentado su responsabilidad y su papel en la toma de decisiones en las estrategias
empresariales, también ha crecido su salario y prestaciones.
El estudiante debe aprender las instrucciones básicas de programación y el enfoque orientado a objetos, para poder
comunicarle al computador que debe hacer este. Debe buscar soluciones óptimas a problemas simples o complejos,
usando instrucciones entendibles por el computador.

3.1 Situación Problémica

El desarrollo de las capacidades de Hardware ha experimentado un auge desmesurado en los últimos años, pero el
aprovechamiento de estas posibilidades no es óptimo si no se dispone del software adecuado. Con este fin se han
diseñado diversos lenguajes de programación, unos de propósito general, es decir, para todo tipo de aplicaciones, y
otros de aplicación particular en algunos de los campos del ámbito informático.

Un lenguaje de programación es una notación para escribir programas, a través de los cuales podemos
comunicarnos con el hardware y dar así las órdenes adecuadas para la realización de un determinado proceso. Un
lenguaje está definido por una gramática o conjunto de reglas que se aplican a un alfabeto constituido por el
conjunto de símbolos utilizados.

Los distintos niveles de programación existentes nos permiten acceder al hardware, de tal forma que según
utilicemos un nivel u otro, así tendremos que utilizar un determinado lenguaje ligado a sus correspondientes
compiladores, depuradores y traductores.

Siendo la información un activo primario de la empresa , esta se origina a través de la manipulación de los datos, la
información oportuna, coherente, estable, segura y verídica es un muy buen indicador de gestión informática a favor
del recurso humano administrativo , permitiendo modelar procesos enfocados a la sistematización integral en la
toma de decisiones en bien de la empresa o la sociedad. Es por esto que se hace importante aprender a dar
soluciones informáticas efectivas programando los computadores usando el lenguaje de programación más
adecuado, para que estos nos entreguen la información en un ambiente web de manera confiable y oportuna
3.2.Planteamiento

 La informática ha supuesto una revolución técnica y conceptual que ha impactado en prácticamente todas las áreas
de conocimiento. Consideramos que es una revolución técnica en cuanto que ha afectado la implementación y el
análisis de las tareas más diversas. De la misma manera, consideramos que es una revolución conceptual porque
ha provocado -con la generación de sistemas expertos, algoritmos genéticos, etc.- la desaparición y reducción de
incertidumbre de las teorías y modelos conceptuales de las disciplinas donde se ha implantado. Evidentemente
estas implicaciones son pertinentes en las ciencias de la actividad física y el deporte, en todas y cada una de sus
áreas de conocimiento e investigación.

Hasta los años sesenta, relativamente poca estructura se había impuesto a la forma en que escribían código los
programadores. No había estructuras bien definidas, y en consecuencia, el control de flujo a través de cientos o
miles de líneas resultaba casi imposible. Un ejemplo de esto, es el uso con frecuencia de instrucciones goto para
lograr saltos a otras partes de un programa.

La programación estructurada evolucionó en los años sesenta y setenta. El nombre se refiere a la práctica de
construir programas usando un conjunto de estructuras bien definidas. Una meta de la programación estructurada
es la eliminación de las instrucciones goto.

Los desarrolladores de software descubrieron que al utilizar la programación estructurada se obtiene una eficiencia
mejorada, pero se tienen inconvenientes en el proceso de construir software rápida y correctamente.

La reutilización es reconocida como la clave de la solución. Reutilizar código permite que los programas se
construyan rápida y correctamente. Las funciones, que son los bloques constructores de la programación
estructurada, son un paso a lo largo de este camino. En los años ochenta, la computación dio otro paso hacia
delante con la programación orientada a objetos (POO). Los bloques constructores de la POO, llamados objetos,
son reutilizables, son componentes modulares. Los expertos afirman que la POO será el enfoque dominante en la
programación durante un buen tiempo.
La Programación de computadores es la ciencia que permite a una persona programar una computadora para que
resuelva tareas de manera rápida. Un Programa de computador se puede definir como una secuencia de
instrucciones que indica las acciones o tareas que han de ejecutarse para dar solución a un problema determinado.
Programar computadores es indispensable en cualquier área de la ingeniería, ya que diferentes problemas que se
puedan presentar tardan tiempo resolverlos de manera manual. el computador resuelve problemas de acuerdo
como se le haya programado de manera rápida.

Para llegar a tener una secuencia de instrucciones que den solución a un problema es necesario ejecutar varias
etapas a saber :
Etapa de análisis. Etapa de Solución general. Etapa de prueba1. Etapa de implementación específica. Etapa de
rueba2.Etapa de uso o puesta en marcha.

3.3 Conocimiento Previos

Con el fin de determinar el grado de aprendizaje obtenido, es importante resolver las siguientes preguntas, para
luego compararlas con lo aprendido durante el desarrollo de este modulo.

 ¿Que es un algoritmo?
 ¿Que es un Diagrama de flujo?
 ¿Que es un Pseudocódigo?
 ¿Que es un compilador?
 ¿Que es un depurador?
 ¿Que es un traductor?
 ¿Que es un lenguaje de programación?
 ¿Para que sirven las variables en un lenguaje de programación?
 ¿Cuál es el alcance de las variables?
 ¿Para que sirven y cuáles son las instrucciones primitivas?
 ¿Para que sirven y cuáles son los tipos de datos en un lenguaje de programación?
 ¿Para que se utiliza los Tipos de operaciones matemáticas y lógicas. En la programación?
 ¿Que diferencia hay entre un lenguaje de programación y un software de propósito especifico?
 Enumere tres diferencias entre lenguajes dinámicos y lenguajes orientados a objetos.
 Diferencias entre prueba de caja blanca y prueba de caja negra.

4. COMPETENCIAS

- Analizar y Comprender los problemas para


encontrar la solución adecuada a los mismos.
- Desarrollar algoritmos eficientes y confiables en
cualquier lenguaje de programación.
- Manejar manuales de referencia de lenguajes
de programación
- Conocer los lenguajes de programación de
Competencias acuerdo a sus características.
cognoscitivas - Aprender los conceptos sobre la programación
orientada a objetos.
- Diseñar interfaces graficas amigables al usuario
- Realizar pruebas de caja blanca y caja negra
para mitigar fallas en el sistema
Competencias
procedimentales - Aplicar estándares en la documentación de los
programas.
- Seleccionar el lenguaje de programación
adecuado para el software a desarrollar
- Verificar y validar la solución realizada de
acuerdo con el diseño y listas de chequeo
- Crear soluciones modelo vista controlador
- Realizar el proceso de pruebas y corrección de
errores.
-Planear, dirigir,desarrollar y administrar soluciones
informáticas para la web.

- Saber abordar problemas de acuerdo a sus


objetivos
- Aprovechar la reutilización de código
- Aprender por interés propio
- Trabajar en equipo para el desarrollo de
proyectos grandes
Competencias
actitudinales - Contribuir con el equipo de manera objetiva y
responsable
- Estar actualizado en lo referente a tecnología de
punta

Competencias  Desarrollar competencias en la gestión de la


integrativas información que le permita movilizarse dentro
de la dinámica de actualización permanente en
el área de las tecnologías de la información y la
comunicación.
 Participar en equipos de trabajo
interdisciplinarios y hacer aportes en lo
relacionado con las Tecnologías de la
información y la comunicación a partir de su
formación académica y profesional.
 Comprender la dimensión ética del trabajo al
interior de una empresa y asimilarla como la
base fundamental para su desempeño
profesional.

5.IDEOGRAMA
6. UNIDADES DE APRENDIZAJE
6.1 UNIDAD DE APRENDIZAJE No. 1: INTRODUCCION A LA PROGRAMACION

NOMBRE Y No. DE LA UNIDAD Tiempo


Horas de
INTRODUCCION A LA acompañamiento
PROGRAMACION tutorial
Horas
de
trabajo Autónomo
Competencias de la unidad de aprendizaje
Elemento No. 1: Resolver problemas cotidianos aplicando las herramientas
propias de la programación orientadas al entorno de la empresa.
TABLA DE SABERES
Saber hacer Saber saber Saber ser
 Aplicar estándares en la  Manejar  Ser proactivo en la
solución de problemas. manuales de adquisición de
 Seleccionar el lenguaje referencia de conocimiento
lenguajes de
de programación  Ser creativo en el
programacion.
adecuado para el  Conocer las desarrollo de
software a desarrollar características de algoritmos
 Crear soluciones modelo lenguajes de buscando
vista controlador programación efectividad
 Planear, dirigir, motores de base  Habilidades para
de datos, y depurar y realizar
desarrollar y administrar
ambientes de
soluciones informáticas búsquedas en
desarrollo.
para la webComprobar y  Saber las manuales
verificar que los prioridaes del  Tener actitud para
componentes del sistema, softwaree de compartir o
tanto físicos como acuerdo al tipo solicitar
de aplicación.
lógicos, cumplan las  Conocer información
características Sistemas  Ser ético en la
demandadas y operativos definición de
expresadas en los  Saber Conceptos algoritmos
de redes.
requerimientos de una  Sabe abordar
 Conocer la
empresa. problemas y retos
Seguridad de
 Interpretar las necesidades teniendo en cuenta
operación del
de los usuarios y proponer los objetivos Ser
software en la
responsable con el
las mejores alternativas de red.
manejo de la
solución  Saber realizar
información a
 Comprobar y verificar la Algoritmos de
cualquier nivel de
programació
instalación, encendido y investigación.
abierta.
arranque de los equipos.  Ser ético en su
 Conocer la base
 Instalar y configurar los profesión.
de diseño grafico
componentes de un  Respetar las
para las
opiniones de los
computador. interfaces de la
demás.
solución.
 tener apertura al
 Conocer
cambio
Metodologías de
tecnológico.
desarrollo.
 Identificar
Requisitos para
elaborar
manuales de
instalación,
configuración y
técnicos
 Manejar
estándares para
denominación
para archivos
que componen
un sistema de
información
 Aplicar
Metodologías y
herramientas de
versiona miento

 Conocer una
Segunda lengua
 Conocer las
tendencias futuras de
los computadores
 Configurar de
manera física y lógica
un sistema
 Interpretar
manuales de
operación de equipos
 Conocer los
componentes básicos
de hardware y
software, periféricos
de entrada, salida y
almacenamiento. Que
son, para que sirven y
como se configuran
6.1.1 Resumen.

El desarrollo de cada una de las generaciones de los lenguajes de programación fue de la mano del desarrollo del
hardware.

En cuanto a su generación, esta clasificación se basa en la línea de tiempo histórica de los lenguajes de
programación.

Más recientes fueron las aportaciones en esta campo de Charles Babbage, quien entre los años 1820 y 1850,
diseñó dos máquinas para computar ninguna de las cuales fue terminada. La más interesante, ya que se parecía a
los computadores digitales modernos, fue la máquina analítica. Los programas para este primer computador
estaban escritos, básicamente, en lenguaje máquina y utilizaban unas ciertas tarjetas de operación y tarjetas de
datos. Junto a Babbage trabajó Ada Augusta, condesa de Lovelace, hija del famoso poeta Lord Byron, que
recientemente ha sido reconocida como la primera programadora y en su honor se llamó ADA al último lenguaje
desarrollado bajo el auspicio del Dpto. de Defensa de los USA.

Durante los años 30 y 40 surge un gran número de gente con ideas sobre notaciones para la programación. La
mayoría eran puramente teóricas. Algunos ejemplos son la máquina de Turing o el cálculo Lambda.

A principios de los años 50 se empezaron a construir máquinas con cierta capacidad de cálculo (aunque muy
limitadas y costosas), que trabajaban con lenguajes de tipo ensamblador.

Un autómata es cualquier mecanismo capaz de realizar un trabajo de forma autónoma (un reloj, una caja de música,
la cisterna del WC, un radiador con termostato).
Todos estos aparatos tienen en común que, una vez conectados, pueden realizar su función sin más intervención
externa. También comparten el hecho de que son bastante simples. Unos autómatas más flexibles serían un
organillo, un video, una lavadora, ya que al menos su repertorio de acciones posibles es más variado. El ejemplo del
organillo es revelador ya que en él aparecen las mismas fases que en el desarollo de un programa: una pieza de
música es "diseñada" por un compositor, codificada en un soporte físico y ejecutada por una máquina.

En estos términos, un ordenador es un autómata de cálculo gobernado por un programa, de tal modo que diferentes
programas harán trabajar al ordenador de distinta forma. Un programa es la codificación de un algoritmo, y un
algoritmo es la descripción precisa de una sucesión de instrucciones que permiten llevar a cabo un trabajo en un
número finito de pasos.

En esta unidad se pretende que el participante conozca el proceso de evolución a través de la historia de los
sistemas informáticos, con base a la evolución constante que han tenido los computadores actualmente,
teniendo en cuenta aspectos como características, diferencias de procesadores, memorias ram, tipos de
almacenamiento, sistemas operativos, entre otros aspectos siempre de la mano en los avances tecnológicos que se
dan a nivel de hardware.

El avance tecnológico que existe actualmente, se debe a la necesidad que tiene el


hombre de obtener información de forma adecuada y rápida a través de medios que le agilicen el diario vivir. Esto
hace que su nacimiento este enmarcado en la antigüedad con el ábaco que es el primer computador personal que
se conoce, pero en el afán de mejorar los procesos se evoluciona con máquinas que agilizan el trabajo y se llega
hasta los computadores que existen actualmente, dicha evolución se dio con el descubrimiento de las válvulas, que
después se convirtieron en transistores y posteriormente en chips.

6.1.2 Desglose general de contenidos.


 INTRODUCCION A LA PROGRAMACION

1.EVOLUCION DE LOS LENGUAJES DE PROGRAMACION.

Charles Babbage definió a mediados del siglo XIX lo que él llamó la máquina analítica. Se considera a esta
máquina el diseño del primer ordenador. La realidad es que no se pudo construir hasta el siglo siguiente. El caso es
que su colaboradora Ada Lovelace escribió en tarjetas perforadas una serie de instrucciones que la máquina iba a
ser capaz de ejecutar. Se dice que eso significó el inicio de la ciencia de la programación de ordenadores.

En la segunda guerra mundial debido a las necesidades militares, la ciencia de la computación prospera y con ella
aparece el famoso ENIAC (ElectronicNumerical Integrator And Calculator), que se programaba cambiando su
circuitería. Esa es la primera forma de programar (que aún se usa en numerosas máquinas) que sólo vale
para máquinas de único propósito. Si se cambia el propósito, hay que modificar la máquina.

Código máquina. Primera generación de lenguajes (1GL):

No mucho más tarde apareció la idea de que las máquinas fueran capaces de realizar más de una aplicación. Para
lo cual se ideó el hecho de que hubiera una memoria donde se almacenaban esas instrucciones. Esa memoria se
podía rellenar con datos procedentes del exterior. Inicialmente se utilizaron tarjetas perforadas para introducir las
instrucciones.

Durante mucho tiempo esa fue la forma de programar, que teniendo en cuenta que las máquinas ya entendían sólo
código binario, consistía en introducir la programación de la máquina mediante unos y ceros. El llamado código
máquina. 

Todavía los ordenadores es el único código que entienden, por lo que cualquier forma de programar debe de ser
convertida a código máquina.
Sólo se ha utilizado por los programadores en los inicios de la informática. Su incomodidad de trabajo hace que sea
impensable para ser utilizado hoy en día. Pero cualquier programa de ordenador debe, finalmente, ser convertido a
este código para que un ordenador pueda ejecutar las instrucciones de dicho programa.

Un detalle a tener en cuenta es que el código máquina es distinto para cada tipo de procesador. Lo que hace que
los programas en código máquina no sean portables entre distintas máquinas.

Lenguaje ensamblado. Segunda generación de lenguajes (2GL):

En los años 40 se intentó concebir un lenguaje más simbólico que permitiera no tener que programar utilizando
código máquina. Poco más tarde se ideó el lenguaje ensamblador, que es la traducción del código máquina a una
forma más textual. Cada tipo de instrucción se asocia a una palabra mnemotécnica (como SUM para sumar por
ejemplo), de forma que cada palabra tiene traducción directa en el código máquina.

Tras escribir el programa en código ensamblador, un programa (llamado también ensamblador) se encargará de
traducir el código ensamblador a código máquina. Esta traducción es rápida puesto que cada línea en ensamblador
tiene equivalente directo en código máquina (en los lenguajes modernos no ocurre esto).

La idea es la siguiente: si en el código máquina, el número binario 0000 significa sumar, y el número 0001 significa
restar. Una instrucción máquina que sumara el número 8 (00001000 en binario) al número 16 (00010000 en binario)
sería: 0000 00001000 00010000

Realmente no habría espacios en blanco, el ordenador entendería que los primeros cuatro BITS representan la
instrucción y los 8 siguientes el primer número y los ocho siguientes el segundo número (suponiendo que los
números ocupan 8 bits). Lógicamente trabajar de esta forma es muy complicado. Por eso se podría utilizar la
siguiente traducción en ensamblador: SUM 8 16

Lenguajes de alto nivel. Lenguajes de tercera generación (3GL) :


Puesto que el ensamblador es una representación textual pero exacta del código máquina; cada programa sólo
funcionará para la máquina en la que fue concebido el programa; es decir, no es portable.

La ventaja de este lenguaje es que se puede controlar absolutamente el funcionamiento de la máquina, lo que
permite crear programas muy eficientes. Lo malo es precisamente que hay que conocer muy bien el funcionamiento
de la computadora para crear programas con esta técnica. Además las líneas requeridas para realizar una tarea se
disparan ya que las instrucciones de la máquina son excesivamente simples.

Tras varios intentos de representar lenguajes, en 1957 aparece el que se considera el primer lenguaje de alto nivel,
el FORTRAN (FORmula TRANslation), lenguaje orientado a resolver fórmulas matemáticos.

En 1960 la conferencia CODASYL se creó el COBOL como lenguaje de gestión en 1960. En 1963 se creo PL/I el


primer lenguaje que admitía la multitarea y la programación modular. Poco a poco fueron evolucionando los
lenguajes formando lenguajes cada vez mejores, así en 1958 se crea LISP como lenguaje declarativo para
expresiones matemáticas.

BASIC se creó en el año 1964 como lenguaje de programación sencillo de aprender en 1964 y ha sido, y es, uno de
los lenguajes más populares; En 1968 se crea LOGO para enseñar a programar a los niños. Pascal se creó con la
misma idea académica pero siendo ejemplo de lenguaje estructurado para programadores avanzados. El creador
del Pascal (Niklaus Wirdth) creo Modula en 1977 siendo un lenguaje estructurado para la programación de
sistemas (intentando sustituir al C).

Lenguajes de cuarta generación (4GL):

En los años 70 se empezó a utilizar éste término para hablar de lenguajes en los que apenas hay código y en su
lugar aparecen indicaciones sobre qué es lo que el programa debe de obtener. Se consideraba que el lenguaje SQL
(muy utilizado en las bases de datos) y sus derivados eran de cuarta generación. Los lenguajes de consulta de
datos, creación de formularios, informes,... son lenguajes de cuarto nivel. Aparecieron con los sistemas de base de
datos.

Actualmente se consideran lenguajes de éste tipo a aquellos lenguajes que se programan sin escribir casi código
(lenguajes visuales), mientras que también se propone que éste nombre se reserve a los lenguajes orientados a
objetos.

Lenguajes orientados a objetos:

En los 80 llegan los lenguajes preparados para la programación orientada a objetos todos procedentes
de Simula (1964) considerado el primer lenguaje con facilidades de uso de objetos. De estos destacó
inmediatamente C++.

A partir de C++ aparecieron numerosos lenguajes que convirtieron los lenguajes clásicos en lenguajes orientados a
objetos (y además con mejoras en el entorno de programación, son los llamados lenguajes visuales): Visual
Basic, Delphi(versión orientada a objetos de Pascal), Visual C++,...

En 1995 aparece Java como lenguaje totalmente orientado a objetos y en el año 2000 aparece C# un lenguaje que
toma la forma de trabajar de C++ y del propio Java.

Lenguajes para la web:

La popularidad de Internet ha producido lenguajes híbridos que se mezclan con el código HTML con el que se
crean las páginas web. HTML no es un lenguaje en sí sino un formato de texto pensado para crear páginas web.
Éstos lenguajes se usan para poder realizar páginas web más potentes.

Son lenguajes interpretados como JavaScript o VB Script, o lenguajes especiales para uso en servidores
como ASP, JSP o PHP. Todos ellos permiten crear páginas web usando código mezcla de página web y
lenguajes de programación sencillos.

2.GENERACIONES DE LOS LENGUAJES DE PROGRAMACION

Los métodos de diseño e implementación de los lenguajes de programación han evolucionado rápidamente desde
los primeros lenguajes de alto nivel que aparecieron a principios de los años 30.
Los lenguajes de programación son muchos y en cada uno de los mismos se puede hacer un juego. Ya sea Java,
C, Visual Basic o el que se desee. Sin embargo los lenguajes poseen dos tipos de clasificaciones. El tipo de nivel y
su generación. Cabe aclarar que la idea de los diferentes tipos de lenguajes se debe a la necesidad de simplificar la
tarea de programar y de utilizar para el mismo un lenguaje que se acerque lo más posible al humano.

Según el desarrollo histórico los lenguajes de programación, se categorizan así :

Primera generación

lenguaje de máquina 1940-1950. Consistía en sucesiones de dígitos binarios. Aún en la actualidad, es el único
lenguaje interno que entiende la computadora; los programas se escriben en lenguajes de mayor nivel y se traducen
a lenguaje de máquina

Antes de que un computador pueda ejecutar una tarea, debe programársele para que lo haga colocando en la
memoria principal un algoritmo apropiado, expresado en lenguaje máquina, que no es más que una secuencia de
números mediante los que se representan las operaciones a realizar y los operandos con los que operar.
Originariamente, este proceso de programación se realizaba por el laborioso método de expresar todos los
algoritmos en el lenguaje de máquina, enfoque que hacía más penosa la ya de por sí difícil tarea de diseñar un
programa, y en la mayoría de los casos daba pie a errores que era necesario localizar y corregir.

El primer paso para eliminar estas complejidades del proceso de programación fue la asignación de nombres
mnemónicos a los diversos códigos de operación, y usarlos en vez de la representación hexadecimal, aumentando
considerablemente la comprensibilidad de las secuencias de instrucciones de la máquina. Luego un programa
especial llamado ensamblador se encargaba la traducción de los códigos mnémonicos a instrucciones en lenguaje
máquina. A estos programas se les llamó ensambladores, pues su tarea era ensamblar instrucciones en lenguaje
máquina a partir de códigos de operación y operandos. Por extensión, a los lenguajes que utilizaban los
mnemónicos se les llamó lenguajes ensamblador.

Segunda generación
lenguajes ensambladores fines 1950. En lugar de usar códigos binarios, las instrucciones se representan con
símbolos fáciles de reconocer, conocidos como mnemotécnicos. Aún se utilizan estos lenguajes cuando interesa un
nivel máximo de eficiencia en la ejecución o cuando se requieren manipulaciones intrincadas.

En la época en que aparecieron los primeros lenguajes ensambladores, parecía que se había dado un gigantesco
salto hacia adelante en la búsqueda de mejores entornos de programación, y es por ello que se les comenzó a
llamar lenguajes de segunda generación, siendo la primera generación la compuesta por los lenguajes máquina.
Estamos en los primeros años 50 y ejemplos de estos lenguajes podrían ser AUTOCODER, SPS, BAL o
EASYCODER.

Una consecuencia importante de la íntima asociación entre los lenguajes ensambalador y de máquina es que
cualquier programa escrito en lenguaje ensamblador depende inherentemente de la máquina; esto es, las
instrucciones del programa se expresan en términos de los atributos de una máquina específica. Por tanto, un
programa escrito en lenguaje ensamblador no se puede transportar fácilmente a otra máquina porque se tiene que
reescribir de modo que se ajuste a la configuración de registros y al conjunto de instrucciones de la nueva máquina.

Otra desventaja de los lenguajes ensambladores es que el programador, aunque no tiene que codificar las
instrucciones en forma de patrones de bits, sí está obligado a pensar en térnimos de los pequeños pasos
incrementales del lenguaje de la máquina, y no puede concentrarse en la solución global de la tarea que está
realizando. En pocas palabras, las instrucciones elementales en que se debe expresar finalmente un programa no
son necesariamente las instrucciones que deben usarse al diseñarlo.

Tercera generación

Años '60. Los lenguajes de esta generación se dividen en tres categorías, según se orienten a: Procedimientos: la
forma en la que se programan. Problema: El problema que intentan resolver. Objeto: Como se encarara el objeto a
desarrollar. De acuerdo con esta idea, a mediados de los 50 se comenzaron a crear lenguajes de programación que
eran más propicios para la elaboración de software que los lenguajes ensamblador de bajo nivel. El resultado fue la
aparición de una tercera generación de lenguajes de programación que difería de las anteriores en que sus
instrucciones eran de alto nivel y además independientes de las máquinas. Una vez escrito el programa con
instrucciones de alto nivel, se utilizaba un programa llamado traductor que traducía a lenguaje máquina los
programas escritos en lenguajes de alto nivel. Estos programas son parecidos a los ensambladores de la segunda
generación, solo que a menudo tienen que compilar, reunir varias instrucciones de máquina para formar secuencias
cortas que simularan la actividad solicitada por la instrucción de alto nivel, y por esta razón se comenzó a llamar
compiladores a este tipo de programa.

Unos de los primeros lenguajes de la tercera generación son FORTRAN y COBOL, por lo que algunas
clasificaciones les colocan en la segunda generación. También está ALGOL60. Después de estos aparecen otros
como BASIC (1965), SNOBOL, APL, PL/1 y SIMULA, entre otros. En los 70 aparecen lenguajes de alto nivel como
PASCAL, C, MODULA y PROLOG. Más recientes son Eiffel, Smalltalk, ADA, ML, C++ y Java.

Con la aparición de los lenguajes de tercera generación se alcanzó, en gran medida la meta de la independencia
respecto a las máquinas. Como las instrucciones de estos lenguajes no hacían referencia a los atributos de ninguna
máquina en particular, se podían compilar con la misma facilidad en una u otras máquinas. Así, en teoría, un
programa escrito en un lenguaje de tercera generación se podía utilizar en cualquier máquina con sólo aplicar el
compilador apropiado. Sin embargo, la realidad no ha resultado ser tan simple.

Las tres primeras generaciones de lenguajes siguen una sucesión en el tiempo, mientras que a partir de ahí, las dos
últimas generaciones han evolucionado paralelamente y en campos bastantes distintos.

La cuarta generación

Las características generales de los lenguajes de cuarta generación son: Uso de frases y oraciones parecidas al
inglés para emitir instrucciones. No operan por procedimientos, por lo que permiten a los usuarios centrarse en lo
que hay que hacer no en cómo hacerlo. Al hacerse cargo de muchos de los detalles de cómo hacer las cosas,
incrementan la productividad. Ejemplo de esta generación son los lenguajes visuales.

Los lenguajes de cuarta generación pretenden superar los problemas surgidos de los lenguajes de tercera
generación:

 Acelerar el proceso de construcción de aplicaciones.


 Hacer aplicaciones fáciles y rápidas de modificar, reduciendo por tanto los costes de mantenimiento.
 Minimizar los problemas de búsqueda y corrección de errores.
 Generar código ejecutable sin errores a partir de los requerimientos deseados, dados con expresiones de alto
nivel.
 Hacer lenguajes fáciles de usar, de manera que el usuario final pueda resolver sus propios problemas usando
él mismo el lenguaje de programación.

Estos lenguajes permiten generar aplicaciones de cierta complejidad con un número de líneas menor que el que
tendríamos si usáramos un lenguaje de tercera generación. Para construir aplicaciones el programador contará,
aparte de un conjunto de instrucciones secuenciales, con una gran diversidad de mecanismos como son: el
rellenado de formularios, la interacción con la pantalla, etc. Un ejemplo de este tipo de lenguajes es SQL.

Quinta generación

La quinta generación de lenguajes se ha relacionado con los lenguajes que se utilizan en el campo de la inteligencia
artificial: sistemas basados en el conocimiento, sistemas expertos, mecanismos de inferencia o procesamiento del
lenguaje natural. Lenguajes como LISP o PROLOG han sido la base de este tipo de lenguajes.

Tipos de lenguajes

Según el estilo de programación se puede hacer esta división:


 Lenguajes imperativos. Son lenguajes donde las instrucciones se ejecutan secuencialmente y van
modificando la memoria del ordenador para producir las salidas requeridas. La mayoría de lenguajes (C,
Pascal, Basic, Cobol, ...son de este tipo. Dentro de estos lenguajes están también los lenguajes orientados a
objetos (C++, Java, C#,...)
 Lenguajes declarativos. Son lenguajes que se concentran más en el qué, que en el cómo (cómo resolver el
problema es la pregunta a realizarse cuando se usan lenguajes imperativos). Los lenguajes que se
programan usando la pregunta ¿qué queremos? son los declarativos. El más conocido de ellos es el lenguaje
de consulta de Bases de datos, SQL.
 Lenguajes funcionales. Definen funciones, expresiones que nos responden a través de una serie de
argumentos. Son lenguajes que usan expresiones matemáticas, absolutamente diferentes del lenguaje usado
por las máquinas. El más conocido de ellos es el LISP.
 Lenguajes lógicos. Lenguajes utilizados para resolver expresiones lógicas. Utilizan la lógica para producir
resultados. El más conocido es el PROLOG.
Con respecto a los niveles encontramos de 4 tipos.

 Lenguaje Maquina: es el lenguaje de los unos y ceros. Es decir como procesan la información los distintos
tipos de dispositivos de la computadora. Un lenguaje que entiende la maquina perfectamente pero que es
muy complicado de programar.
 Lenguaje de Bajo nivel: Lenguajes que dependen de la arquitectura que se este manejando. En ellos se
poseen instrucciones básicas que son traducidas a lenguaje maquina. Su programación no es simple, pero se
obtiene un control absoluto de los dispositivos. El ensamblador es el ejemplo típico

 Lenguaje de Alto nivel: Son independientes de la máquina y se pueden utilizar en cualquier computadora.
Los lenguajes de más alto nivel no ofrecen necesariamente mayores capacidades de programación, pero si
ofrecen una interacción programador/computadora más avanzada. Cuanto más alto es el nivel del lenguaje,
más sencillo es comprenderlo y utilizarlo. El C es el ejemplo típico de estos lenguajes

 Lenguaje de Muy Alto nivel: En el se trata de obtener un dialogo mas "humano" con la maquina. Son los
lenguajes orientados a objetos como C++, Java o Visual Basic

En cada nuevo nivel se requieren menos instrucciones para indicar a la computadora que efectúe una tarea en
particular. Pero los lenguajes de alto nivel son sólo una ayuda para el programador. Un mayor nivel significa que son
necesarios menos comandos, debido a que cada comando o mandato de alto nivel reemplaza muchas instrucciones
de nivel inferior

Intérpretes

A la hora de convertir un programa en código máquina, se pueden utilizar dos tipos de software: intérpretes y
compiladores. En el caso de los intérpretes se convierte cada línea a código máquina y se ejecuta ese código
máquina antes de convertir la siguiente línea. De esa forma si las dos primeras líneas son correctas y la tercera
tiene un fallo de sintaxis, veríamos el resultado de las dos primeras líneas y al llegar a la tercera se nos notificaría el
fallo y finalizaría la ejecución.

El intérprete hace una simulación de modo que parece que la máquina entiende directamente las instrucciones del
lenguaje, pareciendo que ejecuta cada instrucción (como si fuese código máquina directo).
El BASIC era un lenguaje interpretado, se traducía línea a línea. Hoy en día la mayoría de los lenguajes integrados
en páginas web son interpretados, la razón es que como la descarga de Internet es lenta, es mejor que las
instrucciones se vayan traduciendo según van llegando en lugar de cargar todas en el ordenador.

Por eso lenguajes como JavaScript (o incluso, en parte, Java) son interpretados.

Proceso

Un programa que se convierte a código máquina mediante un intérprete sigue estos pasos:

(1) Lee la primera instrucción


(2) Comprueba si es correcta
(3) Convierte esa instrucción al código máquina equivalente
(4) Lee la siguiente instrucción
(5) Vuelve al paso 2 hasta terminar con todas las instrucciones

Ventajas
 Se tarda menos en crear el primer código máquina. El programa se ejecuta antes.
 No hace falta cargar todas las líneas para empezar a ver resultados (lo que hace que sea una técnica idónea
para programas que se cargan desde Internet)

Desventajas
 El código máquina producido es peor ya que no se optimiza al valorar una sola línea cada vez. El código
optimizado permite estudiar varias líneas a la vez para producir el mejor código máquina posible, por ello no
es posible mediante el uso de intérpretes.
 Todos los errores son errores en tiempo de ejecución, no se pueden detectar antes de lanzar el programa.
Esto hace que la depuración de los errores sea más compleja.
 El código máquina resultante gasta más espacio.
 Hay errores difícilmente detectables, ya que para que los errores se produzcan, las líneas de errores hay que
ejecutarlas. Si la línea es condicional hasta que no probemos todas las posibilidades del programa, no
sabremos todos los errores de sintaxis cometidos.
Compiladores

Se trata de software que traduce las instrucciones de un lenguaje de programación de alto nivel a código máquina.
La diferencia con los intérpretes reside en que se analizan todas las líneas antes de empezar la traducción.

Durante muchos años, los lenguajes potentes han sido compilados. El uso masivo de Internet ha propiciado que
esta técnica a veces no sea adecuada y haya lenguajes modernos interpretados o semi-interpretados, mitad se
compila hacia un código intermedio y luego se interpreta línea a línea (esta técnica la siguen Java y los lenguajes de
la plataforma .NET de Microsoft).

Ventajas
 Se detectan errores antes de ejecutar el programa (errores de compilación)
 El código máquina generado es más rápido (ya que se optimiza)
 Es más fácil hacer procesos de depuración de código

Desventajas
 El proceso de compilación del código es lento.
 No es útil para ejecutar programas desde Internet ya que hay que descargar todo el programa antes de
traducirle, lo que ralentiza mucho su uso.

3.Algoritmos, Diagramas de flujo y Pseudocódigos.

El desarrollo de algoritmos es un tema fundamental en el diseño de programas o soluciones. Por lo cual, el


estudiante debe tener buenas bases que le sirvan para poder crear de manera fácil y rápida sus programas.
Facilitarle el desarrollo de su capacidad analítica y creadora, para de esta manera mejorar su destreza en la
elaboración de algoritmos que sirven como base para la codificación de los diferentes programas que tendrá que
desarrollar a lo largo de su carrera. 

¿QUÉ ES ALGORITMO? 
La palabra algoritmo se deriva de la traducción al latín de la palabra árabe alkhowarizmi, nombre de un matemático
y astrónomo árabe que escribió un tratado sobre manipulación de números y ecuaciones en el siglo IX.

Un algoritmo es una serie de pasos organizados que describe el proceso que se debe seguir, para dar solución a un
problema específico. 

El origen de la palabra se piensa que es el nombre de un algebrista árabe llamado Mûsâ al-Khowârizmî, AD 825.

Un algoritmo es un procedimiento especificado paso a paso para resolver un problema en una cantidad finita de
tiempo.

Características:

 Finitud: debe terminar tras un número finito de etapas.


 Definición: cada paso debe estar definido con precisión, siendo riguroso y sin ambiguedad.
 Entrada: tendrá 0 o más entradas, informaciones que se proporcionan al algoritmo antes de funcionar.
 Salida: tendrá 1 o más salidas, y guardarán una relación con las entradas.
 Efectividad: debe poder especificarse en función de operaciones realizables, no fantasiosas.

Por ejemplo está el algoritmo de cambiar una rueda pinchada en un automóvil:

1. Quitar la rueda.
1. Aflojar los tornillos.
2. Levantar el automóvil.
3. Extraer la rueda.
1. Retirar los tornillos.
2. Retirar la rueda.
2. Poner la rueda.
1. Colocar la rueda.
1. Presentar la rueda.
2. Poner los tornillos.
2. Bajar el coche.
3. Apretar los tornillos.

En el algoritmo anterior muchos de los pasos son demasiado vagos para ser considerados bien definidos; de modo
que habría que concretarlos más.

Los algoritmos se suelen expresar utilizando una manera mas o menos formal de lenguaje, llamado pseudocódigo,
que toma diversas formas, alguna de ellas más gráficas, y otras más cercanas al lenguaje humano.

Los primeros algoritmos conocidos están fechados entre los años 3000 y 1500 AC. Fueron encontrados en la zona
conocida como Mesopotamia (actualmente Irak) cerca de la ciudad de Babilonia. Estos algoritmos no tenían ni
condicionales (los expresaban escribiendo varias veces el algoritmo) ni iteraciones (extendían el algoritmo con
tantos pasos como fuera necesario). Probablemente más conocido, es el matemático griego Euclides, que hacia el
año 300 AC., definió un algoritmo para calcular el máximo común divisor de dos enteros positivos. Aunque en este
algoritmo se incluía la iteración, presentaba pocas mejoras respecto a los anteriores.

El algoritmo de Euclides trabaja con dos enteros m y n com m>n>0 y se describe como sigue:

mientras m > 0 hacer t = n mod m

n=m

m=t

devolver n

TIPOS DE ALGORITMOS
Existen dos tipos y son llamados así por su naturaleza: 
 Cualitativos: Son aquellos en los que se describen los pasos utilizando palabras.
 Cuantitativos: Son aquellos en los que se utilizan cálculos numéricos para definir los pasos del proceso.

Lenguajes Algorítmicos 

Un Lenguaje algorítmico es una serie de símbolos y reglas que se utilizan para describir de manera explícita un
proceso. 

Tipos de Lenguajes Algorítmicos 

 Gráficos: Es la representación gráfica de las operaciones que realiza un algoritmo (diagrama de flujo). 

 No Gráficos: Representa en forma descriptiva las operaciones que debe realizar un algoritmo
(pseudocodigo). 
INICIO 
   Edad: Entero 
   ESCRIBA “cual es tu edad?” 
   Lea Edad 
   SI Edad >=18 entonces 
      ESCRIBA “Eres mayor de Edad” 
   FINSI 
   ESCRIBA “fin del algoritmo” 
   FIN

Metodología para la solución de un problema . Creación de un algoritmo.

El computador es una máquina que por sí sola no puede hacer nada, necesita ser programada, es decir, introducirle
instrucciones u ordenes que le digan lo que tiene que hacer. Un programa es la solución a un problema inicial, así
que todo comienza allí: en el Problema. El proceso de programación es el siguiente: Dado un determinado problema
el programador debe idear una solución y expresarla usando un algoritmo (aquí es donde entra a jugar); luego de
esto, debe codificarlo en un determinado lenguaje de programación y por último ejecutar el programa en el
computador el cual refleja una solución al problema inicial. Esto es a grandes rasgos lo que hace el programador de
computadores. 

La parte que corresponde a este curso es la de: “Dado un determinado problema debemos idear una solución y
expresarla usando un ALGORITMO!”. 

Metodología para la solución de problemas  


 DEFINICIÓN DEL PROBLEMA 

Esta fase está dada por el enunciado del problema, el cual requiere una definición clara y precisa. Es
importante que se conozca lo que se desea que realice la computadora; mientras esto no se conozca del todo
no tiene mucho caso continuar con la siguiente etapa. 

 ANÁLISIS DEL PROBLEMA 

Una vez que se ha comprendido lo que se desea de la computadora, es necesario definir:


o Los datos de entrada.
o Cual es la información que se desea producir (salida)
o Los métodos y fórmulas que se necesitan para procesar los datos.

Una recomendación muy práctica es el de colocarse en el lugar de la computadora y analizar qué es lo que
se necesita que se ordene y en qué secuencia para producir los resultados esperados. 

 DISEÑO DEL ALGORITMO 

Las características de un buen algoritmo son:


o Debe tener un punto particular de inicio.
o Debe ser definido, no debe permitir dobles interpretaciones.
o Debe ser general, es decir, soportar la mayoría de las variantes que se puedan presentar en la
definición del problema.
o Debe ser finito en tamaño y tiempo de ejecución.
o Diseño del Algoritmo
o Prueba de escritorio o Depuración
Se denomina prueba de escritorio a la comprobación que se hace de un algoritmo para saber si está bien hecho.
Esta prueba consiste en tomar datos específicos como entrada y seguir la secuencia indicada en el algoritmo hasta
obtener un resultado, el análisis de estos resultados indicará si el algoritmo está correcto o si por el contrario hay
necesidad de corregirlo o hacerle ajustes.

Características:

 Finitud: debe terminar tras un número finito de etapas.


 Definición: cada paso debe estar definido con precisión, siendo riguroso y sin ambiguedad.
 Entrada: tendrá 0 o más entradas, informaciones que se proporcionan al algoritmo antes de funcionar.
 Salida: tendrá 1 o más salidas, y guardarán una relación con las entradas.
 Efectividad: debe poder especificarse en función de operaciones realizables, no fantasiosas.

Por ejemplo está el algoritmo de cambiar una rueda pinchada en un automóvil:

3. Quitar la rueda.
1. Aflojar los tornillos.
2. Levantar el automóvil.
3. Extraer la rueda.
1. Retirar los tornillos.
2. Retirar la rueda.
4. Poner la rueda.
1. Colocar la rueda.
1. Presentar la rueda.
2. Poner los tornillos.
2. Bajar el coche.
3. Apretar los tornillos.

En el algoritmo anterior muchos de los pasos son demasiado vagos para ser considerados bien definidos; de modo
que habría que concretarlos más.
Los algoritmos se suelen expresar utilizando una manera mas o menos formal de lenguaje, llamado pseudocódigo,
que toma diversas formas, alguna de ellas más gráficas, y otras más cercanas al lenguaje humano.

Los primeros algoritmos conocidos están fechados entre los años 3000 y 1500 AC. Fueron encontrados en la zona
conocida como Mesopotamia (actualmente Irak) cerca de la ciudad de Babilonia. Estos algoritmos no tenían ni
condicionales (los expresaban escribiendo varias veces el algoritmo) ni iteraciones (extendían el algoritmo con
tantos pasos como fuera necesario). Probablemente más conocido, es el matemático griego Euclides, que hacia el
año 300 AC., definió un algoritmo para calcular el máximo común divisor de dos enteros positivos. Aunque en este
algoritmo se incluía la iteración, presentaba pocas mejoras respecto a los anteriores.

El algoritmo de Euclides trabaja con dos enteros m y n com m>n>0 y se describe como sigue:

mientras m > 0 hacer t = n mod m

n=m

m=t

devolver n

Etapas del análisis y diseño de programas

Las etapas en el análisis y diseño de programas son:

 Análisis
 Programación
 Codificación

Análisis: Consiste en el estudio detallado del problema con el fin de obtener una serie de documentos en los que
quede totalmente definido el proceso de la automatización.
Programación: Consiste en la realización de una solución o algoritmo del problema planteado. Esta solución se
diseña utilizando una notación intermedia (pseudocódigo) o bien mediante alguna de las notaciones gráficas.

Codificación: Consiste en la escritura en un lenguaje de programación de alto nivel de los algoritmos obtenidos en la
etapa de programación.

Etapas de la implementación y explotación

 Edición
 Compilación
 Enlace
 Prueba de ejecución
 Explotación y mantenimiento

Edición: En esta etapa se transcribe el programa a la computadora, grabándose el mismo en la memoria auxiliar por
medio de un editor de programas o procesador de texto. A este programa almacenado en la computadora y escrito
en lenguaje de alto nivel se le denomina programa fuente.

Compilación: Consiste en obtener un programa objeto, codificado en lenguaje máquina, a partir del programa fuente.
Esta tarea se realiza de forma automática mediante el compilador del lenguaje, el cual, además de efectuar la
traducción, incluye un análisis sintáctico del programa, detectando posibles errores en su escritura y posibilitando la
corrección de los mismos.

Enlace: En esta fase se incluyen determinadas rutinas internas de la librería del lenguaje que sean necesarias en el
programa y si la aplicación consta de varios programas o módulos se enlazan todos ellos, obteniéndose lo que
denominamos programa ejecutable.

Prueba de ejecución: El programa ejecutable obtenido en la etapa anterior se somete a un juego de datos de prueba
capaz de detectar las posibles incorrecciones en su funcionamiento.
Explotación y mantenimiento: Una vez comprobada la corrección del programa y realiza su instalación en el sistema
informático, la aplicación queda a disposición de los usuarios, que la utilizarán hasta tanto se decida abandonarla o
cambiarla por otra. Esto se conoce como explotación de la aplicación. Paralelamente al uso de la aplicación se
realiza el mantenimiento de la misma, que consiste en su evaluación periódica por parte del personal informático,
así como la inclusión de las adaptaciones y modificaciones necesarias para mantenerla actualizada.

Errores

La presencia de errores, surgidos en alguna de las etapas antes descritas, suele ser inevitable. Por ello, es muy
importante saber detectarlos y corregirlos para asegurar la calidad del producto final.

Según la etapa en que se detectan, los errores se clasifican de la manera siguiente:

 Compilación
 Ejecución
 Lógica
 Especificación

Compilación: También son denominados errores sintácticos, son los más fáciles de encontrar y corregir. Se
producen por el incumplimiento de las reglas sintácticas del lenguaje y son detectados por el programa compilador
indicando el lugar en que se encuentran y la clase de error.

Ejecución: Se detectan durante la ejecución del programa por la parada anormal del mismo, y suelen provenir de la
realización de operaciones no permitidas. Se producen o no, dependiendo de los datos de entrada empleados; por
ello, para encontrarlos es necesaria la prueba del programa con un conjunto de datos de ensayo lo suficientemente
amplio que abarque la mayoría de casos y posibilidades de ejecución.

De lógica: Se dice que un programa tiene un error de lógica si produce resultados que no son correctos. Para
detectarlos hay que realizar un número suficiente de ejecuciones con diferentes datos de prueba y comprobar los
resultados obtenidos.
De Especificación: Son los más difíciles de corregir, pues corresponden a incorrecciones sobrevenidas en la etapa
de análisis, por lo que hay que modificar gran parte del trabajo realizado.

Elementos de un programa

Variables

Un elemento que la mayoría de los lenguajes de programación tienen en común son las variables. La información se
almacena en localidades de memoria, a las cuales por simplicidad se les asigna un nombre, con el fin de poder
manejar en forma sencilla los datos contenidos en estas localidades de memoria.

10 A

Z 12.5

Algoritmos y Funciones

Los algoritmos son las series de pasos por los cuales se resuelven los problemas. Los algoritmos se han utilizado
para solucionar un amplio rango de problemas matemáticos.

Los algoritmos representan soluciones a los problemas. Los pasos para la solución (instrucciones) permanecen
iguales, ya sea que esté resolviéndolos por computadora o a mano.

Las funciones son la expresión de los algoritmos en un lenguaje específico de cómputo.

Técnicas de diseño de algoritmos de programación, el Top Down y el Bottom Up.


Top Down 

También conocida como de arriba-abajo y consiste en establecer una serie de niveles de mayor a menor
complejidad (arriba-abajo) que den solución al problema. Consiste en efectuar una relación entre las etapas de la
estructuración de forma que una etapa jerárquica y su inmediato inferior se relacionen mediante entradas y salidas
de información. Este diseño consiste en una serie de descomposiciones sucesivas del problema inicial, que recibe el
refinamiento progresivo del repertorio de instrucciones que van a formar parte del programa. 

La utilización de la técnica de diseño Top-Down tiene los siguientes objetivos básicos: 

 Simplificación del problema y de los subprogramas de cada descomposición.


 Las diferentes partes del problema pueden ser programadas de modo independiente e incluso por diferentes
personas.
 El programa final queda estructurado en forma de bloque o módulos lo que hace mas sencilla su lectura y
mantenimiento.

Bottom Up 

El diseño ascendente se refiere a la identificación de aquellos procesos que necesitan computarizarse con forme
vayan apareciendo, su análisis como sistema y su codificación, o bien, la adquisición de paquetes de software para
satisfacer el problema inmediato. 

Cuando la programación se realiza internamente y haciendo un enfoque ascendente, es difícil llegar a integrar los
subsistemas al grado tal de que el desempeño global, sea fluido. Los problemas de integración entre los
subsistemas son sumamente costosos y muchos de ellos no se solucionan hasta que la programación alcanza la
fecha limite para la integración total del sistema. En esta fecha, ya se cuenta con muy poco tiempo, presupuesto o
paciencia de los usuarios, como para corregir aquellas delicadas interfaces, que en un principio, se ignoran. Aunque
cada subsistema parece ofrecer lo que se requiere, cuando se contempla al sistema como una entidad global,
adolece de ciertas limitaciones por haber tomado un enfoque ascendente. 
Uno de ellos es la duplicación de esfuerzos para acceder el software y mas aún al introducir los datos. 
Otro es, que se introducen al sistema muchos datos carentes de valor. 
Un tercero y tal vez el mas serio inconveniente del enfoque ascendente, es que los objetivos globales de la
organización no fueron considerados y en consecuencia no se satisfacen. 

La diferencia entre estas dos técnicas de programación se fundamenta en el resultado que presentan frente a un
problema dado. 
Imagine una empresa, la cual se compone de varios departamentos (contabilidad, mercadeo, …), en cada uno de
ellos se fueron presentando problemas a los cuales se le dieron una solución basados en un enfoque ascendente
(Bottom Up): creando programas que satisfacían sólo el problema que se presentaba. 
Cuando la empresa decidió integrar un sistema global para suplir todas las necesidades de todos los departamentos
se dio cuenta que cada una de las soluciones presentadas no era compatible la una con la otra, no representaba
una globalidad, característica principal de los sistemas. 
Como no hubo un previo análisis, diseño de una solución a nivel global en todos sus departamentos, centralización
de información, que son características propias de un diseño Descendente (Top Down) y características
fundamentales de los sistemas; la empresa no pudo satisfacer su necesidad a nivel global. 
La creación de algoritmos es basado sobre la técnica descendente, la cual brinda el diseño ideal para la solución de
un problema.
Diagrama de Flujo 

Un diagrama de flujo es la representación gráfica de un algoritmo. También se puede decir que es la representación
detallada en forma gráfica de como deben realizarse los pasos en la computadora para producir resultados. 

Esta representación gráfica se da cuando varios símbolos (que indican diferentes procesos en la computadora), se
relacionan entre si mediante líneas que indican el orden en que se deben ejecutar los procesos. Los símbolos
utilizados han sido normalizados por el instituto norteamericano de normalización (ANSI): 

Símbolo Descripción

Indica el inicio y el final de nuestro diagrama de flujo.

Indica la entrada y salida de datos.

Símbolo de proceso y nos indica la asignación de un valor en la memoria


y/o la ejecución de una operación aritmética.

Indica la salida de información por impresora.

Conector dentro de página. Representa la continuidad del diagrama


dentro de la misma página.
Conector fuera de pagina. Representa la continuidad del diagrama en otra
pagina.

Indica la salida de información en la pantalla o monitor.


Símbolo de decisión. Indica la realización de una comparación de valores.

Símbolo de Selección Múltiple. Dada una expresión permite escoger una


opción de muchas.

Símbolo del Mientras. Dada una expresión al principio de la iteración esta


es evaluada; si la condición es verdadera realizará el ciclo, si es falsa la
repetición cesará.
Símbolo del Para. Esta estructura de control repetitiva se usa
generalmente cuando se conoce de antemano el numero de iteraciones.

Símbolo Repita Hasta. funciona igual que la estructura Mientras, con la


diferencia que al menos una vez hará el grupo de instrucciones y luego
evaluará una condición. Si la condición evaluada es falsa continua dentro
del ciclo y si es verdadera termina la iteración.

Líneas de flujo o dirección. Indican la secuencia en que se realizan las


operaciones.

Recomendaciones para el diseño de Diagramas de Flujo 


 Se deben usar solamente líneas de flujo horizontales y/o verticales.
 Se debe evitar el cruce de líneas utilizando los conectores.
 Se deben usar conectores sólo cuando sea necesario.
 No deben quedar líneas de flujo sin conectar.
 Se deben trazar los símbolos de manera que se puedan leer de arriba hacia abajo y de izquierda a derecha.
 Todo texto escrito dentro de un símbolo deberá ser escrito claramente, evitando el uso de muchas palabras.

es el pseudocódigo y sus ventajas frente a los diagramas de flujos y las definiciones de los diagramas estructurados
y las estructuras algorítmicas.

Pseudocódigo 

Mezcla de lenguaje de programación y español (o ingles o cualquier otro idioma) que se emplea, dentro de la
programación estructurada, para realizar el diseño de un programa. En esencial, el Pseudocódigo se puede definir
como un lenguaje de especificaciones de algoritmos. 

En esencial, el Pseudocódigo se puede definir como un lenguaje de especificaciones de algoritmos.  


Es la representación narrativa de los pasos que debe seguir un algoritmo para dar solución a un problema
determinado. El Pseudocódigo utiliza palabras que indican el proceso a realizar. 

Ventajas de utilizar un Pseudocódigo a un Diagrama de Flujo 

 Ocupa menos espacio en una hoja de papel


 Permite representar en forma fácil operaciones repetitivas complejas
 Es muy fácil pasar de Pseudocódigo a un programa en algún lenguaje de programación.
 Si se siguen las reglas se puede observar claramente los niveles que tiene cada operación.
Diagramas estructurados (Nassi-Schneiderman) 

El diagrama estructurado N-S también conocido como diagrama de chapin es como un diagrama de flujo en el que
se omiten las flechas de unión y las cajas son contiguas. Las acciones sucesivas se pueden escribir en cajas
sucesivas y como en los diagramas de flujo, se pueden escribir diferentes acciones en una caja. Un algoritmo se
represente en la siguiente forma: 

Estructuras Algorítmicas 

Las estructuras de operación de programas son un grupo de formas de trabajo, que permiten, mediante la
manipulación de variables, realizar ciertos procesos específicos que nos lleven a la solución de problemas. Estas
estructuras se clasifican de acuerdo con su complejidad en: 

Estructuras secuenciales, cómo se representan en pseudocódigo y algunos ejemplos prácticos de las


mismas.

La estructura secuencial es aquella en la que una acción (instrucción) sigue a otra en secuencia. Las tareas se
suceden de tal modo que la salida de una es la entrada de la siguiente y así sucesivamente hasta el fin del proceso.  

En Pseudocódigo una Estructura Secuencial se representa de la siguiente forma: 


Observe el siguiente problema de tipo cotidiano y sus respectivos algoritmos representados en Pseudocódigo y en
diagramas de flujos: 

• Tengo un teléfono y necesito llamar a alguien pero no sé como hacerlo. 


El anterior ejemplo es un sencillo algoritmo de un problema cotidiano dado como muestra de una estructura
secuencial. Ahora veremos los componentes que pertenecen a ella: 

Asignación 

La asignación consiste, en el paso de valores o resultados a una zona de la memoria. Dicha zona será reconocida
con el nombre de la variable que recibe el valor. La asignación se puede clasificar de la siguiente forma: 

 Simples: Consiste en pasar un valor constante a una variable (a  15)


 Contador: Consiste en usarla como un verificador del numero de veces que se realiza un proceso (a    a +
1)
 Acumulador: Consiste en usarla como un sumador en un proceso (a   a + b)
 De trabajo: Donde puede recibir el resultado de una operación matemática que involucre muchas variables
(a  c + b*2/4).

En general el formato a utilizar es el siguiente: 

< Variable >       <valor o expresión >

El símbolo       debe leerse “asigne”. 

Escritura o salida de datos 

Consiste en mandar por un dispositivo de salida (p.ej. monitor o impresora) un resultado o mensaje. Esta instrucción
presenta en pantalla el mensaje escrito entre comillas o el contenido de la variable. Este proceso se representa así
como sigue: 

Lectura o entrada de datos 

La lectura o entrada de datos consiste en recibir desde un dispositivo de entrada (p.ej. el teclado) un valor o dato.
Este dato va a ser almacenado en la variable que aparece a continuación de la instrucción. Esta operación se
representa así: 

DECLARACION DE VARIABLES Y CONSTANTES 

La declaración de variables es un proceso que consiste en listar al principio del algoritmo todas las variables que se
usarán, además de colocar el nombre de la variable se debe decir qué tipo de variable es. 

Contador:   ENTERO 
Edad, I:   ENTERO 
Direccion :    CADENA_DE_CARACTERES 
Salario_Basico :    REAL 
Opcion :    CARACTER 

En la anterior declaración de variables Contador, Edad e I son declaradas de tipo entero; Salario_Basico es una
variable de tipo real, Opcion es de tipo carácter y la variable Direccion está declarada como una variable
alfanumérica de cadena de caracteres. 

En el momento de declarar constantes debe indicarse que lo es y colocarse su respectivo valor. 


CONSTANTE Pi 3.14159 
CONSTANTE Msg “Presione una tecla y continue” 
CONSTANTE ALTURA 40 

Cuando se trabaja con algoritmos por lo general no se acostumbra a declarar las variables ni tampoco constantes
debido a razones de simplicidad, es decir, no es camisa de fuerza declarar las variables. Sin embargo en este curso
lo haremos para todos los algoritmos que realicemos, con esto logramos hacerlos más entendibles y organizados y
de paso permite acostumbrarnos a declararlas ya que la mayoría de los lenguajes de programación (entre ellos el
C++) requieren que necesariamente se declaren las variables que se van a usar en los programas. 

Veamos algunos ejemplos donde se aplique todo lo que hemos visto hasta el momento sobre algoritmos: 

Ejemplo 1: Escriba un algoritmo que pregunte por dos números y muestre como resultado la suma de estos. Use
Pseudocódigo y diagrama de flujos. 
Ejemplo 2: Escriba un algoritmo que permita conocer el área de un triángulo a partir de la base y la altura. Exprese
el algoritmo usando Pseudocódigo y diagrama de flujos.
distintas estructuras poniendo ejemplos tanto en diagrama de flujo como en pseudocódigo.

Las estructuras condicionales comparan una variable contra otro(s)valor (es), para que en base al resultado de esta
comparación, se siga un curso de acción dentro del programa. Cabe mencionar que la comparación se puede hacer
contra otra variable o contra una constante, según se necesite. Existen tres tipos básicos, las simples, las dobles y
las múltiples. 

Simples: 
Las estructuras condicionales simples se les conoce como “Tomas de decisión”. Estas tomas de decisión tienen la
siguiente forma: 

Pseudocódigo: Diagrama de flujo:

Dobles: 

Las estructuras condicionales dobles permiten elegir entre dos opciones o alternativas posibles en función del
cumplimiento o no de una determinada condición. Se representa de la siguiente forma: 

Pseudocódigo: Diagrama de flujo:

Donde: 
Si:Indica el comando de comparación 
Condición : Indica la condición a evaluar 
Entonces : Precede a las acciones a realizar cuando se cumple la condición 
Instrucción(es):Son las acciones a realizar cuando se cumple o no la condición 
si no :Precede a las acciones a realizar cuando no se cumple la condición 
Dependiendo de si la comparación es cierta o falsa, se pueden realizar una o más acciones. 

Múltiples: 

Las estructuras de comparación múltiples, son tomas de decisión especializadas que permiten comparar una
variable contra distintos posibles resultados, ejecutando para cada caso una serie de instrucciones especificas. La
forma común es la siguiente: 

Pseudocódigo: Diagrama de flujo:

Múltiples (En caso de): 


Las estructuras de comparación múltiples, es una toma de decisión especializada que permiten evaluar una variable
con distintos posibles resultados, ejecutando para cada caso una serie de instrucciones especificas. La forma es la
siguiente: 

Pseudocódigo: Diagrama de flujo:

Veamos algunos ejemplos donde se aplique todo lo anterior: 

Realizar un algoritmo en donde se pide la edad del usuario; si es mayor de edad debe aparecer un mensaje
indicándolo. Expresarlo en Pseudocódigo y Diagrama de flujos. 

Pseudocódigo: Diagrama de flujo:


Se pide leer tres notas del alumno, calcular su definitiva en un rango de 0-5 y enviar un mensaje donde diga si el
alumno aprobó o reprobó el curso. Exprese el algoritmo usando Pseudocódigo y diagrama de flujos. 

Pseudocódigo: 

INICIO 
   Not1, Not2, Not 3 :REAL 
   Def: REAL 
   LEA Nota1, Nota2, Nota3 
   Def ß (Not1 + Not2 + Not3) /3 
   Si Def < 3 entonces 
      Escriba “Reprobó el curso” 
   Sino 
      Escriba “Aprobó el curso” 
   Fin-Si 
FIN 

Diagrama de flujo: 
Se desea escribir un algoritmo que pida la altura de una persona, si la altura es menor o igual a 150 cm envíe el
mensaje: “Persona de altura baja”; si la altura está entre 151 y 170 escriba el mensaje: “Persona de altura media” y
si la altura es mayor al 171 escriba el mensaje: “Persona alta”. Exprese el algoritmo usando Pseudocódigo y
diagrama de flujos. 
Pseudocódigo: 

INICIO 
   Altura: ENTERO 
   ESCRIBA “Cuál es tu altura? ” 
   LEA Altura 
   Si Altura <=150 entonces 
      ESCRIBA “persona de altura baja” 
   Sino 
      Si Altura <=170 entonces 
         ESCRIBA “persona de altura media” 
      Sino 
         Si Altura>170 ENTONCES 
            ESCRIBA “persona alta” 
         Fin-Si 
      Fin-Si 
   Fin-Si 
FIN 

¡Es importante ser ordenado en el código que se escribe! 

Diagrama de flujo: 
Dado un numero entre 1 y 7 escriba su correspondiente día de la semana así: 
1- Lunes 2- Martes 3- Miércoles 4- Jueves 5- Viernes 6- Sábado 7- Domingo 
Exprese el algoritmo usando Pseudocódigo y diagrama de flujos. 

Pseudocódigo: Pseudocódigo: 

INICIO 
   Dia: ENTERO 
   ESCRIBA “Diga un número para escribir su día” 
   LEA Dia 
   En-caso-de Dia haga 
      Caso 1: ESCRIBA “Lunes” 
      Caso 2: ESCRIBA “Martes” 
      Caso 3: ESCRIBA “Miércoles” 
      Caso 4: ESCRIBA “Jueves” 
      Caso 5: ESCRIBA “Viernes” 
      Caso 6: ESCRIBA “Sábado” 
      Caso 7: ESCRIBA “Domingo” 
     SINO: ESCRIBA “Escribió un numero fuera del rango 1-7” 
   Fin-Caso 
FIN 

Diagrama de flujo: 
estructuras cíclicas; Para, mientras, repetir. Complementamos con tres ejemplos para la correcta
asimilación de estas estructuras.

Se llaman problemas repetitivos o cíclicos a aquellos en cuya solución es necesario utilizar un mismo conjunto de
acciones que se puedan ejecutar una cantidad específica de veces. Esta cantidad puede ser fija (previamente
determinada por el programador) o puede ser variable (estar en función de algún dato dentro del programa). Los
ciclos se clasifican en: 
Ciclos con un Numero Determinado de Iteraciones 

 (Para): Son aquellos en que el número de iteraciones se conoce antes de ejecutarse el ciclo. La forma de
esta estructura es la siguiente:
Pseudocódigo Diagrama de Flujos
   

 Dado un valor inicial exp1 asignado a la variable esta se irá aumentando o disminuyendo de acuerdo a la
exp3 hasta llegar a la exp2; si se omite el paso, significa que la variable aumentará de uno en uno.

Ciclos con un Número Indeterminado de Iteraciones 

Son aquellos en que el numero de iteraciones no se conoce con exactitud, ya que esta dado en función de un dato
dentro del programa. 

 Mientras Que: Esta es una estructura que repetirá un proceso durante “N” veces, donde “N” puede ser fijo o
variable. Para esto, la instrucción se vale de una condición que es la que debe cumplirse para que se siga
ejecutando. Cuando la condición ya no se cumple, entonces ya no se ejecuta el proceso. La forma de esta
estructura es la siguiente: 

Pseudocódigo Diagrama de Flujos


   

 Repita-Hasta: Esta es una estructura similar en algunas características, a la anterior. Repite un proceso una
cantidad de veces, pero a diferencia del Mientras Que, el Repita-Hasta lo hace hasta que la condición se
cumple y no mientras, como en el Mientras Que. Por otra parte, esta estructura permite realizar el proceso
cuando menos una vez, ya que la condición se evalúa al final del proceso, mientras que en el Mientras Que
puede ser que nunca llegue a entrar si la condición no se cumple desde un principio. La forma de esta
estructura es la siguiente: 

Pseudocódigo Diagrama de Flujos


   
Ejemplo 1: 

Realizar un algoritmo que muestre los números de uno en uno hasta diez usando una estructura Para. Exprese
el algoritmo usando Pseudocódigo y diagrama de flujos.
Pseudocódigo Diagrama de Flujos
   
Ejemplo 2: 

Usando una estructura Mientras, realizar un algoritmo que escriba los números de uno en uno hasta 20 

Pseudocódigo Diagrama de Flujos


   
Ejemplo 3: 

Realizar un algoritmo que pregunte al usuario un número comprendido en el rango de 1 a 5. El algoritmo deberá
validar el numero, de manera que no continúe la ejecución del programa mientras no se escriba un numero
correcto. 

Pseudocódigo Diagrama de Flujos


   
4.Estructura de de Datos 

Todos los datos tienen un tipo asociado con ellos. Un dato puede ser un simple carácter, tal como ‘b’, un valor
entero tal como 35. El tipo de dato determina la naturaleza del conjunto de valores que puede tomar una variable.

Tipos de Datos Simples 

Datos Numéricos: 
Permiten representar valores escalares de forma numérica, esto incluye a los números enteros y los reales. Este
tipo de datos permiten realizar operaciones aritméticas comunes. 

Datos lógicos: 
Son aquellos que solo pueden tener dos valores (cierto o falso) ya que representan el resultado de una comparación
entre otros datos (numéricos o alfanuméricos). 

Datos alfanuméricos (string): 


Es una secuencia de caracteres alfanuméricos que permiten representar valores identificables de forma descriptiva,
esto incluye nombres de personas, direcciones, etc. Es posible representar números como alfanuméricos, pero
estos pierden su propiedad matemática, es decir no es posible hacer operaciones con ellos. Este tipo de datos se
representan encerrados entre comillas. 

Identificadores 

Los identificadores representan los datos de un programa (constantes, variables, tipos de datos). Un identificador es
una secuencia de caracteres que sirve para identificar una posición en la memoria de la computadora, que permite
acceder a su contenido. 
Ejemplo:
» Nombre

» Num_hrs

» Calif2

Reglas para formar un identificador 


 Debe comenzar con una letra (A a Z, mayúsculas o minúsculas) y no deben contener espacios en blanco.
 Letras, dígitos y caracteres como la subraya ( _ ) están permitidos después del primer carácter.
 La longitud de identificadores puede ser de varios caracteres. Pero es recomendable una longitud promedio
de 8 caracteres.
 El nombre del identificador debe dar una idea del valor que contiene.
Constantes, variables y expresiones en la programación.

Constantes 

Una constante es un dato numérico o alfanumérico que no cambia durante la ejecución del programa. 
Ejemplo: 
pi = 3.1416 

Variable 

Es un espacio en la memoria de la computadora que permite almacenar temporalmente un dato durante la ejecución
de un proceso, su contenido puede cambiar durante la ejecución del programa. 
Para poder reconocer una variable en la memoria de la computadora, es necesario darle un nombre con el cual
podamos identificarla dentro de un algoritmo. 
Ejemplo: 
area = pi * radio ^ 2 
Las variables son : el radio, el area y la constate es pi 

Clasificación de las Variables 


Por su contenido
 Variables Numéricas: Son aquellas en las cuales se almacenan valores numéricos, positivos o negativos, es
decir almacenan números del 0 al 9, signos (+ y -) y el punto decimal. 
Ejemplo: 
iva = 0.15 pi = 3.1416 costo = 2500
 Variables Lógicas: Son aquellas que solo pueden tener dos valores (cierto o falso) estos representan el
resultado de una comparación entre otros datos.
 Variables Alfanuméricas: Esta formada por caracteres alfanuméricos (letras, números y caracteres
especiales). 
Ejemplo: 
letra = ’a’ apellido = ’lopez’ direccion = ’Av. Libertad #190’

Por su uso
 Variables de Trabajo: Variables que reciben el resultado de una operación matemática completa y que se
usan normalmente dentro de un programa. 
Ejemplo: 
Suma = a + b /c 
 Contadores: Se utilizan para llevar el control del numero de ocasiones en que se realiza una operación o se
cumple una condición. Con los incrementos generalmente de uno en uno.
 Acumuladores: Forma que toma una variable y que sirve para llevar la suma acumulativa de una serie de
valores que se van leyendo o calculando progresivamente.

Expresiones 

Las expresiones son combinaciones de constantes, variables, símbolos de operación, paréntesis y nombres de
funciones especiales. 
Por ejemplo: 
a + (b + 3) / c 

Cada expresión toma un valor que se determina tomando los valores de las variables y constantes implicadas y la
ejecución de las operaciones indicadas. 

Una expresión consta de operadores y operandos. Según sea el tipo de datos que manipulan, se clasifican las
expresiones en:
 Aritméticas
 Relacionales
 Lógicas

operadores y los operando, sus tipos y las prioridades de ejecución.

Operadores 
Son elementos que relacionan de forma diferente, los valores de una o mas variables y/o constantes. Es decir, los
operadores nos permiten manipular valores. 

Operadores Aritméticos

Los operadores aritméticos permiten la realización de operaciones matemáticas con los valores (variables y
constantes). 

Los operadores aritméticos pueden ser utilizados con tipos de datos enteros o reales. Si ambos son enteros, el
resultado es entero; si alguno de ellos es real, el resultado es real. 

Operadores Aritméticos 
+ Suma 
- Resta 
* Multiplicación 
/ División 
mod Modulo (residuo de la división entera) 

Ejemplos:
Expresión     Resultado
7/2     3.5
12 mod 7     5
4 + 2 * 5     14

Prioridad de los Operadores Aritméticos 

Todas las expresiones entre paréntesis se evalúan primero. Las expresiones con paréntesis anidados se evalúan de
dentro a fuera, el paréntesis más interno se evalúa primero. 
Dentro de una misma expresión los operadores se evalúan en el siguiente orden:
1. ^ Exponenciación
2. *, /, mod Multiplicación, división, modulo.
3. +, - Suma y resta.

Los operadores en una misma expresión con igual nivel de prioridad se evalúan de izquierda a derecha. 

Ejemplos: 
4 + 2 * 5 = 14     23 * 2 / 5 = 9.2
3 + 5 * (10 - (2 + 4)) = 23     2.1 * (1.5 + 12.3) = 2.1 * 13.8 = 28.98

Operadores Relacionales 
Se utilizan para establecer una relación entre dos valores. Luego compara estos valores entre si y esta comparación
produce un resultado de certeza o falsedad (verdadero o falso). 
Los operadores relacionales comparan valores del mismo tipo (numéricos o cadenas). Estos tienen el mismo nivel
de prioridad en su evaluación. 
Los operadores relaciónales tiene menor prioridad que los aritméticos. 

Tipos de operadores Relacionales


 > Mayor que
 < Menor que
 > = Mayor o igual que
 < = Menor o igual que
 < > Diferente
 = Igual

Ejemplos: 
Si a = 10, b = 20, c = 30 
a + b > c     Falso
a - b < c     Verdadero
a - b = c     Falso
a * b < > c     Verdadero

Ejemplos no lógicos: 
a < b < c 
10 < 20 < 30 
T > 5 < 30 
(no es lógico porque tiene diferentes operandos) 

Operadores Lógicos 

Estos operadores se utilizan para establecer relaciones entre valores lógicos. Estos valores pueden ser resultado de
una expresión relacional. 

Tipos de operadores Lógicos 


And Y 
Or O 
Not Negación 

Ejemplo: 
Para los siguientes ejemplos T significa verdadero y F falso. 

Operador Not Operador Not 


Operando     Resultado
T     F
F     T

Operador And Operador And 


Operando1     Operador     Operando2     Resultado
T     AND     T     T
T F     F
F T     F
F F     F

Operador Or Operador Or 


Operando1     Operador     Operando2     Resultado
T     Or     T     T
T F     T
F T     T
F F     F

Prioridad de los Operadores Lógicos 


1. Not
2. And
3. Or

Prioridad de los Operadores en General 


1. ( )
2. ^
3. *, /, Mod, Not
4. +, -, And
5. >, <, > =, < =, < >, =, Or
Ejemplos: 
Sea: a = 10 b = 12 c = 13 d =10 
6.1.3 Lecturas Requeridas.

 LECTURA No. 1: lenguajes de programacion

En este documento se analiza de manera adecuada las tecnias de la programación , empezando con los
elementos básicos para llegar a implementar un programa. Se maneja varios técnicas de ñrogramacion.

issuu.com/dianameneses/docs/programacion_tarea02
www.taringa.net/.../Aprender-Programacion-de-Computadoras_-Ciclos.html -
www.slideshare.net/.../introduccin-a-la-programacin-de-computadores -
programandoenc.over-blog.es/article-28741792.html .historia de la program

 LECTURA No. 2: programación interactiva.

Esta lectura describe brevemente las herramientas de la programación inteactiva y demás técnicas y lenguajes
de programación..

http://www.programmingclass.co.uk/Beginners/1/IntroductionG01.htm
6.1.4 Material complementario.

 LECTURA No. 1: ciclos en la programación.

El documento detalla de manera general como está conformado la programación, teniendo en cuenta los ciclos
para desarrollar un buen programa..

www.taringa.net/.../Aprender-Programacion-de-Computadoras_-Ciclos.html -

 VIDEO No. 1: programación I


El video muestra de manera detallada los procesos a la hora de realizar un programa.
http://www.programasprogramacion.com/videos_dir_asp.html

 VIDEO No. 2: programación II

En el video se explica brevemente como funciona el enfoque a la programación..

http://universidad21.blogspot.com/2011/02/c-curso-gratis-video-tutorial-online.html

6.1.5 Actividades de aprendizaje unidad No. 1.

6.1.5.1 Actividades autónomas:

 Nombre de la actividad. Algoritmos y programacion


 Nombre del recurso a utilizar. Correo electrónico.
 Indicaciones pasó a paso. Cada uno de los participantes debe leer comprensivamente las lecturas requeridas y
las complementarias, adicionalmente debe observar y analizar los dos videos.
Una vez realizado lo anterior, debe escribir un ensayo no mayor de tres páginas escrito en letra Arial 12, sobre
los lenguajes de programacion. Este ensayo deberá ser enviado al tutor a más tardar el último día de la segunda
semana del desarrollo del módulo, a través del correo electrónico.
 Actividades previas. Desarrollar las lecturas requeridas y complementarias y observar los videos
 Competencias o indicador de competencias. Comprender las diferencias entre un lenguaje de programación y
otro.
 Producto a entregar. Ensayo.
 Fecha de inicio y limite.
Fecha de inicio: Primer día de la primera semana
Fecha de entrega: Último día de la segunda semana.
Porcentaje de valoración. 5%

6.1.5.2 Actividades colaborativas y de Acompañamiento tutorial:

 Nombre de la actividad. Foro presente y futuro de la programación de computadores.


 Nombre del recurso a utilizar. Foro en plataforma.
 Indicaciones pasó a paso. Una vez realizada las lecturas y observado los videos cada participante debe
realizar una consulta sobre las tendencias de los lenguajes de programación. cada participante deberá responder
las siguientes preguntas
o En que generación de los lenguajes de programación se puede ubicar el lenguaje C.
o Cuáles son las principales características de la segunda generación de los lenguajes de programación.
o Mencione diferencias entre la programación modular y programación interactiva.

Una vez resuelto estos interrogantes cada uno de los participantes deberá participar en uno de los grupos
conformados por el tutor. En cada grupo los participantes socializaran las respuestas dadas a las preguntas
anteriores, unificaran criterios y elaboraran un documento común con una única respuesta a cada pregunta la
cual se publicará en el foro para ser socializado.
 Actividades previas. Realización de las lecturas requeridas, complementarias y observación de videos.
 Competencias o indicador de competencias.
-Compartir el desarrollo de un trabajo.
-Participaren cada una de la actividades propuestas.
-Respetar las opiniones y puntos de vista de los demás participantes.
 Producto a entregar. El documento publicado en la plataforma (foro) con la respuestas
 Fecha de inicio y limite.
Fecha de inicio: Último día de la segunda semana
Fecha de entrega: Último día de la segunda semana
 Porcentaje de valoración.
Foro 10%

6.1.6 Resultados del aprendizaje.

Clasificación Técnicas Recursos Estrategia


Evidencias Estrategias de la e de
estrategia instrumentos tecnológicos mejoramiento
Desarrollo del Argument Actividad Elaboración Correo
ensayo ación y autónoma Electrónico
sustentaci
Conocimiento Identificación ón de
de las planteami
tendencias entos
tecnológicos
Identifica las Partici Actividad Investigación Plataforma
partes del pación Autónoma y individual y chat
Desempeño computador de Colaborativa
activid
Expone las ad en
tendencias foro
tecnológicas
Documento Document Actividad Elaboración Documento
con el o escrito Colaborativa grupal de las para
desarrollo del y respuestas participar en
ensayo Acompañam el Foro en
iento del plataforma
Documento tutor
Producto
con las
respuestas
para
participar en
el foro

6.1.7 Valoración de evidencias.

I NIVEL II NIVEL III NIVEL


INTERPRETATIVA ARGUMENTATIVA PROPOSITIVA
 Aplicar las políticas de  Diseñar reportes técnicos  Aplicar
seguridad para garantizar teniendo en cuenta los responsablemente
la integridad de los requerimientos de los manuales de
recursos información de procesos y
tecnológicos de la empresa. cada proceso en la procedimientos, las
 Identificar y analizar los Unidad Administrativa. normas de gestión
posibles riesgos a que  Elaborar reportes de la calidad, de
pueden estar expuestos los técnicos, teniendo en seguridad e impacto
recursos cuenta los procesos de la ambiental para el
tecnológicos de oficina. Unidad Administrativa. funcionamiento de
 Capacitar a los usuarios  Conservar los soportes losrecursos
para la aplicación, documentales del tecnológicos de la
actualización y sistema de información empresa.
configuración de de la Unidad  Utilizar de manera
programas. Administrativa, de responsable los
 Realizar copias de acuerdo con el tipo, las recursos tecnológicos
seguridad de acuerdo con normas técnicas y la de oficina, teniendo
las normas vigentes y la legislación vigente en cuenta los
tecnología teniendo en cuenta las manuales del usuario
disponible. normas técnicas, las de y de operación, las
 Aplicar las políticas de la la Organización y políticas de la
Organización, normas la legislación vigente. Organización, el
técnicas y legislación  Diseñar aplicacines de manual de procesos
vigente para acuerdo con la tecnología y p rocedimientos, las
laconservación de las disponible y las normas de gestión de
copias de seguridad. necesidades la calidad,seguridad y
 Identificar los tipos de de la Unidad adm. salud ocupacional y
soportes documentales las funciones de la
establecidos en la Unidad  Administrar las Unidad
Administrativa. aplicaciones de acuerdo Administrativa.
con las políticas de la  Instala
Organización y las responsablemente
necesidades de la los recursos
Unidad tecnológicos de
Administrativa. oficina de acuerdo
 Agrupar los datos con las
relevantes teniendo en especificaciones
cuenta la importancia de técnicas, las normas
los procesos Sistema de de gestión de la
Gestión de la Calidad calidad, seguridad y
salud
 ocupacional y la
normatividad legal
vigente. Instala
cuidadosamente las
actualizaciones
(Update) requeridas
por el sistema
operativo.

6.1.8 Evaluación de aprendizajes.

EVALUACIÓN DE APRENDIZAJES

Actividades individuales  Realización de ensayo, teniendo en cuenta


lecturas requeridas, complementarias y la
observación de los videos.

 Consulta sobre las tendencias tecnológicas


Propósitos de la formación Reconocer los diferentes lenguajes de
programacion.
Criterios de evaluación  Análisis de lecturas requeridas,
complementarias y videos.
 Calidad de los argumentos y sustentación.
 Cumplimiento de tiempos estipulados.
 Respeto a los derechos de autor en la
información consultada
Ponderación 8%
Actividades Colaborativas y Trabajo para socializar en el foro sobre: presente
de Acompañamiento tutorial y futuro de los computadores
Propósitos de la formación Aplicar las diferentes herramientas de
programación para resolver problemas
Criterios de evaluación  Calidad y pertinencia de las respuestas
 Respeto a los derechos de autor en la
información consultada
 Respeto y buen trato a los compañeros de
grupo y participantes del foro
Ponderación 10%
Autoevaluación Los siguientes son los parámetros que debe
tener en cuenta en el proceso de autoevaluación:

 Calidad de los trabajos


 Puntualidad en la entrega
 Respeto por los compañeros
 Participación activa en el foro
 Trabajo en grupo
Ponderación 3%
Unidad I Introduccion a la programacion
Horas Horas
Actividad trabajo de de trabajo
acompañamiento autónomo
Lectura comprensiva de los documentos
Observación de los videos 2
Realización del ensayo sobre lenguajes
de programacion 5 3
Consulta individual tendencias de los 5
lenguajes de programación.
Trabajo en grupo sobre el lenguajes de 8
programacion
Participación en foro presente y futuro de 3 3
la programación de computadores
6.2 UNIDAD DE APRENDIZAJE No. 2: LENGUAJES DE PROGRAMACION

NOMBRE Y No. DE LA UNIDAD Tiempo


Lenguajes de Horas
Programación de 20
acompañamiento tutorial
Horas
de 12
trabajo Autónomo
Competencias de la unidad de aprendizaje
Elemento No. 2: Implementar software de propósito general u especifico de
acuerdo a las necesidades de la empresa, manejando lenguajes de
programación OO, dinámicos y otros, respetando las normas de seguridad,
derechos de autor e impacto ambiental de la organización.
TABLA DE SABERES
Saber hacer Saber saber Saber ser
 Verificar y validar la  Interpretar datos  Respetar las
solución realizada de estadísticos de opiniones de los
acuerdo con el diseño autoevaluación de demás.
y listas de chequeo
equipos y software.  Ser responsable con
 Planear Metodología el manejo de la
 Realizar el proceso de para elaborar información a
pruebas y corrección planes.de pruebas cualquier nivel de
de errores  Proponer investigación.
 Identificar los Metodología para
requerimientos de elaborar casos de
software en una empresa. pruebas  Ser ético en su
 Analizar los procesos de  Instalar profesión.
instalación de software, Herramientas  Tener apertura al
teniendo en cuenta los ofimáticas. cambio tecnológico.
demás productos  Elabora de informes
instalados en los equipos. sonbre programas
 Realizar pruebas de instalados en los
funcionamiento al equipos de
software operativo computo..
instalado en los equipos.
 Determinar los - Manejar Herramientas
procedimientos para automatización de
correctivos a realizar en pruebas unitarias
caso de que el software - Conocer Herramientas
instalado presente fallas. para consulta de bases
de datos

 Tomar medidas de
seguridad y protección
para el entorno físico,
en el software
instalado, y en la
información
almacenada en uno o
varios equipos y/o
servidores.
 Determinar técnicas
generales de gestión
de recursos del sistema
informático y las
características, que
utilizan los sistemas
operativos tanto a nivel
multiusuario como
monousuario.
 Identifique la clase de  Conocer los problemas  Ser responsable en el
aplicaciones instaladas y que crea un sistema, momento de adquirir
su desempeño en las con la gestión de los aplicaciones para uso
actividades de un usuario. recursos de forma de la empresa.
 Realizar pruebas de inadecuada y la  Ser ético en su
funcionamiento al importancia de la profesión.
software instalado en los medición,  Respetar las
equipos. contabilización del uso opiniones de los
. de recursos y la demás.
optimización de un  Estar siempre
sistema en uso y dispuesto a la mejora
manejo. en las aplicaciones
 Conocer los criterios de instaladas en las
mejora en el uso del unidades informáticas.
software instalado en
un sistema informático.
 Identificar los  Diagnosticar  Ser responsable con
requerimientos y Problemas que puede pruebas realizadas a
necesidades de usuarios. presentar un sistema sistemas de
 Organizar la información en general como información.
de archivos, carpetas de resultado de accesos y  Ser ético en su
cada usuario, donde su usos indebidos. profesión.
acceso sea adecuada y  Tomar medidas de  Respetar las
que siempre se encuentre carácter preventivo y opiniones de los
disponible. correctivo. demás.
 Realizar a modo de  Estar dispuesto a
prueba diferentes organizar la utilización
aplicaciones para de los sistemas de
determinar cuales se información por parte
ajustan a las necesidades de los usuarios.
de la empresa.

6.2.1 Resumen.

En la unidad se presenta al participante las formas generales de programación de acuerdo a las habilidades y
destrezas del estudiante a la hora de implementar un programa.

La Información y Conocimiento son los dos elementos claves del nuevo milenio ninguna sociedad podrá alcanzar ni
puede ignorar este nuevo esquema ya las naciones no se miden por su riqueza industrial, ni sus activos físicos , ni
por su poder militar, sino por la cantidad de información que produce y consume, así como por la recombinación de
información nueva en un conocimiento de grado superior.

Nuevos sistemas de información, tienden a ser cada vez de mayor alcance y complejidad sobre todo cuando se
toman en cuenta la nuevas necesidades de información y conocimiento que demandan las nuevas organizaciones

Nuevos sistemas de información son costosos en tiempos y recursos, la solución moderna de sistemas de
información exigen herramientas y metodologías que resuelvan rápida, económica, eficiente y de manera global,
problemas de información y conocimiento planteados por las organizaciones.

Además el pleno potencial del hardware tampoco es aprovechado plenamente y existe un considerable retraso con
el software y sus aplicaciones generando lo que se conoce como “crisis del software”.

Actualmente el paradigma de programación se ha enfocado a nuevas necesidades de modernos y globales


sistemas de información basados en redes y mas aun en la red global de internet, actualmente es mas importante
poder concebir y construir sistemas de información con estas nuevas tecnologías de programación.
6.2.2 Desglose general de contenidos.

 LENGUAJES ORIENTADOS A OBJETOS

Antecedentes

Otro enfoque para la creación de programas es el paradigma orientado a objetos, OO. El término programación
orientada a objetos se refiere a un estilo de programación por lo que un lenguaje orientado a objetos puede ser tanto
imperativo como declarativo; lo que los caracteriza es la forma de manejar la información: clase, objeto y herencia.
En este enfoque, las unidades de datos se consideran objetos activos, en vez de las unidades pasivas
contempladas por el paradigma por procedimientos tradicional. Para aclarar esto, consideremos una lista de
nombres. En el paradigma por procedimientos, esta lista no es más que una colección de datos, y cualquier
programa que quiera trabajar con ella deberá incluir los algoritmos para realizar las manipulaciones requeridas. Así,
la lista es pasiva en el sentido de que la mantiene un programa controlador, en vez de tener la responsabilidad de
mantenerse ella misma. En cambio, en el enfoque orientado a objetos la lista se considera como un objeto formado
por la lista misma y por una serie de rutinas para manipularla. Por ejemplo, pueden ser rutinas para insertar una
nueva entrada en la lista, para detectar si la lista está vacía o para ordenar la lista. De este modo, un programa que
obtiene acceso a esta lista no necesita contener algoritmos para efectuar esas tareas; simplemente aprovecha las
rutinas suministradas en el objeto. En cierto sentido, en vez de ordenar la lista como en el paradigma por
procedimientos, el programa pide a la lista que se ordene a sí misma.

Muchas ventajas del paradigma orientado a objetos son consecuencias de la estructura modular que surge como
subproducto natural de la filosofía orientada a objetos, pues cada objeto se implanta como un módulo individual,
bien definido, cuyas características son en gran medida independientes del resto del sistema. Así, una vez
desarrollado un objeto que representa a una determinada entidad, es posible reutilizar ese objeto cada vez que se
requiera dicha entidad. De hecho, un rasgo primoridal de los lenguajes de programación orientados a objetos es la
capacidad de representar definiciones de objetos a modo de esqueletos, clases, que pueden usarse una y otra vez
para construir múltiples objetos con las mismas propiedades, herencia, o modificarse para construir nuevos objetos
con propiedades similares.
Lenguajes orientados a objetos los lenguajes de alto nivel se basan principalmente en la programación estructurada;
sin embargo, los lenguajes orientados a objetos se centran en los datos, objetos, indicando cómo
han de ser y definiendo las operaciones a las que se les va a someter. Existen varios lenguajes que soportan
programación orientada a objetos : Visual Basic, Object Pascal, Smalltalk, C++, C#, Visual C++, Visual J, etc.

La programación OO está adquiriendo popularidad a grandes pasos, y muchos creen que dominará el campo de la
programación en el futuro.

El lenguaje orientado a objetos más conocido es Smalltalk, que apareció en 1976. Es un lenguaje de tipo imperativo
donde se utilizó por primera vez el vocabulario que se ha hecho característico de este tipo de lenguajes. Un lenguaje
que se ha añadido a los llamados orientados a objetos es la extensión de C aparecida en 1986, C++. Aunque es
muy diferente a Smalltalk, ha sido muy popular por ser una extensión del lenguaje C. Uno de los últimos lenguajes
OO aparecidos es Java.
1.LENGUAJE C++

Aunque C++ es un superconjunto de C, existen algunas diferencias entre los dos. En primer lugar, en C cuando una
función no toma parámetros, su prototipo tiene la palabra void. Sin embargo en C++ void no es necesario(opcional).

     Prototipo en C:             char f1(void);


     Prototipo en C++:         char f1();

Otra diferencia entre C y C++ es que en un programa de C++ todas las funciones deben estar en forma de prototipo,
en C los prototipos se recomiendan, pero son opcionales. También si una función de C++ es declarada para
devolver un valor obligatoriamente la sentencia return debe devolver un valor, en C no es necesario que se
devuelva.

Otra diferencia es el lugar donde se declaran las variables locales. En C, deben ser declaradas solo al principio del
bloque, mientras que en C++ las variables se pueden declarar en cualquier punto. Aunque es conveniente realizarlo
siempre al comienzo de la función.

Los programas estructurados se basan en estructuras de control bien definidas, bloques de código, subrutinas
independientes que soportan recursividad y variables locales. La esencia de la programación estructurada es la
reducción de un programa a sus elementos constituidos.

La programación orientada a objetos (POO), permite descomponer un problema en subgrupos relacionados. Cada
subgrupo pasa a ser un objeto autocontenido que contiene sus propias instrucciones y datos que le relacionan con
ese objeto. Todos los lenguajes POO comparten tres características: Encapsulación, Polimorfismo y Herencia.

ENCAPSULACIÓN: Es el mecanismo que agrupa el código y los datos que maneja. Los mantienen protegidos
frente a cualquier interferencia y mal uso. Cuando el código y los datos están enlazados de esta manera se ha
creado un objeto. Ese código y datos pueden ser privados  para ese objeto o públicos para otras partes del
programa.

POLIMORFISMO: Es la cualidad que permite que un nombre se utilice para dos o más propósitos relacionados pero
técnicamente diferentes. El propósito es poder usar un nombre para especificar una clase general de acciones. Por
ejemplo en C tenemos tres funciones distintas para devolver el valor absoluto. Sin embargo en C++ incorpora
Polimorfismo y a cada función se puede llamar abs(). El Polimorfismo se puede aplicar tanto a funciones como a
operadores.

HERENCIA: Proceso mediante el cual un objeto puede adquirir las propiedades de otro objeto. La información se
hace manejable gracias a la clasificación jerárquica.

OBJETO: Conjunto de variables y funciones pertenecientes a una clase encapsulados. A este encapsulamiento es
al que se denomina objeto. Por tanto la clase es quien define las características y funcionamiento del objeto.

Creación de Clases y Objetos

La base del encapsulamiento es la clase, a partir de ellas se le dan las características y comportamiento a los
objetos. Lo primero es crear la clase y después en la función main que sigue siendo la principal crearemos los
objetos de cada una de las clases. Las variables y funciones de una clase pueden
ser publicas, privadas o protegidas. Por defecto si no se indica nada son privadas.

Estos modificadores nos indican en que partes de un programa podemos utilizar las funciones y variables.
private: Solo tendrán acceso los de la misma clase donde estén definidos.
public: Se pude hacer referencia desde cualquier parte del programa.
protected: Se puede hacer referencia desde la misma clase y las subclases.

Creación de una clase:


class nomb_clase{
funciones y variables privadas;
public:
funciones y variables publicas;
}

Creación del objeto:


nomb_clase nombre_objeto1;
nomb_clase nombre_objeto2;

Llamadas a las funciones de una clase:


nombre_objeto.nomb_funcion(parámetros);

Desarrollo de funciones miembro:


val_devuelto nomb_clase::nomb_funcion(parametros){
   cuerpo;
}

EJEMPLO: Declaramos una clase con una variable privada y dos funciones públicas. La clase recibe el nombre
de miclase.
class miclase{
int a;
public:
void funcion1(int num);
int funcion2();
}

Mi Primer Programa

Como ejemplo a lo anterior crearemos el primer programa utilizando objetos y clases para ver la teoría llevada a la
práctica. Seguiremos utilizando las mismas sentencias que usábamos en C, más adelante los programas tomarán la
estructura exclusiva de C++.
#include <stdio.h>
#include <conio.h>

class miclase{
   int a;
   public:
   void pasar_a(int num);
   int mostrar_a();
};

void miclase::pasar_a(int num)


{
   a=num;
}

int miclase::mostrar_a()
{
   return a;
}

void main()
{
   miclase obj1, obj2;
   clrscr();
   obj1.pasar_a(10);
   obj2.pasar_a(99);
   printf("%d\n",obj1.mostrar_a());
   printf("%d\n",obj2.mostrar_a());
   getch();
}
Entrada y Salada por Consola en C++
En C++ se pueden seguir utilizando las mismas sentencias para mostrar información por pantalla o pedirla
mediante teclado. Pero a estas antiguas se añaden 2 nuevas de la misma potencia y mayor facilidad de uso. La
cabecera que utilizan estas dos sentencias es iostream.h.

Mostrar por pantalla:


cout << expresión;

Pedir por teclado:


cin >> variable; La variable pude ser de cualquier tipo.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>

void main()
{
   int i,j;
   double d;
   clrscr();
   i=10;
   j=15;
   cout <<"Introducir valor: ";
   cin>>d;
   cout << "Estos son los valores:  ";
   cout << i << "  "<< j << "  "<< d;
   getch();
}

INDICADORES DE FORMATO: Tres funciones miembro (width, precision y fill) que fijan formato de anchura,
precisión y carácter de relleno. Es necesario fijar la anchura, precisión y carácter de relleno antes de cada sentencia
de escritura.
ANCHURA:      cout.width(ancho);
DECIMALES:   cout.precision(nº digitos);
RELLENO:       cout.fill('carácter');

EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>

void main()
{
     double numero=123.1234567;
     clrscr();
     cout<< "hola" <<"\n";
     cout.width(15);
     cout<< "hola" <<"\n";
     cout.width(15);
     cout.fill('*');
     cout<< "hola"<<"\n";
     cout<<numero <<"\n";
     cout.precision(4);
     cout<<numero <<"\n";
     cout.precision(10);
     cout<<numero;
     getch();
}

MODIFICADORES DE LA CLASE IOS: Estos modificadores son pertenecientes a la clase ios. Cuando se activan
su valor se mantiene, es decir hay que desactivarlos para volver al formato de salida origi nal.
Fijar indicador: 
cout.setf(ios::identificador|ios::identificador2);

Anular identificador: 
cout.unsetf(ios::identificador|ios::identificador2);

IDENTIFICADOR DESCRIPCIÓN
oct Devuelve un entero en octal.

Devuelve un entero en hexadecimal.


hex
scientific Devuelve un número en formato científico.
showpoint Muestra 6 decimales aunque no sea necesario
showpos Muestra el signo + en los valores positivos
left Ajusta la salida a la izquierda.
skipws Omite los espacios a la izquierda de la salida.
uppercase Muestra el texto en mayúsculas.

EJEMPLO: 
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
void main()
{
     float num=200.0;
     int num1=200;
     clrscr();
     cout<<num <<"\n";
     cout.setf(ios::showpos|ios::showpoint);
     cout<<num <<"\n";
     cout.setf(ios::scientific);
     cout<<num <<"\n";
     cout.unsetf(ios::scientific|ios::showpoint|ios::showpos);
     cout<<num <<"\n";
     cout.setf(ios::hex);
     cout<<num1 <<"\n";
     getch();
}

 Funciones Constructoras y Destructoras

En los programas hay partes que requieren inicialización. Esta necesidad de inicialización es incluso más común
cuando se está trabajando con objetos. Para tratar esta situación, C++ permite incluir una función constructora. A
estas funciones se las llama automáticamente cada vez que se crea un objeto de esa clase.

La función constructora debe tener el mismo nombre que la clase de la que es parte, no tienen tipo devuelto, es
ilegal que un constructor tenga un tipo devuelto. Pero si es posible pasarle valores a modo de parámetros.

Prototipo de la función:
nombre_fucion(parámetros);

Desarrollo de la función:
nombre_calse::nombre_funcion(parámetros){
  cuerpo;
}

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
    int a;
public:
   miclase(); 
   void show();
};

miclase::miclase() 

         a=100; 
}

void miclase::show()
{
         cout << a;
}

void main()
{
   clrscr();
   miclase obj; 
   obj.show();
   getch();
}

El complemento de un constructor es la función destructora. A esta función se la llama automáticamente cuando se


destruye el objeto. El nombre de las funciones destructoras debe ser el mismo que el de la clase a la que pertenece
precedido del carácter ~ (alt+126). Los objetos de destruyen cuando se salen de ámbito cuando son locales y al salir
del programa si son globales. Las funciones destructoras no devuelve tipo y tampoco pueden recibir parámetros.

Técnicamente un constructor y un destructor se utilizan para inicializar y destruir los objetos, pero también se
pueden utilizar para realizar cualquier otra operación. Sin embargo esto se considera un estilo de programación
pobre.
PROTOTIPO DE LA FUNCIÓN:
~nombre_funcion(parámetros);

DESARROLLO DE LA FUNCION:
nombre_clase::nombre_funcion(){
cuerpo;
}

EJEMPLO: Mismo programa de antes añadiendo una función destructora.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
int a;
public:
     miclase();
     ~miclase(); 
     void show();
};

miclase::miclase()
{
     a=100;
}

miclase::~miclase() 

     cout << "Destruyendo...\n"; 
     getch(); 
}
void miclase::show()
{
     cout << a;
}

void main()
{
     clrscr();
     miclase obj;
     obj.show();
     getch();
}

CONSTRUCTORES CON PARAMETROS: Es posible pasar argumentos a una función constructora. Para permitir
esto, simplemente añada los parámetros a la declaración y definición de la función constructora. Después, cuando
declare un objeto, especifique los parámetros como argumentos.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
         int a;
public:
         miclase(int x);
     void mostrar();
};

miclase::miclase(int x)
{
         cout << "Constructor";
     a=x;
}

void miclase::miclase()
{
         cout <<"El valor de a es: ";
cout << a;
}

void main()
{
         miclase objeto(4);
     ob.show();
         getch();
}

Funciones InLine y Automáticas

LA ventaja de las funciones insertadas es que se pueden ejecutar más rápidamente que las funciones normales. La
llamada y vuelta de una función normal tardan tiempo y si tienen parámetros incluso más. Para declarar este tipo de
funciones simplemente hay que preceder la definición de la función con el especificador inline.

inline valor_devuelto nombre_función(parámetros)


 {
       cuerpo;
 }

Las llamadas a las funciones insertadas se realiza de la misma manera que cualquier función. Uno de los requisitos
es que se tiene que definir antes de llamarla, es decir definir y desarrollar antes de la función main.
Si el compilador no es capaz de cumplir la petición, la función se compila como una función normal y la solicitud
inline se ignora. Las restricciones son cuatro, no puede contener variables de tipo static, una sentencia de  bucle,
un switch o un goto.

EJEMPLO: En este programa utilizamos una función inline pasando valores. No usa clases ni objetos.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
inline int valor(int x) { return ¡!(X%2);}
void main()
{
  int a;
  cout <<"Introducir valor: ";
  cin >> a;
  if (valor(a))
       cout << "Es par ";
  else
       cout << "Es impar";
}

La característica principal de las funciones automáticas es que su definición es lo suficientemente corta y puede


incluirse dentro de la declaración de la clase. La palabra inline no es necesaria. Las restricciones que se aplican a
las funciones inline se aplican también para este tipo. El uso más común de las funciones automáticas es para
funciones constructoras.

valor_devuelto nombre_funcion(parametros){cuerpo;}

EJEMPLO: Mismo programa anterior pero sin utilizar inline.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class ejemplo{
public:
int valor(int x) { return ¡!(X%2);}
};        

void main()
{
  int a;
  cout <<"Introducir valor: ";
  cin >> a;
  if (valor(a))
       cout << "Es par ";
  else
       cout << "Es impar";
}

Utilización de Estructuras como Clases


En C++, la definición de una estructura se ha ampliado para que pueda también incluir funciones miembro,
incluyendo funciones constructoras y destructoras como una clase. De hecho, la única diferencia entre una
estructura y una clase es que, por omisión, los miembros de una clase son privados y los miembros de una
estructura son públicos.
struct nombre{
       variables y funciones publicas;
  private:
       variables y funciones privadas;
  };

Aunque las estructuras tienen las mismas capacidades que las clases, se reserva el uso de struct para objetos que
no tienen funciones miembro. Una de las razones de la existencia de las estructuras es mantener compatibilidad con
los programas hechos C.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
struct tipo{
         tipo(double b, char *n);
     void mostrar();
private:
         double balance;
     char nombre[40];
};

tipo::tipo(double b, char *n)


{
         balance=b;
     strcpy(nombre,n);
}

void tipo::mostrar()
{
         cout << "Nombre: " << nombre;
     cout << ": $" << balance;
         if (balance<0.0) cout << "****";
     cout << "\n";
}

void main()
{
         clrscr();
     tipo acc1(100.12,"Ricardo");
         tipo acc2(-12.34,"Antonio");
     acc1.mostrar();
         getch();
     clrscr();
         acc2.mostrar();
     getch();
}

Operaciones con Objetos


ASIGNACIÓN DE OBJETOS: Se puede asignar un objeto a otro a condición de que ambos objetos sean del mismo
tipo (misma clase). Cuando un objeto se asigna a otro se hace una copia a nivel de bits de todos los miembros, es
decir se copian los contenidos de todos los datos. Los objetos continúan siendo independientes.
objeto_destino=objeto_origen;

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
    int a,b;
public:
     void obtener(int i, int j){a=i;b=j;}
     void mostrar(){cout << a << " "<< b << "\n";}
};

void main()
{
     miclase o1,o2;
     o1.obtener(10,4);
     o2=o1;
     o1.show();
     o2.show();
     getch();
}

ARRAY DE OBJETOS: Los objetos son variables y tienen las mismas capacidades y atributos que cualquier tipo de
variables, por tanto es posible disponer objetos en un array. La sintaxis es exactamente igual a la utilizada para
declarar y acceder al array. También disponemos de arrays bidimensionales.

DECLARACIÓN:
nombre_clase nombre_objeto[nº elementos];
nombre_clase nombre_objeto[nº elementos]={elementos};

INICIALIZACIÓN:
nombre_objeto[índice].función(valores);

EJEMPLO: Unidimensional.
     #include <iostream.h>
     #include <stdio.h>
     #include <conio.h>
     class ejemplo{
         int a;
     public:
         void pasar(int x){a=x;}
         int mostrar() {return a;}
     };
     void main()
     {
         ejemplo ob[4];
         int indice;
         clrscr();
         for(indice=0;indice<4;indice++)
              ob[indice].pasar(indice);
         for(indice=0;indice<4;indice++)
         {
              cout << ob[indice].mostrar();
              cout << "\n";
         }
         getch();
     }

EJEMPLO: Bidimensional.
     #include <iostream.h>
     #include <stdio.h>
     #include <conio.h>
     class bidi{
         int a,b;
     public:
          bidi(int n, int m){a=n;b=m;}
         int pasa_a(){return a;}
         int pasa_b(){return b;}
     };
     void main()
     {
         clrscr();
         int fil,col;
         bidi objeto[3][2]={
              bidi(1,2),bidi(3,4),
              bidi(5,6),bidi(7,8),
              bidi(9,10),bidi(11,12)};
         for(fil=0;fil<3;fil++)
          {
              for(col=0;col<2;col++)
              {
                   cout << objeto[fil][col].pasa_a();
                   cout << " ";
                   cout << objeto[fil][col].pasa_b();
                   cout << "\n";
              }
         }
         getch();
     }

PASO DE OBJETOS A FUNCIONES: Los objetos se pueden pasar a funciones como argumentos de la misma
manera que se pasan otros tipos de datos. Hay que declarar el parámetro como un tipo de clase y después usar un
objeto de esa clase como argumento cuando se llama a la función. Cuando se pasa un objeto a una función se hace
una copia de ese objeto.

Cuando se crea una copia de un objeto porque se usa como argumento para una función, no se llama a la función
constructora. Sin embargo, cuando la copia se destruye (al salir de ámbito), se llama a la función destructora.

PROTOTIPO DE FUNCIÓN: 
tipo_devuelto nombre(nombre_clase nombre_objeto){
              cuerpo;
}

LLAMADA A  LA FUNCIÓN:
nombre_funcion(objeto);

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class objetos{
         int i;
public:
     objetos(int n){i=n;}
     int devol(){return i;}
};
int sqr(objetos o)
{
         return o.devol()*o.devol();
}
void main()
{
         objetos a(10), b(2);
     cout << sqr(a);
         cout << sqr(b);
     getch();
}

OBJETOS DEVUELTOS POR FUCIONES: Al igual que se pueden pasar objetos, las funciones pueden devolver
objetos. Primero hay que declarar la función para que devuelva un tipo de clase. Segundo hay que devolver un
objeto de ese tipo usando  la sentencia return.

Cuando un objeto es devuelto por una función, se crea automáticamente un objeto temporal que guarda el valor
devuelto. Este es el objeto que realmente devuelve la función. Después el objeto se destruye, esto puede causar
efectos laterales inesperados.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
class ejemplo{
     char cadena[80];
public:
     void muestra(){cout<<cadena<<"\n";}
     void copia(char *cad){strcpy(cadena,cad);}
};
ejemplo entrada()
{
     char cadena[80];
     ejemplo str;
     cout<<"Introducir cadena: ";
     cin>>cadena;
     str.copia(cadena);
     return str;
}
void main()
{
     ejemplo ob;
     ob=entrada();
     ob.muestra();
     getch();
}

PUNTEROS A OBJETOS: Hasta ahora se ha accedido a miembros de un objeto usando el operador punto. Es


posible acceder a un miembro de un objeto a través de un puntero a ese objeto. Cuando sea este el caso, se
emplea el operador de flecha (->) en vez del operador punto. Para obtener la dirección de un objeto, se precede al
objeto con el operador &. Se trabaja de igual forma que los punteros a otros tipos.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
     int a;
public:
     miclase(int x);
     int get();
};
miclase::miclase(int x)
{
     a=x;
}
int miclase::get()
{
     return a;
}
void main()
{
     clrscr();
     miclase obj(200);
     miclase *p;
     p=&obj;
     cout << "El valor del Objeto es " << obj.get();
     cout << "El valor del Puntero es " << p->get();
     getch();
}

Funciones Amigas

Habrá momentos en los que se quiera que una función tenga acceso a los miembros privados de una clase sin que
esa función sea realmente un miembro de esa clase. De cara a esto están las funciones amigas. Son útiles para la
sobrecarga de operadores y la creación de ciertos tipos de  funciones E/S.

El prototipo de esta funciones viene precedido  por la palabra clave friend, cuando se desarrolla la función no es
necesario incluir friend. Una función amiga  no es miembro y no se puede calificar mediante un nombre de objeto.
Estas funciones no se heredan y pueden ser amigas de más de una clase.

PROTOTIPO:
friend tipo_devuelto nombre(parametros);
DESARROLLO:
tipo_devuelto nombre(parametros){
       cuerpo;
}

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
         int n,d;
public:
         miclase(int i, int j){n=i;d=j;}
     friend int factor(miclase ob);
};

int factor(miclase ob)


{
         if (!(ob.n%ob.d))
              return 1;
     else
              return 0;
}

void main()
{
     miclase obj1(10,2), obj2(3,2);
     if(factor(obj1))
              cout << "es factor";
     else
              cout << "no es factor";
     getch();
}

This, New y Delete

This es un puntero que se pasa automáticamente a cualquier miembro cuando se invoca. Es un puntero al objeto
que genera la llamada, por tanto la función recibe automáticamente un puntero al objeto. A este puntero se
referencia como this y solo se pasa a los miembros punteros this.
objeto.funcion(); // a la función recibe automáticamente el puntero this.

EJEMPLO: El primero  sin puntero this. El segundo utilizando el puntero this.

1.-
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
class stock{
      char item[20];
      double coste;
public:
      stock(char *i,double c)
      {
            strcpy(item,i);
            coste=c;
      }
      void muestra();
};
void stock::muestra()
{
      cout<<item << "\n";
      cout<<"PVP: " << coste;
}

void main()
{
      clrscr();
      stock obj("tuerca",5.94);
      obj.muestra();
      getch();
}

2.- 
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
class stock{
      char item[20];
      double coste;
public:
      stock(char *i,double c)
      {
            strcpy(this->item,i);
            this->coste=c;
      }
      void muestra();
};
void stock::muestra()
{
      cout<<this->item << "\n";
      cout<<"PVP: " << this->coste;
}

void main()
{
      clrscr();
      stock obj("tuerca",5.94);
      obj.muestra();
      getch();
}

Hasta ahora si se necesitaba asignar memoria dinámica, se hacía con malloc y para liberar se utilizaba free. En C++
se puede asignar memoria utilizando new y liberarse mediante delete. Estas operadores no se pueden combinar
unas con otras, es decir debe llamarse a delete solo con un puntero obtenido mediante new. Los objetos también se
les puede pasar un valor inicial con la sentencia new.

SINTAXIS:
puntero=new tipo;
delete puntero;
puntero=new tipo(valor_inicial);

También se pueden crear arrays asignados dinámicamente, estos arrays pueden utilizar la sentencia new. La
sintaxis general es:

DECLARACION DEL ARRAY: 


puntero=new tipo[tamaño];

EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
class cosas{
     int i,j;
public:
     void obten(int a,int b){i=a;j=b;}
     int muestra(){return i*j;}
};
void main()
{
     clrscr();
     int *p_var;
     p_var=new int;
//p_var=new int(9); se asigna un valor inicial.
     cosas *p;
     p=new cosas;
     if(!p || !p_var)
     {
         cout<<"Error de asignacion\n";
         exit(1);
     }

     *p_var=1000;
     p->obten(4,5);
     cout<<"El entero en p_var es: " <<*p_var;
     cout<<"\nTotal: " <<p->muestra();
     getch();
}

EJEMPLO: Array asignado dinámicamente.


#include<iostream.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
void main(void)
{
     int *p;
     int i;
     p=new int[5];
     clrscr();
     if(!p)
     {
         cout<<"Error de asignacion\n";
         exit(1);
     }
     for(i=0;i<5;i++)
         p[i]=i+1;
     for(i=0;i<5;i++)
     {
         cout<<"Este es el entero en p["<<i<<"]:";
         cout<<p[i]<<"\n";
     }
     delete[] p;
     getch();
}

Referencias
C++ consta de una particularidad relacionada con los punteros, denominada referencia. Una referencia  es un
puntero implícito que se comporta como una variable normal siendo un puntero. Existen tres modos de utilizar una
referencia. Se puede pasar a una función, ser devuelta de una función y crearse como una referencia independiente.
Lo que apunta una referencia no puede ser modificado. El caso de las referencias independientes es muy poco
común y casi nunca se utilizan, en este manual no se hace referencia a ellas.
En el ejemplo siguiente se compara un programa que utiliza un puntero normal y otro programa que realiza las
mismas operaciones utilizando una referencia que se pasa a una función.

EJEMPLO:
Utilizando punteros normal.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void f(int *n);
void main()
{
     int i=0;
     f(&i);
     cout<<"valor i:" << i;
     getch();
}
void f(int *n)
{
       *n=100;
}

Utilizando referencias.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void f(int &n);
void main()
{
     int i=0;
     f(i);
     cout<<"valor i:"<< i;
     getch();
}

void f(int &n)


{
     n=100;
}

En el caso de las referencias devueltas por una función se puede poner el nombre de la función en el lado izquierdo
de la expresión. Es como asignar un valor a una variable. Hay que tener en cuenta el ámbito de la variable que se
comporta como una referencia.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
int &f();
int x;
void main()
{
     clrscr();
     f()=100;
     cout<<"Valor de x: " <<x;
     getch();
}

int &f()
{
     return x;
}

Herencia
Para empezar, es necesario definir dos términos normalmente usados al tratar la herencia. Cuando una clase
hereda otra, la clase que se hereda se llama clase base. La clase que hereda se llama clase derivada. La clase
base  define todas las cualidades que serán comunes a cualquier clase derivada. Otro punto importante es el
acceso a la clase base. El acceso a la clase base pude tomar 3 valores, public, private y protected.

Si el acceso es public, todos los atributos de la clase base son públicos para la derivada.

Si el acceso es private, los datos son privados para la clase base la derivada no tiene acceso.

Si el acceso es protected, datos privados para la base y derivada tiene acceso, el resto sin acceso.

EJEMPLO: para comprobar los distintos tipos de acceso.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class miclase{
     int a;
protected:
     int b;
public:
     int c;
     miclase(int n,int m){a=n;b=m;}
     int obten_a(){return a;}
     int obten_b(){return b;}
};

void main()
{
     miclase objeto(10,20);
     clrscr();
     objeto.c=30;
     // objeto.b=30; error,sin acceso.
     // objeto.a=30; error,sin acceso.
     cout<<objeto.obten_a() <<"\n";
     cout<<objeto.obten_b() <<"\n";
     cout<<objeto.c;
     getch();
}

FORMATO DE LA CLASE DERIVADA:


class nombre_derivada:acceso nombre_base{
   cuerpo;
};

EJEMPLO: Herencia pública.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class base{
     int x;
public:
     void obten_x(int a){x=a;}
     void muestra_x(){cout<< x;}
};

class derivada:public base{


     int y;
public:
     void obten_y(int b){y=b;}
     void muestra_y(){cout<<y;}
};
void main()
{
     derivada obj;
     clrscr();
     obj.obten_x(10);
     obj.obten_y(20);
     obj.muestra_x();
     cout<<"\n";
     obj.muestra_y();
     getch();
}

 EJEMPLO: Herencia con acceso privado.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class base{
     int x;
public:
     void obten_x(int a){x=a;}
     void muestra_x(){cout<<x <<"\n";}
};

class derivada:private base{


     int y;
public:
     void obten_xy(int a,int b){obten_x(a);y=b;}
     void muestra_xy(){muestra_x();cout<<y<<"\n";}
};

void main()
{
     clrscr();
     derivada ob;
     ob.obten_xy(10,20);
     ob.muestra_xy();
     // ob.obten_x(10); error,sin acceso.
     // ob.muestra_x(); error,sin acceso.
     getch();
}

HERENCIA MULTIPLE: Existen dos métodos en los que una clase derivada puede heredar más de una clase base.
El primero, en el que una clase derivada puede ser usada como la clase base de otra clase derivada, creándose una
jerarquía de clases.  El segundo, es que una clase derivada puede heredar directamente más de una clase base. En
esta situación se combinan dos o más clases base para facilitar la creación de la clase derivada.

SINTAXIS: Para construir la derivada mediante varias clases base.


class derivada:acceso nomb_base1,nomb_base2,nomb_baseN{
      cuerpo;
 };                  

SINTAXIS: Para crear herencia múltiple de modo jerárquico.


class derivada1:acceso base{
         cuerpo;
 };

     class derivada2:acceso derivada1{


         cuerpo;
     };

     class derivadaN:acceso derivada2{


         cuerpo;
     };
 EJEMPLO: Herencia de tipo jerárquica.
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class base_a{
     int a;
public:
     base_a(int x){a=x;}
     int ver_a(){return a;}
};

class deriva_b:public base_a{


     int b;
public:
     deriva_b(int x, int y):base_a(x){b=y;}
     int ver_b(){return b;}
};

class deriva_c:public deriva_b{


     int c;
public:
     deriva_c(int x,int y,int z):deriva_b(x,y){c=z;}
     void ver_todo()
     {
         cout<<ver_a()<<" "<<ver_b()<<" "<<c;
     }
};

void main()
{
     clrscr();
     deriva_c ob(1,2,3);
     ob.ver_todo();
     cout<<"\n";
     cout<<ob.ver_a()<<" "<<ob.ver_b();
     getch();
}

El caso de los constructores es un poco especial. Se ejecutan en orden descendente, es decir primero se realiza el
constructor de la clase base y luego el de las derivadas. En las destructoras ocurre en orden inverso, primero el de
las derivadas y luego el de la base.

 EJEMPLO: Múltiple heredando varias clases base.


#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class B1{
     int a;
public:
     B1(int x){a=x;}
     int obten_a(){return a;}
};

class B2{
     int b;
public:
     B2(int x){b=x;}
     int obten_b(){return b;}
};

class C1:public B1,public B2{


     int c;
public:
     C1(int x,int y,int z):B1(z),B2(y)
     {
         c=x;
     }
     void muestra()
     {
         cout<<obten_a()<<" "<<obten_b()<<" ";
         cout<<c<<"\n";
     }
};

void main()
{
     clrscr();
     C1 objeto(1,2,3);
     objeto.muestra();
     getch();
}

Funciones Virtuales

Una función virtual es miembro de una clase que se declara dentro de una clase base y se redefine en una clase
derivada. Para crear una función virutal hay que preceder a la declaración de la función la palabra clave virtual.
Debe tener el mismo tipo y numero de parametros y devolver el mismo tipo.

Cada redefinición de la función virtual en una clase derivada expresa el funcionamiento especifico de la misma con
respecto a esa clase derivada. Cuando se redefine una función virtual en una clase derivada NO es necesaria la
palabra virtual.

EJEMPLO: 
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
class base{
public:
     int i;
     base(int x){i=x;}
     virtual void func(){cout<<i<<"\n";}
};

class derivada1:public base{


public:
     derivada1(int x):base(x){};
     void func(){ cout <<i*i<<"\n";}
};

class derivada2:public base{


public:
     derivada2(int x):base(x){};
     void func(){cout<<i+i;}
};

void main()
{
     base obj1(10);
     derivada1 obj2(10);
     derivada2 obj3(10);
     obj1.func();
     obj2.func();
     obj3.func();
     getch();
}

Sobrecarga de Funciones y Operadores


En C++ dos o más funciones pueden compartir el mismo nombre en tanto en cuanto difiera el tipo de sus
argumentos o el número de sus argumentos o ambos. Cuando comparten el mismo nombre y realizan operaciones
distintas se dice que están sobrecargadas. Para conseguir la sobrecarga  simplemente hay que declarar y definir
todas las versiones requeridas.

También es posible y es muy común sobrecargar las funciones constructoras. Hay 3 razones por las que
sobrecargar las funciones constructoras. Primero ganar flexibilidad, permitir arrays y construir copias de
constructores.

EJEMPLO:
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
int abs(int numero);
long abs(long numero);
double abs(double numero);

void main()
{
     clrscr();
     cout <<"Valor absoluto de -10 "<< abs(-10) <<"\n";
     cout <<"Valor absoluto de -10L "<< abs(-10L) <<"\n";
     cout <<"Valor absoluto de -10.01 "<< abs(-10.01) <<"\n";
     getch();
}

int abs(int numero)


{
     return numero<0 ? -numero:numero;
}
long abs(long numero)
{
     return numero<0 ? -numero:numero;
}
double abs(double numero)
{
     return numero<0 ? -numero:numero;
}

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void fecha(char *fecha);
void fecha(int anno, int mes, int dia);
void main()
{
     clrscr();
     fecha("23/8/98");
     fecha(98,8,23);
     getch();
}
void fecha(char *fecha)
{
     cout<<"Fecha: "<<fecha<<"\n";
}
void fecha(int anno,int mes,int dia)
{
     cout<<"Fecha: "<<dia<<"/"<<mes<<"/"<<anno;
}

ARGUMENTOS IMPLICITOS: Otra característica relacionada con la sobrecarga es la utilización de argumentos


implícitos que permite dar un valor a un parámetro cuando no se especifica el argumento correspondiente en la
llamada a la función.
PROTOTIPO:
tipo_devuelto(var1=valor,var2=valor,varN=valor);

EJEMPLO:
#include<iostream.h>
#include<stdio.h>
#include<conio.h>
void funcion(int a=0, int b=0)
{
     cout<<"a: "<< a <<" b: "<< b <<"\n";
}

void main()
{
     clrscr();
     funcion();
     funcion(10);
     funcion(20,30);
     getch();
}

Es muy similar a la sobrecarga de funciones, un operador siempre se sobrecarga  con relación a una clase. Cuando
se sobrecarga un operador no pierde su contenido original, gana un contenido relacionado con la clase. Para
sobrecargar un operador se crea una función operadora que normalmente será una función amiga a la clase.

PROTOTIPO:
tipo_devuelto nombre_clase::operator operador(parametros)
     {
         cuerpo;
     }
Se pueden realizar cualquier actividad al sobrecargar los operadores pero es mejor que las acciones de un operador
sobrecargado se ajusten al uso normal de ese operador. La sobrecarga tiene dos restricciones, no puede cambiar la
precedencia del operador y que el numero de operadores no puede modificarse. También hay operadores que no
pueden sobrecargarse.

OPERADORES

Existen 3 tipos de sobrecarga de operadores. Operadores binarios, operadores lógicos-relacionales y operadores


unarios. Cada uno de ellos deben tratarse de una manera especifica para cada  uno de ellos.

BINARIOS: La función solo tendrá un parámetro. Este parámetro contendrá al objeto que este en el lado derecho
del operador. El objeto del lado izquierdo es el que genera la llamada a la función operadora y se pasa
implícitamente a través de this.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class opera{
     int x, y;
public:
     opera() {x=0;y=0;}
     opera(int i, int j) {x=i; y=j;}
     void obtenxy(int &i,int &j) {i=x; j=y;}
     opera operator+(opera obj);
};

opera opera::operator+(opera obj)


{
     opera temp;
     temp.x=x+obj.x;
     temp.y=y+obj.y;
     return temp;
}

void main()
{
     opera obj1(10,10), obj2(5,3),obj3;
     int x,y;
     obj3=obj1+obj2;
     obj3.obtenxy(x,y);
     cout << "Suma de obj1 mas obj2\n ";
     cout << "Valor de x: "<< x << "  Valor de y: " << y;
     getch();
}

LÓGICOS Y RELACIONALES: Cuando se sobrecargan dichos operadores no se deseará que las funciones
operadoras devuelvan un objeto, en lugar de ello, devolverán un entero que indique verdadero o falso. Esto permite
que los operadores se integren en expresiones lógicas y relacionales más extensas que admitan otros tipos de
datos.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class opera{
     int x,y;
public:
     opera() {x=0;y=0;}
     opera(int i,int j) {x=i; y=j;}
     void obtenerxy(int &i, int &j) {i=x; j=y;}
     int operator==(opera obj);
};
int opera::operator==(opera obj)
{
     if(x==obj.x && y==obj.y)
         return 1;
     else
         return 0;
}

void main()
{
     clrscr();
     opera obj1(10,10), obj2(5,3);
     if(obj1==obj2)
         cout << "Objeto 1 y Objeto 2 son iguales";
     else
         cout << " Objeto 1 y objeto 2 son diferentes";
     getch();
}

UNARIOS: El miembro no tiene parámetro. Es el operando el que genera la llamada a la función operadora. Los
operadores unarios pueden preceder o seguir a su operando, con lo que hay que tener en cuenta como se realiza la
llamada.

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
class opera{
     int x, y;
public:
     opera() {x=0;y=0;}
     opera(int i, int j) {x=i;y=j;}
     void obtenxy(int &i, int &j) {i=x; j=y;}
     opera operator++();
};

opera opera::operator++()
{
     x++;
     y++;
}

void main()
{
     clrscr();
     opera objeto(10,7);
     int x,y;
     objeto++;
     objeto.obtenxy(x,y);
     cout<< "Valor de x: " << x <<"  Valor de y: "<< y << "\n";
     getch();
}

Ficheros
Para realizar E/S en archivos debe incluirse en el programa el archivo cabecera fstream.h. Un archivo se abre
mediante el enlace a un flujo. Tenemos 3 tipos de flujo: de entrada, desalida o de entrada-salida. Antes de abrir un
fichero debe obtenerse el flujo. Los 3 flujos tienen funciones constructoras que abren el archivo
automáticamente. Una vez realizadas las operaciones con los ficheros debemos cerrar el fichero mediante la
función close( ).
FLUJO DESCRIPCIÓN
ofstream out De salida.
ofstream in De entrada.
fstream io De salida-entrada.
En C++ podemos trabajar con 3 tipos de ficheros: secuencial, binario sin formato y acceso aleatorio. Todos
comparten el método de apertura, pero cada uno de ellos tienen métodos propios para ir escribiendo y leyendo.

SINTAXIS:
flujo("nombre_fichero.extension");

EJEMPLO: Fichero secuencial.
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
     ofstream out("fichero.tex"); 
     if (!out)
     {
         cout << "El archivo no puede abrirse";
         exit(1);
     }

     char cad[80];


     cout << "Escritura de cadenas. Salir dejar en blanco\n";

     do
     {
         cout<<": ";
         gets(cad);
         out << cad << endl; 
     }while(*cad);

     out.close();
}
BINARIOS SIN FORMATO: Las funciones E/S son read()y write(). La función read() lee numbytes del flujo asociado
y los coloca en la variable. La función write() escribe num bytes de la variable en el flujo asociado. 

PROTOTIPOS:
in.read(variable,num_bytes);
out.write(variable,longitud_cadena);

EJEMPLO: Fichero binario. Escritura.
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
     ofstream out("texto.tex");
     if (!out)
     {
         cout << "El archivo no puede abrirse";
         exit(1);
     }

     char cad[80];


     cout << "Escritura de cadenas. Salir dejar en blanco\n";
     do
     {
         cout<<": ";
         gets(cad);
         out.write(cad,strlen(cad));
     }while(strlen(cad));
     out.close();
}
EJEMPLO: Fichero binario. Lectura.
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void main()
{
     clrscr();
     ifstream in("texto.tex"); 
     if (!in)
     {
         cout << "El archivo no puede abrirse";
         exit(1);
     }
     char cad[80];
     cout << "Lectura de cadenas\n";
     in.read(cad,80);
     cout << cad;

     in.close(); 
     getch();
}

ALEATORIOS: También podemos realizar el acceso aleatorio. Las funciones que se utilizan son seekg() y seekp()
para posicionarnos y las funciones get() y put() para leer y escribir en el fichero. Las funciones de posicionamiento y
leer-escribir van emparejadas.

PROTOTIPOS:
         out.seekp(posicion,lugar_de_comienzo);
         out.put('char');
         in.seekg(posicion,lugar_de_comienzo);
         in.get(var_char);

LUGAR DESCRIPCIÓN
ios::beg Desde el principio.
ios::end Desde el final.
ios::cur Posición actual.

EJEMPLO: Fichero aleatorio. Escritura.
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
void main()
{
     fstream out("texto1.txt",ios::in|ios::out);
     if (!out)
     {
         cout << "El archivo no se puede abrir";
         exit(1);
     }
     out.seekp(4,ios::beg);
     out.put('z');
     out.close();
}

Excepciones
Es un mecanismo de gestión de errores incorporado. Permite gestionar y responder a los errores en tiempo de
ejecución. Las excepciones están construidas a partir de tres palabras clave: try, catch y  throw. Cualquier 
sentencia que provoque una excepción debe haber sido ejecutada desde un bloque try o desde una función que
este dentro del bloque try.
Cualquier excepción debe ser capturada por una sentencia cath que sigue a la sentencia try, causante de la
excepción.

SINTAXIS:
try{
       cuerpo;
 }

catch(tipo1 arg){
       bloque catch;
 }

 catch(tipo2 arg){
       bloque catch;
 }

  catch(tipoN arg){
       bloque catch;
 }

EJEMPLO:
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
void main()
{
     try{
         cout<<"Dentro del bloque try\n";
         throw 10;
         cout<<"Esto se ejecuta si no hay problemas";
     }
     catch(int i){
         cout<<"Capturado el error "<< i;
         cout<<"\n";
     }

     cout << "fin";


     getch();
}

2.lenguaje de programación Java

Java es una tecnología que hace sencilla la construcción de aplicaciones distribuidas, programas que son
ejecutables por múltiples ordenadores a través de la red. En el estado del arte en la programación de red, Java
promete extender el papel de Internet desde el terreno de las comunicaciones hacia una red en la cual puedan
ejecutarse las aplicaciones completas. Su novedosa tecnología permitirá a los negocios proporcionar servicios de
transacción a gran escala y en tiempo real y contener informacion interactiva en Internet. Java simplifica también la
construcción de agentes software, programas que se mueven a través de la red y desempeñan funciones en
ordenadores remotos en nombre del usuario. En un futuro cercano, los usuarios podrán enviar agentes software
desde sus PCs hacia Internet para localizar información específica o para realizar transacciones en el menor tiempo
posible en cualquier lugar del mundo.

Java es un lenguaje originalmente desarrollado por un grupo de ingenieros de Sun, utilizado por Netscape
posteriormente como base para Javascript. Si bien su uso se destaca en el Web, sirve para crear todo tipo de
aplicaciones (locales, intranet o internet).

Java es un lenguaje:
 de objetos
 independiente de la plataforma

Algunas características notables:

 robusto
 gestiona la memoria automáticamente
 no permite el uso de técnicas de programación inadecuadas
 multithreading
 cliente-servidor
 mecanismos de seguridad incorporados
 herramientas de documentación incorporadas

Java llevará estos adelantos todavía más lejos haciendo posible suministrar aplicaciones completamente
interactivas vía Web. Las razones por las cuales se ha prestado tanta atención al lenguaje Java podrían resumirse
en la siguiente lista de posibilidades que Java ofrece a sus usuarios:

 Escribir programas fiables y robustos.


 Construir una aplicación para prácticamente cualquier plataforma, y ejecutar dicha aplicación en cualquier
otra plataforma soportada sin tener que repetir la compilación del código.
 Distribuir sus aplicaciones a lo largo de la red de una forma segura.

En particular, los programas Java se pueden incrustar en documentos Web, convirtiendo páginas estáticas en
aplicaciones que se ejecutan en el ordenador del usuario.

Historia sobre Java

En 1990, Sun Microsystems comenzó un proyecto llamado Green para desarrollar software destinado a electrónica
de consumo. James Gosling, un veterano en el diseño de software de red, fue asignado al nuevo proyecto. Gosling
comenzó a escribir software en C++ para utilizarlo en aparatos como tostadoras, videos, etc. Este software se utilizó
para crear electrodomésticos más inteligentes, añadiéndoles displays digitales o utilizando inteligencia artificial para
controlar mejor los mecanismos. Sin embargo, pronto se dio cuenta de que C++ era demasiado susceptible a
errores que pueden detener el sistema. Y aunque todo el mundo está acostumbrado a que el ordenador se cuelgue,
nadie espera que su tostadora deje de funcionar.

La solución de Gosling a este problema fue un nuevo lenguaje llamado Oak. Oak mantuvo una sintaxis similar a C++
pero omitiendo las características potencialmente peligrosas. Para conseguir que fuese un lenguaje de
programación de sistemas controladores eficiente, Oak necesitaba poder responder a eventos provenientes del
exterior en cuestión de microsegundos. Tambén era necesario que fuese portátil; esto es, que fuese capaz de
ejecutarse en un determinado número de chips y entornos diferentes. Esta independencia del hardware podría
proporcionar al fabricante de una tostadora cambiar el chip que utiliza para hacerla funcionar sin necesidad de
cambiar el software. El fabricante podría utilizar también partes del mismo código que utiliza la tostadora para hacer
funcionar un horno. Esto podría reducir costes, tanto de desarrollo como de hardware, aumentando también su
fiabilidad.

Al mismo tiempo que Oak maduraba, la WWW se encontraba en su periodo de crecimiento y el equipo de desarrollo
de Sun se dio cuenta de que Oak era prefectamente adecuado para la programación en Internet. En 1994
completaron su trabajo en un producto conocido como WebRunner, un primitivo visor Web escrito en Oak.
WebRunner se renombró posteriomente como HotJava y demostró el poder de Oak como herramienta de desarrollo
en Internet.

Finalmente, en 1995, Oak se renombró como Java por razones de marketing y fue presentado en Sun World 1995.
Incluso antes de la primera distribución del compilador de Java en Junio de 1996, Java ya era considerado como el
estándar en la industria para la programación en Internet.

La Arquitectura Java

La fortaleza de Java reside precisamente en su arquitectura única. Los diseñadores de Java necesitaban un
lenguaje que fuera, sobre todo, sencillo de utilizar para el programador. A pesar de todo, y con el propósito de crear
aplicaciones de red eficientes, Java necesitaba también la posibilidad de ejecutarse de forma segura en la red y
trabajar en una amplísima gama de plataformas. Java cumple todos estos puntos y muchos más.
Cómo trabaja Java

Como muchos otros lenguajes de programación, Java utiliza un compilador para convertir el código fuente, legible
para el ser humano, en programas ejecutables. Los compiladores tradicionales genera código que puede ejecutarse
únicamente por un hardware específico. Los compiladores Java generan código binario o bytecode independiente
de la arquitectura. Estos bytecodes se ejecutarán exclusivamente en una Máquina Virtual Java, Virtual Machine, VM,
un procesador Java idealizado que normalmente se implementa por software, aunque la VM se ha implementado
también como un chip hardware por Sun y otros.

Los archivos binarios Java se denominan archivos de clases debido a que contienen clases simples Java. Para
ejecutar bytecodes, la máquina virtual utiliza cargadores de clases para obtener los bytecodes del disco o de la red.
Cada archivo de clases se lleva entonces a un verificador de bytecodes que se asegura de que la clase tienen un
formato correcto y que no llegará a corromper la memoria cuando se ejecute. Una vez verificados los bytecodes se
interpretan por un interprete.

Lenguaje de Objetos
Por qué puse "de" objetos y no "orientado a" objetos? Para destacar que, al contrario de otros lenguajes como C++,
no es un lenguaje modificado para poder trabajar con objetos sino que es un lenguaje creado para trabajar con
objetos desde cero. De hecho, TODO lo que hay en Java son objetos.

Qué es un objeto?

Bueno, se puede decir que todo puede verse como un objeto. Pero seamos más claros. Un objeto, desde nuestro
punto de vista, puede verse como una pieza de software que cumple con ciertas características:

 encapsulamiento
 herencia

Encapsulamiento significa que el objeto es auto-contenido, o sea que la misma definición del objeto incluye tanto los
datos que éste usa (atributos) como los procedimientos (métodos) que actúan sobre los mismos.
Cuando se utiliza programación orientada a objetos, se definen clases (que definen objetos genéricos) y la forma en
que los objetos interactúan entre ellos, a través demensajes. Al crear un objeto de una clase dada, se dice que se
crea una instancia de la clase, o un objeto propiamente dicho. Por ejemplo, una clase podría ser "autos", y un auto
dado es una instancia de la clase.

La ventaja de esto es que como no hay programas que actúen modificando al objeto, éste se mantiene en cierto
modo independiente del resto de la aplicación. Si es necesario modificar el objeto (por ejemplo, para darle más
capacidades), esto se puede hacer sin tocar el resto de la aplicación… lo que ahorra mucho tiempo de desarrollo y
debugging! En Java, inclusive, ni siquiera existen las variables globales! (Aunque parezca difícil de aceptar, esto es
una gran ventaja desde el punto de vista del desarrollo).

En cuanto a la herencia, simplemente significa que se pueden crear nuevas clases que hereden de otras
preexistentes; esto simplifica la programación, porque las clases hijas incorporan automáticamente los métodos de
las madres. Por ejemplo, nuestra clase "auto" podría heredar de otra más general, "vehículo", y simplemente
redefinir los métodos para el caso particular de los automóviles… lo que significa que, con una buena biblioteca de
clases, se puede reutilizar mucho código inclusive sin saber lo que tiene adentro.

Un ejemplo simple

Para ir teniendo una idea, vamos a poner un ejemplo de una clase Java: 
public class Muestra extends Frame {
// atributos de la clase
Button si;
Button no;
// métodos de la clase:
public Muestra () {
Label comentario = new Label("Presione un botón", Label.CENTER);
si = new Button("Sí");
no = new Button("No");
add("North", comentario);
add("East", si);
add("West", no);
}
}

Esta clase no está muy completa así, pero da una idea… Es una clase heredera de la clase  Frame (un tipo de
ventana) que tiene un par de botones y un texto. Contiene dos atributos ("si" y "no"), que son dos objetos del
tipo Button, y un único método llamado Muestra (igual que la clase, por lo que es lo que se llama unconstructor).

Independiente de la plataforma

Esto es casi del todo cierto…

En realidad, Java podría hacerse correr hasta sobre una Commodore 64! La realidad es que para utilizarlo en todo
su potencial, requiere un sistema operativo multithreading (como Unix, Windows95, OS/2…).

Cómo es esto? Porque en realidad Java es un lenguaje interpretado… al menos en principio.

Al compilar un programa Java, lo que se genera es un seudocódigo definido por Sun, para una máquina genérica.
Luego, al correr sobre una máquina dada, el software de ejecución Java simplemente interpreta las instrucciones,
emulando a dicha máquina genérica. Por supuesto esto no es muy eficiente, por lo que tanto Netscape como
Hotjava o Explorer, al ejecutar el código por primera vez, lo van compilando (mediante un JIT: Just In Time
compiler), de modo que al crear por ejemplo la segunda instancia de un objeto el código ya esté compilado
específicamente para la máquina huésped.

Además, Sun e Intel se han puesto de acuerdo para desarrollar procesadores que trabajen directamente en Java,
con lo que planean hacer máquinas muy baratas que puedan conectarse a la red y ejecutar aplicaciones Java
cliente-servidor a muy bajo costo.

El lenguaje de dicha máquina genérica es público, y si uno quisiera hacer un intérprete Java para una Commodore
sólo tendría que implementarlo y pedirle a Sun la aprobación (para que verifique que cumple con los requisitos de
Java en cuanto a cómo interpreta cada instrucción, la seguridad, etc.)
Generación de números aleatorios
 
La clase Random proporciona un generador de números aleatorios. Es más flexible que la función random de la
clase Math, que vimos en funciones matemáticas...
 
 

 
La generación de números aleatorios adquiere gran relevancia para un programador, pudiendo tener distintas
aplicaciones como:
 
·Construcción preliminar de programas, en los que a falta de datos definitivos, introducimos datos aleatorios.
 
·Simulación de procesos aleatorios (número resultante de tirar un dado, elección de un color por parte de una
persona, número premiado en un sorteo de lotería, cantidad de personas que entran a un supermercado en una
hora...)
 
. Verificación de programas, y en particular lo que en verificación de algoritmos se conoce como verificación
aleatoria (probar el programa con distintos supuestos aleatorios).
 
·Otras aplicaciones.
 
Conviene recordar que "aleatorio" no puede confundirse con "cualquier cosa", "descontrol", "incierto", "impredecible",
etc. Usaremos el vocablo “aleatorio”, más en el sentido de “no predeterminado” que  el de “no predecible”, ya que en
general, vamos a definir qué tipo de resultado queremos obtener y en qué rango de valores debe estar. Vamos a
imaginar que Java genera números aleatorios, como si fuera un robot lanzador de dardos muy preciso ( robot rnd).
De este modo, cuando se le dice que comience a tirar dardos en distintas posiciones, repite siempre los lugares. Por
ejemplo, si la diana está marcada con números, cada vez que le decimos que tire, genera la misma secuencia: 7, 5,
6, 3, etc. ¿Cómo conseguir convertir este proceso predefinido en aleatorio? Simplemente, poniendo a girar la diana
(mayordomo randomize), en este caso, a una velocidad que depende del segundo del día en que nos encontremos.
Así pues, el proceso lo dividimos al decirle al mayordomo que ponga a girar la diana y al indicarle al robot que
dispare. Bueno, un poco simple, pero ¿para qué complicarnos? Veamos los pasos sintácticos a emplear para crear
una secuencia de números aleatorios:
 
1. Proporcionar a nuestro programa información acerca de la clase Random. Al principio del programa 
escribiremos la siguiente sentencia:
 
Import java.util.Random;
 
2. Crear un objeto de la clase Random:
 
La clase Random dispone de dos constructores, para crear un objeto. El primer constructor es:
 
Random  rnd = new Random();
 
crea un generador de números aleatorios cuya semilla es inicializada automáticamente, en base al tiempo actual.
Esto conlleva que en cada ejecución la semilla cambie, es decir, que la secuencia de números aleatorios que se
genera en cada ejecución siempre será diferente.
 
El segundo constructor es:
 
Random rnd = new Random(inicializar_semilla);
 
nos permite inicializar la semilla manualmente con un número entero cualquiera. Si este número es el mismo en
cada ejecución, la secuencia de números aleatorios que se genera en cada ejecución será igual.
 
 
Hay cuatro funciones miembro diferentes que generan números aleatorios:
 
Función
Descripción Rango
miembro

rnd.nextInt() Número aleatorio entero de tipo int 2-32 y 232

rnd.nextLong() Número aleatorio entero de tipo long 2-64 y 264

rnd.nextFloat() Número aleatorio real de tipo float [0,1[

rnd.nextDouble() Número aleatorio real de tipo double [0,1[


 
Casi siempre, para generar un número aleatorio, se usa la función miembro rnd.nextDouble().El valor devuelto es
de tipo double. Un aspecto importante a tener en cuenta, es que el valor devuelto se encuentra en el rango mayor o
igual a cero y menor a 1. Es decir, el número devuelto puede ser cero pero no puede ser uno.
 
En el siguiente ejemplo mostraremos todo lo expresado hasta este momento:
 
importjava.util.Random;
 
public class Programa {
 
      public static void main(String arg[ ]) {
 
             Random rnd = new Random();
             System.out.println("Número aleatorio real entre [0,1[ :
"+rnd.nextDouble());
 
      }
 
}
 

En el caso de necesitar números aleatorios enteros en un rango determinado, podemos trasladarnos a un intervalo
distinto, simplemente multiplicando, aplicando la siguiente fórmula general:
 
(int) (rnd.nextDouble() * cantidad_números_rango + término_inicial_rango)
 
donde (int) al inicio, transforma un número decimal double en entero int, eliminando la parte decimal.
 
 
Por ejemplo, si deseamos números enteros comprendidos entre el rango [0,99], incluidos los extremos, la fórmula
quedaría de la siguiente manera:
 
(int)(rnd.nextDouble() * 100 + 0);       -->        (int)(rnd.nextDouble() * 100);
 
 100 es la cantidad de números enteros en el rango [0,99] y 0 es el término inicial del rango.
 
En el caso de querer números aleatorios enteros comprendidos entre [1,6], que son los lados de un dado, la formula
quedaría así.
 
(int)(rnd.nextDouble() * 6 + 1);
 
 6 es la cantidad de números enteros en el rango [1,6] y 1 es el término inicial del rango.
 
A continuación, daremos dos programas completos , como ejemplo para explicar el cambio de semilla en la
generación de números aleatorios:
 
importjava.util.Random;
 
public class Programa {
 
      public static void main(String arg[ ]) {
               Random rnd = new Random();
 
              System.out.println("Primera
secuencia."+"\n");
              System.out.println(rnd.nextDouble());
              System.out.println(rnd.nextDouble());
              System.out.println(rnd.nextDouble());
 
              System.out.println("");
 
              System.out.println("Segunda
secuencia."+"\n");
              System.out.println(+rnd.nextDouble());
              System.out.println(rnd.nextDouble());
              System.out.println(rnd.nextDouble());
      }
}
 
 
Salida
 
Primera secuencia.
0.477306442553755
0.6150676961227264
0.8217343290939352
 
Segunda secuencia.
0.6607147048099735
0.10104896936581531
0.2628223838639594
 
En este primer ejemplo, mostramos dos secuencias de tres números aleatorios, los cuales  están en el rango [0,1[,
incluido el cero pero excluido el uno. Vemos que los números aleatorios en las dos secuencias, son distintos, ya que
en realidad, es una sola secuencia, que tiene como punto de partida la misma semilla. A continuación, lo
compararemos con el siguiente ejemplo, donde utilizaremos la función“setSeed(semilla_nueva)”, para el cambio
de semilla, función resaltada con un comentario flecha:
 
importjava.util.Random;
 
public class Programa {
 
       public static void main(String arg[ ]) {
               Random rnd = new Random();
 
               rnd.setSeed(3816);  //<---
              System.out.println("Primera
secuencia."+"\n");
              System.out.println(rnd.nextDouble());
              System.out.println(rnd.nextDouble());
              System.out.println(rnd.nextDouble());
 
              System.out.println("");
 
              rnd.setSeed(3816);  //<---
             
System.out.println("Segundasecuencia."+"\n");
              System.out.println(rnd.nextDouble());
              System.out.println(rnd.nextDouble());
              System.out.println(rnd.nextDouble());
        }
}
 
 
Salida
 
Primera secuencia.
0.778983378859943
0.36474001734926775
0.9579995205698871
 
Segunda secuencia.
0.778983378859943
0.36474001734926775
0.9579995205698871
 
Observamos que las dos secuencias están formadas por los mismos números aleatorios, ya que a ambas
secuencias, les precede la función de cambio de semilla “rnd.setSeed(3816)”. En dicha instrucción, las dos
funciones  aparecen inicializadas a propósito con la misma semilla “3816”, pudiendo haberse elegido cualquier otro
número, pero con la peculiaridad de que la semilla tiene que ser igual en ambas funciones para producir dos
secuencias con los mismos números aleatorios.
 

Algunas características…
Entre las características que nombramos nos referimos a la robustez. Justamente por la forma en que está diseñado,
Java no permite el manejo directo del hardware ni de la memoria (inclusive no permite modificar valores de
punteros, por ejemplo); de modo que se puede decir que es virtualmente imposible colgar un programa Java. El
intérprete siempre tiene el control.

Inclusive el compilador es suficientemente inteligente como para no permitir un montón de cosas que podrían traer
problemas, como usar variables sin inicializarlas, modificar valores de punteros directamente, acceder a métodos o
variables en forma incorrecta, utilizar herencia múltiple, etc.

Además, Java implementa mecanismos de seguridad que limitan el acceso a recursos de las máquinas donde se
ejecuta, especialmente en el caso de los Applets (que son aplicaciones que se cargan desde un servidor y se
ejecutan en el cliente).

También está diseñado específicamente para trabajar sobre una red, de modo que incorpora objetos que permiten
acceder a archivos en forma remota (via URL por ejemplo).

Además, con el JDK (Java Development Kit) vienen incorporadas muchas herramientas, entre ellas un generador
automático de documentación que, con un poco de atención al poner los comentarios en las clases, crea inclusive
toda la documentación de las mismas en formato HTML!
El Java Development Kit
Todo lo que puedan pedir para desarrollar aplicaciones en Java está en:

 http://java.sun.com/aboutJava/index.html

En particular, deberían bajarse el JDK y el API Documentation de:

 http://java.sun.com/java.sun.com/products/JDK/1.0.2/index.html

(También les puede interesar en particular el Tool Documentation y alguno de los otros paquetes de la página)

Nota: en este site también hay un tutorial de Java, aunque es un poco difícil de seguir para el principiante.

El JDK (versión 1.0.2) está disponible para SPARC/Solaris, x86/Solaris, MS-Windows 95/NT, y MacOS.
También está disponible el fuente para el que quiera adaptarlo para otro sistema operativo, y he leído por ahí que
hay una versión dando vueltas para Linux y HP-UX.

Básicamente, el JDK consiste de:

 el compilador Java, javac


 el intérprete Java, java
 un visualizador de applets, appletviewer
 el debugger Java, jdb (que para trabajar necesita conectarse al server de Sun)
 el generador de documentación, javadoc

También se puede bajar del mismo site un browser que soporta Java (y de hecho está escrito totalmente en Java),
el Hotjava.
Para instalarlo simplemente hay que descompactar el archivo (sugiero que creen un directorio java para eso), pero
tengan en cuenta NO DESCOMPRIMIR el archivo classes.zip!

Importante para los usuarios de Windows95: todas estas aplicaciones deben ejecutarse desde una ventana DOS. En
particular, utilizan nombres largos y distinguen mayúsculas de minúsculas, así que tengan en cuenta esto que es
fuente de muchos errores.

Una cosa muy importante: para que todo ande bien aceitado, agreguen:

 el directorio de los programas en el path (ej: c:\java\bin)


 las variables de entorno:
o CLASSPATH=.;C:\java\lib\classes.zip
o HOMEDRIVE=C:
o HOMEPATH=\
o HOME=C:\

con los valores adecuados a su entorno.

Noten que en CLASSPATH agregué el directorio actual (.), para poder compilar y ejecutar desde cualquier
directorio.

Bueno, suponiendo que hayan instalado todo, y antes de comenzar a programar en Java, una pequeña
aclaración :

En realidad se puede decir que hay tres Javas por ahí:

 Javascript: es una versión de Java directamente interpretada, que se incluye como


parte de una página HTML, lo que lo hace muy fácil y cómodo para aplicaciones muy
pequeñas, pero que en realidad tiene muchas limitaciones:
o no soporta clases ni herencia
o no se precompila
o no es obligatorio declarar las variables
o verifica las referencias en tiempo de ejecución
o no tiene protección del código, ya que se baja en ascii
o no todos los browsers lo soportan completamente; Explorer, por ejemplo, no
soporta las últimas adiciones de Netscape, como las imágenes animadas.
 Java standalone: programas Java que se ejecutan directamente mediante el
intérprete java.
 Applets: programas Java que corren bajo el entorno de un browser (o del
appletviewer)

En sí los dos últimos son el mismo lenguaje, pero cambia un poco la forma en que se implementa el objeto
principal (la aplicación). Vamos a ver cómo crear las aplicaciones para que, sin cambios, se puedan ejecutar casi
igual en forma standalone o como applet (en realidad hay cosas que los applets no pueden hacer, como acceder a
archivos sin autorización). 

Javascript
No vamos a detenernos mucho en Javascript, por las limitaciones antedichas; si les interesa podemos dedicarnos
un poco a este lenguaje en el futuro. Por ahora, sólo un ejemplo sencillo: 

Calculadora en Javascript:
<HTML>
<HEAD>
<SCRIPT LANGUAJE="Javascript">
function calcula(form) {
if (confirm("¿Está seguro?"))
form.resultado.value = eval(form.expr.value)
else
alert("Vuelva a intentarlo...")
}
</SCRIPT>
</HEAD>
<BODY>
<FORM>
Introduzca una expresión:
<INPUT TYPE="text" NAME="expr" SIZE=15>
<INPUT TYPE="button" NAME="Boton" VALUE="Calcular" ONCLICK="calcula(this.form)">
<BR>
Resultado:
<INPUT TYPE="text" NAME="resultado" SIZE=15>
<BR>
</FORM>
</BODY>
</HTML>

Básicamente, el código se encuadra entre los tags <SCRIPT>…</SCRIPT>, y los parámetros se pasan al mismo
mediante un form (<FORM>…</FORM>). El lenguaje utilizado es muy parecido al C++, y básicamente el código
se ejecuta mediante una acción de un botón (…ONCLICK="calcula(this.form)").

Al presionar el botón, se llama a la función calcula con el parámetro this.form, que se refiere al form al que


pertenece el botón.

La función asigna al valor del campo resultado del form que se le pasa como parámetro (form.resultado.value) el


resultado de evaluar el valor de la expresión del campo expr de dicho form (eval(form.expr.value)).

Hay MUCHOS ejemploes de Javascript en:

 http://www.c2.net/~andreww/javascript/
incluyendo decenas de calculadoras, juegos.

Las clases en Java


Bueno, antes que nada conviene saber que en Java hay un montón de clases ya definidas y utilizables.

Éstas vienen en las bibliotecas estándar:

 java.lang - clases esenciales, números, strings, objetos, compilador, runtime,


seguridad y threads (es el único paquete que se incluye automáticamente en todo
programa Java)
 java.io - clases que manejan entradas y salidas
 java.util - clases útiles, como estructuras genéricas, manejo de fecha, hora y strings,
número aleatorios, etc.
 java.net - clases para soportar redes: URL, TCP, UDP, IP, etc.
 java.awt - clases para manejo de interface gráfica, ventanas, etc.
 java.awt.image - clases para manejo de imágenes
 java.awt.peer - clases que conectan la interface gráfica a implementaciones
dependientes de la plataforma (motif, windows)
 java.applet - clases para la creación de applets y recursos para reproducción de
audio.
Para que se den una idea, los números enteros, por ejemplo, son "instancias" de una clase no redefinible, Integer,
que desciende de la clase Number e implementa los siguientes atributos y métodos:
public final class java.lang.Integer extends java.lang.Number {
// Atributos
public final static int MAX_VALUE;
public final static int MIN_VALUE;
// Métodos Constructores
public Integer(int value);
public Integer(String s);
// Más Métodos
public double doubleValue();
public boolean equals(Object obj);
public float floatValue();
public static Integer getInteger(String nm);
public static Integer getInteger(String nm, int val);
public static Integer getInteger(String nm, Integer val);
public int hashCode();
public int intValue();
public long longValue();
public static int parseInt(String s);
public static int parseInt(String s, int radix);
public static String toBinaryString(int i);
public static String toHexString(int i);
public static String toOctalString(int i);
public String toString();
public static String toString(int i);
public static String toString(int i, int radix);
public static Integer valueOf(String s);
public static Integer valueOf(String s, int radix);
}

Mucho, no?

Esto también nos da algunas ideas:


 la estructura de una clase
 caramba, hay métodos repetidos!

De la estructura enseguida hablaremos; en cuanto a los métodos repetidos (como parseInt por ejemplo), al


llamarse al método el compilador decide cuál de las implementaciones del mismo usar basándose en la cantidad y
tipo de parámetros que le pasamos. Por ejemplo, parseInt("134") y parseInt("134",16), al compilarse, generarán
llamados a dos métodos distintos.

Estructura de una clase


Una clase consiste en:
algunas_palabras class nombre_de_la_clase [algo_más] {
[lista_de_atributos]
[lista_de_métodos]
}

Lo que está entre [ y ] es opcional…

Ya veremos qué poner en "algunas_palabras" y "algo_más", por ahora sigamos un poco más.

La lista de atributos (nuestras viejas variables locales) sigue el mismo formato de C: se define primero el tipo y
luego el nombre del atributo, y finalmente el ";".

public final static int MAX_VALUE

También tenemos "algunas_palabras" adelante, pero en seguida las analizaremos.


En cuanto a los métodos, también siguen la sintaxis del C; un ejemplo:
public int incContador() { // declaración y apertura de {
cnt++; // instrucciones, separadas por ";"
return(cnt);
} // cierre de }

Finalmente, se aceptan comentarios entre /* y */, como en C, o bien usando // al principio del comentario (el
comentario termina al final de la línea).

Veamos un ejemplo:
// Implementación de un contador sencillo
// GRABAR EN UN ARCHIVO "Contador.java" (OJO CON LAS MAYUSCULAS!)
// COMPILAR CON: "javac Contador.java" (NO OLVIDAR EL .java!)
// ESTA CLASE NO ES UNA APLICACION, pero nos va a servir enseguida

public class Contador { // Se define la clase Contador

// Atributos
int cnt; // Un entero para guardar el valor actual

// Constructor // Un método constructor…


public Contador() { // …lleva el mismo nombre que la clase
cnt = 0; // Simplemente, inicializa (1)
}

// Métodos
public int incCuenta() { // Un método para incrementar el contador
cnt++; // incrementa cnt
return cnt; // y de paso devuelve el nuevo valor
}
public int getCuenta() { // Este sólo devuelve el valor actual
return cnt; // del contador
}
}
Cuando, desde una aplicación u otro objeto, se crea una instancia de la clase Contador, mediante la instrucción:

new Contador()

el compilador busca un método con el mismo nombre de la clase y que se corresponda con la llamada en cuanto al
tipo y número de parámetros. Dicho método se llama Constructor, y una clase puede tener más de un constructor
(no así un objeto o instancia, ya que una vez que fue creado no puede recrearse sobre sí mismo).

En tiempo de ejecución, al encontrar dicha instrucción, el intérprete reserva espacio para el objeto/instancia, crea
su estructura y llama al constructor.

O sea que el efecto de new Contador() es, precisamente, reservar espacio para el contador e inicializarlo en cero.

En cuanto a los otros métodos, se pueden llamar desde otros objetos (lo que incluye a las aplicaciones) del mismo
modo que se llama una función desde C.

Por ejemplo, usemos nuestro contador en un programa bien sencillo que nos muestre cómo evoluciona:
// Usemos nuestro contador en una mini-aplicación
// GRABAR EN UN ARCHIVO "Ejemplo1.java" (OJO CON LAS MAYUSCULAS!)
// COMPILAR CON: "javac Ejemplo.java" (NO OLVIDAR EL .java!)
// EJECUTAR CON: "java Ejemplo1" (SIN el .java)

import java.io.*; // Uso la biblioteca de entradas/salidas

public class Ejemplo1 { // IMPORTANTE: Nombre de la clase


// igual al nombre del archivo!
// entero para asignarle el valor del contador e imprimirlo
// aunque en realidad no me hace falta.
static int n;
// y una variable tipo Contador para instanciar el objeto…
static Contador laCuenta;

// ESTE METODO, MAIN, ES EL QUE HACE QUE ESTO SE COMPORTE


// COMO APLICACION. Es donde arranca el programa cuando ejecuto "java Ejemplo1"
// NOTA: main debe ser public & static.
public static void main ( String args[] ) {
System.out.println ("Cuenta… "); // Imprimo el título
laCuenta = new Contador(); // Creo una instancia del Contador
System.out.println (laCuenta.getCuenta()); // 0 - Imprimo el valor actual (cero!)
n = laCuenta.incCuenta(); // 1 - Asignación e incremento
System.out.println (n); // Ahora imprimo n
laCuenta.incCuenta(); // 2 - Lo incremento (no uso el valor…
System.out.println (laCuenta.getCuenta()); // …de retorno) y lo imprimo
System.out.println (laCuenta.incCuenta()); // 3 - Ahora todo en un paso!
}
}

En el capítulo III vamos a analizar este programa en detalle. Por ahora veamos la diferencia con un applet que
haga lo mismo: 
// Applet de acción similar a la aplicación Ejemplo1
// GRABAR EN ARCHIVO: "Ejemplo2.java"
// COMPILAR CON: "javac Ejemplo2.java"
// PARA EJECUTAR: Crear una página HTML como se indica luego
import java.applet.*;
import java.awt.*;

public class Ejemplo2 extends Applet {


static int n;
static Contador laCuenta;

// Constructor…
public Ejemplo2 () {
laCuenta = new Contador();
}

// El método paint se ejecuta cada vez que hay que redibujar


// NOTAR EL EFECTO DE ESTO CUANDO SE CAMBIA DE TAMAÑO LA
// VENTANA DEL NAVEGADOR!
public void paint (Graphics g) {
g.drawString ("Cuenta...", 20, 20);
g.drawString (String.valueOf(laCuenta.getCuenta()), 20, 35 );
n = laCuenta.incCuenta();
g.drawString (String.valueOf(n), 20, 50 );
laCuenta.incCuenta();
g.drawString (String.valueOf(laCuenta.getCuenta()), 20, 65 );
g.drawString (String.valueOf(laCuenta.incCuenta()), 20, 80 );
}
}

Ahora es necesario crear una página HTML para poder visualizarlo. Para esto, crear y luego cargar el archivo
ejemplo2.htm con un browser que soporte Java (o bien ejecutar en la ventana DOS: "appletviewer ejemplo2.htm"):
<HTML>
<HEAD>
<TITLE>Ejemplo 2 - Applet Contador</TITLE>
</HEAD>
<BODY>
<applet code="Ejemplo2.class" width=170 height=150>
</applet>
</BODY>
</HTML>

observemos las diferencias entre la aplicación standalone y el applet:

 La aplicación usa un método main, desde donde arranca


 El applet, en cambio, se arranca desde un constructor (método con el mismo nombre
que la clase)

Además:

 En la aplicación utilizamos System.out.println para imprimir en la salida estándar


 En el applet necesitamos "dibujar" el texto sobre un fondo gráfico, por lo que usamos
el método g.drawString dentro del método paint (que es llamado cada vez que es
necesario redibujar el applet)

Con poco trabajo se pueden combinar ambos casos en un solo objeto, de modo que la misma clase sirva para
utilizarla de las dos maneras:
// Archivo: Ejemplo3.java
// Compilar con: javac Ejemplo3.java
import java.applet.*;
import java.awt.*;
import java.io.*;

public class Ejemplo3 extends Applet {


static int n;
static Contador laCuenta;

public Ejemplo3 () {
laCuenta = new Contador();
}

public static void main(String args[]) {


laCuenta = new Contador();
paint();
}

public static void paint () {


System.out.println ("Cuenta...");
System.out.println (laCuenta.getCuenta());
n = laCuenta.incCuenta();
System.out.println (n);
laCuenta.incCuenta();
System.out.println (laCuenta.getCuenta());
System.out.println (laCuenta.incCuenta());
}
public void paint (Graphics g) {
g.drawString ("Cuenta...", 20, 20);
g.drawString (String.valueOf(laCuenta.getCuenta()), 20, 35 );
n = laCuenta.incCuenta();
g.drawString (String.valueOf(n), 20, 50 );
laCuenta.incCuenta();
g.drawString (String.valueOf(laCuenta.getCuenta()), 20, 65 );
g.drawString (String.valueOf(laCuenta.incCuenta()), 20, 80 );
}
}

Esta clase puede ejecutarse tanto con "java Ejemplo3" en una ventana DOS, como cargarse desde una página
HTML con:
<applet code="Ejemplo3.class" width=170 height=150>
</applet>

Notar que conviene probar el applet con el appletviewer ("appletviewer ejemplo3.htm"), ya que éste indica en la
ventana DOS si hay algún error durante la ejecución. Los browsers dejan pasar muchos errores, simplemente
suprimiendo la salida a pantalla del código erróneo.

Notar que en todo este desarrollo de las clases Ejemplo1, Ejemplo2 y Ejemplo3, en ningún momento volvimos a
tocar la clase Contador!

Estructura de clases
Vamos a comenzar analizando la clase Contador, para ir viendo las partes que forman una clase una por una y en
detalle. Este capítulo va a ser un poco aburrido por lo exhaustivo (aunque algunos puntos más complicados como
las excepciones y los threads los dejaremos para después), pero me parece bueno tener un resumen completo de la
sintaxis desde ahora.

Luego iremos armando pequeñas aplicaciones para probar cada cosa.


Recordemos la definición de la clase Contador:
// Implementación de un contador sencillo
public class Contador {
// Atributos
int cnt;
// Constructor
public Contador() {
cnt = 0;
}
// Métodos
public int incCuenta() {
cnt++;
return cnt;
}
public int getCuenta() {
return cnt;
}
}

Declaración de la clase
La clase se declara mediante la línea public class Contador. En el caso más general, la declaración de una clase
puede contener los siguientes elementos:

[public] [final | abstract] class Clase [extends ClaseMadre] [implements Interfase1 [, Interfase2 ]…]

o bien, para interfaces:

[public] interface Interfase [extends InterfaseMadre1 [, InterfaseMadre2 ]…]


Como se ve, lo único obligatorio es class y el nombre de la clase. Las interfases son un caso de clase particular que
veremos más adelante.

Public, final o abstract

Definir una clase como pública (public) significa que puede ser usada por cualquier clase en cualquier paquete. Si
no lo es, solamente puede ser utilizada por clases del mismo paquete (más sobre paquetes luego; básicamente, se
trata de un grupo de clases e interfaces relacionadas, como los paquetes de biblioteca incluídos con Java).

Una clase final (final) es aquella que no puede tener clases que la hereden. Esto se utiliza básicamente por razones
de seguridad (para que una clase no pueda ser reemplazada por otra que la herede), o por diseño de la aplicación.

Una clase abstracta (abstract) es una clase que puede tener herederas, pero no puede ser instanciada. Es,
literalmente, abstracta (como la clase Number definida en java.lang). ¿Para qué sirve? Para modelar conceptos. Por
ejemplo, la clase Number es una clase abstracta que representa cualquier tipo de números (y sus métodos no están
implementados: son abstractos); las clases descendientes de ésta, como Integer o Float, sí implementan los
métodos de la madre Number, y se pueden instanciar.

Por lo dicho, una clase no puede ser final y abstract a la vez (ya que la clase abstract requiere descendientes…)

¿Un poco complejo? Se va a entender mejor cuando veamos casos particulares, como las interfases (que por
definición son abstractas ya que no implementan sus métodos).

Extends

La instrucción extends indica de qué clase desciende la nuestra. Si se omite, Java asume que desciende de la
superclase Object.
Cuando una clase desciende de otra, esto significa que hereda sus atributos y sus métodos (es decir que, a menos
que los redefinamos, sus métodos son los mismos que los de la clase madre y pueden utilizarse en forma
transparente, a menos que sean privados en la clase madre o, para subclases de otros paquetes, protegidos o
propios del paquete). Veremos la calificación de métodos muy pronto, a no desesperar!

Implements

Una interfase (interface) es una clase que declara sus métodos pero no los implementa; cuando una clase
implementa (implements) una o más interfases, debe contener la implementación de todos los métodos (con las
mismas listas de parámetros) de dichas interfases.

Esto sirve para dar un ascendiente común a varias clases, obligándolas a implementar los mismos métodos y, por
lo tanto, a comportarse de forma similar en cuanto a su interfase con otras clases y subclases.

Interface

Una interfase (interface), como se dijo, es una clase que no implementa sus métodos sino que deja a cargo la
implementación a otras clases. Las interfases pueden, asimismo, descender de otras interfases pero no de otras
clases.

Todos sus métodos son por definición abstractos y sus atributos son finales (aunque esto no se indica en el cuerpo
de la interfase).

Son útiles para generar relaciones entre clases que de otro modo no están relacionadas (haciendo que implementen
los mismos métodos), o para distribuir paquetes de clases indicando la estructura de la interfase pero no las clases
individuales (objetos anónimos).
Si bien diferentes clases pueden implementar las mismas interfases, y a la vez descender de otras clases, esto no es
en realidad herencia múltiple ya que una clase no puede heredar atributos ni métodos de una interface; y las clases
que implementan una interfase pueden no estar ni siquiera relacionadas entre sí. 

El cuerpo de la clase
El cuerpo de la clase, encerrado entre { y }, es la lista de atributos (variables) y métodos (funciones) que
constituyen la clase.

No es obligatorio, pero en general se listan primero los atributos y luego los métodos.

Declaración de atributos

En Java no hay variables globales; todas las variables se declaran dentro del cuerpo de la clase o dentro de un
método. Las variables declaradas dentro de un método son locales al método; las variables declaradas en el cuerpo
de la clase se dice que son miembros de la clase y son accesibles por todos los métodos de la clase.

Por otra parte, además de los atributos de la propia clase se puede acceder a todos los atributos de la clase de la
que desciende; por ejemplo, cualquier clase que descienda de la clase Polygon hereda los
atributos npoints, xpoints e ypoints.

Finalmente, los atributos miembros de la clase pueden ser atributos de clase o atributos de instancia; se dice que
son atributos de clase si se usa la palabra clavestatic: en ese caso la variable es única para todas las instancias
(objetos) de la clase (ocupa un único lugar en memoria). Si no se usa static, el sistema crea un lugar nuevo para esa
variable con cada instancia (o sea que es independiente para cada objeto).

La declaración sigue siempre el mismo esquema:

[private|protected|public] [static] [final] [transient] [volatile] Tipo NombreVariable [= Valor];


Private, protected o public

Java tiene 4 tipos de acceso diferente a las variables o métodos de una clase: privado, protegido, público o por
paquete (si no se especifica nada).

De acuerdo a la forma en que se especifica un atributo, objetos de otras clases tienen distintas posibilidades de
accederlos: 

Acceso desde: private protected public (package)


la propia clase S S S S
subclase en el
N S S S
mismo paquete
otras clases en el
N S S S
mismo paquete
subclases en
N X S N
otros paquetes
otras clases en
N N S N
otros paquetes

S: puede acceder

N: no puede acceder

X: puede acceder al atributo en objetos que pertenezcan a la subclase, pero no en los que pertenecen a la clase
madre. Es un caso especial ; más adelante veremos ejemplos de todo esto.

Static y final

Como ya se vio, static sirve para definir un atributo como de clase, o sea único para todos los objetos de la clase.
En cuanto a final, como en las clases, determina que un atributo no pueda ser sobreescrito o redefinido. O sea: no
se trata de una variable, sino de una constante.

Transient y volatile

Son casos bastante particulares y que no habían sido implementados en Java 1.0.

Transient denomina atributos que no se graban cuando se archiva un objeto, o sea que no forman parte del estado
permanente del mismo.

Volatile se utiliza con variables modificadas asincrónicamente por objetos en diferentes threads (literalmente


"hilos", tareas que se ejecutan en paralelo); básicamente esto implica que distintas tareas pueden intentar modificar
la variable simultáneamente, y volatile asegura que se vuelva a leer la variable (por si fue modificada) cada vez
que se la va a usar (esto es, en lugar de usar registros de almacenamiento como buffer).

Los tipos de Java

Los tipos de variables disponibles son básicamente 3:

 tipos básicos (no son objetos)


 arreglos (arrays)
 clases e interfases

Con lo que vemos que cada vez que creamos una clase o interfase estamos definiendo un nuevo tipo.

Los tipos básicos son:

Tipo Tamaño/Formato Descripción


byte 8-bit complemento a 2 Entero de un byte
16-bit complemento a
short Entero corto
2
32-bit complemento a
int Entero
2
64-bit complemento a
long Entero largo
2
Punto flotante, precisión
float 32-bit IEEE 754
simple
Punto flotante, precisión
double 64-bit IEEE 754
doble
16-bit caracter
char Un caracter
Unicode
Valor booleano (verdadero
boolean true, false
o falso)

Los arrays son arreglos de cualquier tipo (básico o no). Por ejemplo, existe una clase Integer; un arreglo de
objetos de dicha clase se notaría:

Integer vector[ ];

Los arreglos siempre son dinámicos, por lo que no es válido poner algo como:

Integer cadena[5];

Aunque sí es válido inicializar un arreglo, como en:

int días[ ] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

char letras[ ] = { 'E', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D' };
String nombres[ ] = new String[12];

Nota al margen: no confundir un String (cadena de caracteres) con un arreglo de caracteres! Son cosas bien
distintas!

Ya hablaremos más adelante de las clases String y StringBuffer.

En Java, para todas las variables de tipo básico se accede al valor asignado a la misma directamente (no se conoce
la dirección de memoria que ocupa). Para las demás (arrays, clases o interfases), se accede a través de un puntero a
la variable. El valor del puntero no es accesible ni se puede modificar (como en C); Java no necesita esto y además
eso atentaría contra la robustez del lenguaje.

De hecho, en Java no existen los tipos pointer, struct o union. Un objeto es más que una estructura, y las uniones
no se hacen necesarias con un método de programación adecuado (y además se evita la posibilidad de acceder a
los datos incorrectamente).

Algo más respecto a los arreglos: ya que Java gestiona el manejo de memoria para los mismos, y lanza
excepciones si se intenta violar el espacio asignado a una variable, se evitan problemas típicos de C como acceder
a lugares de memoria prohibidos o fuera del lugar definido para la variable (como cuando se usa un subíndice más
grande que lo previsto para un arreglo…).

Y los métodos…

Los métodos, como las clases, tienen una declaración y un cuerpo.

La declaración es del tipo:

[private|protected|public] [static] [abstract] [final] [native] [synchronized] TipoDevuelto


NombreMétodo ( [tipo1 nombre1[, tipo2 nombre2 ]…] ) [throwsexcepción1 [,excepción2]… ]
A no preocuparse: poco a poco aclararemos todo con ejemplos.

Básicamente, los métodos son como las funciones de C: implementan, a través de funciones, operaciones y
estructuras de control, el cálculo de algún parámetro que es el que devuelven al objeto que los llama. Sólo pueden
devolver un valor (del tipo TipoDevuelto), aunque pueden no devolver ninguno (en ese
caso TipoDevuelto esvoid). Como ya veremos, el valor de retorno se especifica con la instrucción return, dentro
del método.

Los métodos pueden utilizar valores que les pasa el objeto que los llama (parámetros), indicados con tipo1
nombre1, tipo2 nombre2… en el esquema de la declaración.

Estos parámetros pueden ser de cualquiera de los tipos ya vistos. Si son tipos básicos, el método recibe el valor del
parámetro; si son arrays, clases o interfases, recibe un puntero a los datos (referencia). Veamos un pequeño
ejemplo:
public int AumentarCuenta(int cantidad) {
cnt = cnt + cantidad;
return cnt;
}

Este método, si lo agregamos a la clase Contador, le suma cantidad al acumulador cnt. En detalle:

 el método recibe un valor entero (cantidad)


 lo suma a la variable de instancia cnt
 devuelve la suma (return cnt)

¿Cómo hago si quiero devolver más de un valor? Por ejemplo, supongamos que queremos hacer un método dentro
de una clase que devuelva la posición del mouse.
Lo siguiente no sirve:
void GetMousePos(int x, int y) {
x = ….; // esto no sirve!
y = ….; // esto tampoco!
}

porque el método no puede modificar los parámetros x e y (que han sido pasados por valor, o sea que el método
recibe el valor numérico pero no sabe adónde están las variables en memoria).

La solución es utilizar, en lugar de tipos básicos, una clase:


class MousePos { public int x, y; }

y luego utilizar esa clase en nuestro método:


void GetMousePos( MousePos m ) {
m.x = ……;
m.y = ……;
}

El resto de la declaración

Public, private y protected actúan exactamente igual para los métodos que para los atributos, así que veamos el
resto.

Los métodos estáticos (static), son, como los atributos, métodos de clase; si el método no es static es un
método de instancia. El significado es el mismo que para los atributos: un método static es compartido por todas
las instancias de la clase.
Ya hemos hablado de las clases abstractas; los métodos abstractos (abstract) son aquellos de los que se da la
declaración pero no la implementación (o sea que consiste sólo del encabezamiento). Cualquier clase que contenga
al menos un método abstracto (o cuya clase madre contenga al menos un método abstracto que no esté
implementado en la hija) es una clase abstracta.

Es final un método que no puede ser redefinido por ningún descendiente de la clase.

Las clases native son aquellas que se implementan en otro lenguaje (por ejemplo C o C++) propio de la máquina.
Sun aconseja utilizarlas bajo riesgo propio, ya que en realidad son ajenas al lenguaje. Pero la posibilidad de usar
viejas bibliotecas que uno armó y no tiene ganas de reescribir existe!.

Las clases synchronized permiten sincronizar varios threads para el caso en que dos o más accedan


concurrentemente a los mismos datos. De nuevo, más detalles habrá en el futuro, cuando hablemos de threads.

Finalmente, la cláusula throws sirve para indicar que la clase genera determinadas excepciones. También
hablaremos de las excepciones más adelante.

El cuerpo de los métodos


Otra vez recordaremos nuestra vieja clase Contador:
// Implementación de un contador sencillo
public class Contador {
………………..
public int incCuenta() {
cnt++;
return cnt;
}
…………………
}
Dentro de los métodos pueden incluirse:
 Declaración de variables locales
 Asignaciones a variables
 Operaciones matemáticas
 Llamados a otros métodos:
o dentro de la clase
o de instancia, de otras clases
o de clase, de cualquier clase
 Estructuras de control
 Excepciones (try, catch, que veremos más adelante)

Declaración de variables locales


Las variables locales se declaran igual que los atributos de la clase:

Tipo NombreVariable [= Valor];

Ej: int suma;

float precio;

Contador laCuenta;

Sólo que aquí no se declaran private, public, etc., sino que las variables definidas dentro del método sólo son
accesibles por él.

Las variables pueden inicializarse al crearse:

Ej: int suma = 0;


float precio = 12.3;

Contador laCuenta = new Contador ( );

Asignaciones a variables
Se asigna un valor a una variable mediante el signo =:

Variable = Constante | Expresión ;

Ej: suma = suma + 1;

precio = 1.05 * precio;

laCuenta.cnt = 0;

El último caso es válido si cnt es una variable pública de la clase Contador. Personalmente no creo conveniente
acceder directamente a variables de otro objeto, ya que futuras modificaciones del objeto llamado o del que llama
puede propender la difusión de errores… Es mejor usar métodos como getCuenta o un
hipotéticoinicializarContador para ello. De hecho, algunos sugieren que todas las variables de una clase se
declaren como private.

En el primer caso, o sea en general:

Variable = Variable Operador Expresión;

se puede escribir en forma más sencilla:

Variable Operador= Expresión;


Por ejemplo, suma = suma + 9 - cantidad;

puede escribirse: suma += 9-cantidad;

y precio = precio * 0.97;

como: precio *= 0.97;

Operaciones matemáticas
Hay varios tipos de operadores:

Unarios: + - ++ -- ~ ! (tipo) …..etc.

Se colocan antes (o en algunos casos después) de la constante o expresión.

Por ejemplo: -cnt; // cambia de signo; por ejemplo si cnt es 12 el resultado es -12; cnt no cambia.

++cnt; // equivale a cnt += 1;

cnt++; // equivale a cnt +=1; veremos la diferencia al hablar de estructuras de control

--cnt; // equivale a cnt -= 1;

cnt--; // equivale a cnt -= 1;

Binarios: + - * / % …..etc.

Van entre dos constantes o expresiones o combinación de ambas.


Por ejemplo: cnt + 2; // debuelve la suma de ambos.

promedio + ( valor / 2); // como se ve, se pueden usar paréntesis.

horas / hombres; // división.

acumulado % 3; // resto de la división entera entre ambos.

Nota: + sirve también para concatenar cadenas de caracteres; hablaremos de String y StringBuffer pronto. Cuando
se mezclan Strings y valores numéricos, éstos se convierten automáticamente a cadenas:

"La frase tiene " + cant + " letras"

se convierte en: "La frase tiene 17 letras" // suponiendo que cant = 17

Precedencia de operadores en Java

La siguiente es la precedencia de los operadores en expresiones compuestas. De todos modos, como en todos los
lenguajes, se recomienda usar paréntesis en caso de duda.

Posfijos [] . (params) expr++ expr--

Operadores unarios ++expr --expr +expr -expr ~ !

Creación y "cast" new (type)

Multiplicativos * / %

Aditivos + -
Desplazamiento << >> >>>

Relacionales < > <= >= instanceof

Igualdad == !=

AND bit a bit &

OR exclusivo bit a bit ^

OR inclusivo bit a bit |

AND lógico &&

OR lógico ||

Condicional ? :

Asignación = += -= *= /= %= ^= &= |= <<= >>= >>>=

Algunos ejemplos:

[] define arreglos: int lista[];

(params) es la lista de parámetros cuando se llama a un método: convertir(valor, base);

new permite crear una instancia de un objeto: new Contador();

(type) cambia el tipo de una expresión a otro: (float)(total % 10);


>> desplaza bit a bit un valor binario: base >> 3;

<= devuelve "true" si un valor es menor o igual que otro: total <= maximo;

instanceof devuelve "true" si el objeto es una instancia de la clase: papa instanceof Comida;

|| devuelve "true" si cualquiera de las expresiones es verdad: (a<5) || (a>20)

Llamadas a métodos
Se llama a un método de la misma clase simplemente con el nombre del método y los parámetros entre paréntesis,
como se ve, entre otros, en el ejemplo en negrita:
// Archivo: Complejo.java
// Compilar con: javac Complejo.java
public final class Complejo extends Number {
// atributos:
private float x;
private float y;
// constructor:
public Complejo(float rx, float iy) {
x = rx;
y = iy;
}
// métodos:
public float Norma() {
return (float)Math.sqrt(x*x+y*y);
}
// obligatorios (son abstractos en Number):
public double doubleValue() {
return (double)Norma( );
}
public float floatValue() {
return Norma();
}
public int intValue() {
return (int)Norma();
}
public long longValue() {
return (long)Norma();
}
public String toString() {
return "("+x+")+i("+y+")";
}
}

Pueden probar la clase (mínima) con el siguiente ejemplo de aplicación; la línea en negrita es un ejemplo de un
llamado a un método de un objeto de otra clase. Notar que es este caso, es necesario llamar al método sobre un
objeto (instancia) existente, por lo que se indica:

Nombre_del_Objeto<punto>Nombre_del_Método(parámetros)

// Archivo: Ejemplo4.java
// Compilar con: javac Ejemplo4.java
// Ejecutar con: java Ejemplo4
import java.io.*;

public class Ejemplo4 {


public static void main(String args[]) {
Complejo numComp = new Complejo(4,-3);
System.out.println(numComp.toString());
System.out.println(numComp.Norma());
}
}

En la clase Complejo tenemos también un ejemplo de un llamado a un método de clase, o sea static:
return (float)Math.sqrt(x*x+y*y);

Como el método es de clase, no hace falta llamarlo para un objeto en particular. En ese caso, en lugar del nombre
de un objeto existente se puede utilizar directamente el nombre de la clase:

Nombre_de_la_Clase<punto>Nombre_del_Método(parámetros) 

Las estructuras de control


Las estructuras de control en Java son básicamente las misma que en C, con excepción del goto, que no existe (al
fin un lenguaje serio! )

if…[else]
La más común de todas, permite ejecutar una instrucción (o secuencia de instrucciones) si se da una condición
dada (o, mediante la cláusula else, ejecutar otra secuencia en caso contrario).
if (expresión_booleana) instrucción_si_true;
[else instrucción_si_false;]

o bien:
if (expresión_booleana) {
instrucciones_si_true;
}
else {
instrucciones_si_false;
}

Por ejemplo:
public final String toString() {
if (y<0)
return x+"-i"+(-y);
else
return +x+"+i"+y;
}

Switch…case…brake…default
Permite ejecutar una serie de operaciones para el caso de que una variable tenga un valor entero dado. La
ejecución saltea todos los case hasta que encuentra uno con el valor de la variable, y ejecuta desde allí hasta el
final del case o hasta que encuentre un break, en cuyo caso salta al final del case. El default permite poner una
serie de instrucciones que se ejecutan en caso de que la igualdad no se de para ninguno de los case.
switch (expresión_entera) {
case (valor1): instrucciones_1;
[break;]
case (valor2): instrucciones_2;
[break;]
…..
case (valorN): instrucciones_N;
[break;]
default: instrucciones_por_defecto;
}

Por ejemplo:
switch (mes) {
case (2): if (bisiesto()) dias=29;
else dias=31;
break;
case (4):
case (6):
case (9):
case (11): dias = 30;
break;
default: dias = 31;
}

While
Permite ejecutar un grupo de instrucciones mientras se cumpla una condición dada:
while (expresión_booleana) {
instrucciones…
}

Por ejemplo:
while ( linea != null) {
linea = archivo.LeerLinea();
System.out.println(linea);
}

Do…while
Similar al anterior, sólo que la condición se evalúa al final del ciclo y no al principio:
do {
instrucciones…
} while (expresión_booleana);

Por ejemplo:
do {
linea = archivo.LeerLinea();
if (linea != null) System.out.println(linea);
} while (linea != null);

For
También para ejecutar en forma repetida una serie de instrucciones; es un poco más complejo:
for ( instrucciones_iniciales; condición_booleana; instruccion_repetitiva_x ) {
instrucciones…
}

Si bien las instrucciones pueden ser cualquiera (el bucle se repite mientras la condición sea verdadera), lo usual es
utilizarlo para "contar" la cantidad de veces que se repiten las instrucciones; se podría indicar así:
for ( contador = valor_inicial; contador < valor_final; contador++ ) {
instrucciones…
}

Por ejemplo:
for ( i=0; i<10; i++ ) {
System.out.println( i );
}

o, para contar hacia atrás:


for ( i=10; I>0; I-- ) {
System.out.println( i );
}

Break y continue
Estas instrucciones permiten saltar al final de una ejecución repetitiva (break) o al principio de la misma
(continue).

Por ejemplo, en:


import java.io.*;
class Bucles {
public static void main (String argv[ ]) {
int i=0;
for (i=1; i<5; i++) {
System.out.println("antes "+i);
if (i==2) continue;
if (i==3) break;
System.out.println("después "+i);
}
}
}

La salida es:

antes 1

después 1

antes 2

antes 3

Por qué? "i" comienza en 1 (imprime "antes" y "después"); cuando pasa a 2, el continue salta al principio del bucle
(no imprime el "después"). Finalmente, cuando "i" vale 3, el break da por terminado el bucle for.
Otras...
Hay otras instrucciones que controlan el flujo del programa:

 synchronized (para ver junto con los threads)


 catch,
 throw,
 try,
 finally (para ver con las excepciones)

Ahora sí, podemos usar todo nuestro conocimiento sobre Java para ir creando algunas aplicaciones y de paso ir
viendo las bibliotecas estándar.

Bueno, vamos a hacer una pequeña aplicación para practicar un poco.

Para empezar, vamos a desarrollar un poquito una clase para trabajar con números complejos.

La clase Complejo
// grabar como Complejo.java
// compilar con "javac Complejo.java"
public final class Complejo extends Number {

// atributos:
private float x;
private float y;

// constructores:
public Complejo() {
x = 0;
y = 0;
}
public Complejo(float rx, float iy) {
x = rx;
y = iy;
}

// métodos:
// Norma
public final float Norma() {
return (float)Math.sqrt(x*x+y*y);
}
public final float Norma(Complejo c) {
return (float)Math.sqrt(c.x*c.x+c.y*c.y);
}
// Conjugado
public final Complejo Conjugado() {
Complejo r = new Complejo(x,-y);
return r;
}
public final Complejo Conjugado(Complejo c) {
Complejo r = new Complejo(c.x,-c.y);
return r;
}
// obligatorios (son abstractos en Number):
public final double doubleValue() {
return (double)Norma();
}
public final float floatValue() {
return Norma();
}
public final int intValue() {
return (int)Norma();
}
public final long longValue() {
return (long)Norma();
}
public final String toString() {
if (y<0)
return x+"-i"+(-y);
else
return x+"+i"+y;
}
// Operaciones matemáticas
public static final Complejo Suma(Complejo c1, Complejo c2) {
return new Complejo(c1.x+c2.x,c1.y+c2.y);
}
public static final Complejo Resta(Complejo c1, Complejo c2) {
return new Complejo(c1.x-c2.x,c1.y-c2.y);
}
public static final Complejo Producto(Complejo c1, Complejo c2) {
return new Complejo(c1.x*c2.x-c1.y*c2.y,c1.x*c2.y+c1.y*c2.x);
}
// Nos va a venir bien para aprender excepciones...
// como división por cero!
public static final Complejo DivEscalar(Complejo c, float f) {
return new Complejo(c.x/f,c.y/f);
}
public static final Complejo Cociente(Complejo c1, Complejo c2) {
float x = c1.x*c2.x+c1.y*c2.y;
float y = -c1.x*c2.y+c1.y*c2.x;
float n = c2.x*c2.x+c2.y*c2.y;
Complejo r = new Complejo(x,y);
return DivEscalar(r,n);
}
}

Podemos hacer algunos comentarios...

Primero: no hay include aquí, ya que la única biblioteca que usamos es java.lang y se incluye automáticamente.

Segundo: la clase es public final, lo que implica que cualquier clase en éste u otros paquetes puede utilizarla, pero
ninguna clase puede heredarla (o sea que es una clase estéril...).
Hagamos un resumen de los atributos y métodos de la clase:
// atributos:
private float x;
private float y;

Siendo privados, no podemos acceder a ellos desde el exterior. Como además la clase es final, no hay forma de
acceder a x e y. Además, al no ser static, cada instancia de la clase tendrá su propio x e y.
// constructores:
public Complejo()
public Complejo(float rx, float iy)

La clase tiene dos constructores, que se diferencian por su "firma" (signature), o sea por la cantidad y tipo de
parámetros. El primero nos sirve para crear un objeto de tipo Complejo y valor indefinido (aunque en realidad el
método lo inicializa en cero); con el segundo, podemos definir el valor al crearlo.
// métodos:
public final float Norma()
public final float Norma(Complejo c)
public final Complejo Conjugado()
public final Complejo Conjugado(Complejo c)

Estos métodos también son duales; cuando los usamos sin parámetros devuelven la norma o el conjugado del
objeto individual (instancia):
v = miComplejo.Norma(); // por ejemplo
otroComplejo = miComplejo.Conjugado();

Con parámetros, en cambio, devuelven la norma o el conjugado del parámetro:


v = unComplejo.Norma(miComplejo);
otroComplejo = unComplejo.Conjugado(miComplejo);
Notar que lo siguiente es inválido:

otroComplejo = Complejo.Norma(miComplejo); // NO SE PUEDE!

...porque el método no es static, por lo tanto debe llamarse para una instancia en particular (en este
caso, unComplejo). 
// obligatorios (son abstractos en Number):
public final double doubleValue()
public final float floatValue()
public final int intValue()
public final long longValue()

Estos métodos es obligatorio definirlos, ya que en la clase madre Number son métodos abstractos, o sea que
debemos implementarlos aquí.

Como todos los métodos de esta clase son final, o sea que no puede ser redefinido. No es importante en realidad
puesto que la clase no puede tener descendientes...
public final String toString()

Este método nos sirve para representar el complejo como una cadena de caracteres, de la forma x+iy.
// Operaciones matemáticas
public static final Complejo Suma(Complejo c1, Complejo c2)
public static final Complejo Resta(Complejo c1, Complejo c2)
public static final Complejo Producto(Complejo c1, Complejo c2)
public static final Complejo DivEscalar(Complejo c, float f)
public static final Complejo Cociente(Complejo c1, Complejo c2)

Aquí definimos varias operaciones matemáticas. Notar que se han definido como static, o sea que los métodos son
únicos independientemente de las instancias. Esto permite que los podamos ejecutar sobre una instancia o
directamente sobre la clase:
miComplejo = unComplejo.Suma(comp1,comp2); // vale
miComplejo = Complejo.Suma(comp1,comp2); // TAMBIEN VALE!

Por ejemplo, la siguiente aplicación nos muestra cómo podemos usar algunos de estos métodos:
// Archivo: Ejemplo5.java
// Compilar con: javac Ejemplo5.java
// Ejecutar con: java Ejemplo5
import java.io.*;

public class Ejemplo5 {

public static void main(String args[]) {


Complejo c1 = new Complejo(4,-3);
System.out.println(c1+"\tNorma="+c1.Norma());
Complejo c2 = new Complejo(-2,5);
System.out.println(c2+"\tNorma="+c2.Norma()+"\n");

System.out.println("("+c1+")/4 :"+Complejo.DivEscalar(c1,4));
System.out.println("Suma : "+Complejo.Suma(c1,c2));
System.out.println("Resta : "+Complejo.Resta(c1,c2).toString());
System.out.println("Multip: "+Complejo.Producto(c1,c2).toString());
System.out.println("Divis : "+Complejo.Cociente(c1,c2).toString());
}
}

Hay varias cosas para notar: por ejemplo, que podemos declarar las variables a la vez que las creamos:
Complejo c1 = new Complejo(4,-3);

c1 y c2 son dos objetos (instancias) de la clase Complejo.

Notar también que no hace falta poner para imprimir:


System.out.println(c1.toString().......);
ya que println automáticamente usa el método toString() de la clase para imprimir. Basta con poner c1, como en
el programa, aunque c1.toString() también es válido.

También se ve el uso de los métodos static, accediéndolos directamente por la clase, en:


System.out.println("Suma : "+Complejo.Suma(c1,c2));

Y tampoco aquí usamos toString(), aunque no está mal si se usa Complejo.Suma(c1,c2).toString().

Algo sobre los métodos


Analicemos un poco ahora cómo implementamos los métodos de la clase Complejo.
public final int intValue() {
return (int)Norma();
}

Ya que no podemos convertir así nomás un complejo en un entero, para implementar estos métodos hemos elegido
usar como valor de retorno la norma del complejo. En este caso, y dado que el método Norma() devuelve un float,
usamos typecasting, es decir, lo convertimos en entero precediéndolo con (int).
public final String toString() {
if (y<0)
return x+"-i"+(-y);
else
return x+"+i"+y;
}

Aquí representamos el complejo en forma de cadena de caracteres. Hemos usado el if para representar
adecuadamente el signo de la parte imaginaria. Noten también la asombrosa ayuda que nos brinda Java, al
convertir automáticamente las variables x e y a String para la concatenación (mediante el signo "+")!
public static final Complejo Cociente(Complejo c1, Complejo c2) {
float x = c1.x*c2.x+c1.y*c2.y;
float y = -c1.x*c2.y+c1.y*c2.x;
float n = c2.x*c2.x+c2.y*c2.y;
Complejo r = new Complejo(x,y);
return DivEscalar(r,n);
}

Aquí tengan en cuenta que las variables x e y, definidas como float, no tienen nada que ver con las variables
(atributos) de la clase que están definidas al principio de la misma, sino que son variables locales al método.

Podemos usar return DivEscalar(r,n), ya que DivEscalar es un método propio de la clase; no hace falta


poner Complejo.DivEscalar.

Qué pasa con r, el new Complejo(x,y) que creamos? Nada; cuando un objeto no se usa más, el "recogedor de
basura" de Java lo elimina automáticamente (tarde o temprano) de la memoria.
public final float Norma(Complejo c) {
return (float)Math.sqrt(c.x*c.x+c.y*c.y);
}

Aquí estamos usando otra clase, Math, que nos permite realizar varias operaciones matemáticas. Esta clase
dispone de las constantes E y PI, y los métodos:
abs(x) valor absoluto
acos(x) arco coseno
asin(x) arco seno
atan(x) arco tangente
atan2(x,y) componente angular de la representación polar de x,y
ceil(x) menor entero mayor que x
cos(x) coseno
exp(x) ex
floor(x) mayor entero menor que x
IEEEremainder(x,y) resto de la división x/y según el estándar IEEE 754
log(x) logaritmo natural
max(x,y) el mayor de x e y
min(x,y) el menor de x e y
pow(x,y) xy
random() número aleatorio entre 0 y 1
rint(x) entero más cercano a x (devuelve un doble)
round(x) entero más cercano a x (devuelve un entero o un long)
sin(x) seno
sqrt(x) raíz cuadrada
tan(x) tangente

Algunos de estos métodos disparan excepciones, como sqrt o log de números negativos. Más adelante veremos
cómo se usan las excepciones.

Otra clase que hemos estado usando mucho es la PrintStream, a la que pertenece el método println. En
System.out.println(...)

out es un atributo de la clase System, del tipo (clase) PrintStream:


public final class System extends Object
{
// Fields
public static PrintStream err;
public static InputStream in;
public static PrintStream out;

// Methods
.............

Java a través de la ventana


Para hacer algo un poco más divertido, vamos a empezar a trabajar con la biblioteca java.awt, que es la que
contiene todo un grupo de objetos para trabajar con ventanas y sus contenidos: botones, listas, etc.
Nuestra primera ventana
En Java, la clase Window (descendiente de Container), en la biblioteca java.awt, permite implementar ventanas
"peladas", es decir, sin bordes ni menús. Son la base para cualquier tipo de ventanas (normales, pop-up, diálogos,
etc.). El otro descendiente de Container, Panel, es más sencillo aún y sirve como espacio para que una aplicación
incorpore dentro suyo otros elementos (incluyendo otros paneles).

La interface Java dirige tanto a uno como a otro todos los eventos de teclado, mouse y foco que los afecten (en
seguida veremos cómo usar estos eventos).

De la clase Window descienden Dialog (para implementar diálogos) y Frame, que es una ventana algo más


completa: ya tiene borde y menú, así como los botones de cerrar, maximizar, etc.

El siguiente ejemplo crea una ventana que no hace nada pero contiene varios elementos; se puede usar
directamente (desde la ventana DOS o Unix con java Ejemplo7) o como applet dentro de una página HTML.

Si bien los elementos no disparan ninguna acción, se pueden utilizar con toda su funcionalidad (por ejemplo, editar
el texto dentro de los cuadros de texto o presionar el botón).
// grabar como "Ejemplo7.java"
// compilar con "javac Ejemplo7.java"
import java.awt.*;

public class Ejemplo7 extends Frame {


boolean inAnApplet = true;

public static void main(String args[]) {


Ejemplo7 window = new Ejemplo7();
window.inAnApplet = false;
window.setTitle("Ejemplo");
window.pack();
window.show();
}
public Ejemplo7() {
Panel panelAlto = new Panel();
panelAlto.add("West", new Label("Cartel", Label.CENTER));
panelAlto.add("East", new TextArea("Area de texto", 5, 20));
add("North", panelAlto);

Panel panelBajo = new Panel();


panelBajo.add(new TextField("Campo de Texto"));
panelBajo.add(new Button("Botón"));
add("South",panelBajo);
}

public boolean handleEvent(Event ev) {


if (ev.id == Event.WINDOW_DESTROY) {
if (inAnApplet) {
dispose();
} else {
System.exit(0);
}
}
return super.handleEvent(ev);
}
}

Un poco de detalle

La clase desciende de Frame (o sea que será una ventana con borde, aunque no le vamos a poner menú).

Vamos a usar el flag inAnApplet para saber si se arrancó como applet o como aplicación standalone (hay que
cerrarla en manera diferente en cada caso)
public class Ejemplo7 extends Frame {
boolean inAnApplet = true;
Si se llama como aplicación standalone, lo primero que se ejecuta es main(...); en este caso la aplicación crea una
instancia de Ejemplo7 (ejecutando el constructorEjemplo7() a través de new), define que no es un applet, y llama
a tres métodos de la "abuela" window:

 setTitle que define cuál va a ser el título que aparece en la ventana


 pack que dimensiona los elementos que componen la ventana a su tamaño preferido
 show que muestra la ventana
public static void main(String args[]) {
Ejemplo7 window = new Ejemplo7();
window.inAnApplet = false;
window.setTitle("Ejemplo");
window.pack();
window.show();
}

Ojo! No confundir el objeto (instancia) window con la clase Window!

Si se carga como applet, entonces se ejecuta el constructor Ejemplo7() como en el caso anterior:


public Ejemplo7() {
Panel panelAlto = new Panel();
panelAlto.add("West", new Label("Cartel", Label.CENTER));
panelAlto.add("East", new TextArea("Area de texto", 5, 20));
add("North", panelAlto);

Panel panelBajo = new Panel();


panelBajo.add(new TextField("Campo de Texto"));
panelBajo.add(new Button("Botón"));
add("South",panelBajo);
}
Este constructor define dos paneles que forman el contenido de la ventana (panelAlto y panelBajo), los llena con
un par de componentes y los pone dentro de la ventana (recordar que Ejemplo7 es una ventana!).

Para verlo más claro, se crea el panel (o espacio para contener objetos) con:
Panel panelAlto = new Panel();

Se agregan componentes al panel con el método add:


panelAlto.add("West", new Label("Cartel", Label.CENTER));
panelAlto.add("East", new TextArea("Area de texto", 5, 20));

Se agregan el panel dentro de nuestro objeto con:


add("North", panelAlto);

que equivale a:
this.add("North", panelAlto);

lo que se puede ver (aunque es inválido porque la clase no es static) como:


Ejemplo7.add("North", panelAlto);

Como nuestra clase Ejemplo7 desciende de Frame, ésta de Window, y ésta de Container, el método add lo está
heredando de... su bisabuela! Por otra parte,Panel es hija de Container, y usa el mismo método para agregar sus
componentes. Interesante, no? Veamos la estructura:
Object --- Component --- Container --+-- Panel
|
+-- Window --- Frame --- Ejemplo7

Noten que hemos usado dos métodos add con diferente signature:


panelAlto.add("West", new Label("Cartel", Label.CENTER));
..........
panelBajo.add(new Button("Botón"));

El método add(Component) agrega un componente al final; el método add(String,Component) lo agrega en un


lugar especificado por una palabra que depende del LayoutManager, el objeto que se encarga de ordenar los
componentes dentro del contenedor.

LayoutManager es una interface, y como tal debe implementarse a través de objetos no abstractos de los que hay
varios predefinidos en la librería java.awt:BorderLayout, CardLayout, FlowLayout,
GridBagLayout y GridLayout.

El Layout por defecto es BorderLayout, que define en el contenedor las áreas "North", "South", "West", "East" y
"Center" y es que usamos aquí. CardLayoutpermite "apilar" los componentes como cartas y ver uno por
vez, FlowLayout los ordena de izquierda a derecha como un texto, GridLayout los ordena en una cuadrícula
donde cada componente tiene un tamaño fijo y GridBagLayout los pone en una cuadrícula pero cada uno puede
tener el tamaño deseado.

Noten que no hace falta llamar, en el caso del applet, a Pack() y Show().

Y los eventos...

Ahora vamos a ver un método que viene de la clase tatarabuela! Hace falta decir que me gusta esto de los objetos?
Vamos a redefinir handleEvent(Event), que es el método que analiza los eventos dirigidos al componente y toma
las acciones adecuadas.

La clase Event define básicamente una serie de métodos que permiten saber si hay alguna tecla de control
presionada y muchas constantes que indican si se presionó o movió el mouse, si se presionó alguna tecla en
particular, si se cambió el tamaño de la ventana, etc. En particular hay algunos atributos interesantes:

 id que indica el tipo de evento


 target que indica sobre qué componente se produjo el evento
 key qué tecla se presionó si fue un evento de teclado

etc.

En los descendientes de Component, el método handleEvent se llama automáticamente cada vez que se produce
un evento sobre el componente. En este caso, simplemente vamos a mirar si el evento (sobre nuestro objeto de
clase Ejemplo7) fue "cerrar la ventana", que se identifica mediante event.id = WINDOW_DESTROY (una
constante estática de la clase Event, y como tal la podemos usar con el nombre de la clase
como Event.WINDOW_DESTROY): 
public boolean handleEvent(Event ev) {
if (ev.id == Event.WINDOW_DESTROY) {
if (inAnApplet) {
dispose();
} else {
System.exit(0);
}
}
return super.handleEvent(event);
}
En ese caso, si nuestro ejemplo se disparó como aplicación llamamos al método System.exit(0), que cierra la
aplicación; y si era un applet llamamos a dispose(), implementación de un método de la
interface ComponentPeer que se encarga de remover todos los componentes y la propia ventana.

Noten que cualquier otro tipo de evento deja seguir hasta return super.handleEvent(event), que llama al
método handleEvent de la clase madre: así como el prefijo this. se refiere a un método de la propia clase, el
prefijo super. llama al método de la clase madre (aunque esté redefinido). En este caso, la llamada se remonta
hasta Component.handleEvent, que determina el tipo de evento y llama a uno de los métodos action,
gotFocus, lostFocus, keyDown, keyUp, mouseEnter, mouseExit, mouseMove, mouseDrag,
mouseDown o mouseUp según sea apropiado (y devuelve true). Si ningún método es aplicable, devuelve false.

Es muy común, al redefinir un método, tener en cuenta llamar antes o después al método de la clase antecesora
para inicializar o terminar alguna tarea.

Una ventana con vida


Antes que nada, vamos a crear una página HTML para cargar nuestra clase Ejemplo8, que será un applet (aunque
también la podremos ejecutar en forma standalone con "java Ejemplo8"), por ejemplo:
<!-- Archivo Ejemplo8.htm - HTML de ejemplo -->
<HTML>
<HEAD>
<TITLE>Ejemplo 8 - Ventana de datos</TITLE>
</HEAD>
<BODY>
Aqu&iacute; se tiene que abrir una ventana de entrada de datos
<applet code="Ejemplo8.class" width=170 height=150>
</applet>
</BODY>
</HTML>
Nuestro applet será muy sencillo, ya que utilizará clases que iremos definiendo en este capítulo; por empezar sólo
creará una ventana que definiremos en la claseVentana8:
// Archivo: Ejemplo8.java
// Compilar con "javac Ejemplo8.java"

import java.awt.*;
import java.applet.*;

public class Ejemplo8 extends Applet {

public static void main (String arg[]) { // para poder llamarla con "java Ejemplo8"
new Ventana8("Ejemplo Standalone", true);
}

public void init() { // se ejecuta al abrirse un applet


new Ventana8("Ejemplo Applet", false);
}

Con los parámetros que le pasamos a la clase Ventana8 le indicamos el título de la ventana y si se carga como
applet o no (ya que el método de cierre varía). 

Viajando con Java


Ahora vamos a trabajar con nuestra clase Ventana8, una ventana que nos permita seleccionar una fecha y dos
ciudades (desde y hasta) que simula una ventana de compra de pasajes de, por ejemplo, una terminal de ómnibus.

El ejemplo está basado en uno del libro "Programación Java" de Macary y Nicolas, aunque algo mejorado y
ampliado.
En nuestra ventana podremos entrar una fecha a mano o directamente mediante los botones Hoy y Mañana,
elegiremos la ciudad de salida y la de llegada de dos listas, y presionaremos luego un botón que nos mostrará los
servicios disponibles, nos permitirá comprar los pasajes, etc.

A medida que entramos los datos, en el botón se irá mostrando el detalle de lo que se fue seleccionando.

Nuestra ventana quedará más o menos así: 

Empecemos por armar la estructura de la clase Ventana8:


import java.awt.*;

class Ventana8 extends Frame { // hija de Frame

// aquí agregaremos luego


// algunas variables para guardar datos
// (ciudades de salida y llegada, fecha)
button ok; // también el botón de compra de pasajes
boolean enApplet; // y otra para indicar si es un applet o no

Ventana8 (String titulo, boolean enApplet) { // un constructor


super(titulo); // llama al de Frame
this.enApplet = enApplet; // guardamos esto
// aquí crearemos los botones, listas, etc
// con sus valores iniciales
// y los pondremos en la ventana.
// por ejemplo:
ok = new Button("Viaje: de ? a ? el ?/?/?");
add("South",ok);
pack(); // dimensionamos la ventana
show(); // y la mostramos!
}
public boolean handleEvent(Event e) { // para manejar los eventos
if (e.id == Event.WINDOW_DESTROY) { // cerrar la ventana
if (enApplet) dispose();
else System.exit(0);
}
// aquí miraremos si se presionó un botón
// o se eligió algo de una lista
// y actuaremos en consecuencia
return super.handleEvent(e); // los demás eventos los maneja Frame
}

void ActualizaBoton() {
// aquí pondremos un método que servirá
// para actualizar el botón de compra de pasajes,
// ya que el texto del mismo se actualiza cada
// vez que se selecciona una ciudad o se cambia la fecha
}

void Activar() {
// y aquí un método para cuando se presione
// dicho botón, que se supone que va a consultar
// una base de datos y abrir una ventana
// para vendernos el pasaje
}
}

Nuestro programa ya funciona! Aunque un poquito incompleto, claro...

Igual vamos a analizarlo un poco el constructor, que es lo más interesante aquí.

Primero llamamos al constructor de la clase madre, que se encarga de crear la ventana:


Ventana8 (String titulo, boolean enApplet) { // un constructor
super(titulo); // llama al de Frame
Esto sería como llamar a super.Frame(titulo), o bien Frame(titulo), ya que el método constructor tiene el mismo
nombre de la clase. Luego, con:
this.enApplet = enApplet; // guardamos esto

asignamos a nuestra variable enApplet de la clase el valor del parámetro que se pasó al constructor, que se llama
igual. El prefijo this, que se refiere a la instancia particular de la clase, permite diferenciar uno de otro (esto es
válido tanto para variables como para métodos).
ok = new Button("Viaje: de ? a ? el ?/?/?");
add("South",ok);

Aquí hemos creado un botón ubicado al pie de la ventana (por ahora lo único que pusimos), y luego
dimensionamos la ventana y la mostramos:
pack(); // dimensionamos la ventana
show(); // y la mostramos!

Preparando listas

Ahora vamos a empezar a crear otros objetos para ir completando nuestra aplicación. Comencemos con las listas
de ciudades.

Para eso, vamos a crear un objeto descendiente de Panel que simplemente contenga una lista de ciudades
predefinidas y un título que diga "Seleccione ciudad de", y a continuación "salida" o "llegada".
También agregaremos un método 
import java.awt.*;

class SelecPueblo extends Panel {


private List listaPueblos;

SelecPueblo (String salidaOllegada) {


setLayout (new BorderLayout (20,20));

// armamos el título, que va a ser un Label:


StringBuffer titulo = new StringBuffer();
titulo.append("Seleccione ciudad de ");
titulo.append(salidaOllegada);
titulo.append(": ");
add("North", new Label(titulo.toString()));

// armamos la lista de ciudades, que va a ser un List:


listaPueblos = new List (4, false);
listaPueblos.addItem("Buenos Aires");
listaPueblos.addItem("La Plata");
listaPueblos.addItem("Azul");
listaPueblos.addItem("Rosario");
listaPueblos.addItem("Cordoba");
listaPueblos.addItem("Bahía Blanca");
add("South", listaPueblos);
}

public String getDescription() {


return listaPueblos.getSelectedItem();
}
}
No hay mucho para analizar aquí, creo. La variable listaPueblos es privada, pero puede consultarse cuál es la
ciudad seleccionada mediante getDescription (que es public). Este método llama al método getSelectedItem de
la lista, que devuelve el texto seleccionado.

En el constructor, armamos el texto del título como un StringBuffer. Los objetos StringBuffer son similares a los
de clase String pero pueden ser modificados. En cambio los objetos String, una vez creados, no pueden ser
modificados directamente: sus métodos (concat, toLowerCase, etc.) simplemente crean un nuevo Stringcon el
nuevo valor.

Esto lo hicimos para introducir esta nueva clase; por supuesto hubiera sido más fácil poner, como pueden
comprobar, con el mismo resultado:
String tit = "Seleccione ciudad de "+salidaOllegada+": ";
add("North", new Label(tit));

Por otra parte, creamos el objeto listaPueblos como new List(4, false), que indica que la lista va a tener 4
renglones y sólo se puede seleccionar un ítem por vez. Agregamos luego 6 ítems mediante addItem y la
agregamos al panel.

Ahora ya podemos agregar las listas a nuestra ventana y poner un par de variables para guardarlas:
class Ventana8 extends Frame { // hija de Frame

SelecPueblo cs; // ciudad de salida


SelecPueblo cl; // ciudad de llegada
button ok; // también el botón de compra de pasajes
boolean enApplet; // y otra para indicar si es un applet o no

Ventana8 (String titulo, boolean enApplet) { // un constructor


super(titulo); // llama al de Frame
this.enApplet = enApplet; // guardamos esto
cs = new SelecPueblo("SALIDA"); // CIUDAD DE SALIDA
add ("Center", cs);
cl = new SelecPueblo("LLEGADA"); // CIUDAD DE LLEGADA
add ("East", cl);
ok = new Button("Viaje: de ? a ? el ?/?/?");
add("South",ok);
pack(); // dimensionamos la ventana
show(); // y la mostramos!
}

...........................

Ya pueden ir probando cómo queda, aunque por ahora mucha funcionalidad no tenemos...

Agregando fechas

Otro panel más nos servirá para seleccionar o entrar la fecha:


import java.util.*;
import java.awt.*;

class DiaPartida extends Panel {


private TextField elDia;
private Button hoy;
private Button diasiguiente;

DiaPartida() {
setLayout (new GridLayout (4,1));
elDia = new TextField();
elDia.setText(GetHoy());
hoy = new Button ("Hoy");
diasiguiente = new Button ("Mañana");
add (new Label ("Día salida: "));
add (elDia);
add (hoy);
add (diasiguiente);
}
private String GetHoy() {
Date d = new Date();
int dia = d.getDate();
int mes = d.getMonth();
int ano = d.getYear();
return dia+"/"+mes+"/"+ano;
}

private String GetManana() {


Date d = new Date();
int dia = d.getDate();
int mes = d.getMonth();
int ano = d.getYear();
dia = dia++;
switch (mes) {
case (1):
case (3):
case (5):
case (7):
case (8):
case (10): if (dia>31) {
dia = 1;
mes++;
}
break;
case (12): if (dia>31) {
dia = 1;
mes = 1;
ano++;
}
break;
case (4):
case (6):
case (9):
case (11): if (dia>30) {
dia = 1;
mes++;
}
break;
default: if (dia>28) { // ojo, hay que corregir para bisiestos!
dia = 1;
mes++;
}
}
return dia+"/"+mes+"/"+ano;
}

public String getDescription() {


return elDia.getText();
}

public boolean handleEvent (Event e) {


if (e.target == hoy)
elDia.setText(GetHoy());
if (e.target == diasiguiente)
elDia.setText(GetManana());
return super.handleEvent(e);
}

Este es un poco más largo pero no más complejo. Vamos por parte:
DiaPartida() {
setLayout (new GridLayout (4,1));
elDia = new TextField();
elDia.setText(GetHoy());
hoy = new Button ("Hoy");
diasiguiente = new Button ("Mañana");
add (new Label ("Día salida: "));
add (elDia);
add (hoy);
add (diasiguiente);
}
El constructor crea un panel con cuatro campos en forma de grilla vertical, donde mostrará el texto "Día salida: ",
el campo de entrada de texto elDia y los botoneshoy y diasiguiente.

El método privado getHoy usa los métodos getDate, getMonth y getYear de la clase date para armar


un String con la fecha actual. El método privadogetManana hace lo mismo para leer la fecha actual, y le suma 1
al día para tener el día siguiente. El switch siguiente verifica que si pasó de fin de mes tome el primer día y el mes
siguiente (o el primer día del año siguiente si es en diciembre). Notar que no se consideraron los años bisiestos en
febrero para no complicar el método, pero no es difícil de corregir.

Otra manera sería armar un array con los días de cada mes, corregir los días de febrero para los años bisiestos, y
comparar contra este array en lugar de usar unswitch. La idea siempre es la misma: devolver un String con la
fecha del día siguiente.

Notar algo interesante: como estas clases se cargan y ejecutan en la máquina cliente, la fecha que aparece es la
del cliente y no la del servidor (que puede ser diferente depende la hora y el lugar del mundo en que estén ambas
máquinas).

El método getDescription es público y se usa para acceder a la fecha que se ha ingresado desde las demás clases;
simplemente devuelve el contenido del campoelDia, de clase TextField.

Aquí hemos desarrollado también el método handleEvent:


public boolean handleEvent (Event e) {
if (e.target == hoy)
elDia.setText(GetHoy());
if (e.target == diasiguiente)
elDia.setText(GetManana());
return super.handleEvent(e);
}
En caso de alguna acción sobre uno de los botones, el método setText (de la clase TextField) pone en el campo de
texto elDia el valor del día actual o el siguiente.

Notar que sólo hemos considerado que haya algún evento y no un tipo de evento en particular; en realidad el
método va a actuar por ejemplo tanto al presionar el mouse sobre el botón como al soltarlo. Pero esto no nos
molesta.

super.handleEvent se encarga de otros eventos dirigidos al panel, como la entrada de datos por teclado al campo
de texto por ejemplo.

Unir hasta aquí

Bueno, ahora vamos a reunir las piezas que tenemos hasta ahora agregando estos métodos a nuestra
clase Ventana8 para ver cómo queda la ventana completa:
class Ventana8 extends Frame { // hija de Frame

SelecPueblo cs; // ciudad de salida


SelecPueblo cl; // ciudad de llegada
DiaPartida dp; // día de salida
button ok; // botón de compra de pasajes
boolean enApplet; // para indicar si es un applet o no

Ventana8 (String titulo, boolean enApplet) { // un constructor


super(titulo); // llama al de Frame
this.enApplet = enApplet; // guardamos esto
dp = new DiaPartida(); // DIA DE SALIDA
add ("West", dp);
cs = new SelecPueblo("SALIDA"); // CIUDAD DE SALIDA
add ("Center", cs);
cl = new SelecPueblo("LLEGADA"); // CIUDAD DE LLEGADA
add ("East", cl);
ok = new Button("Viaje: de ? a ? el ?/?/?");
add("South",ok);
pack(); // dimensionamos la ventana
show(); // y la mostramos!
}

...........................

Completando la ventana
Vamos a empezar por completar nuestro método ActualizaBoton, que modificará el texto del botón ok a medida
que seleccionemos las ciudades y la fecha:
void ActualizaBoton() {
StringBuffer b = new StringBuffer("Viaje: de ");
if (cs.getDescription() != null) b.append(cs.getDescription());
else b.append("?");
b.append(" a ");
if (cl.getDescription() != null) b.append(cl.getDescription());
else b.append("?");
b.append(" el ");
if (dp.getDescription() != null) b.append(dp.getDescription());
else b.append("?/?/?");
ok.setLabel(b.toString());
}

Nuestro método comienza por crear un StringBuffer con las palabras "Viaje: de ", y va agregando el resto:

 la ciudad de partida, llamando al método getDescription de cs (ciudad de salida)


 el texto constante " a "
 la ciudad de llegada, llamando al método getDescription de cl (ciudad de llegada)
 el texto constante " el "
 la fecha seleccionada, llamando al método getDescription de dp (día de partida)

Si en cualquier caso recibe un string nulo, pone un signo de pregunta (o ?/?/? para la fecha).

El método setLabel, sobre el objeto ok de tipo Label, modifica la "etiqueta" del botón.

Realmente nos devuelven null los métodos que llamamos si no hay selección hecha?

Veamos:
class SelecPueblo extends Panel {
private List listaPueblos;
............................
public String getDescription() {
return listaPueblos.getSelectedItem();
}
}

El método getSelectedItem de la clase List devuelve null si no hay ítems seleccionados, así que acá andamos


bien. En cuanto a la clase DiaPartida, de entrada inicializa el valor del texto en la fecha actual, así que aquí no se
daría nunca este caso... Aunque al crear el objeto Ventana8 estamos poniendo un texto fijo en el botón, y no el
que devuelve el objeto dp.

Sería mejor, para ser más consistente, modificar el constructor de Ventana8 para que arme el texto mediante el
método ActualizaBotón: 
Ventana8 (String titulo, boolean enApplet) {
........................................
ok = new Button("cualquiera");
ActualizaBoton();
add("South",ok);
pack();
show();
}

Esto ya se ve mejor! Y de paso probamos el método...

Un poco de actividad

Ahora sí, pasemos a completar nuestro manejador de eventos: 


public boolean handleEvent(Event e) {
if (e.id == Event.WINDOW_DESTROY) {
if (enApplet) dispose();
else System.exit(0);
}
if ( (e.target==dp)||(e.target==cs)||(e.target==cl) )
ActualizaBoton();
if (e.target==ok)
Activar();
}
return super.handleEvent(e);
}

Simplemente, si detectamos un evento sobre alguno de nuestros paneles actualizamos el texto del botón; y si se
presiona dicho botón llamamos al método Activar que se supone que va a tomar los datos de la base de datos,
indicarnos servicios disponibles, etc.

Algo importante a notar es que el simple hecho de mover el mouse sobre uno de los paneles ya llama a
ActualizaBoton (se nota porque titila el texto, sobre todo en una máquina lenta). Además, si hacen click sobre el
botón Hoy o Mañana sin mover el mouse, el texto del botón ok no se actualiza ya que el evento va dirigido al
botón presionado y no al panel.

Una forma de filtrar sólo los eventos que nos interesan sería usar, por ejemplo:
if ((e.target=cs.listaPueblos) && (e.id==Event.LIST_SELECT)) ActualizaBoton();

que está dirigida a la lista y no al panel en general, y tiene en cuenta el tipo de evento.

Lamentablemente, listaPueblos es privada dentro de la clase SelecPueblo y por lo tanto dentro de cs. Pero es


mejor así, porque declararla pública y leerla desde afuera sería bastante sucio (así como la leemos podríamos
escribirla).

Hay varias formas de mejorar esto sin cometer la torpeza de declarar pública a listaPueblos. Una posibilidad es
verificar, usando cs.getDescription(), si el texto cambió (y sólo en ese caso modificar el texto del botón).

Otra, es hacer que los objetos de la clase SelecPueblo pasen a sus padres cualquier evento sobre ellos, o mejor
solamente la selección de un elemento de la lista; para eso basta agregar a la clase SelecPueblo:
public boolean handleEvent(Event e) {
if ((e.target==listaPueblos) && (e.id==Event.LIST_SELECT)) {
e.target=this;
}
return super.handleEvent(e);
}
En resumen: si el evento en el panel es una selección de la lista (tanto con mouse como moviendo la selección con
las flechas), cambio el target del evento para que indique el panel (y no la lista); si no, lo paso a la clase
antecesora.

Lo mismo podemos hacer con handleEvent para la clase DiaPartida:


public boolean handleEvent (Event e) {
if (e.target == hoy) {
elDia.setText(GetHoy());
e.target=this;
}
if (e.target == diasiguiente) {
elDia.setText(GetManana());
e.target=this;
}
if (e.target == elDia) {
e.target=this;
}
return super.handleEvent(e);
}

Esto no anda como esperaríamos! El campo de texto no se comporta muy bien...

Esto es porque el código dependiente de la plataforma procesa los eventos de mouse antes de llamar
a handleEvent, pero procesa los de teclado después de llamar a handleEvent.

Lo que significa que, en el caso del campo de texto, handleEvent (y por lo tanto ActualizaBotón) se llama antes de
modificar el texto!

Para corregir esto, deberíamos procesar nosotros las teclas presionadas (lo que podríamos aprovechar para
verificar que se presiona una tecla válida).
Cuidado! En futuras versiones de Java podría implementarse el mismo comportamiento para el mouse, y por lo tanto
tendríamos que repensar la estrategia.

Para colmo, sólo los eventos que la plataforma envía llegan a Java; por ejemplo, Motif no envía eventos de
movimiento de mouse dentro de un campo de texto... lo que significa que nunca podríamos capturar ese tipo de
eventos. Sólo el componente Canvas pasa todos los eventos.

Para simplificar, sólo actualizaremos el texto del botón cuando se presiona Enter (Event.key=10):

if ((e.target == elDia)&&(e.id==Event.KEY_PRESS)) {
if (e.key==10) e.target=this;
}

Ahora debemos modificar el método handleEvent en nuestra clase Ventana8 para que soporte todos estos eventos:

public boolean handleEvent(Event e) {


if (e.id == Event.WINDOW_DESTROY) {
if (enApplet) dispose();
else System.exit(0);
}
if ( ((e.target==dp)&&((e.id==Event.ACTION_EVENT)||(e.id==Event.KEY_PRESS)))
||((e.target==cs)&&(e.id==Event.LIST_SELECT))
||((e.target==cl)&&(e.id==Event.LIST_SELECT)) )
ActualizaBoton();
if (e.target==ok)
Activar();
return super.handleEvent(e);
}

Obviamente, procesar todas las teclas nosotros sería bastante más complicado... de todos modos, el método
en DiaPartida sería más o menos así:
if ((e.target == elDia)&&(e.id==Event.KEY_PRESS)) {
// 1- leer el contenido del campo con: elDia.getText()
// 2- modificarlo de acuerdo a la tecla presionada: e.key
// 3- poner el resultado en el campo con: elDia.setText(texto)
// 4- modificar el objeto del evento al panel con: e.target=this;
// 5- enviar el evento al objeto padre (no la clase padre),
// en este caso Ventana8, mediante: getParent().deliverEvent(e)
// 6- evitar proceso posterior del evento mediante: result(true)
}

Me ahorro explicar estos dos últimos pasos; se complica bastante todo porque hay que manejar la posición del
cursor dentro del campo de texto, etcétera. Con lo que hicimos es bastante... creo!

Y para terminar...

Bueno, sólo nos queda por definir el método Activar(). Primero vamos a llamar a ActualizaBoton() por si alguien
lo último que hizo fue entrar un texto sin presionarEnter, y dejo para otro día más tranquilo consultar un archivo o
base de datos con lo que vamos a mostrar al usuario de nuestro programa.

Por ahora simplemente vamos a mostrar una ventana con la selección y un lindo botón de OK.

Primero vamos a hacer una muy pequeña modificación a ActualizaBoton() para que nos devuelva el valor del
texto del botón (para no calcularlo de nuevo): 
String ActualizaBoton() {
StringBuffer b = new StringBuffer("Viaje: de ");
..............................................
ok.setLabel(b.toString());
}
Y ahora vamos a definir nuestro método, teniendo en cuenta que nuestro botón sólo actuará si se han entrado todos
los datos:
void Activar() {
if ( (cs.getDescription() != null) && (cl.getDescription() != null) )
// también podríamos verificar que la fecha sea válida aquí
Result8 resultado = new Result8("Resultado",ActualizaBoton());
else ok.setLabel("Especificación incompleta!");
}

Sólo nos falta definir una sencilla clase Result8 para nuestra ventanita resultado:
// archivo Result8.java, compilar con javac Result8.java
import java.awt.*;

class Result8 extends Frame {

Button r_ok;

Result8 (String titulo, String texto) { // constructor


super(titulo);
Label r_lbl = new Label(texto);
r_ok = new Button("Ok");
add("Center", r_lbl);
add("South", r_ok);
pack();
show();
}

public boolean handleEvent(Event e) {


if ((e.id == Event.WINDOW_DESTROY)||(e.target==r_ok))
dispose(); // cierra esta ventana pero no la aplicación
return super.handleEvent(e);
}
}
Noten que usé dispose y no System.exit! Esto permite cerrar sólo la ventana de resultado, y seguir usando la
aplicación hasta que se nos ocurra cerrarla mediante meta-F4, alt-F4, el menú de sistema de la ventana, la cruz de
Windows o lo que le resulte a su sistema operativo.

Espero que se haya entendido! Esta aplicación costó bastante pero en el camino hemos tenido oportunidad de
aprender unas cuantas cosas... Si logran juntar todo el código y generar las varias clases que definimos, todo tiene
que andar sobre rieles e independientemente de la plataforma.

http://www.amarillas.com/rock/java/Ejemplo8.htm

Un paréntesis de Entrada/Salida
En Java hay muchas clases para leer y escribir archivos (u otros dispositivos de E/S). Están reunidos en la
biblioteca java.io.

Vamos a empezar como siempre con un pequeño ejemplo funcional y en seguida nos meteremos en el necesario
camino de las excepciones... 

Primera Lectura
// archivo: Ejemplo9.java - compilar con "javac Ejemplo9.java", etc. etc.
import java.io.*;

public class Ejemplo9 {


public static void main(String args[]) throws FileNotFoundException,IOException {
FileInputStream fptr;
DataInputStream f;
String linea = null;
fptr = new FileInputStream("Ejemplo9.java");
f = new DataInputStream(fptr);
do {
linea = f.readLine();
if (linea!=null) System.out.println(linea);
} while (linea != null);
fptr.close();
}
}

(Caramba! ¿Qué hace ese throws ahí?)

El programa de ejemplo simplemente lee un archivo de texto y lo muestra en pantalla, algo así como el type del
DOS o el cat de Unix.

Dejemos por ahora el throws FileNotFoundException,IOException y vamos al código.


fptr = new FileInputStream("Ejemplo9.java");

La clase FileInputStream (descendiente de InputStream) nos sirve para referirnos a archivos o conexiones


(sockets) de una máquina. Podemos accederlos pasando un String como aquí, un objeto de tipo File o uno de tipo
FileDescriptor, pero en esencia es lo mismo. Al crear un objeto de este tipo estamos "abriendo" un archivo,
clásicamente hablando.

Si el archivo no existe (por ejemplo reemplacen "Ejemplo9.java" por alguna otra cosa, como "noexiste.txt"), al
ejecutarlo nos aparece un error:
C:\java\curso>java Ejemplo9
java.io.FileNotFoundException: noexiste.txt
at java.io.FileInputStream.<init>(FileInputStream.java:51)
at Ejemplo9.main(Ejemplo9.java:9)

(Caramba! ¿Dónde vi ese FileNotFoudException antes?)

Justamente, cuando el archivo al que quiero acceder no existe, Java "lanza" una excepción. Esto es, un aviso de
que algo falló y, si no se toma ninguna acción, detiene el programa.

La clase FileInputStream puede "lanzar" (throws) la excepción FileNotFoundException.

¿Cómo capturar y tratar las excepciones? En seguida; primero terminemos con nuestro programa.
f = new DataInputStream(fptr);

La clase DataInputStream nos permite leer, en forma independiente del hardware, tipos de datos de una
"corriente" (stream) que, en este caso, es un archivo. Es descendiente
de FilterInputStream e implementa DataInput, una interface.

Al crear un objeto de tipo DataInputStream lo referimos al archivo, que le pasamos como parámetro (fptr); esta
clase tiene toda una serie de métodos para leer datos en distintos formatos.

En nuestro programa usamos uno para leer líneas, que devuelve null cuando se llega al final del archivo o
un String con el contenido de la línea:
do {
linea = f.readLine();
System.out.println(linea);
} while (linea != null);
En seguida de leer la línea la imprimimos, y repetimos esto mientras no nos devuelva null.

Al final, cerramos el archivo:


fptr.close();

Tanto readLine como close pueden lanzar la excepción IOException, en caso de error de lectura o cierre de


archivo.

En realidad, podríamos no haber usado un DataInputStream y trabajar en forma más directa:


import java.io.*;

public class Ejemplo10 {


public static void main(String args[]) throws FileNotFoundException,IOException {
FileInputStream fptr;
int n;

fptr = new FileInputStream("Ejemplo9.java");


do {
n = fptr.read();
if (n!=-1) System.out.print((char)n);
} while (n!=-1);
fptr.close();
}
}
Ya que la clase FileInputStream también dispone de métodos para leer el archivo. Sólo que son unos pocos
métodos que nos permiten leer un entero por vez o un arreglo de bytes. DataInputStream tiene métodos para leer
los datos de muchas formas distintas, y en general resulta más cómodo.

Capturando excepciones
Ahora sí, vamos a ver cómo nos las arreglamos con las excepciones para que no se nos pare el programa con un
mensaje tan poco estético...

En lugar de lanzar las excepciones al intérprete, vamos a procesarlas nosotros mediante la cláusula catch: 
// Archivo: Ejemplo11.java
// Compilar con: javac Ejemplo11.java
// Ejecutar con: java Ejemplo11 <nombre_archivo>
import java.io.*;

public class Ejemplo11 {


public static void main(String args[]) {
FileInputStream fptr;
DataInputStream f;
String linea = null;

try {
fptr = new FileInputStream(args[0]);
f = new DataInputStream(fptr);
do {
linea = f.readLine();
if (linea!=null) System.out.println(linea);
} while (linea != null);
fptr.close();
}
catch (FileNotFoundException e) {
System.out.println("Hey, ese archivo no existe!\n");
}
catch (IOException e) {
System.out.println("Error de E/S!\n");
}
}
}

También hicimos un cambio para elegir el archivo a imprimir desde la línea de comandos, en lugar de entrarlo fijo,
utilizando para eso el argumento del métodomain(arg[]), que consiste en una lista de Strings con los parámetros
que se pasan en la línea a continuación de java nombre_programa. Por ejemplo, si llamamos a este programa
con:
java Ejemplo11 archi.txt otro.xxx

arg[0] contendrá "archi.txt", arg[1] contendrá "otro.xxx", y así sucesivamente.

Por supuesto, si llamamos a Ejemplo11 sin parámetros se lanzará otra excepción al intentar accederlo:
C:\java\curso>java Ejemplo11
java.lang.ArrayIndexOutOfBoundsException: 0
at Ejemplo11.main(Ejemplo11.java:10)

Pero también podríamos capturarla!

Veamos un poquito cómo es esto de capturar excepciones.

La cláusula try engloba una parte del programa donde se pueden lanzar excepciones. Si una excepción se produce,
Java busca una instrucción catch(nombre_de_la_excepción variable), y, si la encuentra, ejecuta lo que ésta
engloba. Si no encuentra un catch para esa excepción, para el programa y muestra el error que se produjo.
Por ejemplo, para evitar este último error bastaría con agregar:
catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Debe ingresar un nombre de archivo!");
System.out.println("Ej.: java Ejemplo11 pepe.txt");
}

Hay que notar que cuando se lanza una excepción el programa igual se detiene, porque el código que sigue al
lanzamiento de la excepción no se ejecuta. Veremos luego cómo se comporta esto en un objeto que fue creado por
otro, y cómo usar la instrucción finally para poner una parte de código que se ejecute pase lo que pase. 

Los applets y los archivos


Veamos cómo se comporta esta aplicación si la modificamos para usarla como applet.
/*
// ----- Archivo: Ejemplo12.java
*/

import java.io.*;
import java.awt.*;
import java.applet.*;

public class Ejemplo12 extends Applet {

public void init() {


new Ventana12();
}
}

/*
// -------- Esta clase es la que en realidad hace el trabajo
*/
class Ventana12 extends Frame {

TextArea contenido;
Button cerrar;

Ventana12() {
super("Ejemplo de E/S");
contenido = new TextArea();
cerrar = new Button("Cerrar");
CargarArchivo();
add("North",contenido);
add("South",cerrar);
pack();
show();
}

public boolean handleEvent(Event e) {


if ((e.id==Event.WINDOW_DESTROY)||(e.target==cerrar))
dispose();
return super.handleEvent(e);
}

void CargarArchivo() {
FileInputStream fptr;
DataInputStream f;
String linea = null;
try {
fptr = new FileInputStream("Ejemplo12.java");
f = new DataInputStream(fptr);
do {
linea = f.readLine();
if (linea!=null)
contenido.appendText(linea+"\n");
} while (linea != null);
fptr.close();
}
catch (FileNotFoundException e) {
contenido.appendText("Hey, ese archivo no existe!\n");
}
catch (IOException e) {
contenido.appendText("Error de E/S!\n");
}
}
}

Lo cargamos desde la página Ejemplo12.html:


<HTML>
<HEAD>
<TITLE>Ejemplo 12 - Ejemplo con archivo</TITLE>
</HEAD>
<BODY>
<applet code="Ejemplo12.class" width=170 height=150>
</applet>
</BODY>
</HTML>

Mientras corramos esto en la misma máquina, no hay problema (anda muy bien!). Pero qué pasa si intentamos
cargarlo desde la red? Para los que no tengan server html puse una copia en:

http://www.amarillas.com/rock/java/Ejemplo12.htm

El archivo no aparece! En su lugar se produce una excepción; en la línea de estado del Microsoft Internet Explorer,
por ejemplo, se lee:
exception: com.ms.applet.AppletSecurityException: security.file.read: Ejemplo12.java
Esto es debido a una restricción de seguridad de Java: NO SE PUEDEN CARGAR ARCHIVOS QUE ESTEN EN
UNA MAQUINA DISTINTA A AQUELLA DESDE LA CUAL SE CARGO EL APPLET. El applet se corre en
el cliente, e intenta acceder a un archivo local. Eso es lo que provoca la excepción (que, por supuesto, puede
detectarse con un catch y tratarse...)

Por cuestiones de seguridad, los applets son más limitados que las aplicaciones Java locales. Las políticas de
seguridad las manejan los browsers (no Java), y generalmente los límites que se imponen a los applets son:

 Un applet no puede cargar bibliotecas (libraries) ni definir métodos nativos


 No puede leer o escribir normalmente archivos en el cliente que lo carga desde otro
server
 No puede establecer conexiones de red, salvo al servidor del que proviene
 No puede arrancar programas en la máquina donde se está ejecutando
 No puede leer ciertas propiedades del sistema
 En las ventanas de los applets se indica que se trata de un applet

Sin embargo, pueden:

 Reproducir sonidos
 Pueden establecer conexiones con el servidor del que provienen
 Pueden llamar fácilmente páginas HTML desde el browser
 Pueden invocar métodos públicos de otros applets de la misma página
 Si se cargan desde la propia máquina (localmente) no tienen ninguna de las
restricciones anteriores
 Pueden seguir corriendo aunque se cambie de página en el browser
En realidad, la especificación de Java permite que los applets lean archivos en otras máquinas dando la URL
completa; sin embargo, los browsers no lo permiten. Veremos más adelante cómo intercambiar datos entre
máquinas para poder ver un archivo del server, por ejemplo.

Nuestro modesto "Editor"


Para terminar este capítulo, el siguiente applet nos permite cargar, editar y grabar archivos ascii a elección.
Podemos usar inclusive las acciones "cut & paste" del windows manager (Ctrl-C y Ctrl-V en Windows)!

Cargarlo con "appletviewer Ejemplo13" luego de haberlo compilado (o usar una página html desde un browser):

/*
// ----- Archivo: Ejemplo13.java
*/

import java.io.*;
import java.awt.*;
import java.applet.*;

public class Ejemplo13 extends Applet {

public void init() {


new Ventana13();
}
}

/*
// -------- Esta clase es la que en realidad hace el trabajo
*/

class Ventana13 extends Frame {

TextArea contenido;
Botones13 pieVentana;

Ventana13() {
super("Ejemplo de E/S");
contenido = new TextArea();
pieVentana = new Botones13();
add("North",contenido);
add("South",pieVentana);
pack();
show();
}

public boolean handleEvent(Event e) {


if ((e.id==Event.WINDOW_DESTROY)||(e.id==2003))
dispose();
if (e.id==2001) CargarArchivo(pieVentana.toString());
if (e.id==2002) GrabarArchivo(pieVentana.toString());
return super.handleEvent(e);
}

void CargarArchivo(String nombre) {


FileInputStream fptr;
DataInputStream f;
String linea = null;
contenido.setText("");
try {
fptr = new FileInputStream(nombre);
f = new DataInputStream(fptr);
do {
linea = f.readLine();
if (linea!=null) contenido.appendText(linea+"\n");
} while (linea != null);
fptr.close();
}
catch (FileNotFoundException e) {
new Error13("El archivo no existe!");
}
catch (IOException e) {
new Error13("Error leyendo archivo!");
}
}

void GrabarArchivo(String nombre) {


FileOutputStream fptr;
DataOutputStream f;
try {
fptr = new FileOutputStream(nombre);
f = new DataOutputStream(fptr);
f.writeBytes(contenido.getText());
fptr.close();
}
catch (IOException e) {
new Error13("Error grabando archivo!");
}
}
}

/*
// -------- Esta es para los botones y el nombre del archivo
*/

class Botones13 extends Panel {

TextField fname;
Button cargar;
Button grabar;
Button cerrar;

Botones13() {
setLayout(new GridLayout(1,4));
fname = new TextField();
cargar = new Button("Cargar");
grabar = new Button("Grabar");
cerrar = new Button("Cerrar");
add(new Label("Archivo:"));
add(fname);
add(cargar);
add(grabar);
add(cerrar);
}

public boolean handleEvent(Event e) {


if ((e.id==Event.ACTION_EVENT)&&(e.target==cargar))
e.id=2001;
if ((e.id==Event.ACTION_EVENT)&&(e.target==grabar))
e.id=2002;
if ((e.id==Event.ACTION_EVENT)&&(e.target==cerrar))
e.id=2003;
return super.handleEvent(e);
}

public String toString() {


return fname.getText();
}
}

/*
// ------- Para mostrar los errores...
*/

class Error13 extends Frame {

Error13(String error) {
add("Center",new Label(error));
add("South", new Button("Ok"));
pack();
show();
}

public boolean handleEvent(Event e) {


dispose();
return super.handleEvent(e);
}
}

Volviendo al AWT
Para aprender un poquito más sobre la biblioteca gráfica (AWT), vamos a modificar nuestro último programa para
usar menús.

Vamos a volver a poner todo el código (que ampliamos para usar como applet o aplicación local) marcando las
diferencias más notables:
/*
// ----- Archivo: Ejemplo14.java
*/

import java.io.*;
import java.awt.*;
import java.applet.*;

public class Ejemplo14 extends Applet {

public void init() {


new Ventana14(true); // con "true" avisamos que es applet
}

public static void main(String args[]) { // para usarlo como aplicación


Ventana14 v14 = new Ventana14(false); // con "false" avisamos que no es applet
}
}

/*
// -------- Esta clase es la que en realidad hace el trabajo
*/

class Ventana14 extends Frame {

TextArea contenido;
boolean enApplet; // para indicar si lo llamamos como applet
String nombreArchivo; // para guardar el nombre del archivo abierto
MenuItem mArchivoAbrir; // ACA ESTAN LOS ITEMS DE LOS MENUS
MenuItem mArchivoGrabar; // .
MenuItem mArchivoSalir; // .
MenuItem mEditCortar; // .
MenuItem mEditCopiar; // .
MenuItem mEditPegar; // .
MenuItem mEditTodo; // v
String clipboard; // buffer para cortar y pegar
boolean editado = false; // acá indicamos si modificamos el archivo

Ventana14(boolean enApp) {

super("Ejemplo de E/S");
enApplet = enApp; // recordamos si es applet o no

Menu menuArchivo = new Menu("&Archivo"); // CREAMOS LOS MENUS!!!


mArchivoAbrir = new MenuItem("&Abrir...");
mArchivoGrabar = new MenuItem("&Grabar...");
mArchivoSalir = new MenuItem("&Salir");
menuArchivo.add(mArchivoAbrir);
menuArchivo.add(mArchivoGrabar);
menuArchivo.add(new MenuItem("-"));
menuArchivo.add(mArchivoSalir);

Menu menuEdit = new Menu("&Edit");


mEditCortar = new MenuItem("Cor&tar");
mEditCopiar = new MenuItem("&Copiar");
mEditPegar = new MenuItem("&Pegar");
mEditTodo = new MenuItem("&Seleccionar todo");
menuEdit.add(mEditCortar);
menuEdit.add(mEditCopiar);
menuEdit.add(mEditPegar);
menuEdit.add(new MenuItem("-"));
menuEdit.add(mEditTodo);

MenuBar barraMenu = new MenuBar();


barraMenu.add(menuArchivo);
barraMenu.add(menuEdit);
setMenuBar(barraMenu);

contenido = new TextArea(); // solo pongo una ventana de texto


add("Center",contenido);
pack();
show();

clipboard = new String(""); // clipboard vacío,


mEditPegar.disable(); // nada para pegar,
mArchivoGrabar.disable(); // nada para grabar
}

public boolean handleEvent(Event e) {


if ((e.id==Event.WINDOW_DESTROY)||(e.target==mArchivoSalir)) {
if (editado) System.out.println("Pedir confirmación!\n"); // debería confirmar
// si se quiere ir sin grabar!
if (enApplet) dispose();
else System.exit(0);
}
if (e.target==mArchivoAbrir) CargarArchivo(); // acá proceso selecciones
if (e.target==mArchivoGrabar) GrabarArchivo(); // de menú
if (e.target==mEditCortar) {
clipboard = contenido.getSelectedText();
mEditPegar.enable();
contenido.replaceText("",contenido.getSelectionStart(),contenido.getSelectionEnd());
editado=true;
}
if (e.target==mEditCopiar) {
clipboard = contenido.getSelectedText();
mEditPegar.enable();
}
if (e.target==mEditPegar) {
contenido.replaceText("",contenido.getSelectionStart(),contenido.getSelectionEnd());
contenido.insertText(clipboard,contenido.getSelectionStart());
editado=true;
}
if (e.target==mEditTodo) contenido.selectAll();
if ((e.id==Event.KEY_PRESS)&&(e.target==contenido)) editado=true;
mArchivoGrabar.enable(editado);
return super.handleEvent(e);
}

void CargarArchivo() {
FileInputStream fptr;
DataInputStream f;
String linea = null;
if (editado) System.out.println("Pedir confirmación!\n");
FileDialog fd = new FileDialog(this,"Abrir...",FileDialog.LOAD); // elijo archivo
fd.show(); // usando el diálogo estándar del sistema!
nombreArchivo = fd.getFile();
try {
fptr = new FileInputStream(nombreArchivo);
f = new DataInputStream(fptr);
contenido.setText(""); // vacío la ventana antes de cargar nuevo archivo
do {
linea = f.readLine();
if (linea!=null) contenido.appendText(linea+"\n");
} while (linea != null);
fptr.close();
editado=false; // archivo nuevo -> no editado
}
catch (FileNotFoundException e) {
new Error14("El archivo no existe!");
}
catch (IOException e) {
new Error14("Error leyendo archivo!");
}
catch (NullPointerException e) {
;
}
}

void GrabarArchivo() {
FileOutputStream fptr;
DataOutputStream f;
FileDialog fd = new FileDialog(this,"Grabar...",FileDialog.SAVE); // grabo archivo
fd.setFile(nombreArchivo); // usando el diálogo estándar del sistema!
fd.show();
nombreArchivo = fd.getFile();
try {
fptr = new FileOutputStream(nombreArchivo);
f = new DataOutputStream(fptr);
f.writeBytes(contenido.getText());
fptr.close();
editado=false; // recién grabado -> no editado
}
catch (IOException e) {
new Error14("Error grabando archivo!");
}
catch (NullPointerException e) {
;
}
}
}

/*
// ------- Para mostrar los errores...
*/

class Error14 extends Frame {

Error14(String error) {
add("Center",new Label(error));
add("South", new Button("Ok"));
pack();
show();
}

public boolean handleEvent(Event e) {


dispose();
return super.handleEvent(e);
}
}

Menú a la Java
Bueno, lo primero que vamos a ver son los menús.
La barra de menú está compuesta por menúes, que a su vez están compuestos de ítems (que pueden también ser
menúes). Por ejemplo la barra de menú la declaramos con:
MenuBar barraMenu = new MenuBar();

y le agregamos los menúes Archivo y Edit (que habremos creado previamente) con:


barraMenu.add(menuArchivo);
barraMenu.add(menuEdit);

Finalmente la declaramos como EL menú de la ventana (Frame): 


setMenuBar(barraMenu);

Cada uno de los menús los declaramos previamente:


Menu menuArchivo = new Menu("&Archivo");
...
Menu menuEdit = new Menu("&Edit");

Noten que el "&" no se visualiza, sino que la letra que le sigue aparece subrayada: Archivo, Edit. Esto permite que
se pueda seleccionar el menú tanto con el mouse como con la tecla alt- o meta-, seguida de la tecla subrayada.

A su vez, el método add está presente también en la clase Menú y nos permite agregar los ítems:
mArchivoAbrir = new MenuItem("&Abrir...");
mArchivoGrabar = new MenuItem("&Grabar...");
mArchivoSalir = new MenuItem("&Salir");
menuArchivo.add(mArchivoAbrir);
menuArchivo.add(mArchivoGrabar);
menuArchivo.add(new MenuItem("-"));
menuArchivo.add(mArchivoSalir);

A estos ítems los hemos declarado como globales en la clase para usarlos luego en los eventos. Noten además que
menuArchivo.add(new MenuItem("-"));

no agrega un ítem al menú sino una línea de separación, y no necesitamos crearlo como objeto permanente.

Si miramos la arquitectura de las clases, tanto MenuBar como MenuItem descienden de MenuComponent. A su


vez, Menu desciende de MenuItem, por lo que implementa los mismos métodos y vamos a lo que decíamos antes:
un menú puede ser un ítem de otro menú, y así sucesivamente tantos subniveles de menús como queramos.

Finalmente, en nuestro manejador de eventos simplemente necesitamos verificar si se eligió un ítem probando si el
evento ocurrió sobre el ítem determinado:
if ((e.id==Event.WINDOW_DESTROY)||(e.target==mArchivoSalir)) {
if (editado) System.out.println("Pedir confirmación!\n");
if (enApplet) dispose();
else System.exit(0);
}
if (e.target==mArchivoAbrir) CargarArchivo();
................
if (e.target==mEditTodo) contenido.selectAll();
En resumen lo que hago es:

 Si eligió Archivo/Salir (o alt-F4 o lo que sea) salgo del programa


 Si eligió Archivo/Abrir, llamo al método CargarArchivo
 Si eligió Archivo/Grabar, llamo al método GrabarArchivo
 Si eligió Edit/Cortar copio el texto seleccionado a mi clipboard y borro la selección
 Si eligió Edit/Copiar sólo copio el texto seleccionado a mi clipboard
 Si eligió Edit/Pegar borro el texto seleccionado e inserto el de mi clipboard
 Si eligió Edit/Seleccionar_todo marco todo el texto

En todos los casos, si se modifica el texto del contenido lo indico poniendo editado en true; lo mismo si presiono
una tecla sobre el área de edición: 
if ((e.id==Event.KEY_PRESS)&&(e.target==contenido)) editado=true;

Un par de aclaraciones:

 getSelectionStart() y getSelectionEnd() marcan los límites del texto seleccionado (si no lo


hay, son iguales).
 getSelectedText() devuelve el texto seleccionado en el TextArea.
 replaceText() reemplaza una parte (o todo) del TextArea por un String.
 insertText() inserta un String en un lugar determinado del TextArea.
 selectAll() selecciona todo el texto del TextArea.
 MenuItem.enable() habilita un ítem de menú. Lo utilizo para habilitar Edit/Pegar sólo
luego de cortar o copiar algo a mi clipboard.
 En el caso del ítem Archivo/Grabar, lo habilito o no dependiendo de la
variable editado, utilizando la otra forma de enable: MenuItem.enable(boolean).

Diálogos
En Java disponemos de la clase Dialog para crear diálogos, es decir, ventanitas temporarias para entradas de
usuario, que dependen de otra (de hecho la clase Dialoges heredera de la clase Window).

Si bien podemos crear diálogos a medida usando la clase Frame, se supone que usar diálogos debe ser más fácil.
La realidad es que por ahora no se puede usar mucho más que los diálogos estándar (y el único que vale la pena
es FileDialog), ya que las implementaciones actuales de Java tienen un problema: en algunas plataformas el
programa que abre el diálogo sigue, en lugar de esperar que se cierre el diálogo y devuelva la respuesta.

Por eso hemos puesto solamente una indicación adonde debería haber un diálogo de confirmación:
if (editado) System.out.println("Pedir confirmación!\n");

En ese lugar deberíamos llamar por ejemplo a un diálogo que nos permita decidir por sí o por no:
if (editado) {
sino = new ConfirmarDlg(this,"Archivo modificado!");
if (sino.getResponse()==true) ....;
else ....;
}
o algo así. Esto mismo lo podemos hacer de otras maneras, por ejemplo usando threads y comunicaciones entre
procesos, pero se complica mucho para esta altura del curso. Esperemos un poco más adelante, aunque Sun me
prometió que en la versión 1.1 ya va a estar corregido (sale para fines del '96).

Por lo pronto, veamos un caso simple con la clase FileDialog: 


FileDialog fd = new FileDialog(this,"Abrir...",FileDialog.LOAD);
fd.show();
nombreArchivo = fd.getFile();

Primero declaramos una variable de tipo FileDialog, y creamos la instancia con new. Como parámetros se pasa el
padre (this, o sea "esta ventana"), el título de la ventanita de diálogo, y una constante LOAD o SAVE (son static,
por lo que se denominan directamente con el nombre de la clase y no necesariamente de una instancia) que indica
si el diálogo es para cargar o grabar un archivo (Obviamente la tarea en sí de cargar o grabar el archivo la
tenenmos que hacer nosotros, el diálogo sólo espera que elijamos un nombre).

El método show() muestra el diálogo y espera que seleccionemos y presionemos Ok o Cancel. Aquí es donde


fallan los demás diálogos ya que es programa sigue sin esperar.

Finalmente, el diálogo se cierra pero no se elimina el objeto (posiblemente está implementado usando el
método hide(), que lo oculta de la vista pero no se pierde hasta no salir del método que lo creó, donde actuaría
el recogedor de basura de la memoria). Esto hace que aunque no lo veamos podamos llamar al
métodogetFile() sobre este objeto, que nos devuelve el nombre del archivo seleccionado (o null si se presionó
Cancel).

DibuJava
Además de los componentes estándar (botones, listas, etc.), hay un componente para dibujo "libre" que nos
permite implementar cualquier otro tipo de control: la claseCanvas. Típicamente se usa para dibujar, y
corresponde a una zona rectangular dentro de una ventana.

La clase en sí no hace prácticamente nada; el programador debe definir una subclase de Canvas a la que el AWT
le envía todos los eventos de mouse y teclado. Redefiniendo los métodos gotFocus, lostFocus, keyDown, keyUp,
mouseEnter, mouseExit, mouseMove, mouseDrag, mouseDown y mouseUp, el programador puede hacer lo
que se le ocurra dentro de ese rectángulo. Vamos a hacer uso de un Canvas para generar un applet donde habrá
una zona rectangular dentro de la que, haciendo click con el mouse y moviéndolo sin soltar el botón, dibujaremos
un rectángulo dinámicamente.

Esto nos permitirá ver cómo usar un Canvas para dibujar, capturar eventos, etc. El borde tiembla un poco al
redibujar, pero ya veremos cómo evitar eso.

Canvas en acción
Primero vamos a poner, como ya se está haciendo costumbre, el código del applet (Recordar que debe cargarse
desde una página html para verlo! Aquí no creamos ninguna ventana y no podremos verlo como aplicación
standalone) y luego intentaremos explicar cómo funciona.
import java.awt.*;
import java.applet.Applet;

public class Ejemplo15 extends Applet {


public void init() {
Label label = new Label("Pique y arrastre con el mouse!");
miCanvas zonaDib = new miCanvas();
zonaDib.resize(new Dimension (200,200));
add("North", label);
add("Center", zonaDib);
resize(300,250);
}
}

class miCanvas extends Canvas {


Rectangle rectActual;

public boolean mouseDown(Event e, int x, int y) {


rectActual = new Rectangle(x, y, 0, 0);
repaint();
return false;
}

public boolean mouseDrag(Event e, int x, int y) {


rectActual.resize(x-rectActual.x, y-rectActual.y);
repaint();
return false;
}

public boolean mouseUp(Event e, int x, int y) {


rectActual.resize(x-rectActual.x, y-rectActual.y);
repaint();
return false;
}

public void paint(Graphics g) {


Dimension d = size();
g.setColor(Color.red);
g.drawRect(0, 0, d.width-1, d.height-1);
g.setColor(Color.blue);
if (rectActual != null) {
Rectangle box = cortarRect(rectActual, d);
g.drawRect(box.x, box.y, box.width-1, box.height-1);
}
}

Rectangle cortarRect(Rectangle miRect, Dimension areaDib) {


int x = miRect.x;
int y = miRect.y;
int ancho = miRect.width;
int alto = miRect.height;
if (ancho < 0) {
ancho = -ancho;
x = x - ancho + 1;
if (x < 0) {
ancho += x;
x = 0;
}
}
if (alto < 0) {
alto = -alto;
y = y - alto + 1;
if (y < 0) {
alto += y;
y = 0;
}
}

if ((x + ancho) > areaDib.width) {


ancho = areaDib.width - x;
}
if ((y + alto) > areaDib.height) {
alto = areaDib.height - y;
}

return new Rectangle(x, y, ancho, alto);


}
}

El applet-container
En primer lugar hemos tenido en cuenta que un Applet es un Panel, y por lo tanto también un Container, así que
en lugar de crear una ventana aparte simplemente le agregamos dos componentes: un Label y un Canvas. 
zonaDib.resize(new Dimension (200,200));
add("North", label);
add("Center", zonaDib);
resize(300,250);

El método rezise, sobre la clase miCanvas, nos permite redimensionar el mismo al tamaño deseado. Igualmente,
usamos resize sobre el applet para darle un tamaño adecuado. Si se modifica el tamaño de la ventana en el
appletviewer se observará un comportamiento algo extraño en cuanto al posicionamiento relativo del rectángulo y
el cartel, pero para simplificar esto bastará.

Nuestro Canvas a medida


Como no vamos a tomar ninguna acción especial al crear el canvas, no hemos definido el constructor (se utiliza el
constructor por defecto de la clase Canvas).

Simplemente hemos redefinido algunos métodos para actuar al presionar, arrastrar y soltar el mouse, para redibujar
el área de dibujo (canvas) y para recortar el rectángulo dibujado si nos vamos con el mouse fuera del espacio que
ocupa el canvas.

La variable global rectActual, de la clase Rectangle, contendrá las coordenadas del rectángulo que estamos
dibujando. El método Paint se llama automáticamente cada vez que es necesario redibujar el componente, o si
llamamos explícitamente al método repaint():

public void paint(Graphics g) {


Dimension d = size();
g.setColor(Color.red);
g.drawRect(0, 0, d.width-1, d.height-1);
g.setColor(Color.blue);
if (rectActual != null) {
Rectangle box = cortarRect(rectActual, d);
g.drawRect(box.x, box.y, box.width-1, box.height-1);
}
}

En primer lugar le asignamos a una variable d el tamaño del canvas usando el método size(), luego elegimos un
color (rojo) para dibujar un borde y dibujamos un rectángulo del tamaño del componente:
Dimension d = size();
g.setColor(Color.red);
g.drawRect(0, 0, d.width-1, d.height-1);

Dos atributos de la clase Dimension, width y height, se han cargado con el tamaño del canvas y son los que
usamos para dar el tamaño del rectángulo.

Luego, si se está dibujando un rectángulo (rectActual != null) simplemente lo recortamos (en caso de que
hayamos arrastrado el mouse fuera del canvas) y lo dibujamos.

El método que lo recorta a los límites del canvas, cortarRect, asigna a cuatro variables las coordenadas del
rectángulo (que se le pasaron como parámetro miRect al llamarlo):
int x = miRect.x;
int y = miRect.y;
int ancho = miRect.width;
int alto = miRect.height;

Si el ancho (o el alto) es negativo, simplemente lo cambia de signo y toma como coordenada x (y) de origen el otro
vértice del rectángulo, que corresponderá al x que se pasó menos el ancho y más uno (recordar que el origen de
coordenadas empieza en cero y no en uno). Si este vértice está fuera del canvas (x<0), lo pone en cero y le resta al
ancho la parte recortada (notar que ancho+=x, como x es negativo, es en realidad una resta).
if (ancho < 0) {
ancho = -ancho;
x = x - ancho + 1;
if (x < 0) {
ancho += x;
x = 0;
}
}

Si nos vamos del área de dibujo por la derecha (o por abajo), simplemente le recortamos al ancho (alto) el exceso
de modo que llegue hasta el borde del área de dibujo (que también hemos pasado al método como parámetro):
if ((x + ancho) > areaDib.width) {
ancho = areaDib.width - x;

Sólo nos quedan por ver los métodos que responden al mouse.

Cuando presionamos el mouse dentro del canvas, comenzamos la creación de un nuevo rectángulo de ancho y alto
cero que comienza en el punto en que hemos presionado el mouse, y redibujamos el canvas:
public boolean mouseDown(Event e, int x, int y) {
rectActual = new Rectangle(x, y, 0, 0);
repaint();
return false;
}

Al mover el mouse, redimensionamos el rectángulo con ancho x menos el origen de dibujo (y alto y menos el


origen de dibujo), y repintamos:
public boolean mouseDrag(Event e, int x, int y) {
rectActual.resize(x-rectActual.x, y-rectActual.y);
repaint();
return false;
}

Finalmente, al soltar el mouse, redimensionamos como antes y redibujamos:


public boolean mouseUp(Event e, int x, int y) {
rectActual.resize(x-rectActual.x, y-rectActual.y);
repaint();
return false;
}

Como no se toma ninguna medida para guardar el rectángulo dibujado, al crear uno nuevo
(reasignando rectActual a un nuevo rectángulo), el anterior se pierde.

Bueno, para empezar a dibujar no está mal.

DibuJava II
Vamos a retocar un poquito nuestro ejemplo15 para que no se borren los rectángulos cuando queremos dibujar
uno nuevo. Aprenderemos algo sobre la claseVector, perteneciente al paquete java.util.

Vectores en acción
Los vectores nos permiten hacer arreglos de cualquier tipo de objeto, y referirnos individualmente a cualquier
elemento del vector, aunque para utilizarlos (debido a que para java el vector contiene objetos genéricos)
tendremos que decirle qué clase de objeto es mediante un "cast". Vamos a ver cómo quedan nuestras
clasesEjemplo16 (ex Ejemplo15) y miCanvas:
import java.awt.*;
import java.util.*;
import java.applet.Applet;

public class Ejemplo16 extends Applet {


public void init() {
................ (esta parte no cambia)................
}
}

class miCanvas extends Canvas {


Vector v = new Vector(); // inicializamos con tamaño indeterminado
// Java se encarga de manejar la memoria necesaria!

public boolean mouseDown(Event e, int x, int y) {


v.addElement( new Rectangle(x, y, 0, 0) ); // nuevo elemento!
repaint();
return false;
}

public boolean mouseDrag(Event e, int x, int y) {


Rectangle r = (Rectangle)v.lastElement(); // cast: v son rectángulos
r.resize( x - r.x, y - r.y ); // (creé r sólo por claridad)
repaint();
return false;
}

public boolean mouseUp(Event e, int x, int y) {


Rectangle r = (Rectangle)v.lastElement(); // cast: v son rectángulos
r.resize( x - r.x, y - r.y ); // (creé r sólo por claridad)
repaint();
return false;
}

public void paint(Graphics g) {


int i; // contador de rectángulos
Dimension d = size();
g.setColor(Color.red);
g.drawRect(0, 0, d.width-1, d.height-1);
g.setColor(Color.blue);
if (v.size() > 0)
for (i=0; i<v.size(); i++) {
Rectangle box = cortarRect( (Rectangle)v.elementAt( i ), d);
g.drawRect(box.x, box.y, box.width-1, box.height-1);
}
}
........................ (el resto no cambia) ........................
}

Les sugiero utilizar un HTML que reserve espacio suficiente para ver todo el applet, como:
<HTML>
<HEAD>
<TITLE>Ejemplo 16 - Ejemplo con canvas</TITLE>
</HEAD>
<BODY>
<applet code="Ejemplo16.class" width=300 height=250>
</applet>
</BODY>
</HTML>

Veamos los pasos ahora. En primer lugar creamos una variable (global a la clase) llamada v, de clase Vector, y sin
asignarle un tamaño definido:
Vector v = new Vector();

Al crear un nuevo rectángulo agregamos un elemento (objeto) al vector mediante el método add:


v.addElement( new Rectangle(x, y, 0, 0) );

Para acceder a un atributo de un objeto del vector no basta utilizar directamente el vector, como:
v.lastElement().x

(lastElement() nos permite acceder al último elemento agregado al vector). Es necesario aclarar explícitamente
que el elemento en cuestión es un rectángulo, ya que el vector puede contener objetos de cualquier tipo. Para eso
usamos el casting:
(Rectangle)v.lastElement().x

En nuestro código original reemplazaríamos por:


(Rectangle)v.lastElement().resize( x - (Rectangle)v.lastElement().x, ......

Pero es más claro si usamos una variable local de clase Rectangle, le asignamos el mismo objeto que acabamos de
agregar al vector, y lo usamos en su lugar:
Rectangle r = (Rectangle)v.lastElement();
r.resize( x - r.x, y - r.y );
Finalmente, en el método paint() no podemos asignar el elemento hasta no saber que existe (originalmente el
vector estaba vacío!). Así que un if nos permite verificar que el tamaño del vector es mayor que cero (tiene
elementos), y un for nos permite dibujarlos uno por uno.

Se puede acceder a todos los elementos, uno por uno, mediante el método elementAt(x), que nos da el x-ésimo
elemento del vector. El método size() nos da la cantidad de elementos (el primero es el número 0, y así):
if (v.size() > 0)
for (i=0; i<v.size(); i++) {
Rectangle box = cortarRect( (Rectangle)v.elementAt( i ), d);
g.drawRect(box.x, box.y, box.width-1, box.height-1);
}

Aquí no hemos creado variables intermedias ya que igualmente es claro (eso creo...).

Flicker molesto!
Bueno, el problema que nos queda es el molesto "flicker", o sea la manera en que titila el dibujo cuando movemos el
mouse. Esto es porque cada vez que se llama apaint(), el fondo se borra y se redibuja todo el canvas.

Básicamente, la manera de evitarlo es reescribiendo el método update(), que es el que borra el fondo antes de
llamar a paint() para que no lo borre; otro método (que es el que vamos a usar) es dibujar  no sobre la pantalla sino
sobre un "buffer" gráfico, y luego copiar ese buffer sobre la pantalla (lo que es mucho más eficiente que dibujar
sobre la misma).

Para eso vamos a crear un par de objetos:

class miCanvas extends Canvas {


Vector v = new Vector();
Image imgBuff;
Graphics grafBuff;
.............................

Image es una clase abstracta, madre de todas las clases que representan imágenes gráficas. Graphics es también
abstracta y nos permite obtener un contexto en el cual dibujar.

Lo que vamos a hacer es modificar nuestro método paint() para que simplemente llame a update(), y redefinir el
método update():
public void paint(Graphics g) {
update(g);
}

El método update() es el que hará todo el trabajo y básicamente es como nuestro viejo paint() con algunos
agregados:
public void update(Graphics g) {
int i;
Dimension d = size();

if (grafBuff == null) {
imgBuff = createImage(d.width, d.height);
grafBuff = imgBuff.getGraphics();
}
grafBuff.setColor(getBackground());
grafBuff.fillRect(0, 0, d.width, d.height);
grafBuff.setColor(Color.red);
grafBuff.drawRect(0, 0, d.width-1, d.height-1);
grafBuff.setColor(Color.blue);
if (v.size() > 0) for (i=0; i<v.size(); i++) {
Rectangle box = cortarRect((Rectangle)v.elementAt(i), d);
grafBuff.drawRect(box.x, box.y, box.width-1, box.height-1);
}
g.drawImage(imgBuff, 0, 0, this);
}

En negrita hemos indicado los agregados.

Si no está creado todavía (grafBuff==null), creamos nuestro buffer de dibujo. Para crear dicho buffer gráfico (de
clase Graphics), primero creamos una imagen que en este caso tiene las mismas dimensiones que el canvas
(d.width x d.height), y luego asignamos a grafBuff el contexto de dicha imagen mediante el métodogetGraphics().
Imagínense que con createImage(...) crean una "pantalla virtual", y getGraphics() nos da una forma de acceder a
esa pantalla como si fuera real.

Utilizando dicho contexto, elegimos como color el mismo color de fondo del applet (getBackground()) y dibujamos un
rectángulo lleno (fillRect(...)), borrando así cualquier cosa que hubiera estado dibujada.

En itálica hemos indicado las modificaciones a nuestro método anterior. Simplemente, en lugar de usar el contexto
de la pantalla (el parámetro g del método), dibujamos sobre nuestro contexto-pantalla virtual.

Finalmente, y para poder visualizar nuestro dibujo, usamos el método drawImage sobre el contexto de la pantalla
real (g), que copia nuestro contexto imgBuff en las coordenadas (0,0) sobre la pantalla. Se hace también referencia
al canvas (...this): el cuarto parámetro de drawImage es un objeto de clase ImageObserver, una interface que sirve
para que el objeto dentro del cual se dibuja reciba mensajes asincrónicos que le indican cómo está siendo
construida la imagen, y cuándo está lista.

Animate!
Si bien puede ser un poco más complejo de entender que un dibujo directo sobre la pantalla, notarán que la
implementación es directa y no trae ningún problema. Esta misma aproximación puede utilizarse para crear
animaciones.
En este ejemplo, para manejar la ejecución cuadro a cuadro de la animación, usamos Threads. No se preocupen
por eso, lo veremos pronto. Únicamente tengan en cuenta que nuestro applet debe implementar la clase  runnable, y
el thread se encarga de ejecutar el método run() que simplemente llama a repaint() y espera 100 milisegundos entre
cuadro y cuadro.

El trabajo de cálculo y dibujo lo hace update(). Se los dejo para que lo estudien; no es nada complicado y también
usa doble buffering (como el ejemplo anterior).

import java.awt.*;
import java.util.*;
import java.applet.Applet;

public class Ejemplo18 extends Applet implements Runnable {

Thread animador;
Image imgBuff;
Graphics grafBuff;
double ang = 0.0;

public void init() {


resize(new Dimension (200,200));
}

public void start() {


if (animador == null) animador = new Thread(this);
animador.start();
}

public void run() {


while (Thread.currentThread() == animador) {
repaint();
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
break;
}
}
}

public void update(Graphics g) {


int i;
int dx, dy;

Dimension d = size();

if (grafBuff == null) {
imgBuff = createImage(d.width, d.height);
grafBuff = imgBuff.getGraphics();
}
grafBuff.setColor(getBackground());
grafBuff.fillRect(0, 0, d.width, d.height);
grafBuff.setColor(Color.red);
grafBuff.drawRect(0, 0, d.width-1, d.height-1);

grafBuff.setColor(Color.blue);
dx = (int)(50 * Math.abs(Math.cos(ang)));
dy = (int)(50 * Math.abs(Math.sin(ang)));
ang = ang + 0.1;
if (ang>2*Math.PI) ang = 0.0;
grafBuff.drawRect(100-dx, 100-dy, 2*dx, 2*dy);

g.drawImage(imgBuff, 0, 0, this);
}
}

Java en hebras
La clase anterior usamos, en el último ejemplo, un concepto al que vamos a dedicar ahora nuestra atención:
los threads.

La traducción literal de thread es hilo o hebra, y se utiliza también para referirse al hilo de un discurso. El concepto
de threads en los ambientes y sistemas operativos es un poco complejo de explicar pero sencillo de entender:
independientemente del sistema elegido, puede pensarse que un thread es algo así como el lugar de ejecución de
un programa.

En la mayoría de los programas que hemos visto, hemos usado un solo thread; es decir que un programa comienza
y su ejecución sigue un camino único: como un monólogo.

Java es multithreading. Esto significa algo así como que tiene capacidad de diálogo, y más aún: puede ejecutar
muchos threads en paralelo, como si tratáramos de una conversación múltiple y simultánea.

No confundir aquí multithreading con la capacidad de ejecutar varios programas a la vez. Esta es una posibilidad,
pero también un mismo programa puede utilizar varios threads ("caminos de ejecución"?) simultáneamente.

Esto, por supuesto, depende fundamentalmente de la capacidad del sistema operativo para soportar multithreading,
y por esto Java no puede ejecutarse (al menos en forma completa) en sistemas que no lo soporten.

El uso de threads nos permite, por ejemplo, ejecutar simultáneamente varios programas que interactúen entre ellos;
o, también, que un programa, mientras por ejemplo actualiza la pantalla, simultáneamente realice una serie de
cálculos sin tener que hacer esperar el usuario.

Una forma sencilla de verlo es imaginar que tenemos un grupo de microprocesadores que pueden ejecutar, cada
uno, un solo thread; y nosotros asignamos programas (o partes de programas) a cada uno de ellos. Además,
podemos imaginar que esos microprocesadores comparten una memoria común y recursos comunes, de lo que
surgirá una serie de problemas importantes a tener en cuenta cuando se usan threads.

Los pasos básicos

Hay tres cosas a tener en cuenta para usar threads en un programa:

 La clase que queremos asignar a un thread debe implementar la interface Runnable.


 Debemos crear una variable (instancia) del tipo Thread, que nos permitirán acceder y manejar el thread. En
los applets, en el método start() simplemente crearemos el thread (y, posiblemente, lo pondremos a ejecutar)
 Y por último tenemos que crear un método run() que es el que ejecuta el código del programa propiamente
dicho.

La interface Runnable, simplemente definida como:


public interface java.lang.Runnable
{
// Methods
public abstract void run();
}

le asegura al compilador que nuestra clase (la que utilizará el thread para ejecutarse) dispone de método run().

Vamos a ver un par de ejemplos, primero una aplicación standalone y luego un applet.

Reunión de amigos
El siguiente ejemplo (Ejemplo19.java) usa threads para activar simultáneamente tres objetos de la misma clase,
que comparten los recursos del procesador peleándose para escribir a la pantalla.
class Ejemplo19 {

public static void main(String argv[])


throws InterruptedException {
Thread Juan = new Thread (new Amigo("Juan"));
Thread Luis = new Thread (new Amigo("Luis"));
Thread Nora = new Thread (new Amigo("Nora"));
Juan.start();
Luis.start();
Nora.start();
Juan.join();
Luis.join();
Nora.join();
}
}

class Amigo implements Runnable {

String mensaje;

public Amigo(String nombre) {


mensaje = "Hola, soy "+nombre+" y este es mi mensaje ";
}

public void run() {


for (int i=1; i<6; i++) {
String msg = mensaje+i;
System.out.println(msg);
}
}

Como siempre, compilarlo con javac Ejemplo19.java y ejecutarlo con java Ejemplo19.

En un sistema operativo  la salida será más o menos así:


Hola, soy Juan y este es mi mensaje 1
Hola, soy Juan y este es mi mensaje 2
Hola, soy Luis y este es mi mensaje 1
Hola, soy Luis y este es mi mensaje 2
Hola, soy Nora y este es mi mensaje 1
Hola, soy Nora y este es mi mensaje 2
Hola, soy Nora y este es mi mensaje 3
Hola, soy Juan y este es mi mensaje 3
...........etc.
un sistema operativo practico Caso típicos son Unix o Windows : cada tarea utiliza una parte del tiempo del
procesador, y luego lo libera para que puedan ejecutarse otras tareas (otros threads). Por eso se mezclan los
mensajes de salida. Si el sistema operativo es no preemptivo, el procesador no se libera hasta que no termina con el
thread actual, y por lo tanto la salida sería así:
Hola, soy Juan y este es mi mensaje 1
Hola, soy Juan y este es mi mensaje 2
Hola, soy Juan y este es mi mensaje 3
Hola, soy Juan y este es mi mensaje 4
Hola, soy Juan y este es mi mensaje 5
Hola, soy Luis y este es mi mensaje 1
Hola, soy Luis y este es mi mensaje 2
...........etc.

Si ustedes están utilizando un sistema operativo no preemptivo, deben explícitamente indicarle al procesador
cúando puede ejecutar (dar paso) a otra tarea; para eso simplemente modifiquen el método run():
public void run() {
for (int i=1; i<6; i++) {
String msg = mensaje+i;
System.out.println(msg);
Thread.yield();
}
}

En este ejemplo, tanto en sistemas preemptivos como no preemptivos la salida será:


Hola, soy Juan y este es mi mensaje 1
Hola, soy Luis y este es mi mensaje 1
Hola, soy Nora y este es mi mensaje 1
Hola, soy Juan y este es mi mensaje 2
Hola, soy Luis y este es mi mensaje 2
Hola, soy Nora y este es mi mensaje 2
Hola, soy Juan y este es mi mensaje 3
Hola, soy Luis y este es mi mensaje 3
...........etc.

Esto es porque en seguida de imprimir estamos liberando al procesador para que pase a otro thread (si hay alguno
esperando). Noten la diferencia con el primer caso, sin usar yield(), para sistemas preemptivos: el procesador
reparte su trabajo en forma (aparentemente) impredecible, por eso el orden de los mensajes no será el mismo en
cualquier máquina o sistema operativo.

Ya lo vimos funcionar, pero sería bueno que lo entendamos! Por eso, vamos paso a paso.

Creando Threads
Thread es una clase básica en Java, que implementa la interface Runnable y dispone de unos cuantos métodos por
defecto. Lo importante a tener en cuenta que, para usar Threads, debemos crearlas como instancias y ponerlas a
"andar": 
Thread Juan = new Thread (new Amigo("Juan"));
..............
Juan.start();
..............
Juan.join();

Un thread tiene cuatro estados posibles:

creado: ha sido creado mediante new(), pero no se ha puesto en marcha todavía.

activo: está en ejecución, ya sea porque arrancó con start() o fue "despertado" con resume().
dormido: ha sido suspendida su ejecución momentáneamente mediante wait(), sleep() o suspend().

muerto: se ha detenido definitivamente, ya sea porque se terminó el programa o mediante el llamado a stop().

En este ejemplo hemos creado un thread asignándole simultáneamente un objeto que lo utiliza (new
Amigo("Juan")), y seguidamente lo hemos activado, llamando al método start(). Este método se encarga de
inicializar el thread y, finalmente, llamar al método run() que hemos implementado.

De este modo, todo ocurre como si los métodos run() de cada objeto se ejecutaran en paralelo, concurrentemente.
La forma de manejar esto depende del sistema operativo.

El método join() que llamamos al final hace que el programa principal espere hasta que este thread esté "muerto"
(finalizada su ejecución). Este método puede disparar la excepción InterruptedException, por lo que lo hemos
tenido en cuenta en el encabezamiento de la clase.

En nuestro ejemplo, simplemente a cada instancia de Amigo(...) que creamos la hemos ligado a un thread y puesto
a andar. Corren todas en paralelo hasta que mueren de muerte natural, y también el programa principal acaba.

Cuando usamos Thread.yield() (que en rigor debería ser Thread.currentThread().yield(), pero siendo algo de uso


muy común los desarrolladores de Java lo han simplificado), simplemente el thread actual le permite al procesador
dedicarse a otro (si es que hay alguno deseando utilizar sus servicios).

La clase Amigo() es muy simple y con lo que hemos visto hasta ahora no creo que tengamos que explicar nada
más.

Y los applets...?
También podemos usar estos conceptos en los applets. Veamos un ejemplo para terminar la clase de hoy, muy
similar al anterior, donde tres contadores cuentan (en un sistema preemptivo) en forma simultánea. Recuerden
crear una página HTML con el tag
<applet code="Ejemplo20.class" width=300 height=100></applet>

para poder verlo en acción con el appletviewer o su browser favorito (que desde ya supongo que soporta Java! ;-)

El programa es extremandamente sencillo, y pueden verlo en acción si lo desean cargando via Internet la página:

http://www.amarillas.com/rock/java/Ejemplo20.htm 
// Ejemplo de applet que usa multithreading
import java.awt.*;
import java.applet.*;

public class Ejemplo20 extends Applet {

TextField tfa,tfb,tfc;

public void init() {


setLayout(new GridLayout(3,2));
tfa = new TextField("0");
tfb = new TextField("0");
tfc = new TextField("0");
add(new Label("Contador A"));
add(tfa);
add(new Label("Contador B"));
add(tfb);
add(new Label("Contador B"));
add(tfc);
}

public void start() {


Thread A = new Thread (new Counter(tfa));
Thread B = new Thread (new Counter(tfb));
Thread C = new Thread (new Counter(tfc));
A.start();
B.start();
C.start();
}

class Counter implements Runnable {

TextField texto;
String s;

public Counter(TextField txtf) {


texto = txtf;
}

public void run() {


for (int i=0; i<1000; i++) {
texto.setText(s.valueOf(i));
}
}

La liebre y la tortuga (y el guepardo)


Java dispone de un mecanismo de prioridades para los threads, de modo de poder asignar más tiempo de CPU a un
thread que a otro. Típicamente se asigna una prioridad de 1 a 10 (10 es la mayor prioridad) mediante setPriority,
como en el ejemplo que sigue:

public class Ejemplo21 {


static Animal tortuga;

static Animal liebre;

static Animal guepardo;

public static void main(String argv[])

throws InterruptedException {

tortuga = new Animal(2, "T");

liebre = new Animal(3, "L");

guepardo = new Animal(4, "G");

tortuga.start();

liebre.start();

guepardo.start();

tortuga.join();

liebre.join();

guepardo.join();

}
class Animal extends Thread {

String nombre;

public Animal(int prioridad, String nombre) {

this.nombre = nombre;

setPriority(prioridad);

public void run() {

for (int x = 0; x < 30; x++) {

System.out.print( nombre );

yield();

System.out.println("\nLlega "+nombre );

La salida de este programa, ejecutado con java Ejemplo21, es por ejemplo:


C:\java\curso>java Ejemplo21

GGGGGGGGGGGGGGGGGGGGGGGGGGGGGG

Llega G

LTLLLLLLLLLLLLLLLLLLLLLLLLLLLLL

Llega L

TTTTTTTTTTTTTTTTTTTTTTTTTTTTT

Llega T

como se ve, a pesar de haber arrancado antes la tortuga, casi todo el tiempo de CPU lo usa primero el Guepardo,
luego la Liebre (aunque algo queda para la pobre tortuga, como se ve en la T marcada), y finalmente para la
Tortuga. No todas las corridas ni todos los sistemas dan igual salida, ya que ésta depende de la carga del
procesador y de la implementación de Java particular.

Este programa simplemente crea tres animales (clase Animal), asigna un thread a cada uno y los ejecuta. Este
ejemplo está hecho en base a uno del libro "Programación Java" de Macary y Nicolas.

Sincronicemos los relojes


Un problema básico del multithreading es cuando varios programas (o, para el caso, varios threads) acceden a los
mismos datos: ¿cómo sabemos si uno de ellos no los modifica mientras los está usando otro?.

Veamos un ejemplo, donde suponemos que varios threads usan la variable valorImportante:


if (valorImportante > 0 ) {

..... algo se procesa acá ........

valorImportante = valorImportante - 1;

..... sigue.....................

¿Cómo nos aseguramos que valorImportante no cambió entre el if y la línea resaltada? Otros threads pueden
haberlo modificado mientras tanto. Asimismo, puede suceder que dos threads estén ejecutando la misma porción
de código, y se pierda uno de los decrementos. Imaginen algo así:

(antes) valorImportante = 10

(thread 1) lee valorImportante = 10

(thread 2) lee valorImportante = 10

(thread 1) 10 -1 = 9

(thread 2) 10 -1 = 9

(thread 2) asigna 9 a valorImportante

(thread 1) asigna 9 a valorImportante

(después) valorImportante = 9

Como vemos, a pesar de haber restado dos veces, hemos perdido una de las restas. Aunque usemos -= en vez de la
resta es lo mismo, porque el código igualmente se resuelve en varios pasos (varias operaciones atómicas).
Para evitar esto, Java nos brinda la palabra clave Synchronized, que bloquea el acceso a una variable a todos los
threads menos el que lo está usando.

Vamos a ver un caso específico; se trata de dos contadores que usan el mismo sumador para sumar de a uno una
cantidad a. Supuestamente entre los dos deben llevar el sumador (a) hasta 20000.

// Archivo Ejemplo22.java, compilar con javac Ejemplo22.java, ejecutar con java Ejemplo22

public class Ejemplo22 {

public static void main(String argv[]) {

Sumador A = new Sumador(); // un único sumador

Contador C1 = new Contador(A); // dos threads que lo usan...

Contador C2 = new Contador(A); // ...para sumar

C1.start();

C2.start();

try {

C1.join();

C2.join();

catch (Exception e) {

System.out.println(e);
}

class Contador extends Thread {

Sumador s;

Contador (Sumador sumador) {

s = sumador; // le asigno un sumador a usar

public void run() {

s.sumar(); // ejecuto la suma

class Sumador {

int a = 0;
public void sumar() {

for (int i=0; i<10000; i++ ) {

if ( (i % 5000) == 0 ) { // "%" da el resto de la división:

System.out.println(a); // imprimo cada 5000

a += 1;

System.out.println(a); // imprimo el final

Ejecutando esto nos da más o menos así (cada corrida es diferente, dependiendo de cómo se "chocan" los threads y
la carga de la CPU):

C:\java\curso>java Ejemplo22

87

8926
10434

14159

17855

Esto se debe justamente a lo que explicábamos al principio: a veces los dos threads intentan ejecutar a +=
1 simultáneamente, con lo que algunos incrementos se pierden.

Podemos solucionar esto modificando el método run(): 

public void run() {

synchronized (s) {

s.sumar();

Con esto, sólo a uno de los dos threads se les permite ejecutar s.sumar() por vez, y se evita el problema. Por
supuesto, el otro thread queda esperando, por lo que más vale no utilizar esto con métodos muy largos ya que el
programa se puede poner lento o aún bloquearse.

La salida ahora será:


C:\java\curso>java Ejemplo22

0 <

5000 < primer thread

10000 <

10000 (

15000 ( segundo thread

20000 (

Lo mismo logramos (y en forma más correcta) declarando como synchronized al método sumar():

public synchronized void sumar() { .............

Esto es mejor porque la clase que llama a sumar() no necesita saber que tiene que sincronizar el objeto antes de
llamar al método, y si otros objetos (en otros threads) lo llaman, no necesitamos preocuparnos.

Más sincronización
Otra manera de sincronizar el acceso de los threads a los métodos, es lograr que éstos se pongan de acuerdo entre
sí, esperando uno hasta que otro realizó alguna tarea dada. Para esto se usan los métodos wait() y notify(). Cuando
un thread llama a wait() en un método de un objeto dado, queda detenido hasta que otro thread llame a notify() en
algún método del mismo objeto.
Por ejemplo, vamos a suponer cuatro empleados que se encuentran con su jefe y lo saludan, pero sólo luego de que
éste los salude primero.

public class Ejemplo23 {

public static void main(String argv[]) {

Saludo hola = new Saludo();

Personal pablo = new Personal(hola, "Pablo", false);

Personal luis = new Personal(hola, "Luis", false);

Personal andrea = new Personal(hola, "Andrea", false);

Personal pedro = new Personal(hola, "Pedro", false);

Personal jefe = new Personal(hola, "JEFE", true);

pablo.start();

luis.start();

andrea.start();

pedro.start();

jefe.start();

try {

pablo.join();

luis.join();
andrea.join();

pedro.join();

jefe.join();

catch (Exception e) {

System.out.println(e);

class Saludo {

synchronized void esperarJefe(String empleado) {

try {

wait();

System.out.println(empleado+"> Buenos dias jefe!");

catch (InterruptedException e) {

System.out.println(e.toString());
}

synchronized void saludoJefe() {

System.out.println("JEFE> Buenos dias!");

notifyAll();

class Personal extends Thread {

String nombre;

Saludo saludo;

boolean esJefe;

Personal (Saludo s, String n, boolean j) {

nombre = n;

saludo = s;

esJefe = j;
}

public void run() {

System.out.println("("+nombre+" llega)");

if (esJefe)

saludo.saludoJefe();

else

saludo.esperarJefe(nombre);

Usé notifyAll() en lugar de notify(), porque en el segundo caso sólo se notificaría al primer thread (el primer
empleado en llegar) y no a los demás, que se quedarían en el wait().

Como se ve en la salida, a pesar de que los empleados están en condiciones de saludar, no lo hacen hasta que no
llega el jefe: 

C:\java\curso>java Ejemplo23

(Pablo llega)

(Luis llega)
(Andrea llega)

(Pedro llega)

(JEFE llega)

JEFE> Buenos dias!

Luis> Buenos dias jefe!

Pedro> Buenos dias jefe!

Andrea> Buenos dias jefe!

Pablo> Buenos dias jefe!

Multimedia
Java permite cargar y visualizar archivos GIF o JPEG de imagen y AU de audio (solamente en mono, 8 bits,
8000Hz de muestreo).

Para el caso del sonido, un archivo de audio se carga mediante un objeto de la clase AudioClip, mediante el
método getAudioClip(URL, archivo), se ejecuta con los métodos play() o loop() y se detiene con stop().

Noten esto! Si bien dijimos que un applet no puede acceder al disco de la máquina cliente, SI puede leer archivos
del server desde donde se cargó. Por lo tanto, pasándole el URL de la máquina desde donde se cargó el applet,
podemos leer cualquier tipo de archivo a través de la red.
La forma más segura de indicar dicho URL es mediante el método getDocumentBase(), que nos da el URL
adecuado.

Por ejemplo, puedo cargar y reproducir audio con sólo dos líneas:

........

AudioClip sonido = getAudioClip( getDocumentBase(), "sonido.au" );

sonido.play();

.........

Por otra parte, una foto puede cargarse mediante un objeto de clase Image mediante el método getImage(URL,
archivo). Luego la mostramos en un objetoGraphics correspondiente al applet (o al área de dibujo)
mediante drawImage(imagen, x, y, observador). Observador es un objeto que implementa la interface
ImageObserver; los applets, por descender de Component (que implementa dicha interface) también la
implementan. Típicamente, la imagen se visualiza en el método paint(...) del applet:

.............

algunMetodo(...) {

..........

Image imagen = getImage(getDocumentBase(), "imagen.gif");

..........
}

...........

public void paint(Graphics g) {

g.drawImage(imagen, xOffset, yOffset, this); // "this" representa al applet

...............

El problema con las imágenes es asegurarse que fue cargada antes de mostrarla. Para eso se utiliza
un MediaTracker (también debería servir para los archivos de audio, pero en esta versión aún no está
implementado).

Mediante addImage( imagen, grupo) se agrega una imagen a la lista del MediaTracker, y hay métodos para
esperar que sea cargada (como waitForAll() owaitForID(grupo)), para verificar que se haya cargado
correctamente (como checkAll(), checkID(grupo), isErrorAny()...), etcétera.

El siguiente applet utiliza estos conceptos para cargar una imagen y un archivo de audio y mostrarlos:

// Ejemplo24.java

import java.awt.*;

import java.applet.*;
public class Ejemplo24 extends Applet {

MediaTracker supervisor;

String archImagen, archAudio;

Image imagen;

AudioClip audio;

Label titulo;

Panel cuadro;

public void init() {

supervisor = new MediaTracker(this);

archImagen = "javacero.gif";

archAudio = "tada.au";

// carga imagen

imagen = getImage(getDocumentBase(), archImagen);

supervisor.addImage(imagen,0);

try {

supervisor.waitForID(0); // espero que se cargue

}
catch (InterruptedException e) {

System.out.println("Error cargando imagen!");

showStatus("Imagen cargada");

// carga sonido

audio = getAudioClip(getDocumentBase(), archAudio);

// arma layout

setLayout(new BorderLayout());

titulo = new Label(archImagen);

setFont(new Font("helvetica", Font.BOLD, 18));

add("South", titulo);

public void start() {

repaint();

audio.play();

}
public void paint(Graphics g) {

if (supervisor.isErrorAny()) {

g.setColor(Color.black);

g.fillRect(0, 0, size().width, size().height);

return;

g.drawImage(imagen, 0, 0, this);

Para visualizarlo, como siempre, creamos un HTML:

<HTML>

<HEAD>

<TITLE>Ejemplo 24 - Ejemplo Multimedia</TITLE>

</HEAD>

<BODY>
<applet code="Ejemplo24.class" width=150 height=200>

</applet>

</BODY>

</HTML>

Parametrizando un applet
Vamos a aprovechar este ejemplo, modificándolo un poco para indicarle desde el HTML qué archivos debe cargar,
mediante parámetros. Nuestro HTML modificado será: 

<HTML>

<HEAD>

<TITLE>Ejemplo 24 - Multimedia</TITLE>

</HEAD>

<BODY>

<applet code="Ejemplo24.class" width=150 height=200>

<param name="imagen" value="javacero.gif">


<param name="sonido" value="tada.au">

</applet>

</BODY>

</HTML>

Para leer estos parámetros desde el applet, usamos el método getParameter(nombreParámetro), así que
podemos modificar nuestro applet simplemente modificando un par de líneas:

archImagen = getParameter("imagen");

archAudio = getParameter("sonido");

Voilá! Pueden probar de cargar este applet en http://www.amarillas.com/rock/java/Ejemplo24.htm.

De esta manera podemos pasar cualquier valor como parámetro para un applet, haciéndolo más flexible.

Y esto es todo por hoy!

Con esto hemos visto una gran parte de lo que es Java. No hemos profundizado demasiado en cada punto, pero
hemos hecho ejemplos que funcionan para ilustrar cada cosa.
Sin embargo, hemos dejado un punto importante y muy fuerte de Java, que es el de las comunicaciones entre
aplicaciones y, especialmente, el uso de sockets y la programación de aplicaciones cliente-servidor.

por la Red
Es muy sencillo acceder a archivos en la red utilizando Java. El paquete java.net dispone de varias clases e
interfaces a tal efecto.

En primer lugar, la clase URL nos permite definir un recurso en la red de varias maneras, por ejemplo:

URL url1 = new URL ("http://www.rockar.com.ar/index.html");

URL url2 = new URL ("http", "www.rockar.com.ar", "sbits.htm");

Por otra parte, podemos establecer una conexión a un URL dado mediante openConnection:

URLConnection conexion = url.openConnection();


Una vez lograda la conexión, podemos leer y escribir datos utilizando streams (corrientes de datos), como en el
caso de manejo de archivos comunes (ver capítulo X). Un DataInputStream nos permite leer datos que llegan a
través de la red, y un DataOutputStream nos permite enviar datos al host.

Por ejemplo:

DataInputStream datos = new DataInputStream( corrienteEntrada );

En nuestro caso, la corriente de entrada de datos proviene de la conexión al URL. El


método getInputStream() del objeto URLConnection nos provee tal corriente:

DataInputStream datos = new DataInputStream(conex.getInputStream())

De este modo podemos escribir un pequeño programa para, por ejemplo, leer una página HTML desde una
dirección arbitraria de internet. El programa, luego de compilarse mediante javac Ejemplo25.java, se ejecuta
con java Ejemplo25 <url>; por ejemplo: java Ejemplo25

http://www.rockar.com.ar/index.html.
import java.io.*;

import java.net.*;

public class Ejemplo25 {

public static void main(String argv[]) {

String s;

try {

URL url = new URL (argv[0]);

URLConnection conex = url.openConnection();

System.out.println("Cargando "+argv[0]);

DataInputStream datos = new DataInputStream(conex.getInputStream());

do {

s = datos.readLine();

if (s != null) System.out.println(s);

} while (s != null);

catch (ArrayIndexOutOfBoundsException e) {

System.out.println("Sintaxis: java Ejemplo25 <url>");


}

catch (UnknownHostException e) {

System.out.println("El host no existe o no responde");

catch (Exception e) {

e.printStackTrace();

Este programa muestra el HTML como texto en la pantalla, pero podríamos grabarlo a un archivo para guardarlo.
Inclusive, podríamos procesarlo a medida que lo recibimos, identificar los tags <A HREF=url>, guardarlos en un
vector, y seguidamente conectarnos y bajar los links que figuran en la página original hasta bajar un site completo.

Noten que esto no sólo sirve para establecer conexiones a páginas HTML. En realidad, un URL puede referirse
también a otros protocolos, como gopher, ftp, etcétera; si bien según la implementación de Java puede haber
problemas para conectarse a algunos tipos de URL.

Para ver los tipos de URL posibles les recomiendo leer la página:

http://www.ncsa.uiuc.edu/demoweb/url-primer.html
Los Sockets
Los sockets (zócalos, referido a los enchufes de conexión de cables) son mecanismos de comunicación entre
programas a través de una red TCP/IP. De hecho, al establecer una conexión via Internet estamos utilizando
sockets: los sockets realizan la interfase entre la aplicación y el protocolo TCP/IP.

Dichos mecanismos pueden tener lugar dentro de la misma máquina o a través de una red. Se usan en forma
cliente-servidor: cuando un cliente y un servidor establecen una conexión, lo hacen a través de un socket. Java
proporciona para esto las clases ServerSocket y Socket.

Los sockets tienen asociado un port (puerto). En general, las conexiones via internet pueden establecer un puerto
particular (por ejemplo, en http://www.rockar.com.ar:80/index.html el puerto es el 80). Esto casi nunca se
especifica porque ya hay definidos puertos por defecto para distintos protocolos: 20 para ftp-data, 21 para ftp, 79
para finger, etc. Algunos servers pueden definir otros puertos, e inclusive pueden utilizarse puertos disponibles
para establecer conexiones especiales.

Justamente, una de las formas de crear un objeto de la clase URL permite especificar también el puerto:

URL url3 = new URL ("http", "www.rockar.com.ar", 80,"sbits.htm");


Para establecer una conexión a través de un socket, tenemos que programar por un lado el servidor y por otro los
clientes.

En el servidor, creamos un objeto de la clase ServerSocket y luego esperamos algún cliente (de clase Socket)
mediante el método accept(): 

ServerSocket conexion = new ServerSocket(5000); // 5000 es el puerto en este caso

Socket cliente = conexion.accept(); // espero al cliente

Desde el punto de vista del cliente, necesitamos un Socket al que le indiquemos la dirección del servidor y el
número de puerto a usar:

Socket conexion = new Socket ( direccion, 5000 );

Una vez establecida la conexión, podemos intercambiar datos usando streams como en el ejemplo anterior. Como
la clase URLConnection, la clase Socket dispone de métodos getInputStream y getOutputStream que nos dan
respectivamente un InputStream y un OutputStream a través de los cuales transferir los datos.

Un servidor atento
Vamos a crear un servidor Ejemplo26a.java (que podemos correr en una ventana) que atenderá a un cliente de la
misma máquina (lo vamos a correr en otra ventana). Para hacerlo simple, el servidor sólo le enviará un mensaje al
cliente y éste terminará la conexión. El servidor quedará entonces disponible para otro cliente.

Es importante notar que, para que el socket funcione, los servicios TCP/IP deben estar activos (aunque ambos
programas corran en la misma máquina). Los usuarios de Windows asegúrense que haya una conexión TCP/IP
activa, ya sea a una red local o a Internet.

El servidor correrá "para siempre", así que para detenerlo presionen control-C.

// servidor

import java.io.*;

import java.net.*;

public class Ejemplo26a {

public static void main(String argv[]) {

ServerSocket servidor;

Socket cliente;

int numCliente = 0;

try {

servidor = new ServerSocket(5000);

do {
numCliente++;

cliente = servidor.accept();

System.out.println("Llega el cliente "+numCliente);

PrintStream ps = new PrintStream(cliente.getOutputStream());

ps.println("Usted es mi cliente "+numCliente);

cliente.close();

} while (true);

catch (Exception e) {

e.printStackTrace();

Utilizamos un PrintStream para enviar los datos al cliente, ya que es sencillo de utilizar para mandar Strings. El
método PrintStream.println maneja los datos comoSystem.out.println, simplemente hay que indicarle el stream
a través del cual mandarlos al crearlo (en este caso, el OutputStream del cliente, que obtenemos
concliente.getOutputStream()). 

El cliente satisfecho
Ahora vamos a crear la clase cliente, Ejemplo26b.java. El cliente simplemente establece la conexión, lee a través
de un DataInputStream (mediante el métodoreadLine()) lo que el servidor le manda, lo muestra y corta.

// cliente:

import java.io.*;

import java.net.*;

public class Ejemplo26b {

public static void main(String argv[]) {

InetAddress direccion;

Socket servidor;

int numCliente = 0;

try {

direccion = InetAddress.getLocalHost(); // direccion local

servidor = new Socket(direccion, 5000);

DataInputStream datos =

new DataInputStream(servidor.getInputStream());

System.out.println( datos.readLine() );

servidor.close();
}

catch (Exception e) {

e.printStackTrace();

para probar esto, asegúrense que los servicios TCP/IP estén activos, corran java Ejemplo26a en una ventana y
corran varias veces java Ejemplo26b en otra. Las salidas serán más o menos así: 

Ventana servidor:

C:\java\curso>java Ejemplo26a

Llega el cliente 1

Llega el cliente 2

Llega el cliente 3

(----- cortar con control-C -----)

Ventana cliente:
C:\java\curso>java Ejemplo26b

Usted es mi cliente 1

C:\java\curso>java Ejemplo26b

Usted es mi cliente 2

C:\java\curso>java Ejemplo26b

Usted es mi cliente 3

(----- aquí cerramos el servidor -----)

C:\java\curso>java Ejemplo26b

java.net.SocketException: connect

at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:223)

at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:128)

at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:115)

at java.net.Socket.<init>(Socket.java:125)

at java.net.Socket.<init>(Socket.java:101)

at Ejemplo26b.main(Ejemplo26b.java:12)
El ejemplo fue lo más sencillo posible, pero mediante el mismo método el servidor y los clientes pueden
intercambiar datosescribiendo en ambas direcciones. Inclusive, el servidor puede correr en una máquina y los
clientes en otras; además, si bien en este caso utilizamos aplicaciones standalone, se pueden utilizar applets.

 LENGUAJES DINÁMICOS

1.LENGUAJES A NIVEL DEL SERVIDOR

1.1.LENGUAJE ASP

Un archivo de páginas Active Server (ASP) es un archivo de texto con la extensión .asp que contiene
cualquier combinación de :
• Texto
• Etiquetas HTML
• Secuencias de comandos del servidor
Un método rápido para crear un archivo .asp consiste en cambiar la extensión de los archivos HTML
(.html o .htm) por la extensión .asp. Si el archivo no contiene funciones ASP, el servidor prescinde del
proceso de secuencias de comandos ASP y envía el archivo al cliente. Como desarrollador Web, esta
opción proporciona una gran flexibilidad, ya que puede asignar a los archivos la extensión .asp incluso si
no piensa agregar funciones ASP hasta más adelante.
Para publicar el archivo .asp en Web, guarde el nuevo archivo en un directorio virtual de su sitio Web
(asegúrese de que el directorio tenga los permisos Secuencia de comandos o Ejecución). A
continuación, escriba en el explorador la dirección URL del archivo para pedirlo. (Recuerde, las páginas
ASP debe enviarlas el servidor, por lo que no puede pedirlas mediante su ruta física.) Cuando el archivo
se cargue en el explorador, observará que el servidor envió una página HTML. Al principio puede
parecer extraño, pero recuerde que el servidor analiza y ejecuta todas las secuencias de comandos ASP
del servidor antes de enviar el archivo. El usuario siempre recibe código HTML estándar.
Para crear archivos .asp, se puede utilizar cualquier editor de textos. A medida que avance, puede que
encuentre más productivo utilizar un editor más orientado a ASP, como Microsoft(r) Visual InterDev™.
(Para obtener más información, visite el sitio Web de Microsoft Visual InterDev en la dirección
http://msdn.microsoft.com/vinterdev/.)

Agregar secuencias de comandos del servidor

Una secuencia de comandos del servidor es una serie de instrucciones que se utiliza para enviar al
servidor Web comandos de forma secuencial. (Si ya desarrolló antes sitios Web, probablemente
conozca las secuencias de comandos del cliente, que se ejecutan en el explorador Web.) En los
archivos .asp, las secuencias de comandos se separan del texto y de las etiquetas HTML mediante
delimitadores. Un delimitador es un carácter o una secuencia de caracteres que marca el principio o el
final de una unidad. En el caso de HTML, dichos delimitadores son los símbolos menor que (<) y mayor
que (>), que enmarcan las etiquetas HTML.
ASP utiliza los delimitadores <% y %> para enmarcar los comandos. Dentro de los delimitadores puede
incluir cualquier comando válido dentro del lenguaje de secuencia de comandos que esté utilizando. El
ejemplo siguiente muestra una página HTML sencilla que contiene un comando de secuencia de
comandos:
<HTML>
<BODY>
Esta página se actualizó por última vez el <%= Now ()%>.
</BODY>
</HTML>

La función Now() de VBScript devuelve la fecha y la hora actuales. Cuando el servidor Web procesa
esta página, reemplaza <%= Now ()%> con la fecha y la hora actuales, y devuelve la página al
explorador con el siguiente resultado:
Esta página se actualizó el 1/29/99 2:20:00 p.m.
A los comandos enmarcados por delimitadores se les llama comandos principales de secuencias de
comandos, que se procesan mediante el lenguaje principal de secuencia de comandos. Todos los
comandos utilizados dentro de los delimitadores de secuencias de comandos deben ser válidos en el
lenguaje principal de secuencia de comandos. De forma predeterminada, el lenguaje principal de
secuencia de comandos es VBScript, pero también puede establecer un lenguaje diferente. Consulte
Trabajar con lenguajes de secuencias de comandos.
Si ya conoce las secuencias de comandos del cliente, ya sabrá que la etiqueta HTML <SCRIPT> se
utiliza para delimitar las secuencias de comandos y las expresiones. También puede utilizar la etiqueta
<SCRIPT> para las secuencias de comandos del cliente, siempre que necesite definir procedimientos en
múltiples lenguajes en un archivo .asp. Para obtener más información, consulte Trabajar con lenguajes
de secuencias de comandos.

Combinar HTML y comandos de secuencias de comandos


Dentro de los delimitadores de ASP puede incluir cualquier instrucción, expresión, procedimiento u
operador que sea válido en el lenguaje principal para secuencia de comandos. Una instrucción, en
VBScript y en otros lenguajes, es una unidad sintácticamente completa que expresa un tipo de acción,
declaración o definición. La instrucción condicional If...Then...Else que aparece a continuación es una
instrucción de VBScript muy común:
<%
Dim dtmHour
dtmHour = Hour(Now())
If dtmHour < 12 Then
Saludos = "Buenos días"
Else
strGreeting = "Hola"
End If
%>
<%= strGreeting %>
Según la hora, la secuencia de comandos asigna el valor "Buenos días" o el valor "Hola" a la variable de
cadena strGreeting. La instrucción <%= strGreeting %> envía al explorador el valor actual de la variable.
De esta forma, los usuarios que vean esta secuencia de comandos antes de las 12:00 de la mañana
(según la zona horaria del servidor Web) verían la siguiente línea de texto:
Buenos días
Los usuarios que vean esta secuencia de comandos después de las 12:00 de la mañana verían la
siguiente línea de texto:
Hola
Puede incluir texto HTML entre las secciones de una instrucción. Por ejemplo, la secuencia de
comandos siguiente, que combina HTML dentro de una instrucción If...Then...Else, produce el mismo
resultado que la del ejemplo anterior:
<%
Dim dtmHour
dtmHour = Hour(Now())
If dtmHour < 12 Then
%>
Buenos días
<% Else %>
Hola
<%End If %>

Si la condición es verdadera, es decir, si es antes del mediodía, el servidor Web envía al explorador el
código HTML que sigue a la condición (“Buenos días”); de lo contrario, envía el código HTML que sigue
a Else (“Hola”). Esta forma de combinar HTML y comandos de secuencia de comandos es cómoda para
continuar la instrucción If...Then...Else en varias líneas de texto HTML. El ejemplo anterior es más útil si
desea presentar un saludo en varias partes de una página Web. Puede asignar el valor de la variable
una única vez y después presentarla varias veces.
En lugar de mezclar texto HTML con comandos de secuencia de comandos, puede devolver texto HTML
al explorador desde dentro de los comandos de secuencia de comandos. Para devolver texto al
explorador, utilice el objeto integrado Response de ASP. El ejemplo siguiente produce el mismo
resultado que las secuencias de comandos anteriores:
<%
Dim dtmHour
dtmHour = Hour(Now())
If dtmHour < 12 Then
Response.Write "Buenos días"
Else
Response.Write "Hola"
End If
%>

Response.Write envía al explorador el texto que le sigue. Utilice Response.Write desde una
instrucción cuando desee generar de forma dinámica el texto devuelto al explorador. Por ejemplo, puede
generar una cadena de texto que contenga los valores de varias variables. Aprenderá más acerca del
objeto Response, y de los objetos en general, en Utilizar componentes y objetos y Enviar contenido al
explorador. Por ahora, observe simplemente que dispone de varias maneras de insertar comandos de
secuencias de comandos en las páginas HTML.
Puede incluir procedimientos escritos en su lenguaje predeterminado de secuencias de comandos
dentro de delimitadores ASP. Para obtener más información, consulte Trabajar con lenguajes de
secuencias de comandos.
Si va a trabajar con comandos JScript, puede insertar las llaves que indican un bloque de instrucciones
directamente en sus comandos ASP, incluso aunque estén entremezclados con etiquetas y texto HTML.
Por ejemplo:
<%
if (screenresolution == "low")
{
%>
Ésta es la versión de texto de la página.
<%
}
else
{
%>
Ésta es la versión multimedia de la página.
<%
}
%>
-O bien-
<%
if (screenresolution == "low")
{
Response.Write("Ésta es la versión de texto de la página.")
}
else
{
Response.Write("Ésta es la versión multimedia de la página.")
}
%>

Utilizar directivas ASP

ASP proporciona directivas que no forman parte de los lenguajes de secuencias de comandos: Dichas
directivas son la directiva de resultado y la directiva de proceso.
La directiva de resultado de ASP <%= expresión %> presenta el valor de una expresión. Dicha directiva
es equivalente al uso de Response.Write para presentar información. Por ejemplo, la expresión <%=
ciudad %> envía al explorador la palabra Barcelona (el valor actual de la variable).
La directiva de proceso de ASP <%@ palabra clave %> ofrece a ASP la información que necesita para
procesar un archivo .asp. Por ejemplo, la siguiente directiva establece VBScript como lenguaje principal
de secuencia de comandos de la página:

<%@ LANGUAGE=VBScript %>


Las directivas de proceso deben estar en la primera línea de los archivos .asp. Para agregar más de una
directiva a una página, deben incluirse en el mismo delimitador. No ponga las directivas de proceso en
los archivos incluidos con la instrucción #include. Debe incluir un espacio en blanco entre el signo @ y
la palabra clave. La directiva de proceso tiene las siguientes palabras clave:
• La palabra clave LANGUAGE establece el lenguaje principal de secuencia de comandos de la
página.
• La palabra clave ENABLESESSIONSTATE especifica si un archivo ASP utiliza el estado de la
sesión. Consulte Administrar sesiones.
• La palabra clave CODEPAGE establece la página de códigos (la codificación de caracteres) del
archivo .asp.
• La palabra clave LCID establece el identificador de configuración regional del archivo.
• La palabra clave TRANSACTION especifica que el archivo .asp se ejecutará dentro del contexto
de una transacción. Consulte Descripción de las transacciones
Importante Puede incluir más de una palabra clave en una única directiva. Los pares de palabra clave
y valor deben estar separados por un espacio. No ponga espacios ni antes ni después del signo igual
(=).
El ejemplo siguiente establece el lenguaje de secuencia de comandos y la página de códigos:
<%@ LANGUAGE="Jscript" CODEPAGE="932" %>

Espacio en blanco en las secuencias de comandos


Si su lenguaje principal de secuencias de comandos es VBScript o JScript, ASP quita el espacio en
blanco de los comandos. En otros lenguajes, ASP conserva el espacio en blanco para que los lenguajes
que interpreten la posición o la sangría puedan interpretarlo correctamente. El espacio en blanco incluye
espacios, tabuladores, retornos y saltos de línea.
En VBScript y JScript puede utilizar el espacio en blanco que sigue al delimitador de apertura y que
precede al de cierre para facilitar la lectura de los comandos. Todas las instrucciones siguientes son
válidas:
<% Color = "Green" %>
<%Color="Green"%>
<%
Color = "Green"
%>
ASP quita el espacio en blanco que se encuentre entre los delimitadores de cierre de las instrucciones y
los delimitadores de apertura de las instrucciones siguientes. Sin embargo, se recomienda utilizar
espacios para mejorar la legibilidad. Si tiene que conservar el espacio en blanco entre dos instrucciones,
como cuando vaya a presentar los valores de las variables en una frase, utilice el carácter de espacio de
no separación de HTML (&nbsp;). Por ejemplo:
<%
'Define dos variables con valores de cadena.
strFirstName = "Juan"
strLastName = "García"
%>
<P>Esta página Web está personalizada para "<%= strFirstName %>&nbsp;<%= strLastName %>."
</P>

Utilizar variables y constantes


Una variable es una ubicación de almacenamiento con nombre dentro de la memoria del equipo que
contiene datos, como un número o una cadena de texto. A los datos contenidos en una variable se les
llama valor de la variable. Las variables ofrecen una manera de almacenar, recuperar y manipular
valores mediante nombres que ayuden a entender lo que hace la secuencia de comandos.

Declarar y asignar nombre a variables


Siga las reglas y recomendaciones de su lenguaje de secuencias de comandos a la hora de declarar
variables y asignarles nombres. Incluso aunque no necesita declarar una variable para poder utilizarla,
es conveniente hacerlo porque ayuda a prevenir errores. Declarar una variable significa indicar al motor
de secuencias de comandos que existe una variable con un nombre concreto, de forma que pueda
hacer referencia a la variable a lo largo de una secuencia de comandos.

VBScript
VBScript no necesita declaraciones de variables, pero es conveniente declarar todas las variables antes
de utilizarlas. Para declarar una variable en VBScript, utilice la instrucción Dim, Public o Private. Por
ejemplo:
<% Dim NombreUsuario %>
Puede utilizar la instrucción Option Explicit de VBScript en los archivos .asp para hacer obligatoria la
declaración de variables con las instrucciones Dim, Private, Public y ReDim. La instrucción Option
Explicit debe aparecer después de las directivas ASP y antes del texto HTML o de los comandos de la
secuencia de comandos. Esta instrucción sólo afecta a los comandos ASP escritos en VBScript; no
afecta a los comandos escritos en JScript.
<% Option Explicit %>
<HTML>
<%
Dim strNombreUsuario
Public lngNumeroCuenta
%>

Alcance de las variables

El alcance, o vida, de una variable determina qué comandos de secuencia de comandos pueden tener
acceso a dicha variable. Una variable declarada dentro de un procedimiento tiene alcance local; la
variable se crea y se destruye cada vez que se ejecuta el procedimiento. No se puede tener acceso a
ella desde fuera del procedimiento. Una variable declarada fuera de un procedimiento tiene alcance
global; su valor es accesible y modificable desde cualquier comando de secuencia de comandos de una
página ASP.
Nota Al limitar el alcance de la variable a un procedimiento mejorará el rendimiento.
Si declara variables, una variable local y una variable global pueden tener el mismo nombre. La
modificación del valor de una de ellas no afecta al valor de la otra. Sin embargo, si no declara las
variables, podría modificar inadvertidamente el valor de una variable global. Por ejemplo, los siguientes
comandos de secuencia de comandos devuelven el valor 1 incluso aunque haya dos variables llamadas
Y:
<%
Option Explicit
Dim Y
Y=1
SetLocalVariable
Response.Write Y
Sub SetLocalVariable
Dim Y
Y=2
End Sub
%>
Por el contrario, los comandos siguientes devuelven el valor 2 porque las variables no se han declarado
de forma explícita. Cuando la llamada al procedimiento asigna a Y el valor 2, el motor de secuencias de
comandos da por supuesto que el procedimiento pretende modificar la variable global:
<%
Option Explicit
Dim Y = 1
SetLocalVariable
Response.Write Y
Sub SetLocalVariable
Y=2
End Sub
%>
Para evitar problemas, adquiera el hábito de declarar explícitamente todas las variables. Lo cual es
especialmente importante si utiliza la instrucción #include para incluir archivos en su archivo ASP. La
secuencia de comandos incluida está contenida en un archivo aparte, pero se trata como si formara
parte del archivo contenedor. Es muy fácil olvidarse de que hay que utilizar nombres de variables
diferentes en la secuencia de comandos principal y en la secuencia de comandos incluida, a menos que
declare las variables.

Asignar a las variables alcance de sesión o de aplicación


Las variables globales sólo son accesibles en un mismo archivo ASP. Para hacer que una variable sea
accesible en varias páginas, asigne a la variable alcance de sesión o de aplicación. Las variables con
alcance de sesión están disponibles en todas las páginas de una aplicación ASP que pida un mismo
usuario. Las variables con alcance de aplicación están disponibles en todas las páginas de una
aplicación ASP que pida cualquier usuario. Las variables de sesión son una buena manera de
almacenar información para un único usuario, como sus preferencias o el nombre o la identificación del
usuario. Las variables de aplicación son una buena manera de almacenar información para todos los
usuarios de una determinada aplicación, como los saludos específicos o los valores generales
necesarios en la aplicación.
ASP proporciona dos objetos integrados en los que puede almacenar variables: el objeto Session y el
objeto Application.
También puede crear instancias de objetos con alcance de sesión o de aplicación. Para obtener más
información, consulte Establecer el alcance de los objetos.
Alcance de sesión
Para asignar alcance de sesión a una variable, almacénela en el objeto Session asignando un valor a
una entrada con nombre del objeto. Por ejemplo, los siguientes comandos almacenan dos nuevas
variables en el objeto Session:
<%
Session("Nombre") = "Juan"
Session("Apellido") = "Soto"
%>

Para recuperar la información del objeto Session, tenga acceso a la entrada con nombre mediante la
directiva de resultado (<%=) o Response.Write. En el ejemplo siguiente se utiliza la directiva de
resultado para presentar el valor actual de Session("Nombre"):
Reciba nuestra bienvenida,<%= Session("Nombre") %>
Puede almacenar las preferencias del usuario en el objeto Session y después tener acceso a dichas
preferencias para determinar qué página hay que devolver al usuario. Por ejemplo, puede permitir que
los usuarios especifiquen la versión en texto del contenido de la primera página de la aplicación y aplicar
esta opción a las siguientes páginas de la aplicación que el usuario visite.
<%
strScreenResolution = Session("ScreenResolution")
If strScreenResolution = "Low" Then
%>
Ésta es la versión de texto de la página.
<% Else %>
Ésta es la versión multimedia de la página.
<%End If %>
Nota Si hace referencia a una variable con alcance de sesión más de una vez en una secuencia de
comandos, piense en asignarle una variable local, como en el ejemplo anterior, para mejorar el
rendimiento.
Alcance de aplicación
Para asignar alcance de aplicación a una variable, almacénela en el objeto Application asignando un
valor a una entrada con nombre del objeto. Por ejemplo, el comando siguiente almacena en el objeto
Application un saludo específico de una aplicación:
<% Application("Saludo") = "¡Reciba nuestra bienvenida al Departamento de ventas!" %>
Para recuperar la información del objeto Application, utilice la directiva de resultado de ASP (<%=) o

Response.Write para tener acceso a la entrada con nombre desde cualquier página posterior de la aplicación. En el
ejemplo siguiente se utiliza la directiva de resultado para presentar el valor de
Application("Saludo"):
<%= Application("Saludo") %> De nuevo, si hace referencia a una variable con alcance de aplicación en su
secuencia de comandos
repetidamente, debe de asignarle una variable local para mejorar el rendimiento.

Utilizar constantes
Una constante es un nombre que representa un número o una cadena. Algunos de los componentes de

base que se proporcionan con ASP, como ActiveX Data Objects (ADO), definen constantes que se
pueden utilizar en las secuencias de comandos. Un componente puede declarar constantes en la
biblioteca de tipos del componente, un archivo que contiene información acerca de los objetos y los tipos
aceptados por un componente COM. Después de haber declarado una biblioteca de tipos en su archivo
.asp puede usar las constantes definidas en cualquier secuencia de comandos en el mismo archivo .asp.
Igualmente, puede declarar una biblioteca de tipos en el archivo Global.asa para usar las constantes
definidas en cualquier archivo .asp de la aplicación.
Para declarar una biblioteca de tipos, utilice la etiqueta <METADATA> en su archivo .asp o Global.asa.
Por ejemplo, para declarar la biblioteca de tipos de ADO, utilice las siguientes instrucciones:
<!--METADATA NAME="Microsoft ActiveX Data Objects 2.5 Library" TYPE="TypeLib"
UUID="{00000205-0000-0010-8000-00AA006D2EA4}"-->
O bien, en lugar de hacer referencia al identificador único universal (UUID) de la biblioteca de tipos,
puede hacer referencia a la biblioteca de tipos mediante la ruta del archivo:
<!-- METADATA TYPE="typelib" FILE="c:\program files\common files\system\ado\msado15.dll"-->
Entonces puede usar las constantes ADO en el archivo .asp donde declaró la biblioteca de tipos o en un
archivo que reside en una aplicación que contiene un archivo Global.asa con la declaración de biblioteca
de tipos ADO. En el ejemplo siguiente, adOpenKeyset y adLockOptimistic son constantes ADO:
<%
'Crea y abre el objeto Recordset.
Set rsCustomersList = Server.CreateObject("ADODB.Recordset")
rstCustomerList.ActiveConnection = cnnPubs
rstCustomerList.CursorType = adOpenKeyset
rstCustomerList.LockType = adLockOptimistic
%>
En la siguiente tabla se enumeran las bibliotecas de tipos y los identificadores UUID que se utilizan con
más frecuencia:

Biblioteca de tipos UUID

Biblioteca de Microsoft ActiveX Data


Objects 2.5
{00000205-0000-0010-8000-00AA006D2EA4}
Biblioteca de Microsoft CDO 1.2 para
Windows 2000 Server
{0E064ADD-9D99-11D0-ABE5-00AA0064D470}
Biblioteca MSWC de objetos
Advertisement Rotator
{090ACFA1-1580-11D1-8AC0-00C0F00910F9}
Biblioteca MSWC de objetos de
registro de IIS
{B758F2F9-A3D6-11D1-8B9C-080009DCC2FA}

Interactuar con secuencias de comandos del cliente

Es posible aumentar la eficacia de ASP si se utiliza para generar o manipular secuencias de comandos
del cliente. Por ejemplo, puede escribir secuencias de comandos del servidor que construyan
secuencias de comandos del cliente basadas en variables específicas del servidor, el tipo del explorador
o los parámetros de la petición HTTP.
Si intercala instrucciones de secuencias de comandos del servidor en las secuencias de comandos del
cliente (delimitadas mediante etiquetas HTML <SCRIPT>), como se muestra en la plantilla del ejemplo
siguiente, puede inicializar de forma dinámica y alterar las secuencias de comandos del cliente en el
momento de realizar la petición:
<SCRIPT LANGUAGE="VBScript">
<!--
variable = <%=valor definido por el servidor %>
.
.
.
secuencia de comandos del cliente
<% secuencia de comandos del servidor que se utiliza para generar una instrucción del cliente %>
secuencia de comandos del cliente
.
.
.
-->
</SCRIPT>
Al incorporar estas funciones es posible crear algunas aplicaciones útiles e interesantes. Por ejemplo,
ésta es una sencilla secuencia de comandos del servidor (escrita en VBScript) que manipula una
secuencia de comandos del cliente (escrita en JScript):
<%
Dim dtmTime, strServerName, strServerSoftware, intGreeting
dtmTime = Time()
strServerName = Request.ServerVariables("SERVER_NAME")
strServerSoftware = Request.ServerVariables("SERVER_SOFTWARE")
'Genera un número aleatorio.
Randomize
GreetCondition = int(rnd * 3)
%>
<SCRIPT LANGUAGE="JScript">
<!--
//Llama a la función para mostrar el saludo
showIntroMsg()
function showIntroMsg()
{
switch(<%= intGreeting %>)
{
case 0:
msg = "Este es el servidor Web <%= strServerName%> con <%= strServerSoftware %>."
break
case 1:
msg = "Reciba nuestra bienvenida al servidor Web <%= strServerName%>. La hora local es <%=
dtmTime %>."
break
case 2:
msg = "Este servidor utiliza <%= strServerSoftware %>."
break
}
document.write(msg)
}
-->
</SCRIPT>

Escribir procedimientos
Un procedimiento es un grupo de comandos de secuencia de comandos que realizan una tarea
específica y puede devolver un valor. Puede definir sus propios procedimientos e invocarlos
repetidamente desde sus secuencias de comandos.
Puede poner las definiciones de los procedimientos en el mismo archivo .asp que llama a los
procedimientos o bien puede poner los procedimientos utilizados con más frecuencia en un archivo .asp
compartido y utilizar la directiva #include para incluirlo en otros archivos .asp que llamen a los
procedimientos. Como alternativa, puede encapsular dicha funcionalidad en un componente COM.

Definir procedimientos

Las definiciones de los procedimientos pueden encontrarse dentro de etiquetas <SCRIPT> y </SCRIPT>
y deben seguir las reglas del lenguaje de secuencias de comandos. Utilice el elemento <SCRIPT> para
los procedimientos escritos en lenguajes distintos del lenguaje principal para secuencias de comandos.
Sin embargo, utilice los delimitadores de las secuencias de comandos (<% y %>) en los procedimientos
escritos en el lenguaje principal de secuencias de comandos.
Cuando utilice la etiqueta HTML <SCRIPT>, debe emplear dos atributos para asegurar el proceso de la
secuencia de comandos por parte del servidor. La sintaxis de la etiqueta <SCRIPT> es la siguiente:
<SCRIPT LANGUAGE=JScript RUNAT=SERVER>
definición del procedimiento
</SCRIPT>
El atributo RUNAT=SERVER indica al servidor Web que procese la secuencia de comandos en el
servidor. Si no establece este atributo, la secuencia de comandos la procesará el explorador del cliente.
El atributo LANGUAGE determina el lenguaje de secuencia de comandos utilizado en este bloque.
Puede especificar cualquier lenguaje para el que haya instalado un motor de secuencias de comandos
en el servidor. Para especificar VBScript, use el valor VBScript. Para especificar JScript, use el valor
JScript. Si no asigna el atributo LANGUAGE, el bloque de la secuencia de comandos se interpretará en
el lenguaje principal de secuencia de comandos.
Los comandos del bloque de la secuencia de comandos deben componer uno o varios procedimientos
completos en el lenguaje de secuencia de comandos elegido. Por ejemplo, los comandos siguientes
definen el procedimiento JScript MiFuncion.
<HTML>
<SCRIPT LANGUAGE=JScript RUNAT=SERVER >
function MiFuncion()
{
Response.Write("Llamó a MiFuncion().")
}
</SCRIPT>
Importante No incluya en las etiquetas <SCRIPT> del servidor comandos de secuencias de comandos
que no formen parte de procedimientos completos. Los comandos que no formen parte de un
procedimiento pueden provocar resultados impredecibles puesto que deben ejecutarse en un orden
determinado. Además, no puede utilizar la directiva de resultado de ASP <%=%> dentro de los
procedimientos. En su lugar, utilice Response.Write para enviar contenido al explorador.

Llamar a procedimientos
Para llamar a procedimientos, incluya el nombre de los procedimientos en un comando. Si va a llamar a
procedimientos JScript desde VBScript, debe utilizar paréntesis después del nombre del procedimiento;
si el procedimiento no tiene argumentos, utilice paréntesis vacíos. Si va a llamar a procedimientos
VBScript o JScript desde JScript, utilice siempre paréntesis después del nombre del procedimiento.
En VBScript también puede utilizar la palabra clave Call para llamar a un procedimiento. Sin embargo, si
el procedimiento al que llama requiere argumentos, la lista de argumentos debe aparecer entre
paréntesis. Si omite la palabra clave Call, también debe omitir los paréntesis en los que se incluye la
lista de argumentos. Si utiliza la sintaxis Call para llamar a una función integrada o definida por el
usuario, se descartará el valor devuelto por la función.
El ejemplo siguiente ilustra la creación y la llamada a procedimientos en dos lenguajes para secuencias
de comandos diferentes (VBScript y JScript).
<%@ LANGUAGE=VBScript %>
<HTML>
<BODY>
<% Echo %>
<BR>
<% printDate() %>
</BODY>
</HTML>
<%
Sub Echo
Response.Write "<TABLE>" & _
"Response.Write "<TR><TH>Nombre</TH><TH>Valor</TH></TR>"
Set objQueryString = Request.QueryString
For Each strSelection In objQueryString
Response.Write "<TR><TD>" & p & "</TD><TD>" & _
FormValues(strSelection) & "</TD></TR>"
Next
Response.Write "</TABLE>"
End Sub
%>
<SCRIPT LANGUAGE=JScript RUNAT=SERVER>
function PrintDate()
{
var x
x = new Date()
Response.Write(x.toString())
}
</SCRIPT>
Nota Las llamadas de VBScript a las funciones JScript no distinguen entre mayúsculas y minúsculas.
Pasar matrices a procedimientos
Para pasar una matriz entera a un procedimiento en VBScript, utilice el nombre de la matriz seguido de
paréntesis vacíos; en JScript, utilice corchetes vacíos.

Procesar los datos proporcionados por el usuario


Mediante el objeto Request de ASP puede crear sencillas y eficaces secuencias de comandos para
recopilar y procesar datos obtenidos de formularios HTML. En este tema no sólo aprenderá a crear
secuencias de comandos básicas para procesar formularios, sino que también conocerá técnicas útiles
para validar los datos de los formularios, tanto en su servidor Web como en el explorador de Web del
usuario.

Acerca de los formularios HTML

Los formularios HTML, el método más común para recopilar información desde el Web, consiste en un
conjunto de etiquetas HTML especiales que presentan elementos de interfaz de usuario en una página
Web. Los cuadros de texto, los botones y las casillas de verificación son ejemplos de elementos que
permiten que los usuarios intercalen con una página Web y envíen información a un servidor Web.
Por ejemplo, las siguientes etiquetas HTML generan un formulario en el que un usuario puede escribir su
nombre, apellido y edad, e incluye un botón para enviar la información a un servidor Web. El formulario
también contiene una etiqueta de entrada oculta (no presentada por el explorador Web) que puede
utilizar para pasar información adicional al servidor Web.
<FORM METHOD="Post" ACTION="Profile.asp">
<INPUT TYPE="text" NAME="Nombre">
<INPUT TYPE="text" NAME="Apellido">
<INPUT TYPE="text" NAME="Edad">
<INPUT TYPE="Hidden" NAME="EstadoUsuario" VALUE="Nuevo">
<INPUT TYPE="Submit" VALUE="Entrar">
</FORM>
Presentar con detalle el conjunto completo de etiquetas HTML para formularios se sale del ámbito de
este tema, sin embargo, hay numerosas fuentes de información que puede utilizar para aprender a crear
y utilizar formularios HTML. Por ejemplo, puede utilizar la posibilidad que ofrece su explorador para ver
el código fuente con el fin de examinar cómo se crean los formularios HTML en otros sitios Web.
También puede visitar el sitio Web de MSDN de Microsoft en la dirección http://msdn.microsoft.com/
para conocer las técnicas más recientes para utilizar los formularios HTML con otras tecnologías de
Internet.
Procesar datos de formularios con ASP

Después de crear el formulario HTML tendrá que procesar los datos proporcionados por el usuario, lo
que implica enviar la información a un archivo .asp para que la analice y manipule. De nuevo, examine el
código HTML del ejemplo anterior. Observe que el atributo ACTION de la etiqueta <FORM> hace
referencia a un archivo llamado Profile.asp. Cuando el usuario envía información HMTL, el explorador
utiliza el método POST para enviarla a un archivo .asp del servidor, en este caso Profile.asp. Este
archivo .asp puede contener archivos de comandos que procesen la información e interactúen con otras
secuencias de comandos, componentes COM o recursos, como una base de datos.
Existen tres formas básicas de recopilar información de un formulario HTML mediante ASP:
• Un archivo .htm estático puede contener un formulario que envíe sus valores a un archivo .asp.
• Un archivo .asp puede crear un formulario que envíe información a otro archivo .asp.
• Un archivo .asp puede crear un formulario que se envíe información a sí mismo; es decir, al
archivo .asp que contiene el formulario.
Los dos primeros métodos funcionan igual que los formularios que interactúan con otros programas de
servidor Web, con la única diferencia de que con ASP se simplifica mucho la tarea de recuperar y
procesar la información. El tercer método es especialmente útil y se muestra en la sección Validar los
datos de los formularios.

Obtener datos de los formularios


El objeto Request de ASP proporciona dos colecciones que facilitan la tarea de recuperar información
de los formularios enviados con las peticiones URL.

La colección QueryString

La colección QueryString recupera los valores del formulario pasados al servidor Web como texto a
continuación del signo de interrogación de la dirección URL de la petición. Los valores del formulario se
pueden anexar a la dirección URL de la petición mediante el método GET de HTTP o, manualmente, si
se agregan los valores del formulario a la dirección URL.
Si el ejemplo del formulario anterior utilizara el método GET (METHOD = "GET") y el usuario escribiera
Juan, Soto y 30, se enviaría la siguiente petición URL al servidor:
http://Workshop1/Painting/Profile.asp?Nombre=Juan&Apellido=Soto&Edad=30&EstadoUsuario=Nuevo
El archivo Profile.asp podría contener la siguiente secuencia de comandos para procesar formularios:
Hola, <%= Request.QueryString("nombre") %> <%= Request.QueryString("apellido") %>.
Tiene <%= Request.QueryString("edad") %> años.
<%
If Request.QueryString("EstadoUsuario") = "Nuevo" Then
Response.Write"Ésta es su primera visita a este sitio Web"
End if
%>
En este caso, el servidor Web devolvería el texto siguiente al explorador Web del usuario:
Hola Juan Soto. Tiene 30 años. Ésta es su primera visita a este sitio Web
La colección QueryString también tiene un parámetro opcional que puede utilizar para tener acceso a
uno de los múltiples valores que se encuentran en el cuerpo de la petición URL (con el método GET).
También puede utilizar la propiedad Count para contar el número de veces que aparece un determinado
tipo de valor.
Por ejemplo, un formulario que contenga un cuadro de lista con varios elementos puede generar la
siguiente petición:
http://OrganicFoods/list.asp?Comida=Manzanas&Comida=Aceitunas&Comida=Pan
Podría utilizar el siguiente comando para contar los diferentes valores:
Request.QueryString("Comida").Count
Para presentar los tipos de valores, Lista.asp podría contener la secuencia de comandos siguiente:
<%
lngTotal = Request.QueryString("Comida").Count
For i = 1 To lngTotal
Response.Write Request.QueryString("Comida")(i) & "<BR>"
Next
%>
La secuencia de comandos anterior mostraría:
Manzanas
Aceitunas
Pan
También puede mostrar la lista completa de valores como una cadena delimitada por comas, del modo
siguiente:
<% Response.Write Request.QueryString("Item") %>
Aparecería la cadena siguiente:
Manzanas, Aceitunas, Pan

Colección Form

Cuando utiliza el método GET de HTTP para pasar a un servidor Web valores de un formulario grande y
complejo, corre el riesgo de perder información. Algunos servidores Web tienden a restringir el tamaño
de la cadena de petición de URL, por lo que los valores de los formularios grandes pasados con el
método GET podrían quedar truncados. Si necesita enviar una gran cantidad de información desde un
formulario a un servidor Web, debe utilizar el método POST de HTTP. El método POST, que envía los
datos de los formularios en el cuerpo de la petición HTTP, puede enviar un número casi ilimitado de
caracteres a un servidor. Puede utilizar la colección Form del objeto Request de ASP para recuperar los
valores enviados mediante el método POST.
La colección Form almacena valores de manera similar a la colección QueryString. Por ejemplo, si un
usuario completa un formulario escribiendo una larga lista de nombres, se podrían leer los nombres con
la secuencia de comandos siguiente:
<%
lngTotal = Request.Form("Comida").Count
For i = 1 To lngTotal
Response.Write Request.Form("Comida")(i) & "<BR>"
Next
%>

Validar los datos de los formularios

Un formulario Web bien diseñado suele incluir una secuencia de comandos del cliente que valida los
datos proporcionados por el usuario antes de enviar la información al servidor. Las secuencias de
comandos de validación pueden comprobar si el usuario escribió un número válido o si un cuadro de
texto está en blanco. Imagine que su sitio Web incluye un formulario que permite calcular la tasa de
retorno de una inversión. Probablemente querrá comprobar si un usuario realmente escribió texto o
números en los campos apropiados del formulario, antes de enviar al servidor información que podría no
ser válida.
En general, lo mejor es realizar en el cliente tantas comprobaciones como sea posible. Además, de
poder preguntar antes al usuario por los errores, la validación en el cliente mejora el tiempo de
respuesta, reduce la carga del servidor y libera ancho de banda para otras aplicaciones.
La siguiente secuencia de comandos del cliente valida los datos escritos por el usuario (en este caso, la
secuencia de comandos determina si el número de cuenta que escribió el usuario es realmente un
número) antes de enviarlos al servidor:
<SCRIPT LANGUAGE="JScript">
function ComprobarNumero()
{
if (isNumeric(document.UserForm.AcctNo.value))
return true
else
{
alert("Escriba un número de cuenta válido.")
return false
}
}
//Función para determinar si el valor del formulario es un número.
//Nota: El método isNaN JScript es un método más elegante para determinar si
//un valor no es un número. Sin embargo, algunos exploradores no admiten este método.
function isNumeric(str)
{
for (var i=0; i < str.length; i++)
{
var ch = str.substring(i, i+1)
if( ch < "0" || ch>"9" || str.length == null)
{
return false
}
}
return true
}
</SCRIPT>
<FORM METHOD="Get" ACTION="balance.asp" NAME="FormularioUsuario" ONSUBMIT="return
CheckNumber()">
<INPUT TYPE="Text" NAME="NumCuen">
<INPUT TYPE="Submit" VALUE="Enviar">
</FORM>
Sin embargo, si la validación de un formulario requiere el acceso a una base de datos debe considerar la
utilización de la validación del formulario en el servidor. Una forma muy útil de realizar la validación en el
servidor es crear formularios que se envíen la información a sí mismos. Es decir, el archivo .asp contiene
en realidad el formulario HTML que recibe los datos del usuario. (Recuerde, puede utilizar ASP para
interactuar con secuencias de comandos del cliente y código HTML. Para obtener más información,
consulte Interactuar con secuencias de comandos del cliente.) Los datos escritos vuelven al mismo
archivo, que se encarga de validar la información y avisa al usuario si éstos no son correctos.
Mediante este método se pueden mejorar las características de uso y la respuesta de los formularios
basados en Web. Por ejemplo, si se incluye información del error junto al campo del formulario en el que
se escribió la información incorrecta, será más fácil para el usuario descubrir el origen del error.
(Normalmente, los formularios basados en Web reenvían las peticiones a una página Web
independiente que contiene información del error. Los usuarios que no comprendan esta información
podrían sentirse frustrados.)
Por ejemplo, la secuencia de comandos siguiente determina si un usuario escribió un número de cuenta
válido, para lo que se envía la información a sí misma (Verify.asp) y llama a una función definida por el
usuario que realiza una consulta a una base de datos:
<%
strAcct = Request.Form("Cuenta")
If Not AccountValid(strAcct) Then
ErrMsg = "<FONT COLOR=Red>El número de cuenta que ha escrito no es válido.</FONT>"
Else
Procesa los datos del usuario
.
.
.
Server.Transfer("Complete.asp")
End If
Function AccountValid(strAcct)
Aquí se incluirá una secuencia de comandos o una llamada a un método de un componente de
conexión con una base de datos.
End Function
%>
<FORM METHOD="Post" ACTION="Verify.asp">
Número de cuenta: <INPUT TYPE="Text" NAME="Cuenta"> <%= ErrMsg %> <BR>
<INPUT TYPE="Submit">
</FORM>
En este ejemplo, la secuencia de comandos se encuentra en un archivo llamado Verify.asp, el mismo
archivo que contiene el formulario HTML y, para enviarse la información a sí mismo, especifica
Verify.asp en el atributo ACTION.

Importante Si utiliza JScript para la validación en el servidor, asegúrese de colocar un par de


paréntesis vacíos detrás del elemento de la colección Request (QueryString o Form) al asignar la
colección a una variable local. Sin el paréntesis la colección devolverá un objeto en lugar de una
cadena. La secuencia de comandos siguiente muestra el método correcto para asignar variables con
JScript:
<%
var Nombre = Request.Form("Nombre")();
var Contraseña = Request.Form("Contraseña")();
if(Nombre > "")
{
if(Nombre == Contraseña)
Response.Write("El nombre y la contraseña son iguales".)
else
Response.Write("El nombre y la contraseña son diferentes".);
}
%>
VBScript presenta el mismo comportamiento si la colección contiene varios valores separados por
comas o con los que se pueda crear un índice. Esto significa que tanto para VBScript como para JScript,
además de colocar un par de paréntesis detrás del elemento de la colección Request, necesitará
especificar el índice del valor deseado. Por ejemplo, la siguiente línea en JScript devuelve sólo el
primero de los varios valores de un elemento de un formulario:
var Nombre = Request.Form("Nombre")(1);

Acceso al origen de datos

ActiveX Data Objects (ADO) es una tecnología ampliable y de fácil uso para agregar a sus páginas Web
acceso a bases de datos. Puede utilizar ADO para escribir secuencias de comandos compactas y
escalables que le permitan conectarse a orígenes de datos compatibles con OLE DB, como bases de
datos, hojas de cálculo, archivos de datos secuenciales o directorios de correo electrónico. OLE DB es
una interfaz de programación de nivel de sistema que proporciona un conjunto estándar de interfaces
COM para que permitan exponer las funciones del sistema de administración de bases de datos. Con el
modelo de objetos ADO es fácil tener acceso a estas interfaces (mediante lenguajes de secuencias de
comandos, como VBScript o JScript) para agregar funciones de bases de datos a las aplicaciones Web.
Además, también puede utilizar ADO para tener acceso a bases de datos compatibles con la
Conectividad abierta de bases de datos (ODBC, Open Database Connectivity).
Si no tiene mucha experiencia en conectividad con bases de datos, encontrará que la sintaxis de ADO
es sencilla y fácil de utilizar. Si es un programador experimentado, agradecerá el acceso escalable de
alto rendimiento que proporciona ADO para una gran variedad de orígenes de datos.

Crear una cadena de conexión

El primer paso en la creación de una aplicación de datos en Web consiste en proporcionar un método
para que ADO encuentre e identifique el origen de datos. Para ello se utiliza una cadena de conexión,
una serie de argumentos separados mediante un punto y coma que definen parámetros como el
proveedor del origen de datos y la ubicación del mismo. ADO utiliza la cadena de conexión para
identificar el proveedor OLE DB y para dirigir al proveedor al origen de datos. El proveedor es un
componente que representa el origen de datos y que expone la información en la aplicación en forma de
conjuntos de filas.
En la tabla siguiente se enumeran las cadenas de conexión de OLE DB para varios orígenes de datos
habituales:

Origen de datos Cadena de conexión OLE DB

Microsoft(r) Access Provider=Microsoft.Jet.OLEDB.4.0;Data Source=ruta física de


acceso al archivo .mdb
Microsoft SQL Server Provider=SQLOLEDB.1;Data Source=ruta de acceso a la base
de datos del servidor
Oracle Provider=MSDAORA.1;Data Source=ruta de acceso a la base
de datos del servidor
Microsoft Indexing Service Provider=MSIDXS.1;Data Source=ruta de acceso al archivo
Para proporcionar compatibilidad con versiones anteriores, el proveedor OLE DB para ODBC admite la
sintaxis de las cadenas de conexión ODBC. En la tabla siguiente se enumeran las cadenas de conexión
ODBC que se utilizan habitualmente:

Controlador del origen de datos


Cadena de conexión ODBC
Microsoft Access Driver={Microsoft Access Driver (*.mdb)};DBQ=ruta física de
acceso al archivo .mdb
SQL Server DRIVER={SQL Server};SERVER=ruta de acceso al servidor
Oracle DRIVER={Microsoft ODBC for Oracle};SERVER=ruta de
acceso al servidor
Microsoft Excel Driver={Microsoft Excel Driver (*.xls)};DBQ=ruta física de
acceso al archivo .xls; DriverID=278
Microsoft Excel 97 Driver={Microsoft Excel Driver (*.xls)};DBQ=ruta física de
acceso al archivo .xls;DriverID=790
Paradox Driver={Microsoft Paradox Driver (*.db)};DBQ=ruta física de
acceso al archivo .db;DriverID=26
Texto Driver={Microsoft Text Driver (*.txt;*.csv)};DefaultDir=ruta física
de acceso al archivo .txt
Microsoft Visual
FoxPro(r) (con un
contenedor de bases de
datos)
Driver={Microsoft Visual FoxPro
Driver};SourceType=DBC;SourceDb=ruta física de acceso al
archivo .dbc
Microsoft Visual FoxPro
(sin un contenedor de
bases de datos)
Driver={Microsoft Visual FoxPro
Driver};SourceType=DBF;SourceDb=ruta física de acceso al
archivo .dbf
Conectarse al origen de datos
ADO proporciona el objeto Connection para establecer y administrar las conexiones entre las
aplicaciones y los orígenes de datos compatibles con OLE DB o las bases de datos compatibles con
ODBC. El objeto Connection incorpora propiedades y métodos que se pueden utilizar para abrir y cerrar
conexiones con bases de datos, y para enviar consultas de actualización de la información.
Para establecer una conexión con una base de datos, cree primero una instancia del objeto
Connection. Por ejemplo, la secuencia de comandos siguiente crea una instancia del objeto
Connection y procede a abrir una conexión:
<%
'Crea un objeto Connection.
Set cn = Server.CreateObject("ADODB.Connection")
'Abre una conexión mediante la cadena de conexión OLE DB.
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\DatosMercado\VentasPrevistas.mdb"
%>
Nota La cadena de conexión no contiene espacios en blanco ni antes ni después del signo igual (=).
En este caso, el método Open del objeto Connection se refiere a la cadena de conexión.
Ejecutar consultas SQL con el objeto Connection
Con el método Execute del objeto Connection puede emitir comandos al origen de datos, como
consultas de SQL (Lenguaje de consulta estructurado). (SQL, lenguaje estándar para comunicarse con
bases de datos, define comandos para recuperar y actualizar información.) El método Execute acepta
parámetros que especifiquen el comando (o la consulta), el número de registros de datos a los que
afecta y el tipo de comando que se utiliza.
La siguiente secuencia de comandos utiliza el método Execute para enviar una consulta con un
comando INSERT de SQL, que inserta datos en una tabla concreta de la base de datos. En este
caso, el bloque de la secuencia de comandos inserta el nombre José Lugo en una tabla de la
base de datos llamada Customers.
<%
'Define la cadena de conexión OLE DB.
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Datos\Empleados.mdb"
'Crea la instancia del objeto Connection y abre una conexión con la base de datos.
Set cn = Server.CreateObject("ADODB.Connection")
cnn.Open strConnectionString
'Define la instrucción SELECT de SQL.
strSQL = "INSERT INTO Customers (FirstName, LastName) VALUES ('José','Lugo')"
'Utiliza el método Execute para enviar una consulta SQL a la base de datos.
cnn.Execute strSQL,,adCmdText + adExecuteNoRecords
%>
Observe que se especifican dos parámetros en la instrucción que se utiliza para ejecutar la consulta:
adCmdText y adExecuteNoRecords. El parámetro opcional adCmdText especifica el tipo de comando e
indica que el proveedor debe evaluar la instrucción de consulta (en este caso, una consulta SQL) como
una definición textual de un comando. El parámetro adExecuteNoRecords indica a ADO que no debe
crear un conjunto de registros de datos si no se devuelven resultados a la aplicación. Este parámetro
sólo funciona con los tipos de comandos definidos como texto, como las consultas SQL, o con
procedimientos almacenados de bases de datos. Aunque los parámetros adCmdText y
adExecuteNoRecords son opcionales, debe especificarlos al utilizar el método Execute para mejorar así
el rendimiento de la aplicación de datos.
Importante Los parámetros ADO, como adCmdText, deben estar definidos para poder utilizarlos en una
secuencia de comandos. Un método cómodo para definir los parámetros consiste en utilizar una
biblioteca de tipos de componentes, que es un archivo que contiene definiciones para todos los
parámetros ADO. Para implementar una biblioteca de tipos de componentes debe declararla antes.
Agregue la etiqueta siguiente <METADATA> al archivo .asp o a Global.asa para declarar la biblioteca de
tipos ADO:
<!--METADATA NAME="Microsoft ActiveX Data Objects 2.5 Library" TYPE="TypeLib"
UUID="{00000205-0000-0010-8000-00AA006D2EA4}"-->
Si desea obtener más detalles acerca de cómo implementar las bibliotecas de tipos de componentes,
consulte la sección Utilizar constantes del tema Utilizar variables y constantes.
Además del comando INSERT de SQL, puede utilizar los comandos UPDATE y DELETE de SQL para
modificar y quitar información de la base de datos.
Con el comando UPDATE de SQL puede modificar los valores de los elementos de una tabla de la base
de datos. La siguiente secuencia de comandos usa el comando UPDATE para cambiar todos los
campos FirstName de la tabla Customers a Juan en todas las filas cuyo campo LastName contenga el
apellido Soto.
<%
Set cn = Server.CreateObject("ADODB.Connection")
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Datos\Empleados.mdb"
cn.Execute "UPDATE Customers SET FirstName = 'Juan' WHERE LastName = 'Soto' ",,adCmdText +
adExecuteNoRecords
%>
Para quitar determinados registros de una tabla de la base de datos, utilice el comando DELETE de
SQL. La siguiente secuencia de comandos quita todas las filas de la tabla Customers cuyo apellido sea
Soto:
<%
Set cn = Server.CreateObject("ADODB.Connection")
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Datos\Empleados.mdb"
cn.Execute "DELETE FROM Customers WHERE LastName = 'Soto'",,adCmdText +
adExecuteNoRecords
%>
Nota Debe tener mucho cuidado al utilizar el comando DELETE de SQL. Un comando DELETE que no
vaya acompañado de una cláusula WHERE eliminará todas las filas de la tabla. Asegúrese de incluir la
cláusula WHERE de SQL, que especifica las filas exactas que se van a eliminar.

Utilizar el objeto Recordset para manipular los resultados

Para recuperar datos, examinar resultados y modificar su base de datos, ADO proporciona el objeto
Recordset. El objeto Recordset tiene las funciones necesarias para, dependiendo de las restricciones de
las consultas, recuperar y presentar un conjunto de filas, o registros, de una base de datos. El objeto
Recordset mantiene la posición de cada registro devuelto por la consulta, lo que permite recorrer los
resultados de uno en uno.
Recuperar un conjunto de registros
Las buenas aplicaciones de datos Web emplean el objeto Connection para establecer un vínculo, y el
objeto Recordset para manipular los datos devueltos. Al combinar las funciones especializadas de
ambos objetos puede desarrollar aplicaciones de bases de datos que realicen casi cualquier tarea de
tratamiento de datos. Por ejemplo, la siguiente secuencia de comandos del servidor utiliza el objeto
Recordset para ejecutar un comando SELECT de SQL. El comando SELECT recupera un conjunto
específico de información basándose en las restricciones de la consulta. La consulta también contiene
una cláusula WHERE de SQL, que se utiliza para establecer el criterio de selección de la consulta. En
este ejemplo, la cláusula WHERE limita la consulta a todos los registros que contengan el apellido Soto
en la tabla Customers de la base de datos.
<%
'Establece una conexión con un origen de datos.
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Datos\Empleados.mdb"
Set cn = Server.CreateObject("ADODB.Connection")
cnn.Open strConnectionString
'Crea una instancia de un objeto Recordset.
Set rsCustomers = Server.CreateObject("ADODB.Recordset")
'Abre un objeto Recordset con el método Open
'y utiliza la conexión establecida por el objeto Connection.
strSQL = "SELECT FirstName, LastName FROM Customers WHERE LastName = 'Soto' "
rstCustomers.Open strSQL, cnn
'Recorre el conjunto de los registros y presenta los resultados
'e incrementa la posición del registro con el método MoveNext.
Set objFirstName = rstCustomers("Nombre")
Set objLastName = rstCustomers("Apellido")
Do Until rstCustomers.EOF
Response.Write objFirstName & " " & objLastName & "<BR>"
rstCustomers.MoveNext
Loop
%>
Observe que en el ejemplo anterior, el objeto Connection estableció la conexión con la base de datos y
que el objeto Recordset utilizó la misma conexión para recuperar resultados de la base de datos. Este
método es útil cuando tenga que configurar con precisión la forma en que se establece el vínculo con la
base de datos. Por ejemplo, si necesitara especificar el tiempo de espera antes de anular un intento de
conexión, tendría que utilizar el objeto Connection para establecer dicha propiedad. Sin embargo, si sólo
desea establecer una conexión con las propiedades de conexión predeterminadas de ADO, podría
utilizar el método Open del objeto Recordset para establecer el vínculo:
<%
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Datos\Empleados.mdb"
strSQL = "SELECT FirstName, LastName FROM Customers WHERE LastName = 'Soto' "
Set rsCustomers = Server.CreateObject("ADODB.Recordset")
'Abre una conexión con el método Open
'y utiliza la conexión establecida por el objeto Connection.
rstCustomers.Open strSQL, strConnectionString
'Recorre el conjunto de registros, presenta los resultados
'e incrementa la posición del registro con el método MoveNext.
Set objFirstName = rstCustomers("Nombre")
Set objLastName = rstCustomers("Apellido")
Do Until rstCustomers.EOF
Response.Write objFirstName & " " & objLastName & "<BR>"
rstCustomers.MoveNext
Loop
%>

Cuando establece una conexión con el método Open del objeto Recordset, está utilizando
implícitamente el objeto Connection para proteger el vínculo. Para obtener más información, consulte la
documentación acerca de Microsoft ActiveX Data Objects (ADO), disponible en el sitio Web de Microsoft
Universal Data Access en la dirección http://www.microsoft.com/data/.
Nota Para mejorar de forma significativa el rendimiento de las aplicaciones ASP de base de datos,
piense en la posibilidad de cambiar el estado del conjunto de registros a Application. Para obtener más
información, consulte Guardar datos en la memoria caché.
A menudo resulta útil contar el número de registros que se devuelven en un conjunto de registros. El
método Open del objeto Recordset permite especificar un parámetro opcional, cursor, que determina
cómo recupera y recorre el conjunto de registros el proveedor subyacente. Al agregar el parámetro de
cursor adOpenKeyset a la instrucción que se utiliza para ejecutar la consulta, permite que la aplicación
cliente recorra todo el conjunto de registros. Como resultado, la aplicación puede utilizar la propiedad
RecordCount para calcular con precisión el número de registros del conjunto. Vea el siguiente ejemplo:
<%
Set rsCustomers = Server.CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM NewOrders", "Provider=Microsoft.Jet.OLEDB.3.51;Data
Source='C:\PedidosClientes\Pedidos.mdb'", adOpenKeyset, adLockOptimistic, adCmdText
'Utiliza la propiedad RecordCount del objeto Recordset para realizar la cuenta.
If rs.RecordCount >= 5 then
Response.Write "Recibimos estos " & rs.RecordCount & " nuevos pedidos<BR>"
Do Until rs.EOF
Response.Write rs("NombreCliente") & " " & rs("ApellidoCliente") & "<BR>"
Response.Write rs("NumeroCuenta") & "<BR>"
Response.Write rs("Cantidad") & "<BR>"
Response.Write rs("FechaEntrega") & "<BR><BR>"
rs.MoveNext
Loop
Else
Response.Write "Hay menos de " & rs.RecordCount & " nuevos pedidos."
End If
rs.Close
%>

Combinar formularios HTML y el acceso a bases de datos

Las páginas Web que contienen formularios HTML pueden permitir que los usuarios consulten de forma
remota una base de datos y recuperen información concreta. Con ADO puede crear secuencias de
comandos sorprendentemente sencillas que recopilen información del formulario del usuario, creen una
consulta personalizada para la base de datos y devuelvan información al usuario. Mediante el objeto
Request de ASP puede recuperar la información escrita en los formularios HTML e incorporar dicha
información a sus instrucciones SQL. Por ejemplo, el siguiente bloque de secuencia de comandos
inserta en una tabla la información suministrada por un formulario HTML. La secuencia de comandos
recopila información del usuario con la colección Form del objeto Request.
<%
'Abre una conexión mediante el objeto Connection. El objeto Command
'no tiene un método Open para establecer la conexión.
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Catálogo\Semillas.mdb"
Set cn = Server.CreateObject("ADODB.Connection")
cnn.Open strConnectionString
'Crea una instancia del objeto Command
'y utiliza la propiedad ActiveConnection para adjuntar
'la conexión al objeto Command.
Set cm= Server.CreateObject("ADODB.Command")
Set cmn.ActiveConnection = cnn
'Define la consulta SQL.
cmn.CommandText = "INSERT INTO MySeedsTable (Type) VALUES (?)"
'Define la información de configuración de los parámetros de la consulta.
cmn.Parameters.Append cmn.CreateParameter("type",adVarChar, ,255)
'Asigna el valor de la entrada y ejecuta la actualización.
cmn("type") = Request.Form("SeedType")
cmn.Execute ,,adCmdText + adExecuteNoRecords
%>
Para obtener más información acerca de los formularios y el uso del objeto Request de ASP, consulte
Procesar los datos introducidos por el usuario.

Transferencia entre archivos .ASP


Para utilizar Response.Redirect para redirigir un explorador se necesita un viaje de ida y vuelta, lo que
significa que el servidor envía al explorador una respuesta HTTP en la que indica la ubicación de la
nueva dirección URL. El explorador abandona automáticamente la cola de la petición del servidor y
envía una nueva petición HTTP para la dirección URL. Después, el servidor agrega esta petición a la
cola de peticiones, junto con las peticiones que mientras tanto llegan desde otros clientes. En un sitio
Web con mucha carga, este sistema puede desperdiciar ancho de banda y reducir el rendimiento del
servidor, especialmente si se redirige el explorador a un archivo que se encuentre en el mismo servidor.
Puede utilizar el método Server.Transfer para realizar la transferencia de un archivo .asp a otro que se
encuentre en el mismo servidor, en lugar del método Response.Redirect. Con Server.Transfer puede
transferir directamente las peticiones de archivos .asp sin necesidad de abandonar la cola de peticiones,
lo que elimina viajes de ida y vuelta.
Por ejemplo, la secuencia de comandos siguiente muestra cómo podría utilizar Server.Transfer para
saltar entre las páginas de una aplicación según la información de estado:
<%
If Session("blnSaleCompleted") Then
Server.Transfer("/Pedido/Gracias.asp")
Else
Server.Transfer("/Pedido/MasInfo.asp")
End if
%>

Server.Transfer envía peticiones desde un archivo .asp en ejecución a otro archivo. Durante la
transferencia, el archivo .asp que se pidió inicialmente finaliza inmediatamente la ejecución sin vaciar el
búfer de salir (para obtener más información, consulte la sección Almacenamiento en búfer del
contenido). La petición de información se pone a disposición del archivo de destino cuando éste
comienza la ejecución. Durante la ejecución, el archivo tiene acceso al mismo conjunto de objetos
intrínsecos (Request, Response, Server, Session y Application) que el archivo que se pidió
inicialmente.

También se puede utilizar Server.Transfer para realizar una transferencia entre archivos .asp que se
encuentren en diferentes aplicaciones. Sin embargo, al hacerlo el archivo se comportará como si
formara parte de la aplicación que inició la transferencia (es decir, el archivo sólo tendrá acceso a las
variables con alcance en la aplicación inicial, no en la aplicación en la que realmente reside el archivo).
Por ejemplo, si realiza una transferencia desde un archivo que se encuentra en la aplicación Ventas a
otro que se encuentra en Personal, la aplicación Ventas tomará prestado el archivo de la aplicación
Personal y lo ejecutará como si fuera parte de ella.
ASP proporciona también el comando Server.Execute que permite transferir un archivo, ejecutar el
contenido y volver al archivo que inició la transferencia. Si tiene conocimientos de VBScript, le ayudará
pensar en Server.Execute como análogo a una llamada a un procedimiento, con la diferencia de que en
lugar de ejecutar un procedimiento se ejecuta un archivo .asp completo.
Por ejemplo, la secuencia de comandos siguiente muestra cómo podría utilizar Server.Execute para
incluir archivos .asp de forma dinámica:
<%
.
.
If blnUseDHTML Then
Server.Execute("DHTML.asp")
Else
Server.Execute("HTML.asp")
End If
.
.
%>
Mientras el archivo de destino pertenezca a una aplicación del mismo servidor, la aplicación inicial se
transferirá a este archivo, ejecutará su contenido y continuará con la ejecución del archivo que inició la
transferencia. Igual que sucede con Server.Transfer, al ejecutar un archivo .asp éste se comporta como
si formara parte de la aplicación inicial. Sin embargo, Server.Execute, no funciona cuando los servidores
son distintos. Para obtener más información, consulte Server.Execute.
Enviar contenido al explorador
A medida que se procesa una secuencia de comandos ASP, el texto y los gráficos que no se encuentren
entre delimitadores ASP o etiquetas <SCRIPT> se devuelve directamente al explorador. También puede
enviar explícitamente contenido al explorador mediante el objeto Response.
Enviar contenido
Para enviar contenido al explorador desde delimitadores ASP o desde un procedimiento, utilice el
método Write del objeto Response. Por ejemplo, la instrucción siguiente envía un saludo diferente al
usuario dependiendo de si el usuario ha visitado la página con anterioridad o no:
<%
If blnFirstTime Then
Response.Write "<H3 ALIGN=CENTER>Reciba nuestra bienvenida a la página de introducción</H3>"
Else
Response.Write "<H3 ALIGN=CENTER>Gracias por volver a la página de introducción</H3>"
End If
%>
Fuera de un procedimiento, no tiene que utilizar Response.Write para devolver contenido al usuario. El
contenido que no se encuentra dentro de delimitadores de secuencia de comandos se envía
directamente al explorador, que da formato y presenta este contenido. Por ejemplo, la secuencia de
comandos siguiente produce el mismo resultado que la secuencia de comandos anterior:
<H3 ALIGN=CENTER>
<% If blnFirstTime Then %>
Reciba nuestra bienvenida a la página de introducción.
<% Else %>
Gracias por volver a la página de introducción.
<%End If %>
</H3>
Intercale secuencias de comandos y código HTML cuando tenga que devolver el resultado una vez o
cuando sea más cómodo agregar instrucciones a texto HTML existente. Utilice Response.Write cuando
no desee dividir una instrucción con delimitadores o cuando desee generar la cadena de texto que vaya
a devolver al explorador. Por ejemplo, podría generar una cadena de texto que creara una fila de una
tabla con los valores enviados por un formulario HTML:
Response.Write "<TR><TD>" & Request.Form("Nombre") _
& "</TD><TD>" & Request.Form("Apellido") & "</TD></TR>"
Request.Form devuelve los valores enviados por un formulario HTML (consulte Procesar los datos
introducidos por el usuario).
Nota El carácter & es el carácter de continuación de cadenas de VBScript. El carácter de subrayado (_)
es el carácter de continuación de línea de VBScript.
Secuencias de comandos sencillas
La siguiente secuencia de comandos ilustra las técnicas básicas que se utilizan en las secuencias de
comandos ASP. Si no tiene experiencia en el desarrollo de aplicaciones o nunca ha escrito secuencias
de comandos, éste es un buen lugar para empezar.
Elija un ejemplo en la siguiente lista:
• Variables: Muestra cómo crear y manipular variables en una secuencia de comandos ASP.
• Bucles: Proporciona un ejemplo de las tres construcciones más comunes para crear bucles, For
... Next, Do ... Loop y While ... Wend.
• Operadores condicionales: Ilustra el uso de los operadores condicionales, como If ... Then, en
las secuencias de comandos ASP.
• Matrices: Muestra cómo crear, administrar y tener acceso a matrices.
• Archivos de inclusión del servidor: Muestra el uso de los archivos de inclusión del servidor.
• Funciones y procedimientos: Muestra cómo crear y utilizar funciones y procedimientos en una
secuencia de comandos ASP.

Variables

Todas las aplicaciones escritas a lo largo de la historia, independientemente del lenguaje de


programación empleado, han utilizado variables de algún tipo y las secuencias de comandos ASP no
son una excepción. Tanto VBScript como JScript permiten crear y administrar variables de forma fácil y
sencilla.
Cada lenguaje realiza de forma diferente la declaración de variables. JScript y VBScript son bastante
flexibles en lo que respecta a las variables y su declaración. En VBScript, cualquier variable se considera
automáticamente de tipo Variant si se declara inicialmente con la instrucción Dim. A cada variable se le
asigna un subtipo, como Numeric y Array. JScript es parecido; la variable se declara inicialmente con la
instrucción var. En general, ambos lenguajes tienden a realizar automáticamente gran parte de la
administración de tipos de datos, incluida la conversión de tipos. De hecho, ni siquiera es necesario
emplear las instrucciones Dim o var para utilizar una nueva variable; en sus respectivos lenguajes son
opcionales.

código
Este ejemplo declara varios tipos diferentes de variables, realiza algunas operaciones sencillas en ellas
y las muestra al explorador cliente con los delimitadores especiales de secuencias de comandos <% =
...%>. Se asigna un entero a la variable intVariable, se suma a sí mismo y se envía el resultado al
explorador cliente. A la variable StrVariable se le asigna el nombre, se agrega a Soto y se envía al
explorador cliente. Del mismo modo se declaran o crean, inicializan, manipulan y muestran los valores
booleanos y las fechas.
Observaciones
El último paso de la demostración de la variable de fecha es especialmente interesante. En VBScript,
primero se asigna la variable a una cadena de fecha literal y después se muestra. Después se
restablece y se asigna el valor devuelto por la función Now de VBScript, que devuelve la hora actual del
sistema. El ejemplo de JScript utiliza la función Date de JScript para establecer el literal inicial, para lo
que pasa parámetros a la función, y establecer después la fecha actual del sistema en la variable, sin
pasar parámetros a la función.
<%@ LANGUAGE = VBScript %>
<% Option Explicit %>
<HTML>
<HEAD>
<TITLE>Variable Sample</TITLE>
</HEAD>
<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">
<!-- Display header. -->
<FONT SIZE="4" FACE="ARIAL, HELVETICA">
<B>Variable Sample</B></FONT><BR>
<HR>
<H3>Integer Manipulation</H3>
<%
'Declare variable.
Dim intVar
'Assign the variable an integer value.
intVar = 5
%>
<P><%= intVar %> + <%= intVar %> = <%= intVar + intVar %></P>
<HR>
<H3>String Manipulation</H3>
<%
'Declare variable.
Dim strVar
'Assign the variable a string value.
strVar = "Jemearl"
%>
<P>This example was done by <%= strVar + " Smith" %></P>
<HR>
<H3>Boolean Manipulation</H3>
<%
'Declare variable.
Dim blnVar
'Assign the variable a Boolean value.
blnVar = true
'Output message based on value.
If (blnVar) Then
Response.Write "<P>The Boolean value is True.</P>"
Else
Response.Write "<P>The Boolean value is False.</P>"
End If
%>
<HR>
<H3>Date and Time</H3>
<%
'Declare variable.
Dim dtmVar
'Assign the variable a value.
dtmVar = #08 / 27 / 97 5:11:42pm#
%>
<P>The date and time is <%= dtmVar %>
<%
'Set the variable to the web server date and time.
dtmVar = Now()
%>
<P>The <STRONG>system</strong> date and time is <%= dtmVar %></P>
</BODY>
</HTML>

Bucles

Los bucles representan uno de los mecanismos más importantes de control de flujo en un lenguaje de
programación. Las construcciones en bucle proporcionan la base de cualquier aplicación que deba
realizar una tarea de forma repetitiva, como sumar 1 a una variable, leer un archivo de texto o procesar y
enviar un mensaje de correo electrónico.

código

VBScript y JScript proporcionan varios mecanismos para realizar bucles. Este ejemplo demuestra las
tres instrucciones más comunes para realizar bucles, For ... Next, Do ... Loop y While ... Wend. Estas
tres instrucciones son ligeramente diferentes y la situación indicará cuál de las tres es la más indicada.
Sin embargo, para este ejemplo, cada tipo de instrucción de bucle se utiliza para realizar la misma tarea:
imprimir un saludo cinco veces, cada una de ellas con una fuente mayor. En cada instrucción de bucle
se inicializa la variable i y se define la condición de prueba, de forma que i nunca sea mayor que 5. La
variable se incrementa en 1 unidad en cada iteración del bucle.

<%@ LANGUAGE = VBScript %>


<% Option Explicit %>
<HTML>
<HEAD>
<TITLE>Looping</TITLE>
</HEAD>
<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">
<!-- Display header. -->
<FONT SIZE="4" FACE="ARIAL, HELVETICA">
<B>Looping with ASP</B></FONT><BR>
<HR SIZE="1" COLOR="#000000">
<!-- Looping with a For loop. -->
<%
Dim intCounter
For intCounter = 1 to 5 %>
<FONT SIZE=<% = intCounter %>>
Hello World with a For Loop!<BR>
</FONT>
<% next %>
<HR>
<!-- Looping with a While...Wend loop. -->
<%
intCounter = 1
While(intCounter < 6) %>
<FONT SIZE=<% = intCounter %>>
Hello World with a While Loop!<BR>
</FONT>
<% intCounter = intCounter + 1 %>
<% wend %>
<HR>
<!-- Looping with a Do...While loop. -->
<%
intCounter = 1
Do While(intCounter < 6) %>
<FONT SIZE=<% =intCounter %>>
Hello World with a Do...While Loop!<BR>
</FONT>
<% intCounter = intCounter+1 %>
<% loop %>
</BODY>
</HTML>

Operadores condicionales

Los operadores condicionales, junto con las variables y las construcciones de bucle, forman los pilares
básicos de los lenguajes de programación y, por tanto, de las aplicaciones. Las aplicaciones basadas en
Web que se implementan mediante secuencias de comandos ASP pueden aprovechar el control de flujo
que proporcionan los operadores condicionales, así como la interactividad y la sofisticación de HTML.

código

Este ejemplo demuestra las instrucciones If ... Then o if ... else en VBScript y JScript, así como las
instrucciones Select ... Case y switch ... case, más complejas. La demostración de cada una de estas
instrucciones realiza la misma tarea: enviar una página al explorador cliente con la fecha y la hora
actuales y un saludo. El texto del saludo será "Buenos días" o "Buenas tardes", dependiendo de si en el
reloj del sistema aparece a.m. o p.m.
<%@ LANGUAGE = VBScript %>
<% Option Explicit %>
<HTML>
<HEAD>
<TITLE>Conditional Operator Sample</TITLE>
</HEAD>
<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">
<!-- Display header. -->
<FONT SIZE="4" FACE="ARIAL, HELVETICA">
<B>Conditional Operator Sample</B></FONT><BR>
<HR SIZE="1" COLOR="#000000">
<!-- If...Then example -->
<%
Dim varDate
varDate = Date()
%>
<P>The date is: <%= varDate %></P>
<%
'Select Case statement to display a message based on the day of the month.
Select Case Day(varDate)
Case 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Response.Write("<P>It's the beginning of the month.</P>")
Case 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
Response.Write("<P>It's the middle of the month.</P>")
Case Else
Response.Write("<P>It's the end of the month.</P>")
End Select
%>
<P>The time is: <%= Time %></P>
<%
'Check for AM/PM, and output appropriate message.
If (Right(Time,2)="AM") Then
Response.Write("<P>Good Morning</P>")
Else
Response.Write("<P>Good Evening</P>")
End If
%>
</BODY>
</HTML>

Funciones y procedimientos

Las funciones y los procedimientos proporcionan un método para evitar tener que escribir varias veces
un mismo bloque de código cada vez que desee realizar una tarea determinada. Tanto VBScript como
JScript permiten llamar a una función o a un procedimiento desde cualquier lugar de una secuencia de
comandos. Este ejemplo demuestra cómo puede crear y utilizar estas herramientas en secuencias de
comandos ASP.
Si no tiene ninguna función en la página ASP, el motor ASP se limita a procesar el archivo completo, de
principio a fin, cada vez que lo pide un explorador cliente. Sin embargo, las funciones y los
procedimientos se ejecutan sólo cuando se les llama, no con el resto del código.
En VBScript o JScript las funciones y los procedimientos se indican mediante la instrucción Function.
Además, VBScript establece una diferencia entre una función que devuelve un valor y otra que no lo
hace; la primera de ellas se indica con la instrucción Sub, que la identifica como una subrutina.
código

Este ejemplo define una función, PrintOutMsg, que toma como parámetros un mensaje y un número
que especifica cuántas veces se escribirá el mensaje en el explorador cliente mediante el método

Response.Write. Para este ejemplo, la función se limita a devolver al explorador cliente el número de
veces que se imprimió el mensaje.
Observaciones
Es importante tener en cuenta el atributo RUNAT de la etiqueta <SCRIPT>. SI no se incluye, ASP
asumirá que se trata de una secuencia de comandos del cliente y devolverá el código al explorador para
que lo procese. Esto haría que ASP no reconociera la llamada a la función PrintOutMsg, devolviera un
error y anulara la ejecución.
<%@ LANGUAGE = VBScript %>
<% Option Explicit %>
<SCRIPT LANGUAGE=VBScript RUNAT=Server>
'Define Server Side Script Function.
Function PrintOutMsg(strMsg, intCount)
Dim i
'Output Message count times.
For i = 1 to intCount
Response.Write(strMsg & "<BR>")
Next
'Return number of iterations.
PrintOutMsg = intCount
End Function
</SCRIPT>
<HTML>
<HEAD>
<TITLE>Functions</TITLE>
</HEAD>
<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">
<!-- Display header. -->
<FONT SIZE="4" FACE="ARIAL, HELVETICA">
<B>Server Side Functions</B></FONT><BR>
<P>
The function "PrintOutMsg" prints out a specific message a set number of times.<P>
<%
'Store number of times function printed message.
Dim intTimes
'Call function.
intTimes = PrintOutMsg("This is a function test!", 4)
'Output the function return value.
Response.Write("<p>The function printed out the message " & intTimes & "
times.")
%>
</BODY>
</HTML>

Datos introducidos por el usuario en un formulario con POST

Probablemente, la forma más básica de interactividad Web es el formulario HTML. Es importante tener
en cuenta que ASP no sustituye a los formularios, sino que los mejora y hace que sea más fácil
implementarlos y administrarlos.
La etiqueta HTML <FORM> especifica qué método utilizará el formulario para comunicar la información
a la secuencia de comandos que la procesará. El atributo del método POST indica que la información
del formulario pasará a través de una conexión HTTP independiente a la secuencia de comandos o al
programa que la procesará. La secuencia de comandos o el programa pueden analizar la información y
realizar cualquier tarea que sea necesaria, y devolver el resultado al explorador cliente.
código
Este ejemplo muestra cómo implementar un formulario sencillo mediante el atributo del método POST de
HTTP, así como una de las principales ventajas de la creación de formularios mediante ASP: la
posibilidad de combinar el formulario y el código de proceso real en un mismo archivo. Este ejemplo crea
un pequeño formulario con dos cuadros de entrada de texto, uno para el nombre del usuario (fname) y
otro para el apellido (lname). Para obtener el valor de las variables fname y lname en la petición se tiene
acceso a la colección Request.Forms y después se muestran los resultados en la parte inferior de la
página.
La primera vez que se ejecuta la secuencia de comandos no aparece ningún texto debajo de la línea
horizontal. Esto se debe a que no había información disponible para pasarla a la secuencia de
comandos cuando se inició y ASP pasa por alto las búsquedas de Request.Forms si no existe
información. Sin embargo, si hace clic en el botón Enviar, se cargará de nuevo la página y la secuencia
de comandos ya dispondrá de la información que escribió en los cuadros de texto.
<%@ Language = VBScript %>
<% Option Explicit %>
<HTML>
<HEAD>
<TITLE>Form Posting</TITLE>
</HEAD>
<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">
<!-- Display header. -->
<FONT SIZE="4" FACE="ARIAL, HELVETICA">
<B>Form Posting</B></FONT><BR>
<HR>
<P>This page will take the information entered in the form fields, and use the POST
method to send the data to an ASP page.
<FORM NAME=Form1 METHOD=Post ACTION="Form_VBScript.asp">
First Name: <INPUT TYPE=Text NAME=fname><P>
Last Name: <INPUT TYPE=Text NAME=lname><P>
<INPUT TYPE=Submit VALUE="Submit">
</FORM>
<HR>
<% Response.Write Request.form("fname")%> <BR>
<% Response.Write Request.form("lname")%> <BR>
</BODY>
</HTML>

Llenar los campos

Puede utilizar formularios para recopilar datos de los usuarios, pero también puede utilizarlos para
mostrar información. Por ejemplo, si un explorador cliente tiene acceso al motor de búsqueda de su
directorio de teléfonos, querrá mostrar los resultados de la búsqueda. La secuencia de comandos de
búsqueda (que también puede implementar mediante ASP) acepta los datos introducidos por el usuario,
tiene acceso a la base de datos y envía el resultado al formulario de presentación en una cadena de
consulta. Este ejemplo es una demostración sencilla de cuál sería la apariencia del formulario.

Paseo por el código

Para este ejemplo, los datos se incluyen en el código de la secuencia de comandos pero, obviamente, la
información podría provenir de un formulario interactivo, de una base de datos o de un archivo de texto.
Al iniciarse el ejemplo se inicializan las variables. Después, crea un formulario con las etiquetas HTML
<FORM> y define cuatro cuadros de texto. Por último, con los delimitadores de secuencias de comandos
del servidor <%= ... %>, la secuencia de comandos llena los cuadros de texto con los valores
establecidos en la inicialización.
<%@ LANGUAGE = VBScript %>
<% Option Explicit %>
<%
'Create and set variables that will be used in populating 'the form. In a typical application, these
values would come from a database or text file.
Dim strFirstName
Dim strLastName
Dim strAddress1
Dim strAddress2
Dim blnInfo
strFirstName = "John"
strLastName = "Doe"
strAddress1 = "1 Main Street"
strAddress2 = "Nowhere ZA, 12345"
%>
<HTML>
<HEAD>
<TITLE>PopulateForm Sample</TITLE>
</HEAD>
<BODY BGCOLOR="White" TOPMARGIN="10" LEFTMARGIN="10">
<!-- Display header. -->
<FONT SIZE="4" FACE="ARIAL, HELVETICA">
<B>PopulateForm Sample</B></FONT><BR>
<HR SIZE="1" COLOR="#000000">
<FORM ACTION="">
<!-- Use ASP variables to fill out the form. -->
<P>First Name: <INPUT TYPE="TEXT" NAME="FNAME" VALUE="<%= strFirstName
%>"></P>
<P>Last Name: <INPUT TYPE="TEXT" NAME="LNAME" VALUE="<%= strLastName
%>"></P>
<P>Street: <INPUT TYPE="TEXT" NAME="STREET" VALUE="<%= strAddress1%>"></P>
<P>City State, Zip: <INPUT TYPE="TEXT" NAME="FNAME" VALUE="<%= strAddress2
%>"></P>
</BODY>
</HTML>
Conectividad con bases de datos

Si va a crear una aplicación basada en Web, lo más probable es que tenga formularios. Posiblemente,
también tendrá que conectarla de alguna forma con una base de datos. ActiveX® Data Objects (ADO)
proporciona un conjunto de eficaces herramientas que le permitirán tener acceso a orígenes de datos y
manipularlos.
Los ejemplos de esta sección ilustran las técnicas necesarias para utilizar ADO de forma efectiva y cómo
puede utilizar mejor estas funciones en una aplicación basada en Web.
• Consulta sencilla: Muestra cómo utilizar ADO y ASP para realizar consultas sencillas en una
base de datos.
• Limitar los resultados de una consulta: Muestra cómo es posible utilizar ASP y ADO en las
secuencias de comandos para limitar el número de filas devueltas en un conjunto de registros.
• Consulta desplazable: Muestra cómo realizar con ADO una consulta desplazable
multidireccional.
• Agregar o eliminar registros: Presenta las técnicas necesarias para agregar y eliminar registros
de un origen de datos mediante ASP y ADO.
• Actualizar registros: Muestra cómo utilizar ADO en una aplicación para actualizar los registros
existentes.
• Ejecutar procedimientos almacenados: Muestra cómo utilizar ADO con las secuencias de
comandos ASP para ejecutar procedimientos almacenados de la base de datos.
Para obtener más información acerca de ADO y de las herramientas de acceso a datos de Microsoft en
general, consulte la documentación de Microsoft Data Access.
Consulta sencilla
Introducción
Aunque una base de datos puede ser un sistema muy complicado y las herramientas de acceso a datos
deben ser eficaces y sensibles, es igualmente importante que las tareas sencillas de acceso a bases de
datos sean fáciles de realizar. Este ejemplo demuestra cómo ADO proporciona un método sencillo para
realizar este tipo de tareas.
Paseo por el código
El objetivo de esta aplicación de ejemplo es obtener un pequeño conjunto de registros de una base de
datos de Microsoft® Access e imprimir el resultado. El primer paso consiste en crear una instancia del
objeto Connection mediante el método Server.CreateObject. El ejemplo utiliza la instancia del objeto
Connection para abrir el proveedor de datos OLE DB y, después, para ejecutar un comando SELECT
de SQL y así obtener todos los registros de la tabla Autores. Para terminar, la secuencia de comandos
recorre la colección del conjunto de registros obtenido y muestra los resultados. Después se cierran el
conjunto de registros y la conexión con el origen de datos OLE DB.
Importante OLE DB debe estar correctamente configurado en el servidor para que este ejemplo
funcione correctamente.
<%@ LANGUAGE = VBScript %>
<% Option Explicit %>
<HTML>
<HEAD>
<TITLE>Simple ADO Query</TITLE>
</HEAD>
<BODY BGCOLOR="White" topmargin="10" leftmargin="10">
<!-- Display Header -->
<font size="4" face="Arial, Helvetica">
<b>Simple ADO Query with ASP</b></font><br>
<hr size="1" color="#000000">
Contacts within the Authors Database:<br><br>
<%
Dim oConn
Dim oRs
Dim filePath
Dim Index
' Map authors database to physical path
filePath = Server.MapPath("authors.mdb")
' Create ADO Connection Component to connect
' with sample database
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filePath
' Execute a SQL query and store the results
' within recordset
Set oRs = oConn.Execute("SELECT * From Authors")
%>
<TABLE border = 1>
<%
Do while (Not oRs.eof) %>
<tr>
<% For Index=0 to (oRs.fields.count-1) %>
<TD VAlign=top><% = oRs(Index)%></TD>
<% Next %>
</tr>
<% oRs.MoveNext
Loop
%>
</TABLE>
<%
oRs.close
oConn.close
%>
</BODY>
</HTML>

Agregar o eliminar registros


Introducción
Este ejemplo muestra las técnicas que necesita conocer para utilizar ASP y ADO con el fin de agregar y
eliminar registros de una base de datos.
Paseo por el código
Primero se utiliza CreateObject para crear una instancia del objeto Connection, que a su vez se utiliza
para abrir una conexión con el proveedor de datos OLE DB. Se utiliza de nuevo CreateObject para
crear un objeto Recordset vacío. Se configura la propiedad ActiveConnection para hacer referencia al
nuevo objeto Connection.
Aunque el objeto Recordset de ADO proporciona el método AddNew para agregar nuevos registros a
una base de datos, puede que la escalabilidad mejore si envía comandos INSERT de SQL directamente
al motor de base de datos. Este ejemplo utiliza el comando Recordset.Execute, junto con la cadena de
comandos apropiada de SQL, para insertar información acerca de un nuevo autor.
En este momento se crea otra instancia del objeto Recordset y se abre con otro comando SQL. Se
selecciona el registro recién agregado y se elimina, para lo cual se pasa el comando DELETE de SQL
directamente al motor de base de datos. Por último, finaliza la secuencia de comandos.
Importante OLE DB debe estar correctamente configurado en el servidor para que este ejemplo
funcione correctamente.
<%@ LANGUAGE = VBScript %>
<% Option Explicit %>
<% Response.Expires= -1 %>
<!--METADATA TYPE="typelib"
uuid="00000205-0000-0010-8000-00AA006D2EA4" -->
<HTML>
<HEAD>
<TITLE>Add/Delete Database Sample</TITLE>
</HEAD>
<BODY BGCOLOR="White" topmargin="10" leftmargin="10">
<!-- Display Header -->
<font size="4" face="Arial, Helvetica">
<b>Add/Delete Database Sample</b></font><br>
<hr size="1" color="#000000">
<%
Dim oConn
Dim oRs
Dim filePath
' Map authors database to physical path
filePath = Server.MapPath("authors.mdb")
' Create ADO Connection Component to connect with sample database
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filePath
' To add, delete and update recordset, it is recommended to use
' direct SQL statement instead of ADO methods.
oConn.Execute "insert into authors (author, YearBorn) values ('Paul Enfield', 1967)"
' Output Result
Set oRs = oConn.Execute (" select * from authors where Author= 'Paul Enfield'
and YearBorn =1967 " )
Response.Write("<p>Inserted Author: " & oRs("Author") & "," & oRs("YearBorn"))
' Close Recordset
oRs.Close
Set oRs= Nothing
' Delete the inserted record
oConn.Execute "Delete From authors where author='Paul Enfield' and YearBorn
= 1967 "
' Output Status Result
Response.Write("<p>Deleted Author: Paul Enfield, 1967")
%>
</BODY>
</HTML>
Actualizar registros
Introducción
Este ejemplo muestra cómo utilizar ADO en una aplicación para actualizar los registros existentes.
Paseo por el código
Primero se utiliza CreateObject para crear una instancia del objeto Connection, que a su vez se utiliza
para abrir una conexión con el proveedor de datos OLE DB. Se utiliza de nuevo CreateObject para
crear un objeto Recordset vacío. Se configura la propiedad ActiveConnection para hacer referencia al
nuevo objeto Connection.
Después se configura el nuevo conjunto de registros. El método Recordset.Execute utiliza como
parámetro una cadena de comandos SQL. Este ejemplo utiliza una cadena de comandos UPDATE de
SQL para realizar la actualización en los registros adecuados de la base de datos.
<%@ LANGUAGE = VBScript %>
<% Option Explicit %>
<!--METADATA TYPE="typelib"
uuid="00000205-0000-0010-8000-00AA006D2EA4" -->
<HTML>
<HEAD>
<TITLE>Update Database</TITLE>
</HEAD>
<BODY BGCOLOR="White" topmargin="10" leftmargin="10">
<!-- Display Header -->
<font size="4" face="Arial, Helvetica">
<b>Update Database</b></font><br>
<hr size="1" color="#000000">
<%
Dim oConn ' object for ADODB.Connection obj
Dim oRs ' object for output recordset object
Dim filePath ' Directory of authors.mdb file
' Map authors database to physical path
filePath = Server.MapPath("authors.mdb")
' Create ADO Connection Component to connect with sample database
Set oConn = Server.CreateObject("ADODB.Connection")
oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filePath
' To add, delete and update recordset, it is recommended to use
' direct SQL statement instead of ADO methods.
oConn.Execute "Update Authors Set Author ='Scott Clinton'" _
& "where Author='Scott Guthrie' "
Set oRs = oConn.Execute ( "select * from Authors where author" _
& "= 'Scott Clinton'" )
%>
Changed Author: <%= oRs("Author") %>, <%= oRs("Yearborn") %> <P>
<%
oConn.Execute "Update Authors Set Author ='Scott Guthrie'" _
& "where Author='Scott Clinton' "
Set oRs = oConn.Execute ( "select * from Authors where author" _
& "= 'Scott Guthrie'" )
%>
Changed Author: <%= oRs("Author") %>, <%= oRs("Yearborn") %>
</BODY>
</HTML>
MapPath
El método MapPath asigna al directorio físico correspondiente del servidor la ruta virtual o relativa
especificada.
Sintaxis
Server.MapPath( Ruta )
Parámetros
Ruta
Especifica la ruta virtual o relativa que se asignará a un directorio físico. Si Ruta comienza con una barra
diagonal (/) o con una barra diagonal inversa (\), el método MapPath devuelve la ruta como si Ruta fuera
una ruta virtual completa. Si Ruta no comienza con una barra diagonal, el método MapPath devuelve
una ruta relativa al directorio del archivo .asp que se procesa.
Observaciones
El método MapPath no comprueba si la ruta que devuelve existe en el servidor o si es válida.
Como el método MapPath asigna la ruta independientemente de si los directorios especificados existen
o no, puede utilizarlo para asignar una ruta a una estructura física de directorios y, después, pasarla a un
componente que cree en el servidor el directorio o el archivo especificado.
Puede utilizar la sintaxis de ruta relativa para el parámetro Ruta si el valor de la propiedad
AspEnableParentPaths es TRUE (que es el valor predeterminado). Si le preocupa permitir que las
secuencias de comandos tengan acceso a la estructura física de directorios, puede deshabilitar esta
característica si asigna el valor FALSE a la propiedad AspEnableParentPaths. Para ello puede utilizar
el complemento Servicios de Internet Information Server o una secuencia de comandos.

Ejemplo
Para los siguientes ejemplos, el archivo data.txt se encuentra en el directorio C:\Inetpub\Wwwroot\Script,
al igual que el archivo test.asp, que contiene las siguientes secuencias de comandos. El directorio
C:\Inetpub\Wwwroot se establece como directorio particular del servidor.
El siguiente ejemplo utiliza la variable de servidor PATH_INFO para asignar la ruta física al archivo
actual. La siguiente secuencia de comandos
<%= server.mappath(Request.ServerVariables("PATH_INFO"))%><BR>
produce el resultado
c:\inetpub\wwwroot\script\test.asp<BR>
Como los parámetros de la ruta de los siguientes ejemplos no empiezan con un carácter de barra
diagonal, se asignan de forma relativa al directorio actual, en este caso C:\Inetpub\Wwwroot\Script. Las
siguientes secuencias de comandos
<%= server.mappath("data.txt")%><BR>
<%= server.mappath("script/data.txt")%><BR>
producen el siguiente resultado
c:\inetpub\wwwroot\script\data.txt<BR>
c:\inetpub\wwwroot\script\script\data.txt<BR>
Los dos ejemplos siguientes utilizan el carácter de barra diagonal para especificar que la ruta que se
obtiene debe buscarse como ruta virtual completa del servidor. Las siguientes secuencias de comandos
<%= server.mappath("/script/data.txt")%><BR>
<%= server.mappath("\script")%><BR>
producen el siguiente resultado
c:\inetpub\wwwroot\script\data.txt<BR>
c:\inetpub\wwwroot\script<BR>
Los siguientes ejemplos muestran cómo puede utilizar una barra diagonal (/) o una barra diagonal
inversa (\) para obtener la ruta física al directorio particular. Las siguientes secuencias de comandos
<%= server.mappath("/")%><BR>
<%= server.mappath("\")%><BR>
producen el siguiente resultado
c:\inetpub\wwwroot<BR>
c:\inetpub\wwwroot<BR>
El siguiente documento es un manual de ASP, trata los principales comandos de ASP, desde lo mas
sencillo o lo intermedio, comandos y utilidades basicas para el desarrollo de paginas Web interactivas,
haciendo uso del Microsoft Internet Information Service.
Dicho manual fue tomado de los principales puntos de la ayuda de Windows 2000 Professional. P.P/p.p.

http://www.softdownload.com.ar
 
1.2.LENGUAJE PHP

Historia de PHP
PHP es un lenguaje creado por una gran comunidad de personas. El sistema fue desarrollado originalmente en el
año 1994 por Rasmus Lerdorf como un CGI escrito en C que permitía la interpretación de un número limitado de
comandos. El sistema fue denominado Personal Home Page Tools y adquirió relativo éxito gracias a que otras
personas pidieron a Rasmus que les permitiese utilizar sus programas en sus propias páginas. Dada la aceptación
del primer PHP y de manera adicional, su creador diseñó un sistema para procesar formularios al que le atribuyó el
nombre de FI (Form Interpreter) y el conjunto de estas dos herramientas, sería la primera versión compacta del
lenguaje: PHP/FI.

La siguiente gran contribución al lenguaje se realizó a mediados del 97 cuando se volvió a programar el analizador
sintáctico, se incluyeron nuevas funcionalidades como el soporte a nuevos protocolos de Internet y el soporte a la
gran mayoría de las bases de datos comerciales. Todas estas mejoras sentaron las bases de PHP versión 3.
Actualmente PHP se encuentra en su versión 4, que utiliza el motor Zend, desarrollado con mayor meditación
para cubrir las necesidades actuales y solucionar algunos inconvenientes de la anterior versión. Algunas mejoras de
esta nueva versión son su rapidez -gracias a que primero se compila y luego se ejecuta, mientras que antes se
ejecutaba mientras se interpretaba el código-, su mayor independencia del servidor web -creando versiones de PHP
nativas para más plataformas- y un API más elaborado y con más funciones.
Gráfica del número de dominios y direcciones IP que utilizan PHP.Estadística de Netcraft.En el último año, el
número de servidores que utilizan PHP se ha disparado,logrando situarse cerca de los 5 millones de sitios y 800.000
direcciones IP, lo que le ha convertido a PHP en una tecnología popular.

¿Qué es PHP?
El lenguaje PHP es un lenguaje de programación de estilo clásico, es decir, es un lenguaje de programación con
variables, sentencias condicionales, ciclos (bucles), funciones…. No es un lenguaje de marcado como podría ser
HTML, XML o WML. Está más cercano a JavaScript o a C, para aquellos que conocen estos lenguajes.
Pero a diferencia de JavaScript que se ejecuta en el navegador, PHP se ejecuta en el servidor, por eso nos permite
acceder a los recursos que tenga el servidor como por ejemplo podría ser una base de datos. El programa PHP es
ejecutado en el servidor y el resultado enviado al navegador. El resultado es normalmente una página HTML pero
igualmente podría ser una pagina WML.

Al ser PHP un lenguaje que se ejecuta en el servidor no es necesario que su navegador lo soporte, es
independiente del browser, pero sin embargo para que las páginas PHP funcionen, el servidor donde están alojadas
debe soportar PHP.

¿Qué se necesita para que funcione PHP?

_ Versión compilada de PHP (http://www.php.net).


_ Un servidor web (Apache, PWS, IIS, Etc.).
_ Si desea manejar base de datos se recomienda Mysql Server
(http://www.mysql.com).

Iniciar con PHP

_ Instalar el servidor WEB. Trabajaremos con sistemas operativos Microsoft Windows (2000 Professional y XP
Professional), por lo que vamos a instalar un IIS (versión 5 para w2k y 5.1 para wXP).

Para instalarlo tenemos que seguir los siguientes pasos:


_ Ir al panel de control de Microsoft Windows©
_ Seleccionar lo opción Agregar o quitar programas
_ Seleccionar la opción de Agregar o quitar componentes y ahí elegir la
opción Servicios de Internet Information Server (IIS)

_ Tenemos que esperar a que se instale


_ Después de estos pasos ya esta instalado nuestro servidor de web que
necesitamos para ejecutar páginas de Internet.
La forma de saber si se ha instalado correctamente nuestro servidor es tecleando en la barra de direcciones de
nuestro navegador (Internet Explorer o Netscape Navigator) la siguiente dirección http://localhost y nos debe
aparecer la siguiente página web:

_ Instalar el modulo de PHP.


Los pasos para instalar el modulo de PHP son los siguientes:
_ Al iniciar el programa de instalación veremos la siguiente pantalla.
_ La siguiente pantalla es la de bienvenida, solo hay que presionar el botón de Next >.
_ La pantalla que sigue es la licencia de PHP, si la aceptamos debemos de presionar I Agree.

_ Lo que sigue es elegir el tipo de instalación, cuenta con dos opciones, estándar y avanzado, para nuestras
necesidades elegiremos la forma estándar, por lo tanto seleccionamos el botón de radio que dice Standar.
_ Ahora tendremos que elegir el directorio en el cual se instalará el PHP, el instalador trae por default el directorio
C:\PHP, lo dejaremos así, por lo tanto presionamos Next.
_ Lo que nos pide la siguiente pantalla son los datos para el administrador del sistema por si falla algo en PHP, para
este curso solo presionamos Next, pero también puede introducir una dirección válida.

_ Ahora se nos pregunta el tipo de servidor que estamos utilizando, como ya había mencionado antes, asaremos IIS
versión 5 y 5.1, por lo tanto seleccionamos el botón de radio que tiene la opción de Microsoft IIS 4 or higher.
_ La siguiente pantalla nos avisa que ya esta listo para instalar PHP, así que
solo presionamos Next.
_ Veremos como va el proceso de la instalación.

_ La siguiente pantalla lo que nos dice es que seleccionemos que parte del IIS queremos que ejecute PHP, como
solo tenemos instalado el servicio de web, solo nos presenta esa opción, pero con eso es suficiente, así que
seleccionamos el checkbox que dice WWW Service Master Properties.
_ Por ultimo nos dice que la instalación se ha completado y estamos listo para
ejecutar PHP en nuestro servidor.
La forma de saber si se ha instalado correctamente el PHP en nuestro servidorhaciendo un pequeño programita
PHP, el mas básico que nos servirá de prueba para ver sise ha instalado correctamente, entonces abrimos un editor
de texto cualquiera (con el cualharemos nuestros programas PHP, puede ser el NotePad), y escribimos las
siguientes
líneas:
<?
phpinfo();
?>
después de escribir estas líneas guardamos nuestro archivo en el directorio c:\inetpub\wwroot\taller\ el cual va a
ser nuestro directorio de trabajo para este curso,(como información, el IIS utiliza como directorio raíz el directorio
c:\inetpub\wwroot), le pondremos al archivo prueba.php ahora tecleamos en la barra de direcciones de nuestro

navegador (Internet Explorer o Netscape Navigator) la siguiente dirección http://localhost/taller/prueba.php y nos


debe aparecer la siguiente página web: si no aparece esta página, entonces esta mal instalado el PHP y hay que
volverlo a instalar, aunque hay algunas ocasiones que se necesita reiniciar el sistema para que funcione.

Programación con PHP

Ahora que ya tenemos instalado nuestro servidor y el modulo de PHP, podemos


iniciar ha hacer programas PHP, pero ¿Cómo hacerlos?, un ejemplo nos aclarará las cosas:
<html>
<head>
<title>Ejemplo PHP</title>
</head>
<body>
<?php echo "Hola, este es un ejemplo con PHP"; ?>
</body>
</html>
Podemos ver que no es lo mismo que un script CGI escrito en otro lenguaje de programación como Perl o C -- En
vez de escribir un programa con muchos comandos para crear una salida en HTML, escribimos el código HTML con
cierto código PHP embebido (introducido) en el mismo, que producirá cierta salida (en nuestro ejemplo, producir un
texto). El código PHP se incluye entre etiquetas especiales de comienzo y final que nos permitirán entrar y salir del
modo PHP.
Pero cuales son estas etiquetas especiales de comienzo y final??, esto nos lleva a que hay 4 formas de salir de
HTML y entrar en modo PHP, las cuales son las siguientes:
• <? echo (“Forma 1"); ?>
• <?php echo(“Forma 2"); ?>
• <script language="php"> echo (“Forma 3"); </script>
• <% echo("Etiquetas tipo ASP"); %>

Separación de instrucciones
Las instrucciones se separan igual que en C o Pascal terminando cada sentencia con un punto y coma.
La etiqueta de cierre ( ?> ) también implica el fin de la sentencia, así lo siguiente es equivalente:
<?php echo "Esto es una prueba"; ?>
<?php echo "Esto es una prueba" ?>

Comentarios en PHP

PHP soporta comentarios tipo 'C', 'C++' y Shell de Unix. Por ejemplo:
<?php
echo “Prueba"; // Comentario tipo C++ para una línea
?>

<?php
/*
Esto es un comentario multilínea
otra línea más de comentario
*/
echo "Esto es aún otra prueba"; ?>
<?php
echo "Prueba"; # Comentario tipo shell de Unix
?>

Variables
Antes de ver como se utilizan las variables en PHP veremos una pequeña introducción a las variables, para los que
no conozcan que es una variable. Una variable consiste en un elemento al cual le damos un nombre y le atribuimos
un determinado tipo de información. Las variables pueden ser consideradas como la base de la
programación.De este modo podríamos escribir en un lenguaje ficticio:
a="perro"
b="muerde"
La variable que nosotros llamamos "a" posee un elemento de información de tipo texto que es "perro". Asimismo, la
variable "b" contiene el valor "muerde". Podríamos definir una tercera variable que fuese la suma de estas dos:
c=a+b
Si introdujésemos una petición de impresión de esta variable en nuestro lenguaje ficticio:
imprimir(c)
El resultado podría ser:
perro muerde
Podríamos de la misma forma trabajar con variables que contuviesen números y construir nuestro programa:
a=3
b=4
c=a+b

imprimir(c)
El resultado de nuestro programa sería:7
En PHP las variables se representan como un signo de pesos seguido por el nombre de la variable. El nombre de la
variable es sensible a minúsculas y mayúsculas.
$var = "Santana";
$Var = "Pedro";
echo "$var, $Var";
// produce la salida “Santana, Pedro"
Variables variables
A veces es conveniente tener nombres de variables variables. Dicho de otro modo,son nombres de variables que se
pueden establecer y usar dinámicamente. Una variable normal se establece con una sentencia como:
$a = "Hola";
Una variable variable toma el valor de una variable y lo trata como el nombre de una variable. En el ejemplo anterior,
Hola, se puede usar como el nombre de una variableutilizando dos signos de peso. p.ej.
$$a = "mundo";
Probemos las siguientes sentencias:
echo "$a ${$a}";
echo "$a $Hola";
Los dos no regresarán “Hola mundo”

Tipos de datos

Enteros:
Los enteros se puede especificar usando una de las siguientes sintaxis:
$a = 1234; # número decimal
$a = -123; # un número negativo
$a = 0123; # número octal (equivalente al 83 decimal)
$a = 0x12; # número hexadecimal (equivalente al 18 decimal)

Números en punto flotante:


Los números en punto flotante ("double") se pueden especificar utilizando
cualquiera de las siguientes sintaxis:
$a = 1.234;
$a = 1.2e3;

Cadenas:
El único operador de cadenas que existen es el de concatenación, el punto. Pero no
se preocupen, PHP dispone de toda una gama de funciones que nos permitirán trabajar
cómodamente con las cadenas.
$a = "Hola";
$b = $a . "Mundo"; // Ahora $b contiene "Hola Mundo"
En este punto hay que hacer una distinción, la interpretación que hace PHP de las

simples y dobles comillas. En el segundo caso PHP interpretará el contenido de la cadena.


$a = "Mundo";
echo = 'Hola $a'; //Esto escribirá "Hola $a"
echo = "Hola $a"; //Esto escribirá "Hola Mundo"
Si la cadena está encerrada entre dobles comillas ("), las variables que estén dentro de la cadena serán expandidas
(sujetas a ciertas limitaciones de interpretación). Como en C y en Perl, el carácter de barra invertida ("\") se puede
usar para especificar caracteres especiales:

Caracteres protegidos
\n Nueva línea
\r Retorno de carro
\t Tabulación horizontal
\\ Barra invertida
\$ Signo del dólar
\" Comillas dobles
\[0-7]{1,3} La secuencia de caracteres que coincida con la expresión regular es
un carácter en notación octal
\x[0-9A-Faf]{
1,2}
La secuencia de caracteres que coincida con la expresión regular es
un carácter en notación hexadecimal

Operadores de Comparación:
$a < $b $a menor que $b
$a > $b $a mayor que $b
$a <= $b $a menor o igual que $b
$a >= $b $a mayor o igual que $b
$a == $b $a igual que $b
$a != $b $a distinto que $b
Operadores Lógicos:

$a AND $b Verdadero si ambos son verdadero


$a && $b Verdadero si ambos son verdadero
$a OR $b Verdadero si alguno de los dos es verdadero
$a !! $b Verdadero si alguno de los dos es verdadero
$a XOR $b Verdadero si sólo uno de los dos es verdadero
!$a Verdadero si $a es falso

Operadores de Asignación:

$a = $b Asigna a $a el contenido de $b
$a += $b Le suma a $b a $a
$a -= $b Le resta a $b a $a
$a *= $b Multiplica $a por $b y lo asigna a $a
$a /= $b Divide $a por $b y lo asigna a $a
$a .= $b Añade la cadena $b a la cadena $a

Operadores Bit a bit

Los operadores bit a bit te permiten activar o desactivar bits individuales de un entero.

ejemplo nombre resultado

$a &
$b Y Se activan los bits que están activos tanto en $a como $b.
$a |
$b O Se activan los bits que están activos en $a o que lo están
en $b.
$a ^
$b Xor ("o exclusiva") Se activan los bits que están activos en $a o en $b pero
no en ambos a la vez.
~ $a No Se activan los bits que no están activos en $a.
$a
<<
$b
Desplazamiento a la izquierda Desplaza los bits de $a, $b posiciones hacia la izquierda
(por aritmética binaria, cada posición desplazada equivale a multiplicar por dos el valor de $a)
$a Desplazamiento a la Desplaza los bits de $a, $b posiciones hacia la derecha

ejemplo nombre resultado

>>
$b
derecha (por aritmética binaria, cada posición desplazadaequivale a dividir entre dos el valor de $a)
Para demostrar el uso de algunos operadores mostraré algunos ejemplos en PHP: El siguiente programa calcula el
salario de un trabajador con un impuesto
<html>
<body>
<?php
$SalarioTrabajador = 3500;
$Impuesto = 20; // Porcentaje
$SueldoReal = $SalarioTrabajador - (($SalarioTrabajador /
100) * $Impuesto);
echo “Sueldo del trabajador sin impuesto:
$SalarioTrabajador<BR>”;
echo “Con el impuesto :$SueldoReal”;
?>
</body >
</html>
Programa en PHP que calcula el área de un triangulo cuya formula es a=(b*h)/2
<?php
$Base=15;
$Altura=12;
$Area = ($Base * $Altura)/2;
printf (“El area del triangulo es: $Area”);
?>
Programa que dados 2 números calcule la suma, resta, multiplicación, división, y modulo.
<?php
$Num1=8;
$Num2=5;
printf(“La suma de $Num1 y $Num2 es: <b>%d</b><br>”, $Num1 +
$Num2 );
printf(“La resta de $Num1 y $Num2 es: <b>%d</b><br>”, $Num1
- $Num2 );
printf(“La multiplicación de $Num1 y $Num2 : <b>%d</b><br>”,
$Num1 * $Num2 );
printf(“La division de $Num1 y $Num2: <b>%0.2f</b><br>”,
$Num1 / $Num2 );
printf(“El modulo de $Num1 y $Num2 es <b>%0.1f</b><br>”,
$Num1 % $Num2 );
?>

Constantes

PHP define varias constantes y proporciona un mecanismo para definir más en tiempo de ejecución. Las constantes
son como las variables, salvo por las dos circunstancias de que las constantes deben ser definidas usando la
función define(), y que no pueden ser redefinidas más tarde con otro valor. Las constantes predefinidas (siempre
disponibles) son:
__FILE__

El nombre del archivo de comandos que está siendo interpretado


actualmente. Si se usa dentro de un archivo que ha sido incluido o requerido,
entonces se da el nombre del archivo incluido, y no el nombre del archivo
padre.
__LINE__

El número de línea dentro del archivo que está siendo interpretado en la


actualidad. Si se usa dentro de un archivo incluido o requerido, entonces se
da la posición dentro del archivo incluido.
PHP_VERSION
La cadena que representa la versión del analizador de PHP en uso en la actualidad.
PHP_OS
El nombre del sistema operativo en el cuál se ejecuta el analizador PHP.
TRUE
Valor verdadero.
FALSE
Valor falso.
E_ERROR
Denota un error distinto de un error de interpretación del cual no es posible recuperarse.
E_WARNING
Denota una condición donde PHP reconoce que hay algo erróneo, pero continuará de todas formas; pueden ser
capturados por el propio archivo de comandos.

E_PARSE
El interprete encontró sintaxis inválida en el archivo de comandos. La
recuperación no es posible.
E_NOTICE
Ocurrió algo que pudo ser o no un error. La ejecución continúa. Los ejemplos incluyen usar una cadena sin comillas
como un índice "hash", o acceder a una variable que no ha sido inicializada. Las constantes E_* se usan
típicamente con la función error_reporting() para configurar el nivel de informes de error. Se pueden definir
constantes adicionales usando la función define(). Nótese que son constantes, con una constante sólo se pueden
representar datos escalares válidos. Veremos un ejemplo del uso de estas constantes:
<?php
function report_error($archivo, $linea, $mensaje) {
echo "Un error ocurrió en $archivo en la línea $linea:
$mensaje.";
}
report_error(__FILE__,__LINE__, "Algo esta mal!");
?>
Ahora veremos como definir nuestras propias constantes:
<?php
define("CONSTANTE", "Hola mundo.");
echo CONSTANTE; // muestra "Hola mundo."
?>

Sentencias de control
Las sentencias de control permiten ejecutar bloque de códigos dependiendo de unas condiciones. Para PHP el 0 es
equivalente a Falso y cualquier otro número es Verdadero.
if...else
La sentencia if...else permite ejecutar un bloque de instrucciones si la condición es Verdadera y otro bloque de
instrucciones si ésta es Falsa. Es importante tener en cuenta que la condición que evaluemos ha de estar encerrada
entre paréntesis (esto es aplicable a todas la sentencias de control).

if (condición) {
Este bloque se ejecuta si la condición es VERDADERA
} else {
Este boque se ejecuta si la condición es FALSA
}
Existe una forma sencilla de usar la sentencia IF cuando no tenemos que usar el else y solo tenemos que ejecutar
una línea de código.
if ($a > 4) echo "$a es mayor que 4";
Ahora realizaremos un ejemplo con mas con IF el cual consistirá en un pequeño juego de adivinanzas el cual
necesitará de dos archivos adivina.htm y adivina.php, en este ejemplo se utilizará un formulario, lo cual aun no
hemos visto, se usa solo para muestra, por el momento no es muy importante conocer esa teoría sino un poco mas
adelante.

adivina.htm
<HTML>
<BODY>
<FORM METHOD=GET ACTION="adivina.php">
En que numero del 1 al 10 estoy pensando?
<INPUT NAME="adivina" TYPE="Text">
<BR>
<BR>
<INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>
adivina.php
<HTML>
<HEAD></HEAD>
<BODY>
<?php
srand((double)microtime()*1000000);
$Numero = rand(1,10);
if ($adivina > $Numero) {
echo "Fue muy grande"; echo "<BR>Yo pensé el número
$Numero. Lo siento no ";
}
if ($adivina < $Numero) {
echo "Fue muy pequeño"; echo "<BR>Yo pensé el número
$Numero. Lo siento no ";
}
?>

GANASTE
</BODY>
</HTML>

if...elseif...else
La sentencia IF...ELSEIF...ELSE permite ejecutar varias condiciones en cascada. Para este caso veremos un
ejemplo, en el que utilizaremos los operadores lógicos.
<?php
if ($nombre == ""){
echo "Tú no tienes nombre";
} elseif (($nombre=="eva") OR ($nombre=="Eva")) {
echo "
echo "Tu nombre es EVA";
} else {
echo "Tu nombre es " . $nombre;
}
switch...case...default
Una alternativa a if...elseif...else, es la sentencia switch, la cuál evalúa y compara cada expresión de la sentencia
case con la expresión que evaluamos, si llegamos al final de la lista de case y encuentra una condición Verdadera ,
ejecuta el código de bloque que haya en default. Si encontramos una condición verdadera debemos ejecutar un
break para que la sentencia switch no siga buscando en la lista de case. Veamos un ejemplo.
<?php
switch ($dia) {
case "Lunes":
echo "Hoy es Lunes";
break;
case "Martes":
echo "Hoy es Martes";
break;
case "Miercoles":
echo "Hoy es Miercoles";
break;
case "Jueves":
echo "Hoy es Jueves";
break;
case "Viernes":
echo "Hoy es Viernes";
break;
case "Sábado":
echo "Hoy es Sábado";
break;
case "Domingo":
echo "Hoy es Domingo";
break;
default:
echo "Esa cadena no corresponde a ningún día de la
semana";

}
?>

while
La sentencia while ejecuta un bloque de código mientras se cumpla una determinada
condición.
<?php
$num = 1;
while ($num < 5) {
echo $num;
$num++
}
?>
Podemos romper un ciclo while utilizando la sentencia break.
<?php
$num = 1;
while ($num < 5) {
echo $num;
if ($num == 3){
echo "Aquí nos salimos \n";
break
}
$num++
}
?>
do...while

Esta sentencia es similar a while, salvo que con esta sentencia primero ejecutamos
el bloque de código y después se evalúa la condición, por lo que el bloque de código se
ejecuta siempre al menos una vez.
<?php
$num = 1;
do {
echo $num;
if ($num == 3){
echo "Aquí nos salimos \n";
break
}
$num++
} while ($num < 5);
?>

for

El ciclo for no es estrictamente necesario, cualquier ciclo for puede ser sustituido fácilmente por otro while. Sin
embargo, el ciclo for resulta muy útil cuando debemos ejecutar un bloque de código a condición de que una variable
se encuentre entre un valor mínimo y otro máximo. El ciclo for también se puede romper mediante la sentencia
break.
<?php
for ($num = 1; Snum <=5; $num++){
echo $num;
if ($num == 3){
echo "Aquí nos salimos \n";
break
}
}
?>
A continuación muestro las 4 formas en que se puede usar el ciclo for.
/* ejemplo 1 */
for ($i = 1; $i <= 10; $i++) {
print $i;
}
/* ejemplo 2 */
for ($i = 1;;$i++) {
if ($i > 10) {
break;
}
}
print $i;
}
/* ejemplo 3 */
$i = 1;
for (;;) {
if ($i > 10) {
break;
}
print $i;
$i++;
}

/* ejemplo 4 */
for ($i = 1; $i <= 10; print $i, $i++) ;
Hay que realizar los siguientes programas con ciclos.
· Imprima los números del 1 al 100
for ($i = 1; $i <= 100; print $i."<br>", $i++) ;

· Imprima los números pares del 1 al 100


for ($i = 2; $i <= 100; print $i."<br>", $i=$i+2) ;
· Un programa que le des un número y obtenga su tabla de multiplicar (tablas.php)
tablas.php
<?php
$numero=4;
for ($i=1; $i<=10; $i++)
{
echo $i." x ".$numero." = ".$i*$numero."<br>";
}
?>
Vectores (tablas)

Las tablas (o array en inglés), son muy importantes en PHP, ya que generalmente, las funciones que devuelven
varios valores, como las funciones ligadas a las bases de datos, lo hacen en forma de tabla. En PHP disponemos de
dos tipos de tablas. El primero sería el clásico, utilizando
índices:
<?php
$ciudad[] = "París";
$ciudad[] = "México";
$ciudad[] = "Roma";
$ciudad[] = "Sevilla";
$ciudad[] = "Londres";
print ("yo vivo en " . $ciudad[1] . "<BR>\n");
?>
Esta es una forma de asignar elementos a una tabla, pero una forma más formal es
utilizando la función array
<?php
$ciudad = array("París", "Roma", "Sevilla", "Londres");
//contamos el número de elementos de la tabla
$numelentos = count($ciudad);
//imprimimos todos los elementos de la tabla
for ($i=0; $i < $numelentos; $i++)
{
print ("La ciudad $i es $ciudad[$i] <BR>\n");
}
?>
Sino se especifica, el primer índice es el cero, pero podemos utilizar el operador =>
para especificar el índice inicial.

$ciudad = array(1=>"París", "Roma", "Sevilla", "Londres");


Un segundo tipo, son las tablas asociativas, en las cuáles a cada elemento se le asigna un valor (key) para
acceder a él. Para entenderlo, que mejor que un ejemplo, supongamos que tenemos una tabla en al que cada
elemento almacena el número de visitas a nuestra web por cada día de la semana. Utilizando el método clásico de
índices, cada día de la semana se representaría por un entero, 0 para lunes, 1 para martes, etc.
$visitas[0] = 200;
$visitas[1] = 186;
Si usamos las tablas asociativas sería
$visitas["lunes"] = 200;
$visitas["martes"] = 186;
o bien,
$visitas = array("codigo">$visitas = array("lunes"=>200;
"martes"=>186);

Ahora bien, recorrer una tabla y mostrar su contenido es sencillo utilizando los índices, pero ¿cómo hacerlo en las
tablas asociativas?. La manipulación de las tablas asociativas se a hace través de funciones que actúan sobre un
puntero interno que indica laposición. Por defecto, el puntero se sitúa en el primer elemento añadido en la tabla,
hasta que es movido por una función:
current - devuelve el valor del elemento que indica el puntero.
pos - realiza la misma función que current
reset - mueve el puntero al primer elemento de la tabla
end - mueve el puntero al último elemento de la tabla
next - mueve el puntero al elemento siguiente
prev - mueve el puntero al elemento anterior
count - devuelve el número de elementos de una tabla.
Veamos un ejemplo de las funciones anteriores:
<?php
$semana = array("lunes", "martes", "miércoles", "jueves",
"viernes", "sábado", "domingo");
echo count($semana); //7
//situamos el puntero en el primer elemento
reset($semana);
echo current($semana); //lunes

next($semana);
echo pos($semana); //martes
end($semana)
echo pos($semana); //domingo
prev($semana);
echo current($semana); //sábado
?>
Recorrer una tabla con las funciones anteriores se hace un poco enredoso, para ello se
recomienda utilizar la función each().
<?php
$visitas = array("lunes"=>200, "martes"=>186,
"miércoles"=>190, "jueves"=>175);
reset($visitas);
while (list($clave, $valor) = each($visitas))
{
echo "el día $clave ha tenido $valor visitas<BR>";
}
?>
La función each() devuelve el valor del elemento actual, en este caso, el valor del
elemento actual y su clave, y desplaza el puntero al siguiente, cuando llega al final
devuelve falso, y termina el bucle while().

Tablas multidimensionales
Las tablas multidimensionales son simplemente tablas en las cuales cada elemento
es a su vez otra tabla.
<?php
$calendario[] = array (1, "enero", 31);
$calendario[] = array (2, "febrero", 28);
$calendario[] = array (3, "marzo", 31);
$calendario[] = array (4, "abril", 30);
$calendario[] = array (5, "mayo", 31);
while (list($clave, $valor ) = each($calendario)){
{
$cadena = $valor[1];
$cadena .= " es el mes número " . $valor[0];
$cadena .= "y tiene " . $varlor[2] . " días<BR>";
echo $cadena;
}
?>
La función list() es más bien un operador de asignación, lo que hace es asignar valores a unas lista de variables. En
este caso los valores son extraídos de una tabla por la función each().

Formularios

Los Formularios no forman parte de PHP, sino del lenguaje estándar de Internet, HTML, pero como éstos van a
aparecer muchas veces durante el curso, vamos a dedicar esta algunas líneas a ellos.
Todo formulario comienza con la etiqueta <FORM ACTION="lo_que_sea.php" METHOD="post/get">. Con
ACTION indicamos el script que va procesar la información que recogemos en el formulario, mientras que METHOD
nos indica si el usuario del formulario va ha enviar datos (post) o recogerlos (get). La etiqueta </FORM>
indica el final del formulario.
A partir de la etiqueta <FORM> vienen los campos de entrada de datos que pueden ser:
Botón de comando:
<input type="submit" value="enviar" name="enviar">
Cuadro de texto:
<input type="text" name="nombre" size="20" value="jose">
Veamos un ejemplo con PHP:
Las siguientes dos paginas tienen el objetivo de preguntar cual es tu equipo de fútbol
favorito y desplegar en otra pagina el seleccionado (equipo.htm y equipo.php).

equipo.htm
<html>
<title>Equipo Favorito</title>
<body>
<form method=post ACTION=”equipo.php”>
Cual es tu equipo de fútbol favorito ?
<input name=”equipo” type “TEXT”>
<br>
<br>
<input type=submit>
</form>
</body>
<html>

equipo.php
<html>
<body>
Tu equipo favorito es:
<?php Echo “<h1><B>$equipo</B></h1>”; ?>
</body>
</html>
Hay que poner especial atención en el parámetro name de un elemento del formulario ya que es el mismo nombre
con el que se le referenciará en php, como pudimos ver en el ejemplo anterior el elemento <input name=”equipo”
type “TEXT”> lo manejamos en php como $equipo, así es con todos los elementos de formularios.
Cuadro de texto con barras de desplazamiento:
<textarea rows="5" name="descripcion" cols="20">Es de color rojo</textarea>
Ahora veamos un ejemplo con PHP:
Programa PHP que pide WebSites favoritos y los muestra como salida (sites.htm y sites.php). sites.htm
<html>
<title>Web Sites Favoritos</title>
<body>
<form method=POST ACTION=”sites.php”>
Mencióname algunos de tus WebSites Favoritos:
<br>
<textarea name=”websites” cols=”50” rows=”5”>
http://
http://
http://
http://
</textarea>
<br>
<br>
<input type=submit>
</form>
</body>
<html>
sites.php
<html>
<body>
Tus webs favoritos son:<br>

<?php Echo “<h3><B>$websites</B></h3>”; ?>


</body>
</html>
Casilla de verificación o checkbox:
<input type="checkbox" name="cambiar" value="ON">
Ahora veamos un ejemplo con PHP:
Programa que pregunta lo que haces al levantarte y lo despliega como salida
(checkboxes.htm y checkboxes.php).
checkboxes.htm
<HTML>
<HEAD></HEAD>
<BODY>
<FORM METHOD=POST ACTION=”checkboxes.php”>
Qué haces en cuanto te levantas?<br><br>
Lavarme la cara<INPUT NAME=”sel1” TYPE=”Checkbox”
VALUE=”Lavarse la Cara”><BR>
Asearse la boca<INPUT NAME=”sel2” TYPE=”Checkbox”
VALUE=”Asearse los dientes”><BR>
Desayunar<INPUT NAME=”sel3” TYPE=”Checkbox” VALUE=”Desayunar”
><BR>
<BR>
<INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>
checkboxes.php
<html>
<body>
<?php
if (isset($sel1))
Echo “$sel1 <br>”;
if (isset($sel2))
Echo “$sel2 <br>”;
if (isset($sel3))
Echo “$sel3 <br>”;
?>
</body>
</html>

Botón de radio u opción:


<input type="radio" value="azul" checked name="color">
Ahora veamos un ejemplo con PHP:
Programa que nos presenta una suma, nosotros tenemos que elegir la respuesta entre
tres opciones posibles y la salida nos muestra la opción que elegimos (radio.htm y
radio.php).
radio.htm
<HTML>
<BODY>
<FORM METHOD=GET ACTION=”radio.php”>
Cuantos son 2 + 2?
<BR>
<BR>
<INPUT NAME=”Resp” TYPE=”Radio” VALUE=”44”>44
<BR>
<INPUT NAME=”Resp” TYPE=”Radio” VALUE=”22”>22
<BR>
<INPUT NAME=”Resp” TYPE=”Radio” VALUE=”4”>4
<BR>
<BR>
<INPUT TYPE=SUBMIT>
</FORM>
</BODY>
radio.php
<HTML>
<BODY>
<?php Echo “seleccionaste $Resp”;?>
</BODY>
</HTML>

Menú desplegable:
<select size="1” class="codigo"><select size="1" name="dia">
<option selected value="lunes">lunes</option>
<option>martes</option>
<option value="miercoles">miercoles</option>
</select>
Ahora veamos un ejemplo en PHP:

Programa que pregunta opciones para armar una computadora y despliega las
opciones elegidas (lista.htm y lista.php).
lista.htm
<HTML>
<HEAD></HEAD>
<BODY>
<FORM METHOD=GET ACTION=”lista.php”>
Elije la computadora a comprar
<BR>
<BR>
<SELECT NAME=”compu”>
<OPTION>Pentium</OPTION>
<OPTION>Celeron</OPTION>
<OPTION>K6</OPTION>
<OPTION>MAC</OPTION>
</SELECT>
<BR>
<BR>
Selecciona los dispositivos de la computadora?
<BR>
<BR>
<SELECT NAME=”dispo[]” MULTIPLE>
<OPTION>KIT MULTIMEDIA</OPTION>
<OPTION>QUEMADORA</OPTION>
<OPTION>WEB CAM</OPTION>
<OPTION>MICROFONO</OPTION>
</SELECT>
<BR>
<BR>
<INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>
lista.php
<HTML>
<BODY>
<?php
Echo “Seleccionaste una computadora: <B>$compu</B>
con:<br>”;
Echo “$dispo[0]<br>”;
Echo “$dispo[1]<br>”;
Echo “$dispo[2]<br>”;
Echo “$dispo[3]<br>”;
?>
</BODY>
</HTML>

Campo oculto:
<input type="hidden" name="edad" value="55">
Este último tipo de campo resulta especialmente útil cuando queremos pasar datos ocultos en un formulario. Ahora
pasemos a ver ejemplos que necesitan mas código PHP, como son ciclos y arrays, implementándolos en conjunto
con los formularios. Para el uso del FOR un programita para créditos bancarios (banco.htm y banco.php).
banco.htm
<HTML>
<HEAD></HEAD>
<BODY>
<B>Crédito bancario</B>
<FORM METHOD=POST ACTION="banco.php">
<BR>
Cual de estos paquetes te interesa tomar?<BR><BR>
<INPUT NAME="valor" TYPE="Radio" VALUE=1000>Nuestro paquete
de $1,000 Con el 5.0% interes
<BR>
<INPUT NAME="valor" TYPE="Radio" VALUE=5000>Nuestro paquete
de $5,000 Con el 6.5% interes
<BR>
<INPUT NAME="valor" TYPE="Radio" VALUE=10000>Nuestro paquete
de $10,000 Con el 8.0% interes
<BR>
<BR>
Cuanto es lo que deseas pagar al mes ?
<INPUT NAME=pagomes TYPE=Text SIZE=5>
<BR>
<BR>
<INPUT TYPE=SUBMIT VALUE="Pulse aquí para calcular">
</FORM>
</BODY>
</HTML>
banco.php
<HTML>
<HEAD></HEAD>
<BODY>
<?php
$Duracion=0;
switch ($valor) {
case 1000:
$Interes = 5;
break;

case 5000:
$Interes = 6.5;
break;
case 10000:
$Interes = 8;
break;
default:
echo "No seleccionaste ningun paquete favor de presionar el boton back y seleccionar alguno";
exit;
}
while ($valor > 0)
{
$Duracion = $Duracion + 1;
$Mensualmente = $pagomes - ($valor * $Interes/100);
if ($Mensualmente<=0)
{
echo "Tu necesitas hacer pagos mas grandes!";
exit;
}
$valor = $valor - $Mensualmente;
}
echo "La duracion es de: $Duracion meses con un
porcentaje de intereses del $Interes.";
?>
</BODY>
</HTML>
El siguiente programa demuestra como se pueden trabajar los array como elementos
hash (estados.php y capital.php).
estados.php
<html>
<head>
<title>Estados de México</title>
</head>
<body bgcolor="#FFFFFF">
De que estado te gustaría conocer su capital?
<?
$Estados=array(1=>"Colima","Jalisco","Sinaloa");
echo "<form method=post action='capital.php'>";
echo "<select name='estado'>";
for ($counter=1; $counter<4; $counter++)
echo "<option value=$counter>$Estados[$counter]</option>";
echo "</select><br><br>";
echo "<input type=submit>";
echo "</form>";
?>
</body>
</html>

capital.php
<html>
<head>
<title>Capitales</title>
</head>
<body bgcolor="#FFFFFF">
<?php
$Capital=array(1=>"Colima","Guadalajara","Culiacan");
for ($counter=0;$counter<4;$counter++)
{
if ($counter==$estado)
{
echo "la capital del estado elegido es
&Capital[$counter]";
}
}
?>
</body>
</html>
Como podemos observar los dos archivos tienen extensión .php, esto se debe a que es necesario ejecutar código
php en los dos, para poder formar dinámicamente las dos páginas. Para tener más material con formularios
ealizaremos un programa PHP que contenga varios elementos de formulario juntos: Desarrollar un programa en
PHP que pida el Nombre (textbox), el apellido (textbox), la edad (textbox), domicilio (text area), seleccione el rango
de sueldo que le gustaría ganar (listbox) y que seleccione como considera así mismo su desempeño laboral (radio
button). El programa no aceptará curriculums que elijan un sueldo muy bajo, ni un sueldo extremo, ni tampoco si se
considera pésimo (minicu.htm y minicu.php).
minicu.htm

<HTML><HEAD></HEAD><BODY><B>Minicurriculum </B>
<FORM METHOD=POST ACTION="minicu.php">
Nombres:
<INPUT NAME="nombres" TYPE="Text">
Apellidos:
<INPUT NAME="apellidos" TYPE="Text">
Edad:
<INPUT NAME="edad" TYPE="Text"SIZE="3">
<BR>
<BR>
Domicilio:
<TEXTAREA NAME="Domicilio" ROWS=4 COLS=40>
</TEXTAREA>
<BR>
<BR>
Que salario deseas ganar?
<SELECT NAME="Salario">
<OPTION VALUE=0> Menos de $1000</OPTION>
<OPTION VALUE=1000>Entre $1,000 y $3,000</OPTION>
<OPTION VALUE=3000>Entre $3,000 y $5,000</OPTION>
<OPTION VALUE=5000>mas de $5,000</OPTION>
</SELECT>
<BR>
<BR>
Como consideras tu desempeño?<BR><BR>
<INPUT NAME="Desempe" TYPE="Radio" VALUE=0>Pesimo
<BR>
<INPUT NAME="Desempe" TYPE="Radio" VALUE=5>Regular
<BR>
<INPUT NAME="Desempe" TYPE="Radio" VALUE=10>Excelente
<BR>
<BR>
<INPUT TYPE=SUBMIT VALUE="Presione cuando este listo(a)">
<INPUT TYPE=RESET VALUE="Borra todo">
</FORM>
</BODY>
</HTML>
minicu.php
<HTML>
<BODY>
Sr(a) <?php Echo "$nombres $apellidos ";?>
en base a su edad (<?php Echo "$edad";?>) y sus aspiraciones <br>
económicas y su auto estimación hemos determinado que:<br>
<?php
echo "Salario deseado: $Salario <br>" ;
echo "Su desempeño elegido: $Desempe <br>";
if ((($Salario==0) OR ($Salario ==5000)) OR ($Desempe ==0))
{
Echo "Usted no cumple los requisitos para ser parte de
nuestra empresa";
}
else
{
Echo "Usted cumple satisfactoriamente nuestras
aspiraciones";
}
?>
</BODY>
</HTML>

Archivos
fopen
fopen -- Abre un archivo o una URL

int fopen (string filename, string mode [, int use_include_path])


Si filename comienza con "http://" (no es sensible a mayúsculas), se abre una conexión HTTP 1.0 hacia el servidor
especificado y se devuelve un apuntador de archivo al comienzo del texto de respuesta. No maneja redirecciones
HTTP, por eso se debe incluir una barra final cuando se trata de directorios. Si filename comienza con "ftp://" (no es
sensible a mayúsculas), se abre una conexión ftp hacia el servidor especificado y se devuelve un apuntador al
archivo requerido. Si el servidor no soporta ftp en modo pasivo, esto fallará. Se pueden abrir
archivo via ftp para leer o para escribir (pero no ambas cosas simultáneamente). Si filename no comienza con nada
de lo anterior, el archivo se abre del sistema de archivos, y se devuelve un apuntador al archivo abierto, si el abrir el
archivo falla, la función devuelve false. mode puede ser cualquiera de lo siguiente:
• 'r' - Abre para sólo lectura; sitúa el apuntador del archivo al comienzo del
mismo.
• 'r+' - Abre para lectura y escritura; sitúa el apuntador del archivo al comienzo del archivo.
• 'w' - Abre para sólo escritura; sitúa el apuntador del archivo al comienzo del archivo y trunca el archivo con longitud
cero. Si el archivo no existe, trata de crearlo.
• 'w+' - Abre el archivo para lectura y escritura; sitúa el apuntador del archivo al comienzo del archivo y trunca el
archivo con longitud cero. Si el archivo no existe, trata de crearlo.
• 'a' - Abre sólo para escribir (añadir); sitúa el apuntador del archivo al final del mismo. Si el archivo no existe, trata
de crearlo.
• 'a+' - Abre para lectura y escritura (añadiendo); sitúa el apuntador del archivo al final del mismo. Si el archivo no
existe, trata de crearlo.
Además, mode puede contener la letra 'b'. Esto es útil para sistemas que diferencian entre archivos binarios y de
texto (es inútil en Unix). Si no se necesita, será ignorado.

Puede usarse el tercer parámetro opcional y fijarlo a "1".


fwrite
fwrite -- Escribe archivos en modo binario Descripción
int fwrite (int fp, string string [, int length])
fwrite() escribe el contenido de string al fichero apuntado por fp. Si se da el argumento length, la escritura acaba
antes de que length bytes sean escritos o se alcance el final de string, lo que ocurra primero.
fread
fread -- Lee archivos en modo binario Descripción
string fread (int fp, int length)
fread() lee hasta length bytes del apuntador de fichero referenciado por fp. La lectura acaba cuando length bytes se
han leido o se alcanza EOF, lo que ocurra primero. Con esta teoría ya podemos realizar nuestro propio contador de
visitas en nuestro sitio web, así sabremos que tan popular es nuestro sitio, es necesario tener permisos de
escritura en nuestro directorio donde va a estar el contador (contador.php).

contador.php
<?php
$contador_archivo="c:/inetpub/wwwroot/taller/conta.dat";
if (!($fp=fopen($contador_archivo,"r")))
die("No se encontro $contador_archivo");
$contador=(int)fread($fp,20);
fclose($fp);
$contador++;
echo "Eres el visitante número: <b>$contador</b>";
$fp=fopen($contador_archivo,"w");
fwrite($fp,$contador);
fclose($fp);
?>
La instrucción die envía a la salida un mensaje y finaliza la ejecución del script. No devuelve nada.

Bases de Datos

Hasta ahora hemos visto la funciones básicas de PHP, lo que viene a continuación ya es sobre la forma en como
podemos acceder a bases de datos, veremos como acceder a ellas en dos sistemas de bases de datos diferentes,
los cuales son MySQL Server y Microsoft Access.
El primer sistema que veremos es MySQL Server, pero antes de ver código PHP, aprenderemos un poco de este
sistema, para los ejemplos en PHP ya va a ser necesario que tengamos una base de datos creada por lo tanto
pondremos atención en las formas en que estas se crean.

Qué es MySQL

Administrador de Base de Datos


Una base de datos es un conjunto de datos estructurados. Esto podría ser cualquier cosa, desde una simple lista de
compras hasta una galería de pinturas o la gran cantidad de información que se maneja en una corporación. Para
agregar, acceder y procesar los datos almacenados en una base de datos computacional, se necesita un sistema
administrador de base de datos tal como MySQL. Además los computadores son muy buenos manejando grandes
cantidades de datos, el administrador de base de datos juega un rol central en la computación, ya sea como utilidad
autónoma o parte de otra aplicación.
Sistema administrador de base de datos relacionales
Una base de datos relacional almacena datos en tablas separadas, más bien colocando todos los datos en un gran
almacén. Esto agrega velocidad y flexibilidad. Las tablas son enlazadas por relaciones definidas haciendo posible
combinar datos desde varias tablas solicitadas. El SQL forma parte de MySQL, conocido como Lenguaje de
Consultas Estructurado, es el lenguaje estandarizado más común usado para acceder base de datos.
Software de Fuente Abierta
Fuente abierta significa que es posible que pueda ser usado y modificado por cualquiera. Alguien puede bajar
MySQL desde Internet y usar éste sin tener que pagar nada. Alguien puede estudiar el código fuente y cambiarlo de
acuerdo a sus necesidades. MySQL usa el GPL de la GNU, para definir lo que se puede hacer con el software en
diferentes situaciones.
Uso de MySQL
MySQL es muy rápido, seguro y fácil de usar. MySQL también ha desarrollado un conjunto de características muy
prácticas, en estrecha cooperación con otros usuarios. MySQL fue desarrollado para manejar grandes bases de
datos mucho más rápido que las soluciones existentes y ha sido usado exitosamente en ambientes de producción
con altas demandas, por varios años. Aunque está bajo un desarrollo constante, MySQL siempre ofrece conjunto de
funciones muy poderoso y eficiente. La conectividad, velocidad y seguridad hace de MySQL una suite poderosa
para acceder a bases de datos en Internet.

Características Técnicas de MySQL

MySQL es un sistema Cliente/Servidor que consta de un servidor SQL multi-hilo que soporta diferentes backends,
variados programas cliente y de librerías, administrador de herramientas y un programa de interface.
MySQL contribución para muchos de los software disponibles Es mucho más probable que se encuentre que
diversas aplicaciones ya soportan MySQL. Los valores centrales de MySQL son :
• La mejor y más usada base de datos en el mundo.
• Disponible y Accesible para todos
• Fácil de usar
• Se está perfeccionando continuamente mientras permanece rápida y segura.
• Divertida para usar y perfeccionar.
• Libre de molestias.

Características principales de MySQL

A continuación se describen algunas de las características más importantes de MySQL:


• Escrito en C y C++, testado con GCC 2.7.2.1. Usa GNU autoconf para portabilidad.
• Clientes C, C++, Eiffel,PHP,Python,JAVA, Perl, TCL.
• Multiproceso, es decir puede usar varias CPU si éstas están disponibles.
• Puede trabajar en distintas plataformas y S.O. distintos.
• Sistema de contraseñas y privilegios muy flexible y segura.
• Todas la palabras de paso viajan encriptadas en la red.
• Registros de longitud fija y variable.
• 16 índices por tabla, cada índice puede estar compuesto de 1 a 15 columnas o partes de ellas con una longitud
máxima de 127 bytes.
• Todas las columnas pueden tener valores por defecto.
• Utilidad Isamchk para chequear, optimizar y reparar tablas.
• Todos los datos están grabados en formato ISO8859_1.
• Los clientes usan TCP o UNIX Socket para conectarse al servidor.
• Todos los comandos tienen -help o -? Para las ayudas.
• Soporta diversos tipos de columnas como enteros de 1, 2, 3, 4, y 8 bytes, coma flotante, doble precisión, carácter,
fechas, enumerados, etc.
• ODBC para Windows 95 (con fuentes), se puede utilizar ACCESS para conectar
con el servidor.
• Muy rápida usando joins, optimizada para un barrido multi-joins.

• Todas las funciones y operadores soportan en el SELECT y WHERE como partes


de consultas. Ejemplo:

• mysql> SELECT CONCAT(nombre," ",apellido) FROM nombre_tabla
• WHERE ingreso >10000 AND edad >30
• Todas las clausulas SQL soportan GROUP BY y ORDER BY.

Instalando MySQL Server

Bien, ya conocemos que es MySQL, ahora procedamos a instalarlo en nuestro servidor para poder realizar los
programas PHP con bases de datos MySQL.
• Al iniciar el instalador veremos la pantalla de “preparándose para instalar”, en esta solo hay que esperar que
termine el 100%.
• Después tenemos la pantalla de bienvenida, solo hay que dar clic en Next.

• La siguiente interfaz nos muestra la información de la versión de MySQL


que estamos instalando.
• Ahora tendremos la ventana de donde queremos instalarlo, para evitar
complicaciones con archivos de configuración, presionemos Next y se
instalará en C:\mysql.
• Hay que elegir el tipo de instalación, elijamos Typical.

• Esperamos un poco a que se instale.


• Cuando termine hay que dar clic en Finish.
Después de estos sencillos pasos ya tenemos instalado MySQL Server, ahora lo que sigue es iniciarlo, debemos ir a
la siguiente ruta en nuestro disco duro C:\mysql\bin\ y ejecutar el programa winmysqladmin.exe.
• Cuando este en ejecución WinMySQLadmin en su primera ocasión pedirá un nombre de usuario y contraseña para
el administrador del sistema de base de datos.

• Ahora si ya lo tendremos ejecutándose siempre que el sistema inicie, y estará en la barra de inicio del sistema con
un icono de un semáforo, hay que darle clic en el icono para que nos muestre sus opciones. • Al darle clic en Show
Me aparecerá el administrador de MySQL, desde ahí podemos ver todas los componentes del sistema de bases de
datos. Con esto es suficiente sobre la instalación de MySQL Server, ahora veamos como crear bases de datos en
el.

Conectándose y desconectándose al servidor MySQL


Para conectarse al servidor, generalmente se necesita proveer a MySQL un nombre de usuario, y un password. Si
el servidor corre en una máquina distinta a la que se está utilizando se debe especificar el nombre del host
(máquina). Cuando se conocen todos estos parámetros la conexión se realiza de la siguiente manera:
shell> mysql -h host -u user -p
Enter password:*********
Si la conexión se realizó con éxito, mysql despliega el siguiente mensaje:
Welcome to the MySQL monitor. Commands end with; or\g.
Your MySQL connection id is 459 to server version: 3.22.20a-log
Type "help" for help.
mysql>

El prompt indica que mysql está listo para recibir los comandos que ingrese el usuario. Algunas instalaciones de
MySQL admiten usuarios anonymous (sin nombre) cuando el servidor corre en el host local. En este caso, se debe
invocar a el servidor mysql sin ninguna opción:
shell>mysql
Una vez que se ha realizado la conexión con éxito, para desconectarse al servidor en
cualquiera de los dos casos anteriores se debe escribir QUIT o control-D.
Creando y usando una base de datos
Visualización de las bases de datos existentes en el servidor MySQL
Antes de crear una base de datos, se debe conocer que base de datos existen
actualmente en el servidor, para ello se utiliza el comando SHOW, de la siguiente manera:
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql |
| test |
| tmp |
+----------+
Esta lista probablemente no es igual en todas las máquinas, pero las bases de datos mysql y test están siempre
entre ellas. La base de datos mysql se requiere porque en ella se describe la información de los privilegios de
acceso a los usuarios. La base de datos test proporciona el espacio de trabajo para los usuarios.

Selección de una base de datos


Para seleccionar o acceder a una base de datos determinada se utiliza el comando USE:
mysql> USE test
Database changed
Una vez, que se ha realizado la conexión con éxito se puede comenzar a trabajar con la base de datos, pero
siempre y cuando se tengan los permisos adecuados. Si no se tienen los permisos el administrador debe darle los
permisos al usuario para poder trabajar, esto se realiza con la ejecución del siguiente comando:
mysql> GRANT ALL ON nombre_database.* TO nombre_usuario;

Creación de una base de datos


Para crear una base de datos se debe tener permiso para poder crear base de datos en el servidor MySQL , si se
tiene el permiso entonces la sentencia a seguir es:
mysql> CREATE DATABASE nombre_database;
Bajo Unix, los nombres de las bases de datos y de las tablas son sensibles, esto quiere decir que se hace diferencia
entre minúsculas y mayúsculas, así es que para referirse a una base de datos determinada hay que llamarla tal
como se le nombro cuando fue creada.

Creación de tablas
Para crear las tablas que va a contener la base de datos, se realiza de la siguiente forma:
mysql> CREATE TABLE nombre_tabla(campo_1 tipo(tamaño), campo_2
tipo(tamaño),...,campo_n tipo(tamaño));
El campo indica el nombre de la columna y tipo(tamaño) específica el tipo de dato y el espacio que se va a
conservar para cada dato almacenado en esa columna. Ejemplo: codigo int(5), nombre char(25), fecha date, etc..
Cuando se trata de fechas no se específica el tamaño, puesto que ya está determinado. Para visualizar las tablas
que tiene una base de datos se usa el mismo comando utilizado para ver las bases de datos, pero con la diferencia
de que en vez de database se coloca tables, es decir:
mysql> SHOW TABLES;
Para verificar que la tabla ha sido creada de la forma indicada, se usa el comando DESCRIBE. Ejemplo: Se va a
crear una tabla llamada clientes, de la siguiente forma:
mysql> CREATE TABLE clientes( rut char(8),nombre char(25),
direccion char(50), telefono int(10));
mysql> DESCRIBE clientes;
+----------+-----------+------+-----+--------+-------+
| Field | Type | Null | Key | Default| Extra |
+----------+-----------+------+-----+--------+-------+
| rut | char(12) | YES | | NULL | |
| nombre | char(25) | YES | | NULL | |
| direccion| char(50) | YES | | NULL | |
| telefono | int(10) | YES | | NULL | |
+----------+-----------+------+-----+--------+-------+
Esto es muy útil cuando se olvida el nombre o tipo de una columna. El Field indica el nombre de la columna, Type es
el tipo de dato que acepta esa columna, Null indica si la columna puede contener valores NULL, Key indica la clave
por la cual la columna se va a indexar y Default específica el valor por defecto que tiene la columna.
Ingreso de Datos a las tablas
Para ingresar información a una tabla se puede hacer básicamente de dos maneras. La primera se utiliza cuando se
tiene mucha información a ingresar de una sola vez entonces es conveniente almacenar esta información en un
archivo de texto, es decir, .txt. Una vez que se tiene este archivo, se procede de la siguiente forma:
mysql> LOAD DATA LOCAL INFILE "nombre_archivo.txt" INTO TABLE
nombre_tabla;
Para el caso que se desee ingresar un solo registro, entonces la sentencia a seguir es:
mysql> INSERT INTO nombre_tabla VALUES
(``valor_1'',''valor_2'',....,
Los datos a ingresar se separan por comas y van entre comillas. Estos datos indican
los valores que va a tomar cada una de las columnas, según el orden en que fueron creadas.
En el caso que se quiera ingresar un valor NULL no es necesario las comillas, sólo se
coloca NULL.

Recuperación de la Información

Para recuperar la información que está contenida en una tabla, la sentencia general a
seguir es:
mysql> SELECT qué_es_lo_que_se_desea_ver FROM nombre_tabla WHERE
condiciones_a_satisfacer;
Para los casos en que, se requiera:
o Ver o seleccionar toda la información de una tabla:
o mysql> SELECT * FROM nombre_tabla;
o Seleccionar filas en particular:
o mysql> SELECT * FROM nombre_tabla WHERE nombre_columna="lo
que se desee buscar"
o Seleccionar columnas en particular:
o mysql> SELECT nombre_columna_1, nombre_columna_n FROM
nombre_tabla;
Esto es conveniente cuando no se desea ver toda la fila o registro, entonces solo se
seleccionan aquellas columnas en las que se esté interesado.
MySQL Front

Ya vimos como crear bases de datos y tablas de la manera tradicional de MySQL, pero como podemos ver es algo
complejo, y como ya estamos acostumbrados a interfaces gráficas (GUI por sus siglas en ingles), les mostraré como
crear bases de datos de una manera completamente visual para no tener que tocar línea de comandos
de MySQL, para esto utilizaremos el software MySQL Front desarrollado por Ansgar Becker con correo electrónico
chef@anse.de y dirección de su página http://my.anse.de/forum.php en Alemania, aunque yo personalmente he
intentado entrar a esa dirección y no he podido, pero son los datos que trae el programa.
Veamos como usarlo:
• La primera vez que lo corremos no presentara un formulario en blanco y sin forma de poder ingresar datos, es
necesario presionar el botón New, para habilitarlo.
• Una vez presionado New aparecen unos datos ya predefinidos, lo único que tenemos que cambiar es nuestro
usuario y contraseña.

• Al momento de entrar nos mostrará esta interfaz.


• Para crear una base de datos nueva, hay que ir al menú Extra y la opción Create Database…
• Hay que ingresar el nombre de la base de datos, podemos crear ya la base que utilizaremos en nuestros ejemplos
de PHP, así que pongámosle de nombre basecurso.

• Ahora hay que crear una tabla donde almacenaremos los datos, asi que seleccionamos la nueva base y de nuevo
vamos al menú Extra solo que ahora seleccionamos Create Table…
• En la ventana que aparece ponemos el nombre de la tabla el cual será tablacurso, en esa misma pantalla
crearemos los campos, los cuales serán id (con propiedades de primario y auto incremento), nombre, direccion,
telefono, email e imagen (todos de tipo varchar), ya que los agregamos presionamos Create!
• Nos mostrará la tabla creada con sus respectivos campos y propiedades.

• También si nosotros lo deseamos podemos ingresar información a la base desde el mismo MySQL Front, pero
este no es el caso. Ahora que si nosotros deseamos usar el método de línea de comandos del MySQL la
información de la tabla es esta:
CREATE TABLE tablacurso (
id tinyint(3) unsigned NOT NULL auto_increment,
nombre varchar(30) DEFAULT '0' ,
direccion varchar(30) DEFAULT '0' ,
telefono varchar(30) DEFAULT '0' ,
email varchar(30) DEFAULT '0' ,
imagen varchar(30) DEFAULT '0' ,
PRIMARY KEY (id)
);
Después de tanta información sobre MySQL ya es tiempo de iniciar a hacer programas PHP para manejo de bases
de datos de MySQL.

PHP para bases de datos MySQL


Conectarse
Empecemos con el primer script, que nos mostrará como conectarnos a un base de datos

(conectarse.php).
conectarse.php
<html>
<head>
<title>Ejemplo de PHP</title>
</head>
<body>
<?php
function Conectarse()
{
if
(!($link=mysql_connect("localhost","pecesama","pruebas")))
{
echo "Error conectando a la base de datos.";
exit();
}
if (!mysql_select_db("basecurso",$link))
{
echo "Error seleccionando la base de datos.";
exit();
}
return $link;
}
Conectarse();
echo "Conexión con la base de datos conseguida.<br>";
?>
</body>
</html>
Como podemos ver en el ejemplo anterior aislé lo necesario para la conexión en una
función, ahora esa función la pondremos en un archivo PHP solo (conec.php).
conec.php
function Conectarse()
{
if (!($link=mysql_connect("localhost","pecesama","pruebas")))
{
exit();
}
if (!mysql_select_db("basecurso",$link))
{
exit();
}
return $link;
}

Ya que tenemos la función en un archivo separado solo hay que mandarlo llamar cuando sea necesario, de esta
forma cuando tengamos aplicaciones complejas que use muchas páginas php y sea necesario cambiarle algo a la
conexión solo se le tenga que hacer el cambio a este pequeño archivo y no a todas las páginas.

Agregar registros
Veremos un ejemplo de agregar registros a la base de datos (insertareg.php y
agregar.php).
insertareg.php
<html>
<head>
<title>Ejemplo de PHP</title>
</head>
<body>
<H1>Ejemplo de uso de bases de datos con PHP y MySQL</H1>
<FORM ACTION="agregar.php">
<TABLE>
<TR>
<TD>Nombre:</TD>
<TD><INPUT TYPE="text" NAME="nombre" SIZE="20"
MAXLENGTH="30"></TD>
</TR>
<TR>
<TD>Direccion:</TD>
<TD><INPUT TYPE="text" NAME="direccion" SIZE="20"
MAXLENGTH="30"></TD>
</TR>
<TR>
<TD>Telefono:</TD>
<TD><INPUT TYPE="text" NAME="telefono" SIZE="20"
MAXLENGTH="30"></TD>
</TR>
<TR>
<TD>Email:</TD>
<TD><INPUT TYPE="text" NAME="email" SIZE="20"
MAXLENGTH="30"></TD>
</TR>
<TR>
<TD>Imagen:</TD>
<TD><INPUT TYPE="text" NAME="imagen" SIZE="20"
MAXLENGTH="30"></TD>
</TR>
</TABLE>
<INPUT TYPE="submit" NAME="accion" VALUE="Grabar">
</FORM>
<hr>
<?php
include("conec.php");
$link=Conectarse();

$result=mysql_query("select * from tablacurso",$link);


?>
<TABLE BORDER=1 CELLSPACING=1 CELLPADDING=1>
<TR>
<TD>&nbsp;Nombre</TD>
<TD>&nbsp;Dirección&nbsp;</TD>
<TD>&nbsp;Telefono&nbsp;</TD>
<TD>&nbsp;Email&nbsp;</TD>
<TD>&nbsp;Imagen&nbsp;</TD>
</TR>
<?php
while($row = mysql_fetch_array($result)) {
printf("<tr><td>&nbsp;%s</td><td>&nbsp;%s&nbsp;</td><td>&nbsp
;%s&nbsp;</td><td>&nbsp;%s&nbsp;</td><td>&nbsp;<img
src=%s>&nbsp;</td></tr>",
$row["nombre"],$row["direccion"],$row["telefono"],$row["email
"],$row["imagen"]);
}
mysql_free_result($result);
?>
</table>
</body>
</html>
agregar.php
<?php
include("conec.php");
$link=Conectarse();
$Sql="insert into tablacurso
(nombre,direccion,telefono,email,imagen) values
('$nombre','$direccion', '$telefono', '$email', '$imagen')";
mysql_query($Sql,$link);
header("Location: insertareg.php");
?>

Modificar registros

Veremos un ejemplo de modificar registros a la base de datos, consta de tres archivos diferentes, el primero para
introducir la consulta por el campo nombre, el segundo para realizar los cambios necesarios y el tercero para
modificar la base de datos (consulta.htm, busca.php y modifica.php).

consulta.htm
<html>
<head>
<title>Ejemplo de PHP</title>
</head>
<body>

<H1>Ejemplo de modificar</H1>
<FORM ACTION="busca.php">
Nombre:
<INPUT TYPE="text" NAME="nombre" SIZE="20" MAXLENGTH="30">
<INPUT TYPE="submit" NAME="accion" VALUE="Buscar">
</FORM>
</body>
</html>
busca.php
<html>
<body>
<?php
include("conec.php");
$link=Conectarse();
$Sql="select * from tablacurso where nombre like '%$nombre%'";
echo $Sql;
$result=mysql_query($Sql,$link);
?>
<TABLE BORDER=1 CELLSPACING=1 CELLPADDING=1>
<TR>
<TD>&nbsp;Nombre</TD>
<TD>&nbsp;Dirección&nbsp;</TD>
<TD>&nbsp;Telefono&nbsp;</TD>
<TD>&nbsp;Email&nbsp;</TD>
<TD>&nbsp;Imagen&nbsp;</TD>
</TR>
<form name="form1" method="post" action="modifica.php">
<?php
while($row = mysql_fetch_array($result))
{
printf("<tr><td><INPUT TYPE='text' NAME='nombre' SIZE='20'
MAXLENGTH='30' value='%s'></td><td>&nbsp;<INPUT TYPE='text'
NAME='direccion' SIZE='20' MAXLENGTH='30'
value='%s'>&nbsp;</td><td>&nbsp;<INPUT TYPE='text'
NAME='telefono' SIZE='20' MAXLENGTH='30'
value='%s'>&nbsp;</td><td>&nbsp;<INPUT TYPE='text'
NAME='email' SIZE='20' MAXLENGTH='30'
value='%s'>&nbsp;</td><td>&nbsp;<INPUT TYPE='text'
NAME='imagen' SIZE='20' MAXLENGTH='30'
value='%s'>&nbsp;</td></tr>",
$row["nombre"],$row["direccion"],$row["telefono"],$row["email
"],$row["imagen"]);
}
mysql_free_result($result);
?>
</form>
</body>
</html>

modifica.php

<?php
include("conec.php");
$link=Conectarse();
$Sql="UPDATE tablacurso SET nombre='$nombre',
direccion='$direccion', email='$email', telefono='$telefono'
imagen='$imagen' WHERE nombre='$nombre'";
mysql_query($Sql,$link);
header("Location: consulta5.php");
?>

Eliminar registros
Pasemos a la eliminación de registros, este consta de dos archivos, los dos .php el primero es para elegir el
registros a borrar y el segundo lo borra (eliminareg.php y borra.php).

eliminareg.php
<html>
<head>
<title>Ejemplo de PHP</title>
</head>
<body>
<H1>Ejemplo de uso de bases de datos con PHP y MySQL</H1>
<?php
include("conec.php");
$link=Conectarse();
$result=mysql_query("select * from tablacurso",$link);
?>
<TABLE BORDER=1 CELLSPACING=1 CELLPADDING=1>
<TR>
<TD>&nbsp;Nombre</TD>
<TD>&nbsp;Dirección&nbsp;</TD>
<TD>&nbsp;Telefono&nbsp;</TD>
<TD>&nbsp;Email&nbsp;</TD>
<TD>&nbsp;Imagen&nbsp;</TD>
<TD>&nbsp;Borra&nbsp;</TD>
</TR>
<?php
while($row = mysql_fetch_array($result)) {
printf("<tr><td>&nbsp;%s</td><td>&nbsp;%s&nbsp;</td><td>&nbsp
;%s&nbsp;</td><td>&nbsp;%s&nbsp;</td><td>&nbsp;%s&nbsp;</td><
/td><td><a href=\"borra.php?id=%d\">Borra</a></td></tr>",
$row["nombre"],$row["direccion"],$row["telefono"],$row["email
"],$row["imagen"],$row["ID"]);
}
mysql_free_result($result);
?>
</table>
</body>
</html>
borra.php
<?php
include("conec.php");
$link=Conectarse();
mysql_query("delete from tablacurso where ID = $id",$link);
header("Location: eliminareg.php");
?>
Ya conocemos como manejar una base de datos de MySQL con PHP, pero que pasa si nosotros tenemos nuestra
base de datos en Microsoft Access y es una base de datos enorme, que nos llevaría mucho tiempo en convertirla en
MySQL, existe una solución para poder usarla en PHP, esta opción es ODBC, del cual les platicaré un poco.

Conceptos básicos sobre ODBC


¿Qué es ODBC?
Open DataBase Conectivity (ODBC) es un desarrollo de Microsoft que se ha convertido en estándar, para el acceso
a través de él a gran cantidad de tipos de datos. Básicamente, por tanto, cualquier aplicación simple que emplee
ODBC puede acceder a las Bases de datos soportadas por este estándar. El funcionamiento es: la aplicación sólo
necesita comunicarse con un paquete de archivos (ODBC), e instantáneamente puede trabajar con cualquier tipo de
datos soportados por este paquete.
• Hay dos posibles accesos a la Base de datos (DIRECTO e INDIRECTO) el que denomino DIRECTO consiste en
que normalmente, una compañía diseña una aplicación que accederá a datos. Esta aplicación se desarrolla hacia un
tipo de datos, y por tanto sólo se implementa el acceso para ese tipo de datos. Si se requiere acceso a otro DBMS,
es necesario por tanto, implementar un nuevo controlador o driver de acceso. Este sistema hace que el acceso sea
directo a la Base de datos, pero tiene el inconveniente de que hay que desarrollar el enlace para cada DBMS
que se quiera soportar.
• Otro posible acceso es el INDIRECTO, es decir, si el DBMS posibilita que conODBC puedan ser accedidos los
datos, es decir funciona con lo que se denomina ODBC data source, (o fuente de datos ODBC) la aplicación accede
a través del paquete de archivos ODBC "indirectamente", y si añadimos que ODBC es soportado por los DBMS más
comunes, con una misma aplicación y con un mismo paquete de drivers, podremos acceder a todas las DBMS sin
necesidad de hacer un desarrollo para cada tipo.

Ventajas del uso del acceso "indirecto" a través del ODBC:


Quizás, la mayor ventaja es que el acceso a datos a través del ODBC permite el poder gestionar un amplio rango de
datos con una sola interface. Desde que los más populares DBMS ofrecen drivers ODBC, muchas son las
aplicaciones que lo incluyen como drivers de acceso.
Otra ventaja es que al poderse variar la fuente de datos, el cambio de una DBMS a otra es simplista. Por ejemplo, si
se diseña un informe usando Oracle Data source, y más tarde, la empresa decide cambiar a Microsoft SQL Server,
simplemente con cambiar el ODBC data source usado por el informe, se accede a la nueva DBMS. El único
requerimiento es que la nueva fuente de datos ha de tener la misma estructura de tablas y campos que la fuente de
datos original. Además, el SQL que se envía al ODBC puede ser revisado y corregido antes de su envío, y por tanto
se controla exactamente los datos que se quieren recuperar de la fuente.

Desventajas del ODBC:

La principal desventaja son las capas a través de las cuales tiene que pasar la consulta, esto hace que el tiempo de
respuesta hasta que se obtienen los datos se incremente. El proceso es que la petición ha de "traducirse" a ODBC,
para que éste entienda la consulta. ODBC determina que fuente de datos contiene los datos que se piden
y transmite la petición a la siguiente capa que es la fuente de datos ODBC (ODBC data source). La fuente de datos
analiza la petición y "traduce" de nuevo la consulta a un formato que pueda ser "comprendido" por la DBMS. Este
complejo proceso puede verse alterado por cualquier fallo en cualquiera de sus fases y por tanto la consulta no
tendría éxito.

Cabe añadir que, las fuentes de datos ODBC deben estar configuradas correctamente en el ODBC.INI y en el
ODBCINST.INI antes de poder ser usada. Si intentas crear un informe en un sistema y tratas de abrirlo con otro
sistema, probablemente no empleen el mismo ODBC data source, y por tanto no se establecerá la conexión.
Además hay que asegurarse que el SQL usado en el ODBC ha de estar basado en los estándares establecidos por
el American National Standards Institute (ANSI) para el lenguaje SQL. Ahora vamos a verlo gráficamente. Soy
usuario de una aplicación de PHP que usa bases de datos externas para almacenar información, esta aplicación
trabaja directamente con MySQL, pero mi intención es tener una conexión con una base de datos de Microsoft
Access, porque es más fácil; PHP no trabaja directamente con Access, pero puede entenderse con él usando ODBC
de por medio. Necesito crear un origen de datos en ODBC para que PHP sepa a qué base de datos me refiero
cuando le solicite información.
Primero vamos a buscar a ODBC, que está en el Panel de Control.
Bueno, y ahora, el Data Source Administrator del Open DataBase Conectivity, u ODBC. Lo que sigue es crear
una fuente u origen de datos, pero antes unas explicaciones: Vas a notar que las primeras tres pestañas se refieren
a User DSN, System DSN y File DSN. Perdón, pero tengo la versión en inglés, voy a traducir un poco:
User DSN, nombre del origen de datos para el usuario. A veces, una máquina es utilizada por más de un
usuario, los orígenes de datos declarados aquí son exclusivos del usuario.
System DSN, nombre del origen de datos para el sistema. Todos los usuarios de la máquina tienen acceso a
estos orígenes de datos.
User DSN, nombre del origen de datos en archivo. Se crea un archivo con la extensión DSN, que sirve como
origen de datos y puede ser distribuido a otros usuarios.
Este origen es el que usa Excel por omisión cuando hace consultas, cuidado con eso. Está otra pestaña importante
que es ODBC Drivers u Controladores ODBC. Aquí se ven todos los controladores disponibles en la máquina. De
está forma puedes consultar si dispones del controlador que necesitas y si es la versión conveniente. Regularmente
los controladores de bases de datos vienen con un programa SETUP que los instala y quedan dados de alta en esta
lista.
Las otras pestañas merecen artículos aparte pues sirven más a los administradores y desarrolladores de sistemas.
Para el fin de crear un origen de datos, con lo que hemos visto tenemos. Lo siguiente: Vamos a seleccionar la
pestaña System DSN, nombre de origen de datos del sistema y presionamos el botón Add…, agregar..
Luego señalamos el controlador o driver del tipo de base de datos que queremos accesar: Microsoft Access Driver
(o controlador, en la versión en español) y presionamos Finalizar; pero fíjate que todavía no acabamos.
Lo que tenemos que hacer ahora es darle al nuevo origen de datos un nombre peculiar y distintivo, como estamos
creando un origen de datos para una base de datos que se llama MyTown.mdb pues le llamo MiPueblo y le damos
una descripción (que en realidad no es necesaria).

Eso es todo, ahora solamente se debe cerrar el administrador de ODBC presionado el botón Aceptar. Tenemos un
origen de datos nuevo que le será útil a aplicaciones que de otra forma no podrían leer una base de datos Access El
controlador de ODBC de Microsoft Access se puede instalar, si es que no lo tienes, desde el CD de Office o de
Access sí lo tienes como versión independiente.
Para más información y recursos respecto a ODBC puedes visitar: Ya conocemos que es ODBC y como crear un
DSN, ahora veamos como usar esas bases con PHP:

PHP con ODBC


Conectarse

Veamos como realizar una conexión con ODBC a un DSN de nombre base y
mostrar los resultados (conectarODBC.php).
conectarODBC.php
<?
$conexion = odbc_connect("base","","","");
$rs= odbc_exec($conexion,"select * from usuarios");
while (odbc_fetch_row($rs))
{
echo odbc_result($rs,"Nombre");
echo $idusuario=odbc_result($rs,"idusuario");
}
odbc_close_all();
?>
Agregar registro

Vamos a agregar un registro a la base de datos (agregarODBC.php)


agregarODBC.php
<?
$conexion = odbc_connect("base","","","");
$rs= odbc_exec($conexion,"select * from usuarios");
$sql="insert into usuarios (idusuario, Nombre)
values('1','Pedro')";
$rs=odbc_exec($conexion,$sql);
odbc_close_all();
?>
Modificar registro

Vamos a modificar un registro a la base de datos (modificarODBC.php)


modificarODBC.php
<?
$conexion = odbc_connect("base","","","");
$rs= odbc_exec($conexion,"select * from usuarios");
$sql=" update usuarios set Nombre='pecesama'";
$rs=odbc_exec($conexion,$sql);
odbc_close_all();
?>

Eliminar registro

Vamos a eliminar un registro a la base de datos (eliminarODBC.php)


eliminarODBC.php
<?
$conexion = odbc_connect("base","","","");
$rs= odbc_exec($conexion,"select * from usuarios");
$sql=" delete from usuarios where idusuario='1'";
$rs=odbc_exec($conexion,$sql);
odbc_close_all();
?>
Como puedes ver no me extendi mucho en el tema, pero ya conoces mucho de PHP,
tu puede crear ya las aplicaciones y con esto que puse para conecatarse y manejo de
registros es suficiente para que ya desarrolles tu, pero por si te falta mas información te
pongo la sintaxis de las funciones que tiene PHP para ODBC:
• (int) odbc_autocommit($connection_id, $OnOff)
• (void) odbc_close($connection_id)
• (void) odbc_close_all(void)
• (int) odbc_commit($connection_id)
• (int) odbc_connect($dsn, $user, $password)
• (int) odbc_pconnect($dsn, $user, $password)
• (string) odbc_cursor($result_id)
• (int) odbc_do($connection_id, $query_string)
• (int) odbc_exec($connection_id, $query_string)
• (int) odbc_prepare($connection_id, $query_string)
• (int) odbc_execute($result_id, $array)
• (int) odbc_fetch_row($result_id, $row_number)
• (int) odbc_fetch_into($result_id, $row_number, $array_ptr)
• (int) odbc_field_len($result_id, $field_number)
• (string) odbc_field_name($result_id, $field_number)
• (string) odbc_field_type($result_id, $field)
• (int) odbc_free_result($result_id)
• (int) odbc_num_fields($result_id)
• (int) odbc_num_rows($result_id)
• (string) odbc_result($result_id, $field)
• (int) odbc_result_all($result_id, $format)
• (int) odbc_rollback($connection_id)

Ahora que ya manejamos archivos y bases de datos, vamos a ver un poco más de
PHP, algo más avanzado, como las sesiones e incluso algunas funciones con protocolos de
Internet.

Funciones de red

Cookies
La principal utilidad de las cookies (galletas) es la de solventar el problema de la
falta de estado en la navegación a través de las paginas web.
Con las cookies, pequeñas porciones de información se quedan registradas en el
navegador permitiendo identificar a este a través de diferentes páginas de un mismo sitio e
incluso durante visitas entre distintos días.
Realmente las cookies no son mas que cadenas de texto que son enviadas desde el
servidor al cliente (navegador) y almacenadas en este, luego el navegador envía estas
cookies al servidor permitiendo así la identificación del cliente en el servidor.

Funcionamiento
La cookie es enviada al navegador desde el servidor y si este la acepta permanece en él.
Las páginas piden la cookie al navegador...
El navegador las envía, permitiendo la identificación del usuario por parte del
servidor.
A continuación vamos a ver como usar las cookies para nuestro beneficio.

Cómo usar las cookies

El manejo de cookies en PHP se realiza mediante el uso de la función setcookie, esta


función esta disponible a partir de la versión 3 de PHP.
int setcookie (string Nombre [, string Valor [, int Expire [, string
Path [, string Dominio [, int Secure]]]]])
Setcookie() define una cookie que es enviada junto con el resto de la información de la
cabecera(header). Las cookies deben ser enviadas antes de cualquier etiqueta (tag) de html,
por lo tanto deberemos realizar la llamada a estas funciones antes de cualquier etiqueta
<HTML> o <HEAD>. Esta es una restricción de las cookies no de PHP.
Todos los argumentos excepto el nombre son opcionales.
• Nombre. Nombre de la cookie. Si creamos una cookie solamente con el nombre, en
el cliente se eliminará la cookie que exista con ese nombre. También podemos
reemplazar cualquier argumento con una cadena vacía ("").
• Value. Valor que almacenará la cookie en el cliente.
• Expire. El argumento expire es un argumento entero que indica la hora en que se
eliminara la cookie. Normalmente se usa time() + N. segundos de duración, para
especificar la duración de una cookie.
• Path. Subdirectorio en donde tiene valor la cookie.
• Dominio. Dominio en donde tiene valor la cookie. Si ponemos como dominio
www.domain.com la cookie no se transmite para domain.com, mientras que si
ponemos domain.com la cookie se transmite tanto para domain.com como para
www.domain.com
• Secure. El argumento secure indica que la cookie solo se transmitirá a través de una
conexión segura HTTPS.
setcookie("usuario", "Pedro", time()+3600,"/","www.pecesama.com");
En este ejemplo establecemos una cookie de nombre usuario que contiene el valor
Pedro, que dura 1 hora (3600 segundos) válida para todo el dominio www.pecesama.com.

Ejemplo de uso de cookies

En este ejemplo vamos a ver como establecer una cookie y cómo se recupera su valor.
Se establece la cookie ejemusuario, cuya duración es una hora (cookies.php).
cookies.php
<?php
setcookie("ejemusuario", “Pedro”, time()+3600,"/","");
?>
<html>

<head>
<title>Ejemplo de PHP</title>
</head>
<body>
<H1>Ejemplo de uso de cookie</H1>
Se ha establecido una cookie de nombre <b>ejemusuario</b> con el
valor: <b><? print $ejemusuario; ?></b> que será válida durante 1
hora.
</body>
</html>

Sesiones

¿Qué son las sesiones?, básicamente una sesión es la secuencia de páginas que un
usuario visita en un sitio web. Desde que entra en nuestro sitio, hasta que lo abandona.
El término sesión en PHP, session en inglés, se aplica a esta secuencia de navegación,
para ello crearemos un identificador único que asignamos a cada una de estas sesiones de
navegación. A este identificador de sesión se le denomina, comúnmente, como la sesión.
El proceso en cualquier lenguaje de programación podría ser algo así:
¿Existe una sesión?, si existe lo retomamos, si no existe la creamos y le damos un identificador único.
Y para que no perdamos el hilo de la navegación del usuario deberemos asociar esta sesión a todas las direcciones
(URLs) y acciones de formularios. Podemos también crear una cookie que incluya el identificador de sesión, pero es
conveniente recordar que la disponibilidad o no de las cookies depende del usuario, y no es conveniente fiarse de lo
que un usuario pueda o no tener habilitado. Lo contado hasta ahora es teoría pura y es aplicable a cualquier
lenguaje de programación C, Perl, etc. Los que programamos en PHP4 tenemos la suerte de que toda la
gestión de sesiones la hace el mismo PHP.
Por lo tanto lo comentado aquí sobre sesiones es solo aplicable a PHP4.

Inicialización de la sesión
Para utilizar sesiones en PHP lo primero es inicializarlas. Podemos hacerlo explícitamente, mediante la función
session_start(), o al registrar una variable en una sesiónmediante session_register('miVariable'). En ambos casos se
crea una nueva sesión, si no existe, o se retoma la sesión actual.

Veamos un sencillo ejemplo:

<?php
session_start();
echo "Se inició la sesión";
?>

Esta es la forma más básica, si el usuario tiene las cookies activadas, PHP habrá insertado de forma automática la
sesión y ésta será pasada de una página a otra sin hacer nada más. Desde un punto de vista práctico la sesión es
operativa, pero no vemos nada. Podemos obtener la sesión en cualquier momento mediante la función session_id().
<?php
session_start();
echo 'La sesión actual es: '.session_id();
?>
En este caso session_start() comprueba en las cookies que existe una sesión y continua con ella, session_id()
devuelve el identificador actual.
Veamos otro ejemplo que, tal vez, te lo aclare un poco más:
<?php
session_register('contador');
echo '<a href="'.$PHP_SELF.'?'.$SID.'">Contador vale:
'.++$contador.'</a>';
?>
Como dije anteriormente la sesión se crea si no existe o se recoge mediante
session_start(), o también cuando se registra una variable de sesión mediante
session_register().
Si no has utilizado nunca las sesiones, el concepto de variable de sesión, puede resultar
un poco extraño. Básicamente es una variable, como cualquiera de las que gestiona PHP4,
pero que reside en un espacio específico en el servidor, junto con el identificador de sesión,
y que pertenece únicamente a un usuario.
En nuestro ejemplo anterior, registramos la variable $contador en la primera línea del
script. En la segunda línea, entre otras cosas, cada vez que recarguemos la página o
hagamos click sobre el enlace, el valor de $contador se incrementará en 1.
En esta línea hacemos uso de la variable reservada $PHP_SELF, que hace referencia
al propio script en ejecución y una constante propia de PHP4, $SID, que contiene el
nombre de la sesión y el identificador de la misma.
Podemos averiguar también el nombre de la sesión, o modificarlo, mediante la función
session_name(). Veamos una prueba práctica (sesion.php):
sesion.php
<?php
session_name('misesion');
session_register('contador');
echo '<a href="'.$PHP_SELF.'?'.SID.'">Contador vale:
'.++$contador.'</a><br>';

echo 'Ahora el nombre es '.session_name().' y la sesión


'.$misesion.'<br>';
?>
La asignación del nombre de sesión debe realizarse antes que ninguna otra función con
sesiones, antes que session_start() o session_register().

Error común

Uno de los errores más comunes cuando se utilizan sesiones es dejar líneas en blanco
antes de la inicialización de PHP o enviar alguna salida a la pantalla. Para probarlo crea una
línea en blanco o con cualquier cosa antes de <?php.
Si tienes las cookies activadas, te encontrarás un error de este tipo:
Warning: Cannot send session cookie - headers already sent by (output
started at /taller/sesiones.php:2) in / taller/sesiones.php on line 4
PHP está informando de que no puede activar las cookies en el navegador del usuario,
porque las cabeceras ya han sido enviadas. Simplemente por la existencia de una línea en
blanco. Como medida práctica, no dejes espacios ni antes del inicio del script, ni después de
la finalización.
Si después de todo lo comentado aún no entiendes para que sirven las sesiones,
veamos un ejemplo práctico. Imagina que quisieras crear un sistema de carrito de compras
Carrito de compra
Si después de todo lo comentado aún no entiendes para que sirven las sesiones,

veamos un ejemplo práctico. Imagina que quisieras crear un sistema de carrito de compras,
en su forma básica podría ser algo así (carrito.php):
carrito.php
<?php
session_start();
session_register('itemsEnCesta');
if ($item){
if (!isset($itemsEnCesta)){
$itemsEnCesta[$item]=$cantidad;
}else{
foreach($itemsEnCesta as $k => $v){
if ($item==$k){
$itemsEnCesta[$k]+=$cantidad;
$encontrado=1;
}
}
if (!$encontrado) $itemsEnCesta[$item]=$cantidad;
}
}

?>
<html>
<body>
<tt>
<form action="<?=$PHP_SELF."?".SID?>" method="post">
Dime el producto <input type="text" name="item" size="20"><br>
Cuantas unidades <input type="text" name="cantidad" size="20"><br>
<input type="submit" value="Añadir a la cesta"><br>
</form>
<?
if (isset($itemsEnCesta)){
echo'El contenido de la cesta de la compra es:<br>';
foreach($itemsEnCesta as $k => $v){
echo 'Artículo: '.$k.' ud: '.$v.'<br>';
}
}
?>
</tt>
</body>
</html>
Una breve explicación. En la línea 4 comprobamos si el usuario ha pasado algún artículo, desde el formulario. En la
5 si el array itemsEnCesta no existe, lo creamos con el nuevo producto y la cantidad indicada. Si el array existe
recorremos su contenido, entre las líneas 8 y 13, y si encontramos un artículo igual, añadimos la cantidad en la línea
10. Si no lo encontramos, es un nuevo artículo, por lo tanto, añadimos el nuevo producto con la
correspondiente cantidad a itemsEnCesta en la línea 14. Y a continuación imprimimos el formulario y los resultados,
si los hubiera, a partir de la línea 18, donde empieza el HTML.
¿Te imaginas las posibilidades de un sistema de almacenamiento de información de estas características?. No
necesitas archivos, ni bases de datos, ni tienes que andar pasando valores de una página a otra. PHP va
gestionando estos datos por nosotros, hasta el momento en que decidamos almacenar la información donde más
nos interese.
Envió de e-mails
PHP nos ofrece la posibilidad de enviar emails de una manera sencilla y fácil, para ello el lenguaje nos proporciona
la instrucción mail( )
<?php
mail(destinatario, tema, texto del mensaje);
?>
En el parámetro destinatario pondremos la dirección de email a donde se enviará el
mensaje, en el parámetro tema el tema o subject del mensaje y el parámetro texto del
mensaje el cuerpo del mensaje en formato texto plano.

Existe una sintaxis extendida de la instrucción mail( ) que nos permite añadir
información adicional a la cabecera del mensaje.
<?php
mail(destinatario, tema, texto del mensaje, información adicional de
cabecera);
?>
En la información de cabecera podremos incluir parámetros adicionales al mensaje
como Reply-To:, From:, Content-type:... que nos permiten tener un mayor control sobre el
mensaje.
Ahora veamos un pequeño ejemplo de cómo enviar un correo electrónico con PHP
(email.htm y email.php).
email.htm
<html>
<head>
<title>Ejemplo de PHP</title>
</head>
<body>
<H1>Ejemplo de envió de email</H1>
Introduzca su direccion de email:
<FORM ACTION="email.php" METHOD="GET">
<INPUT TYPE="text" NAME="direccion"><BR><BR>
Formato: <BR>
<INPUT TYPE="radio" NAME="tipo" VALUE="plano" CHECKED> Texto
plano<BR>
<INPUT TYPE="radio" NAME="tipo" VALUE="html"> HTML<BR><BR>
<INPUT TYPE="submit" VALUE="Enviar">
</FORM>
</body>
</html>
email.php
<html>
<head>
<title>Ejemplo de PHP</title>
</head>
<body>
<H1>Ejemplo de envió de email</H1>
<?
if ($direccion!=""){
if ($tipo=="plano"){
// Envio en formato texto plano
mail($direccion,"Ejemplo de envió de
email","Ejemplo de envió de email de texto
plano\n\n\nhttp://www.pecesama.com","FROM: Pedro
<pedro.santana@pecesama.com>\n");
} else {
// formato HTML

mail($direccion,"Ejemplo de envió de
email","<html><head><title>PecesamaSoft. Taller de
PHP</title></head><body>Ejemplo de envió de email
de HTML<br><br>
nhttp://www.pecesama.com</body></html>","Contenttype:
text/html\n", "FROM: Pedro
<pedro.santana@pecesama.com>\n");
}
echo "Se ha enviado un email a la direccion:
",$direccion," en formato <b>",$tipo,"</b>.";
}
?>
<br>
</FORM>
</body>
</html>

B.LENGUAJES A NIVEL DELCLIENTE.

1.LENGUAJE JAVA SCRIPT.

Introducción
De todos los servicios que ofrece INTERNET, no cabe duda de que el más popular es la WWW (World Wide Web).
La WWW no es más que millones de páginas en formato electrónico, con los contenidos y temáticas más diversas a
las que podemos acceder gracias a un computador + modem + browser (navegador).
Una página WEB no es más que un fichero de texto (ASCII), escrito en formato HTML (Hyper Text Markup
Language = lenguaje etiquetado de hipertexto).

La programación en HTML no tiene ninguna utilidad para un usuario normal, ya que en el mercado existen
herramientas que evitan la necesidad de tener que introducir manualmente los “tags”: HotMetal, FontPage, Word,
etc.Lo que sí tienen sentido es el estudio de la programación en JavaScript.

JavaScript es un lenguaje de programación creado por la empresa Netscape (creadora de uno de los navegadores
más conocido) Es el lenguaje de programación más utilizado en Internet para añadir interactividad a las páginas web
No confundir el JavaScript con el Java. El Java es un lenguaje de programación de propósito general como lo son
el C++ o el Visual Basic. Un programa en JavaScript se integra en una página Web (entre el código HTML) y es el
navegador el que lo interpreta (ejecuta). Es decir el JavaScript es un lenguaje interpretado, no compilado (no se
genera ningún tipo de fichero objeto o exe).

Para programar en JavaScript sólo necesitamos un editor de texto (utilizaremos el Bloc de Notas del Windows) y
un navegador (utilizaremos el Microsoft Internet Explorer) para ejecutarlo.

¿Porqué el JavaScript y no otro lenguaje de programación?

• Es moderno (tiene pocos años)


• Es sencillo (su hermano mayor: el Java, es bastante más complejo)
• Es útil (el desarrollo de Internet, se prevé muy rápido en los próximos años)
• Es potente: permite la moderna POO (programación orientada a objetos)
• Es barato: sólo necesitamos un editor de textos (el “Bloc de Notas” está incluido en
el Windows) y un navegador (es gratuito, ya sea el “Internet Explorer” o el
“Netscape”).
• Es visual: permite la moderna “programación visual” (ventanas, botones, colores,
formularios, etc.).
En definitiva: es ideal para un primer curso de introducción a la programación.
Y has de tener en cuenta que hay un “dicho” en informática, que afirma: “Si dominas
un lenguaje de programación, los conoces todos”.

El HTML es un lenguaje basado en pares de tags (etiquetas). Un tag es un código entre<>, si es de apertura o un
código entre </ > si es de cierre.

Los browsers (navegadores de Internet), son capaces de traducir estas etiquetas (tags) de
forma que presentan visualmente la página.

Estructura de un fichero HTML

Básicamente consta de cuatro pares de etiquetas:


<HTML>
<HEAD>
JavaScript U.Manizales
<TITLE>Nuestra primera página</TITLE>
</HEAD>
<BODY>
</BODY>
</HTML>

• El par <HTML> y </HTML>


Determina que un fichero sea HTML
• El par <HEAD> y </HEAD>
Determina la cabecera del fichero HTML, que puede contener un título.
• El par <TITLE> y </TITLE>
Encierra el “título”: frase de texto que aparecerá en el marco del navegador
(primera línea), al ejecutar el fichero HTML
• El par <BODY> y </BODY>
Encierra el contenido de la página html, es decir lo que se visualizará en el
navegador.
Los navegadores (browsers) más conocidos son:
• Netscape Comunicator
• Microsoft Internet Explorer
- Ejecuta el “Bloc de Notas”, es decir:
[Inicio]
Programas
Accesorios
Bloc de Notas
- Escribe:
<HTML>
<HEAD>
<TITLE>PROG000.HTM</TITLE>
</HEAD>
<BODY>
<P>Esto aparecerá en el navegador porque es un párrafo</P>
<P>Esto es otro párrafo</P>
<P>Observa lo que aparece en la línea de título</P>
<P>La línea de título es la frase que aparece en el marco
del navegador, línea superior</P>
<P>¿Está claro para qué sirven los tags P, /P?</P>
</BODY>
</HTML>
- Graba el fichero anterior con el nombre PROG000.HTM en TuCarpeta
- Ejecuta el “Explorador de Windows”. Sitúate en TuCarpeta y haz un doble click en
PROG000.HTM
De esta forma, se ejecuta el navegador de tu ordenador (supondré que es el Internet
Explorer) y se “carga” la página PROG000.HTM
El navegador nos muestra la página HTML “visualmente”, para ver su código debes hacer

Sintaxis básica de javascript

- Escribe, utilizando el “Bloc de Notas” del Windows, el siguiente programa:


<HTML>
<HEAD>
<TITLE>PROG001.HTM</TITLE>
<SCRIPT LANGUAGE="JavaScript">
alert("¡Hola Mundo!");
</SCRIPT>
</HEAD>
<BODY>
<P>
Programa 1 en JavaScript
JavaScript Fermí Vilà 5
</P>
</BODY>
</HTML>
- Graba el fichero anterior en TuCarpeta con el nombre Prog001.htm
- Ejecuta el programa Prog001.htm, es decir:
• Ejecuta el “Explorador de Windows”
• Sitúate en TuCarpeta
• Clic-Click en Prog001.htm
- Estudio del Prog001.htm:

Un programa “JavaScript” se escribe integrado en una página HTML, por lo tanto no es más que un fichero de texto
que contiene una serie de pares de tags correspondientes a la página Web (como mínimo el par: <HTML>,
</HTML>), además del par de tags característico de un programa JavaScript. Dicho fichero se ha de grabar
necesariamente con la extensión HTM (característica de una página HTML).

Un programa “JavaScript” no es más que una secuencia de ordenes, que deben terminar en punto y coma, entre
los tags:
<SCRIPT LANGUAGE=”JavaScript”>
y
</SCRIPT>
• En nuestro Prog001.htm, hemos incluido el programa en la cabecera (HEAD) de la página, pero podríamos
colocarlo en cualquier parte del fichero htm , Nuestro primer programa JavaScript contiene una única sentencia:
alert(“”¡Hola
Mundo!”);
Que “abre” una ventana con el mensaje que tenemos entre comillas. Al hacer clic en el [Aceptar] de la ventana
“alert”, se acaba el programa JavaScript (se encuentra el tag </SCRIPT>) y continua ejecutándose la página
HTML.
- Utilizando el “Bloc de Notas” escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG002.HTM
var nom;
nom=prompt("Escribe tu nombre ","Paco");
alert("Mucho gusto "+ nom);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog002.htm
- Ejecútalo varias veces, observando detenidamente lo que sucede.
- Estudio del Prog002.htm
1º) Primera y última línea: <HTML> y </HTML>
Es decir: página html mínima que necesitamos para incluir un programa JavaScript.
2º) Segunda y penúltima líneas: <SCRIPT LANGUAGE=.....> y </SCRIPT>, es decir
programa en JavaScript
3º) Primera sentencia del programa: // PROG002.HTM

Única línea del programa que no es necesario acabarla con punto y coma.
Todas las líneas que empiezan por // son comentarios para el programador, es decir no forman parte del programa,
dicho de otra forma: el navegador si encuentra una línea que empieza por //, la salta.
4º) var nom;
Definimos una variable de nombre nom
5º) nom = prompt(“Escribe tu nombre”,”Paco”);
Aparece un recuadro con un mensaje y un campo donde podemos escribir algo; el mensaje corresponde a lo que
escribimos en el primer argumento de la función prompt, encerrado entre comillas. El segundo argumento del
prompt contiene el valor que aparece por defecto en el campo del cuadro de diálogo.
El valor del prompt es nom, es decir lo que nosotros escribamos en el cuadro será el valor que tomará la variable
nom. Si no escribimos nada y hacemos click en [Aceptar], el prompt, es decir la variable nom
tomará el valor de Paco, porque es el valor que aparece por defecto.
6º) alert("Mucho gusto "+nom); Aparece un cuadro con el mensaje "Mucho gusto" y a continuación el valor de la
variable "nom", que será lo que hemos escrito en el primer cuadro que nos ha aparecido.
En definitiva:
- La función prompt nos permite introducir "valores", dichos valores se han de guardar en
variables, que previamente hemos de declarar con la palabra reservada "var"
- La función "alert" muestra mensajes y/o valores de variables.
- Utilizando el "Bloc de Notas del Windows" escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG003.HTM
/*Programa que sirve para calcular
el área de un rectángulo */
var base,altura;
base=prompt("Escribe la base del Rectángulo","");
altura=prompt("Escribe la altura del Rectángulo","");
alert("El área del Rectángulo es = "+(base*altura));
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog003.htm
- Ejecútalo varias veces. Sería conveniente utilizar números enteros y también decimales (5.72, 0.531: observa que
has de utilizar el punto decimal inglés).
- Si has ejecutado el programa una vez, para volverlo a ejecutar, no es necesario que
"cierres" el navegador, basta que hagas:
Menú Ver
Actualizar o si quieres ir más rápido, pulsa la tecla [F5]
- Es importante que tengas claro este programa:
• Declaramos dos variables (var), que necesitamos para introducir la base y la altura
del rectángulo, a través de dos "prompts":
base= prompt......

altura= prompt.....
• Por último necesitamos dos "alerts" que nos muestre el resultado del programa,
que es simplemente el producto base * altura
- El único elemento nuevo que aparece en el Prog003.htm es:
/*Programa que sirve para calcular
el área de un rectángulo */
Todo lo que aparece escrito entre /* y */ no es más que un comentario para el programador, igual que pasaba con
las líneas que empezaban por // La diferencia entre // y /* */ está en que esta última forma de incluir un comentario,
nos permite colocarlo de forma que ocupe más de una línea.

Variables

- Declaración de variables
Una variable se puede declarar en JavaScript, de dos formas:
• Forma Explícita: var nombre Variable;
• Forma Implícita: var nombre Variable= valor;
En el último caso no es imprescindible escribir var, pero es conveniente, ya que de esta forma
localizamos rápidamente todas las variables del programa.
El "JavaScript" es un lenguaje de programación "Case Sensitive", esto es: no es lo mismo las
mayúsculas que las minúsculas. Es decir, para el JavaScript: pepe es distinto de Pepe y distinto de pEpe.
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE=''JavaScript''>
// PROG004.HTM
/* Programa que utiliza una variable explícita
y dos implícitas */
var Expli;
var pi=3.141592;
var radio=7;
Expli=pi*radio*radio;
alert("Área del Círculo = "+Expli);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog004.htm
- Ejecútalo

Tipos de Datos

Cuando declaramos una variable, ésta no pertenece a ningún tipo de dato en concreto, se dice
que es Undefined. Es al asignarle un valor cuando pasa a ser de uno u otro tipo, según el dato
que albergue.
Existen 6 tipos de datos:
String: cadenas de texto Object: objetos.
Number: valores numéricos Null: nulo.
Boolean: true o false Undefined: no definido.
Podemos averiguar el tipo de dato que contiene una variable si utilizamos la función incorporada typeof
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE=''JavaScript''>
// PROG005.HTM
var Pepe;
var PEPE="Hola que tal ";
var pepE=75.47;
var pEpe=" ¿Como estás?";
Pepe=PEPE+pEpe;
alert("PEPE="+PEPE);
alert("PEPE es "+typeof(PEPE));
alert("pepE="+pepE);
alert("pepE es "+typeof(pepE));
alert("pEpe="+pEpe);
alert("pEpe es "+typeof(pEpe));
alert("Pepe="+Pepe);
alert("Pepe es "+typeof(Pepe));
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog005.htm
- Ejecútalo tantas veces como quieras.

El tipo de dato "String":

En JavaScript los textos se denotan por comillas dobles o comillas simples, pero no ambas a la vez.
Variable1 = "Pepito"
Variable2 = 'Paquito'
Podemos incluir un carácter de control en una cadena de texto, si utilizamos el llamado carácter de escape que
es: \
Los caracteres de control más usados son:
\n salto de línea
\t tabulador
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">

// PROG006.HTM
var num;
alert("Hola que tal");
alert("Hola \nque tal");
alert("Hola\t"+"que"+"\n"+"tal");
alert("Hola\n que\n t\nal");
num=prompt("Escribe un número: ","");
alert("El \ndoble\n es: \n"+(num*2));
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog006.htm
- Ejecútalo, observando detenidamente la acción de \n y \t
- Si no introducimos un número en el "prompt", en el "alert" correspondiente al doble del número, aparecerá NaN,
que quiere decir que no es un número.

El tipo de datos "Number"

Podemos guardar indistintamente en una variable number un número entero, decimal, positivo o negativo.
Ejemplos:
var numNatural= 1234;
var numEntero = -479;
var numDecimal = 3.141592;
var numDecimal2 = -0.123;
- Bases de Numeración en JavaScript (números enteros)
Por defecto, el sistema de numeración es el decimal.
• Base Hexadecimal (base 16): anteponemos el prefijo 0X
• Base Octal (base 8): anteponemos un cero
Dígitos del sistema decimal: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Dígitos del sistema hexadecimal: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A (que corresponde al 10 en base
decimal), B (que corresponde al 11 en decimal), C (12), D (13), E (14), F (15)
Ejemplo:
FF32 en base 16 es 2 + 3*16 + 15*162 + 15*163 = 65330 en sistema decimal
Es decir: 0xFF32 (número en base 16, según notación de JavaScript) = FF3216 = 6533010
123458 = 5 + 4*8 + 3*82 + 2*83 + 1*84 = 534910
Es decir: 012345 (número en base 8, según notación de JavaScript) = 123458 = 534910
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE=''JavaScript''>
// PROG007.HTM

var n1=57; // número en base 10


var n2=012345; //base 8, porque empieza por 0
var n3=0xFF32; //base 16, porque empieza por 0x
alert("número decimal= "+n1);
alert("el 12345 en base 8 es en decimal= "+n2);
alert("el FF32 en base 16 es en decimal= "+n3);
/* Observa que al escribir una variable numérica en un "alert"
siempre nos da el número en decimal,
aunque sea en octal o hexadecimal */
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog007.htm y ejecútalo. En el programa anterior aparecen 3 “alerts”, uno
para cada uno de los tres números. No hay ningún problema para incluir los tres “alerts” en uno solo.
- En efecto, escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE=''JavaScript''>
// PROG007b.HTM
var n1=57; // número en base 10
var n2=012345; //base 8, porque empieza por 0
var n3=0xFF32; //base 16, porque empieza por 0x
alert("número decimal= "+n1+"\n"+
"el 12345 en base 8 es en decimal= "+n2+"\n"+
"el FF32 en base 16 es en decimal= "+n3);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog007b.htm y ejecútalo.
- Observa que la solución de nuestro problema está:
• Unir texto (entre comillas) y variables (sin comillas), con el signo “+”
• Cada vez que deseemos un cambio de línea, incluimos “\n”
Veamos otra forma de incluir en un “alert” muchos datos ...
- Escribe:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// Prog007bb.htm
var x,y,z;
salida="";
var x1="Pepito Grillo", y1="Paquita González";
var num1=37, num2=3.752;
x=prompt("Escribe tu nombre:","");
y=prompt("Escribe tu primer apellido:","");
z=prompt("Escribe tu segundo apellido:","");
salida=salida+"Ahora un alert largo ";

salida=salida+x+y+z;
salida=salida+x1+" "+y1;
salida=salida+num1+" "+num2;
salida=salida+" ,ya me he cansado";
alert(salida);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog007bb.htm y ejecútalo.
- Observa de qué forma acumulamos muchos datos en un solo “alert” (ésta será la forma de
proceder, cuando necesitemos una “salida” con muchos valores):
• definimos una variable “vacía”: var salida=””;
• acumulamos a la variable salida todo lo que queramos: salida=salida+ lo que sea
• “lo que sea” puede ser una cadena (un texto) o una variable (sea numérica o de
texto).
salida=salida + x1 + “ “ + y1;
salida=salida + “ya me he cansado”;
• Para acabar, un solo “alert”: alert(salida);

Variables nulas.

Cuando una variable no contiene ningún valor, su contenido es nulo


Ejemplo: miVariable = "Hola";
miVariable= null; // la vaciamos para que no ocupe memoria.
Valores especiales para variables numéricas
NaN: no es un número.
Infinity: infinito, por ejemplo 3/0
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG008.HTM
var var1="Pepe";
var var2="Paquito";
var var3=5/0;
alert("Pepe es "+var1);
alert("Paquito + 2 es ="+(var2+2));
alert("5/0 es ="+var3);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog008.htm y ejecútalo.

Contadores

Uno de los instrumentos más utilizados en todo lenguaje de programación es el llamado contador
Observa:
var x= 10;
x = x+1;
x = x-5;
Declaramos una variable "x", que es numérica y que inicialmente es 10.
La línea "x = x+1" es un contador, que hemos de leer: El nuevo valor de "x" es igual al
anterior valor de "x" más una unidad. Es decir, que en estos momentos nuestra variable "x"
es igual a 11.
La siguiente línea: "x = x-5" es otro contador que hemos de leer: el nuevo valor de "x" es
igual al anterior valor de "x" menos 5 unidades. Es decir, que el valor de la variable "x" es
ahora 11 - 5 = 6
- Haz un programa para comprobar lo que hemos dicho sobre los contadores, es decir:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG009.HTM
var x=10;
alert("El valor inicial de x es "+x);
x=x+1;
alert("Después de x=x+1, x="+x);
x=x-5;
alert("Después de x=x-5, x="+x);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog009.htm y ejecútalo.

Conversión entre tipos de datos

- Conversión implícita de tipos

Observa: var var1 = "75";


var var2 = 25;
var var3, var4;
var3 = var1 + var2;
var4 = var2 + var1;
Las varibles var3 y var4 contienen ¿números o textos?
Cuando se suman cadenas de texto con cualquier otra cosa, los otros tipos de datos se
convierten en cadenas de texto. Pero si restamos, multiplicamos o dividimos "cadenas de
texto", ¿sucede lo mismo?. Vamos a descubrirlo en los siguientes programas.
- Escribe el siguiente programa:

<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG010.HTM
var num1="30";
var num2="15";
// Observa que definimos dos cadenas de texto
alert("30+15= "+(num1+num2));
alert("30*15= "+(num1*num2));
</SCRIPT>
</HTML>
- Graba el programa en TuCarpeta con el nombre Prog010.htm
- Ejecútalo.
- La conclusión está clara:
• Si sumamos dos cadenas (aunque contengan números) de texto se produce la concatenación (unión) de los dos
textos.
• Si multiplicamos (o hacemos cualquier operación aritmética que no sea la suma), dos cadenas de texo que en
realidad contienen números, se produce una conversión implícita de las cadenas a números y aparece el producto
aritmético de los números.
- ¿Qué sucede si introducimos dos números a través de la función prompt?. Vamos a verlo:
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
//PROG011.HTM
var num1,num2;
num1=prompt("Escribe un número","");
num2=prompt("Escribe otro número","");
alert("La suma es ="+(num1+num2));
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta, con el nombre Prog011.htm
- Ejecútalo. No funciona como deseamos debido a que el resultado de un prompt, siempre es una cadena de texto.
El problema que tenemos pendiente, es ¿cómo sumar en JavaScript?

Conversión explícita de tipos


parseFloat(cadena)
Toma la "cadena" y la transforma en un número en coma flotante, si es posible.
parseFloat ("123.456") = 123.456
parseFloat ("123ABC") = 123

parseFloat ("ABC") = NaN

parseInt(cadena, número)
Devuelve números enteros, el segundo argumento nos permite escoger la base de numeración (entre 2 y 36)
parseInt ("ABC",16) = 2748 ABC16 = 274810 Si no especificamos el segundo argumento, por defecto es 10.
Si la cadena empieza por 0x y no existe el segundo argumento, se entiende que es 16. Si la cadena empieza por 0 y
no existe el segundo argumento, se entiende que es 8

toString(argumento)
Si argumento = número
Devuelve una cadena que contiene el número Puede haber un argumento opcional:
(13).toString(16) =”d” siendo 1310 = d16 ,(13).toString(2) = “1101” siendo 1310 = 11012
- Vamos a hacer un programa que sume números en JavaScript.
Escribe:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
//PROG012.HTM
var num1,num2;
num1=prompt("Escribe un número","");
num1=parseFloat(num1);
num2=prompt("Escribe otro número","");
num2=parseFloat(num2);
alert("La suma es ="+(num1+num2));
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog012.htm
- Ejecútalo, utilizando números enteros, naturales y decimales.
A partir de este momento hemos de tener claro si los “prompts” corresponden a números
enteros, decimales o de texto:
- Si “x” ha de ser un número entero escribiremos:
x = parseInt(prompt(“Escribe un número entero”,””));
- Si “x” ha de ser un número decimal escribiremos:
x = parseInt(prompt(“Escribe un número entero o decimal”,””));
- Si “x” ha de ser una cadena de texto escribiremos:
x = prompt(“Escribe el texto correspondiente”,””);
- Escribe el siguiente programa:
<HTML>
JavaScript Fermí Vilà 15
<SCRIPT LANGUAGE="JavaScript">
// Prog012b.htm
var x,y;
x=parseInt(prompt("Escribe un entero ",""));
y=parseInt(prompt("Escribe otro entero ",""));
alert("La suma de "+ x +" + " + y +" es =" + (x+y) +"\n"+
"El producto de "+ x +" y "+ y +" = "+(x*y)+"\n"+
"El promedio de "+ x +" y "+ y +" es "+ (x+y)/2);
</SCRIPT>
</HTML>
- Grábalo con el nombre Prog012b.htm, y ejecútalo.
En el ejercicio Prog007.htm habíamos visto una forma de convertir un número en base 8 o
base 16 en base 10. Pero dichos números debíamos de escribirlos implícitamente, es decir en
el programa. Nos gustaría hacer un programa que:
- Nos preguntara un número en base 16 (prompt)
- Nos diera como resultado el número anterior pero en base 10
Vamos a ver si lo conseguimos:
- Escribe:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// Prog012bb.htm
var m,n,x;
m=prompt("Escribe un número en base 16","");
n=parseInt(m,16);
alert("El número "+m+" en base 16, es igual a "+n+" en base 10");
</SCRIPT>
</HTML>
- Grábalo con el nombre Prog012bb.htm en TuCarpeta y ejecútalo para el número “FF32”, a
ver si es verdad que nos da “65330” como resultado.
Observa el funcionamiento del programa Prog012bb.htm:
• m = prompt(“Escribe un número en base 16”, “”)
Lo que escribamos (un número en base 16), se guardará en la variable “m” como texto
(ya que no hemos puesto ningún “parseInt” ni “parseFloat”).
• n =parseInt(m,16)
La variable “n” guardará el número en base 10, Es decir: parseInt(cadena, 16), transforma la “cadena”, en nuestro
ejemplo un número escrito en base 16, en el correspondiente número (no cadena) pero en base decimal.
Vamos a ver si el procedimiento sirve para cualquier otra base...
Antes de todo veamos unos cuantos números en diferentes bases:
367 = 6 + 3.7 = 27 en base 10
1234 = 3 + 2.4 + 1.42 = 27 en base 10
51346 = 4 + 3.6 + 1.62 + 5.63 = 1138 en base 10

- Escribe:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// Prog012bbb.htm
var m7,n7;
var m4,n4;
var m6,n6;
m7=prompt("Escribe un número en base 7","");
n7=parseInt(m7,7);
m4=prompt("Escribe un número en base 4","");
n4=parseInt(m4,4);
m6=prompt("Escribe un número en base 6","");
n6=parseInt(m6,6);
alert("El número "+m7+" en base 7, es igual a "+n7+" en base 10\n"+
"El número "+m4+" en base 4, es igual a "+n4+" en base 10\n"+
"El número "+m6+" en base 6, es igual a "+n6+" en base 10");
</SCRIPT>
</HTML>
- Grábalo con el nombre Prog012bbb.htm y ejecútalo, probándolo con los números
anteriores. Veamos el problema inverso: dado un número en base 10, nos interesa convertirlo a base 7,
por ejemplo.Matemáticamente:
Sea 593 un número en base 10
59310 = 15057 , porque:
En JavaScript deberíamos hacerlo de la siguiente forma,
escribe:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// Prog012bbbb.htm
var m,n;
n=parseInt(prompt("Escribe un número entero en base 10",""));
m=(n).toString(7);
alert("El número "+n+" en base 10, es igual a "+m+" en base 7");
</SCRIPT>
</HTML>
Grábalo con el nombre Prog012bbbb.htm y ejecútalo, probando su funcionamiento con el número 593

Estructuras de Programaciónen Java script

1.- Operadores Lógicos y Relacionales

>, <, <=, >=


== igualdad
!= diferente
&& y
|| o
! No

2.- La estructura “if-else”

- Escribe el siguiente programa:


<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG013.HTM
var num;
num=parseFloat(prompt("Escribe un número",""));
if(num==100)
{
alert("El número que has escrito es 100");
}
else
{
alert("El número que has escrito no es 100");
}
if(num>0)
{
alert("El número que has escrito es positivo");
}
else
{
alert("El número es negativo o 0");
}
</SCRIPT>
</HTML>
- Grábalo con el nombre Prog013.htm en TuCarpeta
- Ejecútalo.
- La Estructura de programación “if-else”
Sintaxis:
if(condición)
{
sentencia1;
sentencia2;
sentencia3;
}
else
{
sentencia4;
sentencia5;
sentencia6;
}

Significado:
Si se cumple la condición, se ejecutan las sentencias 1, 2 y 3 y si no se cumple se ejecutan las
sentencias 4, 5, 6. La opción “else” es opcional.
- Observa la diferencia entre “=” y “==”
a = 3*9 es una asignación, es decir la variable “a” es 27. En cambio if(a==5) es una condición:
si “a” es idéntico a 5 (si el valor de “a” es el número 5)…
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG014.HTM
var a,b;
a=parseFloat(prompt("Escribe el primer número",""));
b=parseFloat(prompt("Escribe el segundo número",""));
if(a==b) alert("Los dos números son iguales");
if(a != b) alert("Los dos números son distintos");
if(a>b)
{
alert("El primer número es mayor que el segundo");
}
else
{
alert("El primer número no es mayor que el segundo");
}
if((a>b) && (100>a))
{
alert("El primero es mayor que el segundo");
alert("Además los dos son menores de 100");
}
else
{
alert("El primero no es mayor que el segundo");
alert("O uno de los dos números es mayor o igual a 100");
}
</SCRIPT>
</HTML>
- Grábalo con el nombre Prog014.htm en TuCarpeta.
- Ejecuta el programa para los siguientes casos, observando detenidamente lo que aparece:
1) a=70, b=2
2) a=50, b=30
3) a=7, b=11
4) a=100, b=50
5) a=50, b=100
- Observa:
a==b “a” es igual a “b”
a != b “a” es diferente a “b”
(a>b) && (100>a)
“a” es mayor que “b” y además “100 es mayor que –a-“
El else correspondiente a la condición anterior, sería equivalente a no(a>b) ||
no(100>a), es decir la negación de la primera condición o la negación de la segunda (o las dos
negaciones a la vez).
JavaScript Fermí Vilà 26

3.- La estructura de programación “while”

Sintaxis:
while(condición)
{
setencia1;
sentencia2;
sentencia3;
}
Significado:
“Mientras” se cumpla la condición, se irán repitiendo las sentencias 1, 2 y 3.
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG015.HTM
var x=0;
while(x<6)
{
alert("El valor de x es= "+x);
x=x+1;
}
</SCRIPT>
</HTML>
- Grábalo con el nombre Prog015.htm en TuCarpeta y ejecútalo.
- Estudio del Prog015.htm
• En “palabras”, nuestro programa nos dice: “mientras” la x sea inferior a 6;
escribe el valor de “x”;
incrementa en una unidad el valor de “x”;
• Al principio x=0
Se cumple la condición del while: x<6
Aparece escrito x=0
Al pasar por el contador x=1
Se cumple la condición x<6
Aparece escrito x=1
Al pasar por el contador x=2
Aparece escrito x=2


Cuando x=6 no se cumple la condición y por lo tanto se acaba el programa.

4.- Contadores en JavaScript

a=a+1 es equivalente a escribir a++


a=a-1 es equivalente a escribir a—
num=num+2 es equivalente a escribir num += 2
num=num*2 es equivalente a escribir num *= 2
num=num/2 es equivalente a escribir num /= 2

- Escribe el siguiente programa:


<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG016.HTM
var i=2;
var res="";
var j=7;
while (i<j)
{
res=res+" "+i+" "+j+"\n";
i++;
j--;
}
alert(res);
</SCRIPT>
</HTML>
- Grábalo con el nombre Prog016.htm en TuCarpeta
- Ejecuta el programa, es importante que tengas claro el funcionamiento del Prog016.htm:
compara el listado del programa con lo que sucede al ejecutarlo. Observa cómo
conseguimos escribir toda la salida en un único “alert” (variable “res”).
Programa que repite un texto cualquiera, el número de veces que queramos, utilizando un “while”
- Escribe el siguiente programa:

<SCRIPT LANGUAGE="JavaScript">
// PROG017.HTM
var nom;
var indice=1;
var num;
var respuesta=" ";
nom=prompt("Escribe tu nombre","");
num=prompt("Cuántas veces quieres que lo repita","");
num=parseInt(num,10); // era una cadena y ahora es un número
while (indice <= num)
{
respuesta=respuesta+nom+"\n";
indice++;
}
alert(respuesta);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog017.htm y ejecútalo
- Recuerda que en el “ParseInt” no es necesario escribir el 10, ya que por defecto (si no lo
escribimos), es base 10.
Programa que acumula la suma y el producto de los números que queramos
- Escribe:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG018.HTM
var num;
var sum=0;
var pro=1;
var respuesta="";
num=prompt("Escribe un número diferente de cero=","");
num=parseFloat(num);
while(num != 0)
{
sum=sum+num;
pro=pro*num;
respuesta=respuesta+num+"\tsuma parcial:"+sum+"\tproducto
parcial:"+pro+"\n";
num=prompt("Escribe otro número (para acabar introduce cero)","");
num=parseFloat(num);
}
alert(respuesta);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog018.htm y ejecútalo.
- Observa como acumulamos la suma y el producto:
Contador que acumula la suma de los números “num”: sum=sum+num;
Hemos de inicializar a 0 la variable “sum”.
Contador que acumula el producto de los números “num”: pro=pro*num
Hemos de inicializar a 1 la variable “pro”.

5.- La Estructura de programación “For”


for (contador = valor inicial; condición; expresión de incremento)
{
…;
…;
…;
}
Ejemplo:
for (i=1;i<=10;i++)
{
sentencia1;
sentencia2;
sentencia3;
}
En palabras significa:

“Desde i=1, hasta i=10 de 1 en 1, repite las sentencias 1, 2 y 3”


Es decir: Repite 10 veces las sentencias 1, 2 y 3
Observa que el contador o índice del “for” (en nuestro caso la “i”), es una variable que no es
necesario declararla, ya que la expresión “i=1” la declara e inicializa.
Programa que repite un texto cualquiera en número de veces que queramos, utilizando un “for”
- Escribe el siguiente programa:

<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG019.HTM
var texto;
var num;
var salida="";
texto=prompt("Escribe un texto","");
num=prompt("Cuántas veces quieres que lo repita","");
num=parseInt(num,10);
for(i=1;i<=num;i++)
{
salida=salida+texto+"\n";
}
alert(salida);
</SCRIPT>
</HTML>
- Graba el fichero en TuCarpeta, con el nombre Prog019.htm y ejecútalo unas cuántas
veces.
Programa que calcula todos los múltiplos de 11 menores de 3000 y por último nos da la suma de todos
ellos.
- Escribe el siguiente programa:

<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG020.HTM
var salida="";
var sum=0;
for(multi=11;multi<3000;multi=multi+11)
{
salida=salida+multi+" ";
sum=sum+multi;
}
alert(salida+"\nLa Suma de todos ellos es= "+sum);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta, con el nombre Prog020.htm y ejecútalo.

Programa que calcula el factorial de un número


Recuerda que el factorial del número “x” es: 1*2*3*4*5*…*x
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG021.HTM
var salida="";
var fact=1;
var num;
num=prompt("Cálculo del factorial del numero ","");
num=parseInt(num,10);
for(i=1;i<=num;i++) fact=fact*i;
alert("El factorial de "+num+" es "+fact);
</SCRIPT>
</HTML>
- Grábalo en TuCarpeta con el nombre Prog021.htm y ejecútalo varias veces.
Observa que nuestro “for” no necesita llaves, porque contiene una única sentencia.
Programa que calcula los 10 primeros múltiplos del número que queramos, por último
nos da la suma de todos ellos.
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG022.HTM
var salida="";
var num;
var mult;
var sum=0;
num=prompt("¿Múltiplos de qué número?","");
num=parseInt(num,10);
for(i=1;i<=10;i++)
{
mult=num*i;
salida=salida+mult+" ";
sum=sum+mult;
}
alert(salida+"\nSuma= "+sum);
</SCRIPT>
</HTML>

- Grábalo con el nombre Prog022.htm en TuCarpeta y ejecútalo varias veces.


Tabla de valores de la función y=x2-5x+10
- Escribe el siguiente programa:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG023.HTM
var x1,x2,paso;
var salida="";
var y;
x1=prompt("Escribe el menor valor de x","");
x1=parseFloat(x1);
x2=prompt("Escribe el mayor valor de x","");
x2=parseFloat(x2);
paso=prompt("Escribe el incremento de x:","");
paso=parseFloat(paso);
for(i=x1;i<=x2;i=i+paso)
{
y=i*i-5*i+10;
salida=salida+i+" "+y+"\n";
}
alert(salida);
</SCRIPT>
</HTML>
- Graba el fichero en TuCarpeta con el nombre Prog023.htm y ejecútalo varias veces.
- Al ejecutar el programa anterior, nos podemos encontrar con una serie de problemas, por
ejemplo si introducimos en el valor menor de “x” (x1), un valor que sea mayor que el
introducido en la variable x2, o también puede suceder que en la variable paso escribamos
un número negativo.
- Vamos a solucionar estos posibles problemas, es decir vamos a “mejorar” el programa
anterior.
Escribe:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG024.HTM
var x1,x2,paso;
var salida="";
var y;
x1=prompt("Escribe el menor valor de x de la tabla","");
x1=parseFloat(x1);
x2=prompt("Escribe el mayor valor de x de la tabla","");
x2=parseFloat(x2);

if (x1>=x2)
{
alert("No tiene sentido lo que intentas hacer");
}
else
{
paso=prompt("Escribe el incremento de x","");
paso=parseFloat(paso);
if (paso<=0)
{
alert("No tine sentido lo que intentas hacer");
}
else
{
for (i=x1;i<=x2;i=i+paso)
{
y=i*i-5*i+10;
salida=salida+i+" "+y+"\n";
}
alert(salida);
}
}
</SCRIPT>
</HTML>
- Grábalo con el nombre Prog024.htm en TuCarpeta y ejecútalo, convendría probar los
casos x1>=x2 y paso<0
- Observa de qué forma salimos del programa si introducimos datos que no tienen sentido.

6.- El Objeto “Math”

Nos permite trabajar con funciones matemáticas. Concretamente:


Math.log(x) = ln(x)
Math.exp(x) = ex
Math.sqrt(x) = raiz cuadrada de “x”
Math.pow(a, b) = ab
Math.floor(): número entero más cercano y menor
Math.ceil(): número entero más cercano y mayor
Math.round(): redondea al entero más próximo.
Math.random(): número aleatorio entre 0 y 1
Math.round(y-x)*Math.random()+x: número aleatorio entre “x” e “y”.
Math.sin(x)= sin(x) x en radianes
Math.cos(x)= cos(x) x en radianes
Math.tan(x)= tg(x) x en radianes
Math.atan(x)= arctg(x) resultado en radianes
Math.abs(x): valor absoluto de “x”
Math.max(a,b) : máximo valor de los dos
Math.min(a,b): mínimo valor de los dos.
Programa que calcula la hipotenusa de un triángulo rectángulo
- Escribe:

<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG025.HTM
var cat1,cat2,hipo;
cat1=prompt("Escribe el valor de un cateto","");
cat2=prompt("Escribe el valor del otro cateto","");
cat1=parseFloat(cat1);
cat2=parseFloat(cat2);
hipo=Math.sqrt(cat1*cat1+cat2*cat2);
alert("La hipotenusa del triángulo de catetos "+cat1+" y "+cat2+" es
"+hipo);
</SCRIPT>
</HTML>
- Graba el fichero con el nombre Prog025.htm en TuCarpeta y ejecútalo unas cuantas
veces.
Programa que calcula tantas hipotenusas como queramos
- Escribe:
<HTML>
<SCRIPT LANGUAGE="JavaScript">
// PROG026.HTM
var opcion="S";
var cat1,cat2,hipo;
while(opcion=="S" || opcion=="s")
{
cat1=prompt("Escribe el valor de un cateto","");
cat2=prompt("Escribe el valor del otro cateto","");
cat1=parseFloat(cat1);
cat2=parseFloat(cat2);
hipo=Math.sqrt(cat1*cat1+cat2*cat2);
alert("La hipotenusa del triángulo de catetos "+cat1+" y "+cat2+" es
"+hipo);
opcion=prompt("¿Quieres calcular otra hipotenusa? (S/N)","");
}
alert("Adiós muy buenas");
</SCRIPT>
</HTML>
- Graba el programa en TuCarpeta con el nombre Prog026.htm y ejecútalo.
Programa que resuelve una ecuación de segundo grado
- Escribe:
<HTML>
<SCRIPT LANGUAGE="JavaScript">

// PROG027.HTM
var a,b,c;
var discri;
var x1,x2;
a=prompt("Escribe el coeficiente de la x^2","");
a=parseFloat(a);
b=prompt("Escribe el coeficiente de la x","");
b=parseFloat(b);
c=prompt("Escribe el término independiente","");
c=parseFloat(c);
discri=b*b-4*a*c;
if(discri<0) alert("Soluciones Imaginarias");
if(discri==0)
{
x1=-b/(2*a);
alert("Solución doble que es "+x1);
}
if(discri>0)
{
x1=(-b+Math.sqrt(discri))/(2*a);
x2=(-b-Math.sqrt(discri))/(2*a);
alert("Las soluciones son = "+x1+" y "+x2);
}
</SCRIPT>
</HTML>
- Graba el programa en TuCarpeta con el nombre Prog027.htm
- Ejecútalo para los casos:
a= 1, b= 1, c= 1
a= 2, b=-6, c= -20
a= 1, b= 4, c= 4

2.LENGUAJE VISUAL BASIC SCRIPT.

Características Generales de Visual-BasicScript

Visual-Basic script es una herramienta de diseño de aplicaciones para Windows, en la que estas se desarrollan en una gran parte a partir
del diseño de una interface gráfica. En una aplicación Visual - Basic, el programa está formado por una parte de código puro, y otras partes
asociadas a los objetos que forman la interface gráfica.

Es por tanto un termino medio entre la programación tradicional, formada por una sucesión lineal de código estructurado, y la programación
orientada a objetos. Combina ambas tendencias. Ya que no podemos decir que VB pertenezca por completo a uno de esos dos tipos de
programación, debemos inventar una palabra que la defina : PROGRAMACION VISUAL.

La creación de un programa bajo Visual Basic lleva los siguientes pasos:

- Creación de un interface de usuario. Este interface será la principal vía de comunicación hombre máquina, tanto para salida de datos
como para entrada. Será necesario partir de una ventana - Formulario - a la que le iremos añadiendo los controles necesarios.

- Definición de las propiedades de los controles - Objetos - que hayamos colocado en ese formulario. Estas propiedades
determinarán la forma estática de los controles, es decir, como son los controles y para qué sirven.

- Generación del código asociado a los eventos que ocurran a estos objetos. A la respuesta a estos eventos (click, doble click,
una tecla pulsada, etc.) le llamamos Procedimiento, y deberá generarse de acuerdo a las necesidades del programa.
- Generación del código del programa. Un programa puede hacerse solamente con la programación de los distintos
procedimientos que acompañan a cada objeto. Sin embargo, VB ofrece la posibilidad de establecer un código de programa
separado de estos eventos. Este código puede introducirse en unos bloques llamados Módulos, en otros bloques llamados
Funciones, y otros llamados Procedimientos. Estos Procedimientos no responden a un evento acaecido a un objeto, sino que
responden a un evento producido durante la ejecución del programa.

No es necesario entender de momento lo anterior. Visual Basic introduce un concepto nuevo de programación, y es necesario cambiar
hasta el argot del programador. Posiblemente se le habrán acumulado demasiados términos de una sola vez. Es normal. A poco que siga
leyendo verá las cosas mas claras cuando se explique una por una.

VARIABLES. DEFINICION Y ENTORNO

Basic, desde siempre, al contrario de otros sistemas de programación, no exigió la definición previa de una variable. Una variable, como
Vd. seguro que conoce, es un nombre que en el programa le asignamos a un dato. Ese dato podrá cambiar. Piense por ejemplo, en un
programa consistente en la toma de datos de los alumnos de un centro escolar. Existirán varias variables para poder introducir los datos de
los alumnos. Estas variables pueden tener nombre tales como:

Nombre
Apellido1
Apellido2
Dirección
Teléfono
DNI

La variable Nombre tomará valores distintos según vayamos introduciendo los datos de los distintos alumnos. Es posible, que a lo largo de
la ejecución del programa, esta variable Nombre valga:

José
Pedro
María
Luis

Espero que su intuición o conocimiento anterior le lleve a conocer el concepto de variable. Mas adelante lo verá mas claro.

Decíamos que Basic no exige la definición previa de las variables. Otras herramientas exigen que se haga así. Por lo tanto es normal
encontrar, en otros sistemas de programación, que un programa comienza de la siguiente forma:
Declare Nombre As String Le dice que Nombre es una sucesión de letras
Declare Apellido1 As String
Declare Apellido2 As String
Declare Dirección As String
Declare Teléfono As String Le dice que Teléfono es una sucesión de letras
Declare DNI As Número Le dice que DNI es un número

Mediante estas declaraciones, el programa sabe de que tipo de dato se trata y por tanto cómo debe trabajar con él. En otros sistemas de
programación distintos de Basic, es necesario realizar esta declaración antes de introducir una variable.

Basic permite que no se declaren. Cuando a lo largo del programa le introducimos una variable nueva, asume que es una variable y que el
tipo es el adecuado para el valor que le estamos introduciendo en ese momento.

Por ejemplo, si Basic encuentra estas instrucciones

DNI=50000000
Nombre ="Pedro"
Teléfono = "1234567"

entiende que DNI, Nombre y Teléfono son variables, que DNI es un número (No hemos metido su valor entre comillas), y que Nombre y
Teléfono son sucesiones de caracteres alfanuméricos (su valor está entre comillas)

Esta particularidad de no necesitar declarar las variables hace que sea sencillo introducir una variable nueva. Sin embargo entraña un gran
peligro. Imagínese que en un paso posterior del programa, le mandamos escribir esos tres datos anteriores con la instrucción PRINT

Print DNI
Print Nombre
Print Telwfono

Habrá observado en tercer lugar la palabra Telwfono, que por error ha introducido el programador. Basic interpreta que Telwfono es una
variable e irá a leer en memoria el valor que tiene. No tendrá ningún valor. Por lo tanto no escribirá nada y encima no dará ningún aviso de
que se ha cometido un error. Nada es gratis en esta vida, y la facilidad para introducir variables se paga con la posibilidad de un error.

Basic ha pensado en ese problema, y se puede solucionar con esta que será la primera instrucción BASIC que vamos a estudiar:

OPTION EXPLICIT
Obliga a declarar previamente las variables que se vayan a usar. De no haberla declarado antes de usarla, el programa
dará una comunicación de error.

TIPOS DE VARIABLES

Las variables pueden ser de los siguientes tipos: (El número indicado en segundo lugar indica el número de Bytes que ocupa en memoria.)

Booleana (2) Admite los valores 0 y 1, o True (verdadero) y False (falso)


Byte (1) Números enteros, en el rango de 0 a 255
Integer (2) Números enteros en el rango de -32768 a 32767
Long (4) Números enteros en el rango de -2147483648 a 2147483647
Single (4) Punto flotante, simple precisión
Doble (8) Punto flotante, doble precisión.
Currency (8) Entero, con punto decimal fijo (Típico de monedas)
String (*) Cadenas alfanuméricas de longitud variable o fija
Date (8) Fechas
Objet (4) Referencia a objetos
Variant (**) Otros tipos de datos

(*) Una variable tipo String ocupa el mismo número de bytes que caracteres tenga la cadena.
(**) Una variable tipo Variant ocupa 16 bytes si se trata de un número y 22 bytes + longitud de la cadena si se trata de un dato tipo cadena
de caracteres.

Existen también variables definidas por el usuario (Ya verá la sentencia Type). En este tipo de variables se pueden introducir muchos datos
de distinto tipo. Los bytes necesarios para almacenar esa variable dependerá de los datos que se hayan definido.

Dentro de las variables Objet (variables que se refieren a objetos) existe una gran variedad que a estas alturas del curso no debemos
complicarnos con ellas. Pero para adelantar algo, veremos que una variable puede ser del tipo Form - Formulario - , tipo Picture, etc. etc.

Cada tipo de variable ocupa unos determinados bytes. Si no se define una variable, VB toma como tipo por defecto para la variable el tipo
Variant. Este tipo ocupa mas bytes que, por ejemplo, un integer. Si el tipo de dato que vamos a introducir en una variable es un integer, y no
la hemos declarado como tal, VB asumirá para esa variable que es del tipo Variant, lo que le llevará a gastar mas bytes de memoria (16)
que los que necesitaría (2) si la hubiésemos declarado previamente. Si esa variable va a estar en el rango de 0 a 255, y no declaramos
previamente que la variable va a se del tipo Byte, o la declaramos como integer, p. e., estamos desperdiciando memoria RAM y
posiblemente, retardando la ejecución del programa. Lo mismo podemos decir del resto de las variables, y lo importante que es definirlas y
definirlas bien.
NOTA. Observe en la lista anterior que un dato Booleano ocupa 2 Bytes, mientras que un dato tipo Byte ocupa un byte. En muchas
ocasiones declaramos variables tipo Boolean con la intención de que ocupen menos espacio. Paradoja del VB. Si la declaramos como Byte
ocupamos menos espacio en memoria. Declarar una variable como Boolean tiene también sus ventajas (escribirá menos código por lo
general cuando necesite leer o escribir una variable tipo Boolean), pero tenga presente esta observación respecto a los datos Boolean.

Puede declarar el tipo de la variable mediante un carácter después del nombre de la variable. Esta técnica, obligatoria en Quick-Basic, está
en desuso en VB. No es recomendable definir el tipo de esta forma, pues existe un serio peligro de error. De cualquier forma, eso es
potestativo del programador y de sus costumbres.

Los caracteres que definen cada tipo de variable son:

% Integer & Long ! Single

# Double @ Currency $ String

Ejemplos Prácticos de declaración de variables

En Visual Basic, cuando declaramos una variable como String (Cadena de caracteres), no es necesario declarar su longitud. VB aceptará
cualquier número de caracteres. Si desea evitar que se puedan introducir más de un determinado número de caracteres, debe declarar su
número. Por ejemplo :

Dim Var1 as String Var1 puede tener cualquier número de caracteres

Dim Var2 as String * 15 Var2 puede tener un máximo de 15 caracteres.

En este segundo caso, si se introduce como Var2 una cadena de caracteres con mas de 15 caracteres, Var2 tomará solamente los 15
primeros. Visual basic no presenta ningún aviso de que esa variable ha omitido los caracteres que han sobrepasado la cifra de 15. Si
desea que el usuario conozca esa circunstancia, debe introducir el código oportuno para producir el aviso.

La declaración de variables tipo String con número de caracteres predefinido presenta también inconvenientes a la hora de tratar esa
cadena de caracteres con sentencias tales como Mid, Left y Right, o a la hora de añadir una cadena a otra. La experiencia nos indica que
NO merece la pena declarar variables tipo String con el número de caracteres prefijado.

En una gran parte de los casos una variable que se compone de números debe declararse como una variable de cadena de caracteres
(String), y no como numérica. Cuando pensamos por ejemplo en un número de DNI, compuesto por 7 u 8 cifras, un código postal, el
número de una calle, el piso de un edificio, parecen invitar a que la variable que los contenga sea una variable de tipo numérico (Byte,
Integer, Long, ...). Estas variables, aunque su contenido sean números, siempre se deben declarar como String, ya que se tratan en
realidad de cadenas de caracteres, aunque estos sean números. Para aclarar mas estas ideas, piense en el número del DNI con la letra del
NIF incluido, o que el lugar del DNI se deba rellenar con el número del permiso de residencia, (lleva letras). Piense en el código postal de
una provincia que comienza por 0 ( 08XXX = Barcelona ) . Si la variable que va a contener ese código postal se declara como numérica, el
cero de la izquierda lo desprecia, por lo que ese código postal quedaría reducido al 8XXX, número de 4 cifras que el cartero nunca
reconocería como un código postal, que necesariamente ha de tener 5 cifras. Para terminar, piense la forma de introducir en una variable
numérica el número 32Bis de una calle o el piso S2 de un edificio. O piense en una variable que va a contener un código de un producto.
Ese código siempre va a ser un número, por ejemplo de 9 cifras. ¿Ha pensado como trataría el ordenador una variable numérica que
contiene el código 000100123 ?. El resultado sería que convertiría ese código en la cifra 100123, y Vd. deberá buscarse la vida para añadir
los ceros iniciales a la hora de sacarlo a una impresora, por ejemplo.

En todos los casos anteriores, el número no representa una cantidad numérica, sino un nombre. Lo que ocurre es que ese nombre contiene
solamente números.

¿Qué variables debemos declarar entonces como numéricas ? La respuesta es bien sencilla : Aquellas que van a contener datos con lo
que vamos a realizar operaciones matemáticas.

Las variables booleanas (True/False) pueden en muchos casos sustituirse por una variable del tipo Byte. Si ese datos True / False se va a
introducir en una base de datos o en fichero en el disco, puede ser mas prudente poner 0 en vez de False y 1 en vez de True.

Una variable byte ocupa muy poco, simplemente 1 byte como su nombre indica. Pero no puede contener números mayores de 255 ni
números negativos.

Cada vez que declare una variable numérica piense en los valores que puede tener, sobre todo cuando esa variable va a ser el resultado
de una operación matemática. Recuerde el escaso margen de una variable tipo Integer ( de -32768 a 32767)

Si la aplicación va a tratar moneda, piense en la forma de expresar los números decimales y el número de ellos permitidos, así como el
redondeo. La variable correcta para este caso es Currency, pero Currency le añade automáticamente el tipo de moneda de cada país (Pts.
Para España) lo que con frecuencia es un engorro. Los datos del tipo de moneda los toma del sistema operativo del ordenador, por lo que
no se extrañe si le expresa el número de pesetas en dólares. Cambie el país en su S. O.

Tipos de declaración de variables.


Sentencia DIM Es la forma mas común de declarar una variable como
Privada. Puede emplearse en un Procedimiento, Función, Formulario o Módulo. La sintaxis es de la
siguiente forma:

Dim nombrevariable As Integer (o el tipo que sea)

Declarando una variable con la sentencia DIM, en un formulario, Función, procedimiento o módulo, el entorno de la variable será el
explicado anteriormente para una variable declarada como Privada. Es decir, esa variable no sale del formulario, procedimiento ó módulo
donde se declaró. Cada vez que entremos al formulario, procedimiento o módulo, esa variable tomará el valor cero (si es numérica) o nulo
(si es string).

Sentencia PRIVATE Es la forma de declarar una variable como Privada. Puede


emplearse solamente en la sección de declaraciones de un Formulario o Módulo. La sintaxis es de la
siguiente forma:

Private nombrevariable As Tipovariable

Declarando una variable mediante la sentencia PRIVATE en un Formulario o Módulo, esa variable puede usarse en todo ese Formulario o
Módulo (En todos sus Procedimientos y Funciones), pero NO fuera del Formulario o Módulo donde se declaró.

La sentencia Private no puede usarse en un procedimiento o función.

Sentencia PUBLIC Es la forma de declarar una variable como Pública. Puede


emplearse solamente en la sección de declaraciones de un Formulario o Módulo. La sintaxis es de la
siguiente forma:

Public nombrevariable As Tipovariable

Declarando una variable de esta forma en la sección de declaraciones de un Módulo, esa variable puede usarse en cualquier parte del
programa citándola simplemente por su nombre.
Si se declara de esta forma en la sección de declaraciones de un Formulario, esa variable puede usarse en toda el programa. Para
nombrarla, si estamos en el Formulario donde se declaró basta con citarla por su nombre. Si no estamos en ese Formulario, habrá que
citarla por el nombre del Formulario, seguido del nombre de la variable, separados por un punto :
NombreFormulario.Nombrevariable

En un Módulo puede usarse también la sentencia Global en vez de Public :

Sentencia GLOBAL Declara una variable que es válida en todo el programa. La sintaxis es:

Global nombrevariable As tipovariable

La sentencia Global sólo puede usarse en el apartado de declaraciones de un Módulo.

Mediante la sentencia Global la variable puede usarse en todo el espacio del programa.

Sentencia STATIC

Como se dijo anteriormente, una variable declarada en un procedimiento pierde su valor al salir de él. Lo peor es que una vez que el
programa vuelva a entrar en ese procedimiento, la variable estará puesta a cero. Afortunadamente, esto último tiene solución. Si
declarásemos una variable en un procedimiento o función, como estática, esa variable, aunque no la podremos utilizar fuera de ese
procedimiento o función, cuando volvamos a él conservará el valor que tenía cuando lo abandonamos. Esta declaración como estática se
realiza mediante la intrucción Static

Static nombrevariable As tipovariable

El nombre de una variable puede ser tan largo como queramos. hasta un máximo de 40 caracteres. En la versión VB para España se
pueden usar incluso la Ñ y vocales acentuadas. Es indiferente usar mayúscula ó minúsculas. No se sorprenda, si por ejemplo, la ha
declarado con mayúsculas y luego la cita con minúsculas al escribir el código, que automáticamente se cambie a mayúsculas. El nombre de
una variable siempre debe comenzar por una letra.

No hay problema por utilizar variables largas. Al compilar el programa no se lleva el nombre, es decir, no le va a ocupar mas espacio. Utilice
siempre nombres que le definan la variable con algún sentido. Es muy útil a la hora de acordarse como se llaman, y sobre todo, a la hora de
rehacer un programa que realizó hace seis meses.

Pese a que Visual Basic no obliga a declarar variables, es muy útil hacerlo. De esta forma se tiene control sobre el programa. La
experiencia se lo irá demostrando.

Resumimos la forma de declarar una variable  :


En un Procedimiento (La variable no puede usarse fuera de esta Procedimiento)

Dim Variable As Tipovariable

En un Procedimiento, como permanente (La variable no puede usarse fuera de este procedimiento, y dentro de él conserva el valor
aunque se salga y se vuelva a entrar)

Static Variable As Tipovariable

En un Formulario (En su sección de declaraciones)

Como Privada (Solamente se puede usar en ese Formulario)

Dim Variable As Tipovariable ó

Private Variable As Tipovariable

Como Pública (Puede usarse en toda la aplicación)

Public Variable As Tipovariable

En un Módulo

Como Privada (Solamente puede usarse en ese Módulo)

Dim Variable As Tipovariable ó

Private Variable As Tipovariable

Como Pública (Puede usarse en toda la aplicación)

Public Variable As Tipovariable ó

Global Variable As Tipovariable

Error típico de un programador novel de Visual Basic


Creo que esta costumbre viene del lenguaje C. Pero no vale en VB. Se trata de declarar varias variables juntas en una misma línea :

Dim Variable1, Variable2, Variable3, Variable4 As String

Esta declaración está MAL hecha. Visual Basic interpretará que Variable1, Variable2 y Variable3 son del tipo Variant, y solamente Variable4
la supone como tipo String

La forma correcta de hacerlo, si queremos declarar esas variables un una sola línea, es la siguiente :

Dim Variable1 As String, Variable2 As String, Variable3 As String, Variable4 As String.

Sentencias condicionales.

Llamamos sentencias condicionales a aquellas que se realizan si se cumple una determinada condición. Son las sentencias por las que
empieza cualquier texto de Basic, y este no va ser menos.

La sentencia condicional mas usada es:

Si se cumple una condición Entonces

Realiza estas instrucciones

Si no se cumple

Realiza estas otras instrucciones

Fin de la sentencia.

Así de fácil es programar en Basic. Lo que ocurre es que esta herramienta habla inglés, y lo descrito anteriormente toma la forma:

If condición Then
Instrucciones
Else
Otras instrucciones
End If

En este ejemplo, la condición era que, o se cumple una condición y ejecuta unas determinadas instrucciones, o no se cumple, y ejecuta
otras condiciones distintas. Puede ocurrir que, caso de no cumplirse la condicione primera, se abra un abanico de dos o tres posibilidades.
La sentencia condicional tendría entonces la forma:

If condición 1 Then
Instrucciones
ElseIf Condición 2
Otras instrucciones
ElseIf Condición 3
Otro juego de instrucciones
Else
Instrucciones que debe realizar caso de no cumplir las condiciones 1, 2 y 3.
End If

Como decíamos anteriormente, este es el tipo de sentencia condicional mas usada. Existe otra:

Select Case

Su nombre casi nos define lo que es: Selecciona, dependiendo del caso, un determinado juego de instrucciones:

Select Case variable ' variable es una variable que puede tomar los valores (p.e.) de 1 a 4

Case 1
Instrucciones a ejecutar en caso de que variable = 1
Case 2
Instrucciones a ejecutar en caso de que variable = 2
Case 3
Instrucciones a ejecutar en caso de que variable = 3
Case 4
Instrucciones a ejecutar en caso de que variable = 4
End Select

Este procedimiento resulta mucho mas sencillo y rápido que las sentencias If Then Else
vistas anteriormente, cuando el margen de elección es mayor que 2.

Cuando lo que queremos es elegir un valor, no ejecutar instrucciones como hacíamos anteriormente, disponemos de otras dos funciones:
Choose y Switch.
Switch toma una serie de parámetros, todos por parejas. El primer término de cada pareja es la expresión a evaluar. El segundo es el valor
que tiene que devolver. En realidad Switch es una función (las funciones las veremos muy pronto)

A = Switch (B=1, 5, B=2, 7, B=3, 11)

Esta instrucción obtiene un valor para A que dependerá del valor que tome B entre los valores posibles (1, 2 ó 3)

La sentencia Choose es casi igual, cambia solamente la forma. La misma intrucción anterior puede realizarse con Choose de la siguiente
forma:

A = Choose ( B, 5, 7, 11 )

En estas sentencias, Switch y Choose, si el valor de B no coincide con ninguno de los valores que se le habían establecido (1, 2 ó 3 en
nuestro caso), la sentencia devuelve el valor Nulo ( Null ). Esto puede producir algún error si no se contempla esa posibilidad.

Con estas sentencias condicionales es posible realizar bifurcaciones del programa, cambiar las propiedades de un objeto, obtener
resultados de operaciones, ....

Sentencias de bucle.

Es muy común utilizar bucles a lo largo de un programa. Un bucle es una sucesión repetitiva de instrucciones, que se estarán realizando
mientras se cumpla una condición o mientras no se cumpla otra condición. Es tan sencillo como esto:

Mientras condición

Instrucciones

Fin del bucle

Existen dos formas de bucle: Una, que realiza un número determinado de recorridos por el bucle. Es el denominado bucle por contador.
Otra, realiza el bucle hasta que se cumpla (o deje de cumplirse) una condición. Es el llamado bucle por condición.

Bucle por contador

Realiza el bucle tantas veces como le indiquemos. Por ejemplo, en este bucle nos va a presentar las 26 letras mayúsculas del
alfabeto inglés
For N=65 To 90

Label1.caption = Chr ( N )

Next N

Este "programa" nos presentará en una caja (Label) los caracteres cuyo número ASCII vaya desde el 65 (A) al 90 (Z) Comenzará
presentando el correspondiente al número 65, e irá presentando sucesivamente el 66, el 67, etc., hasta llegar al 90, donde se parará.

Bucles por condición

Ejecuta las instrucciones del bucle mientras se cumple una condición

X=0
Do While X < 1000
X=X+1
Loop

El programa toma una variable ( X ) que previamente tuvimos la curiosidad de ponerla a cero, e incrementa su valor una unidad. Analiza si
el valor de X es menor que 1000, y si es cierto, vuelve a realizar el bucle. Así hasta que X ya no sea menor que 1000. Al dejar de cumplirse
que X sea menor que 1000, sale del bucle. Acabamos de realizar un temporizador, y también de exponer las sentencias condicionales y los
bucles, inicio de cualquier curso de Basic. Como final de lección, se propone un problema. Con el primer bucle, donde visualizábamos los
caracteres A a la Z, posiblemente no nos diese tiempo de ver cada una de las letras que iban apareciendo en la pantalla, en la etiqueta
Label1, dado que cambiaría con mucha velocidad, y solamente veríamos la Z, que es donde se detuvo el programa. Podemos poner un
temporizador cada vez que presente una letra, y así nos dará tiempo a verla. Con los dos bucles vistos anteriormente ya podemos hacerlo.

Si lo que queremos es que el programa se ejecute mientras no se cumpla una determinada condición, la sentencia será:

X=0
Do Until X > 1000
X=X+1
Loop

Observe que la diferencia entre una y otra es la condición, While para indicar Mientras se cumpla que ... y Until para indicar
Mientras no se cumpla que ....

Para terminar bien el programa anterior utilizaremos la condición de While (Mientras se cumpla la condición)
For N=65 To 90
Label1.caption = Chr ( N )
Label1.RefreshN ' Refresca la etiqueta
X=0
Do While X < 1000
X=X+1
Loop
Next N

Este es nuestro primer programa en BASIC. En VISUAL BASIC es idéntico, pero nos falta la interface gráfica. Para realizarla basta con
abrir el VB y sobre el formulario que aparece al abrirlo, introducir una etiqueta, (Label) que llevará el nombre por defecto de Label1. Solo
nos queda pensar donde introducimos el código anterior. Podemos introducir un botón de comando (Command Button) que saldrá con el
nombre por defecto de Command1. Haga doble click sobre el botón. Aparecerá el procedimiento Click. Este procedimiento es el que se
realiza cuando hacemos click sobre ese botón. Escriba en ese procedimiento este código.

Private Sub Command1_Click() ' Esta línea sale automáticamente


For N=65 To 90
Label1.caption = Chr ( N )
Label1.RefreshN ' Refresca la etiqueta
X=0
Do While X < 1000 ' Bucle de temporización
X=X+1
Loop
Next N ' Termina el bucle de temporización
End Sub ' Esta línea sale automáticamente
FUNCIONES CON NUMEROS
_________________________

Visual Basic puede operar con números tal como lo haría cualquier persona. Conoce las 4 reglas, y puede utilizar paréntesis de la misma
forma que los escribimos sobre el papel.

Los operadores que utiliza para las operaciones básicas son:

+ Suma
- Resta
* Multiplicación
/ División
\ División sin decimales
Mod Resto de una división
^ Eleva a un exponente

Ejemplos

Resultado = 12 + 15 ----> Resultado = 27


Resultado = 15 - 12 ----> Resultado = 3
Resultado = 15 * 12 ----> Resultado = 180
Resultado = 15 / 12 ----> Resultado = 1.25
Resultado = 15 \ 12 ----> Resultado = 1
Resultado = 15 Mod 12 ----> resultado = 3
Resultado = 12 ^ 2 ----> Resultado = 144

resultado = ( ( 4 * 3 ) / 2 ) ^ 2 ----> Resultado = 36

Estos operadores se denominan Operadores aritméticos.

Existen otras operaciones que se pueden realizar con números: comparaciones. Los operadores que realizan comparaciones se denominan
Operadores relacionales. El resultado de las operaciones realizadas con estos operadores solamente admiten dos resultados: True
(Cierto) o False (Falso) Estos operadores son:
= Igual que
<> No igual que
< Mayor que
<= Mayor o igual que
> Menor que
=> Igual o menor que

Estos operadores se suelen utilizar en estructuras de programa donde se tome una decisión.

El operador = puede usarse también para comparar cadenas o fechas.

Operadores Lógicos

Estos operadores sólo tienen sentido cuando hablemos de variables Booleanas, es decir, aquellas que solamente pueden tomar los valores
cero y uno.

Operador Función Devuelve True si Devuelve False si

And Función AND A=True y B=True Cualquier otro caso

Or Función OR A=True o B=True A=False y B=False

Xor Función XOR A=True y B=False A=True y B=True


A=False y B=True A=False y B=False

Eqv F. Equivalente A=True y B=True A=True y B=False


A=False y B=False A=False y B=True

Imp Implicación A=True y B=True A=True y B=False


A=False y B=True
A=False y B=False

Not Negación A=False A=True

Like Igualdad A=True A=False


Otras Funciones con números

CInt Parte entera Devuelve la parte entera de un número con decimales

Abs Valor Absoluto Devuelve el valor absoluto de un número

Sgn Signo Devuelve el signo de un número

Sqr Raíz cuadrada Devuelve la raíz cuadrada de un número

Exp ExponenciaciónDevuelve el número elevado al exponente indicado

Log Logaritmo Devuelve el logaritmo natural de ese número

Trigonométricas

Sin Seno Devuelve el valor del seno de un ángulo (Expresado


en radianes)

Cos Coseno Devuelve el coseno de un ángulo (En radianes)

Tan Tangente Devuelve la tangente de un ángulo

Atn Arco Tang. Devuelve un arco cuya tangente sea el número


(Angulo en radianes)

Una función curiosa

Timer Tiempo acumulado Devuelve el tiempo (en segundos) que ha


pasado desde las 12 de la noche.

Generación de números aleatorios

Randomize (Numero) Inicia el generador aleatorio tomando como dato de partida el Numero. Devuelve
el resultado en una variable llamada Rnd.
NOTA MUY IMPORTANTE.- Los números aleatorios generados de esta forma son siempre iguales, eso sí, dependiendo del
número que se le introduzca como parámetro. Esta generación de números no produce números aleatorios pues como se dijo,
dependen del numero que se meta como parámetro, y si este se repite, se repite la sucesión de números que nos crea el
generador aleatorio.

La forma de obtener números realmente aleatorios es introducir como parámetro un número que sea variable con el tiempo. Ese número no
puede ser otro que el número timer visto antes. Y siempre con la precaución de que medie mas de un segundo entre dos instrucciones
Randomize. La función toma entonces la forma:

Randomize Timer

La función Randomize devuelve una variable Rnd con un número comprendido entre 0 y 1 (Nunca será 0 ni 1) Leyendo el valor de
la variable sucesivas veces, se puede obtener una sucesión de números aleatorios. No es necesario ejecutar la instrucción Randomize
Timer cada vez que se quiera obtener un dato de la variable Rnd.

Un ejemplo. Generador de números para la Lotería Primitiva

Supongamos que tenemos un formulario con una etiqueta de nombre Label1, un botón de comando de nombre Command1. Cuando
hagamos click sobre el botón de comando deberá generar un número comprendido entre el 1 y el 49. En el procedimiento click de
Command1 pondremos el siguiente código:

Private Sub Command1.click

Randomize Timer
A = Rnd
A = Rnd * 100
A = CInt(A)
Do While A > 49
A = A - 49
Loop
Do While A < 1
A = A + 49
Loop
Label1.caption = A
End Sub

Realice este pequeño programa, con la instrucción Randomize Timer y sin ella.
Tras esta pequeña introdución al lenguaje Basic ya estamos en disposición de encender el ordenador y comenzar a trabajar con Visual-
Basic. Se supone que su PC tiene instalado el programa Visual basic, bien en su versión de 16 bits si dispone de Windows 3.xx o la de 32
bits si dispone ce Win95 ó Windows NT.

Entre en el programa VB. Le aparecerá en pantalla algo similar a

esto 

Este es el comienzo del programa . Observe que en esta pantalla existen varias cosas. En la parte superior , la barra de título del
programa Visual Basic, con el texto :

Proyect1 - Microsoft Visual Basic (Diseño)

Por debajo de esta barra de Título del VB, encontramos la barra de menú de VB, con las leyendas :

Archivo Edición Ver Insertar Ejecutar Herramientas Complementos Ayuda

Por debajo de esta barra de menú tenemos la barra de herramientas, donde podrá ver varios iconos, que cada uno representa un
determinada operación que Vd. puede realizar. Estas operaciones está todas en la línea de menú, y puede acceder a ellas abriendo los
menús desplegables que existen en cada una de las palabrea Archivo Edición Ver ...... de esta línea de menú. El hecho de colocar las
operaciones mas usuales en un icono en la barra de herramientas se hace para mayor comodidad del usuario.

A la izquierda de la pantalla tiene una caja rectangular con tres columnas de iconos. Esa caja es la Caja de Herramientas (No la confunda
con la barra de herramientas de la parte superior)

Esta caja de herramientas es, salvando las distancias, lo mismo que una caja de herramientas real que pueda tener un mecánico para
realizar su trabajo. En ella están los iconos que representan a los controles con los que Vd. va a desarrollar su aplicación VB. No están
todos los que pueden estar, al igual que en una caja de herramientas de un mecánico no están todas las herramientas que puede usar.
Están solamente las mas usuales. Si necesita alguna mas, puede cogerla de otra parte (barra de Menú, Herramientas, Controles
personalizados) y agregarlos a esa caja de herramientas, al igual que lo haría un mecánico con una herramienta especial, que la metería en
su caja sólo cuando va a realizar un trabajo determinado para el que la necesite.

Posiblemente esta caja de herramientas no le aparezca tal y como la ve en estos apuntes. Eso depende si Ud. tiene la versión personal o la
profesional, o si usa la versión de 16 ó 32 bits. Esa caja de herramientas puede personalizarla a su gusto. Para ello, deberá cargar un
proyecto ya existente en los discos de distribución de Visual Basic, llamado AUTO32LD.VBP (versión 32 bits) ó AUTO16LD.VBP (Versión
16 bits) que se encontrará en el directorio donde haya cargado el programa Visual Basic. Este proyecto no tiene otra función que determinar
las herramientas con las que quiere abrir el VB. Para introducir herramientas nuevas en la caja de herramientas, basta con desplegar el
menú Herramientas de la barra de menú, e ir a Controles personalizados. Haciendo click en esta línea de controles personalizados,
podemos seleccionar nuevos controles para añadir a la caja de herramientas, marcando la casilla que está a la izquierda del nombre del
control que quiere introducir. Una vez seleccionados todos los nuevos controles, haga click en ACEPTAR, y podrá observar que esos
nuevos controles ya se le han añadido a la caja de herramientas. Para que esos nuevos controles le aparezcan de entrada cuando inicia
una sesión de VB, debe salir de Visual basic guardando los cambios. Vuelva a entrar y observará que ya le aparecen esos nuevos controles
en la caja. No es prudente meter muchos controles en la caja. Ponga solamente los que necesite normalmente en sus aplicaciones.
Ocupará menos memoria y tardará menos tiempo en cargar el programa VB. Además, cuando realice una aplicación y la distribuya una vez
compilada, Visual Basic entregará en los disquetes de distribución las DLL’s u OCX’s correspondientes a todos los controles
personalizados que Vd. tenga en la caja de herramientas, los necesite el programa o no los necesite. Esto le va a suponer que está
cargando subprogramas inútiles en el ordenador destino de su aplicación. A la hora de compilar el programa (Crear archivo .EXE) quite
todos los controles personalizados que no necesite su aplicación. (Sólo los controles personalizados. Los controles comunes -
CommandButton, Label, TextBox, etc.-, no se pueden eliminar de la caja de herramientas)

Para quitar controles de su caja de herramientas, debe proceder de forma análoga, cargando el programa AUTOxxLD.VBP, abriendo menú
de herramientas, Controles personalizados, quitando la marca al cuadro situado en la parte izquierda del control a eliminar, y guardando el
proyecto al salir.

En el centro, y ocupando casi toda la pantalla, tenemos el Formulario. Este Formulario es la interface gráfica de su aplicación, sobre el que
podrá añadir los controles que necesite. Lo veremos mas adelante con todo detalle.

Observa dos ventanas, una denominada Ventana de Propiedades, donde puede ver las propiedades del formulario, Form1, y otra,
denominada Ventana de Proyecto. Existe otra ventana, que no está en la figura anterior, la Ventana de Depuración. Por cada formulario
y cada control que introduzca en el proyecto, le aparecerá otra ventana, denominada ventana de código.

No se extrañe de que esta presentación gráfica del Visual Basic coincida con otros sistemas de desarrollo (Delphi, p.e.). La lógica de
desarrollo de una aplicación en Windows ha llevado a varios fabricantes de software a utilizar un entorno gráfico similar (diríamos idéntico).
A Visual basic le queda el orgullo de ser el primero en utilizarlo.

Con lo descrito anteriormente ya tenemos, al menos, fijado el argot con el que expresarnos para comenzar a estudiar el VISUAL BASIC.
Veamos con un poco mas detalle la Ventana de Código.
Esta figura le muestra un Formulario con su ventana de código. Cada objeto gráfico de VB tiene su propia ventana de código. Así, si en
este formulario hubiésemos introducido un Label y dos CommandButton, todos ellos tendrían su propia ventana de código. La ventana de
código la podemos ver haciendo doble click sobre cualquier objeto de nuestro proyecto. En este caso hemos hecho doble click sobre el
único objeto que teníamos : el formulario.

Observe las dos cajas de la parte superior, uno con la inscripción Objeto : que en el momento que le sacamos la foto tenía Form, y el otro
con la inscripción Proc : (procedimiento), que en el momento de la foto tenía Load. A estas cajas les denominamos Lista de Objetos y
Lista de Procedimientos respectivamente.

Haciendo click sobre la flecha de cada lista, se despliega un menú, en la lista de objetos se desplegará una lista con los nombres de cada
objeto existente en ese momento dentro del formulario. Haciendo click sobre uno de los nombres, nos presentará la ventana de código de
ese objeto. Todos los objetos gráficos (controles) existentes dentro de un formulario y el propio formulario aparecerán en la misma lista de
objetos.

Haciendo click sobre la flecha de la lista de procedimientos, se despliega la lista con todos los procedimientos posibles para ese objeto.
Siempre saldrá uno. Si tenemos escrito código en uno de los procedimientos, saldrá por defecto ese procedimiento para el cual hemos
escrito el código. Si no hay código en ninguno de los procedimientos, saldrá el que tenga por defecto cada objeto.

Solamente nos queda por decir, para cerrar este capítulo, que es un procedimiento.

Para ello vamos a explicar lo que es un evento. Un Evento es algo que le puede ocurrir a un objeto. En una internase gráfica, lo que le
puede ocurrir a un objeto es que se le haga click, doble click, que se pase el cursor del ratón por encima, etc. Este es el Evento. El
Procedimiento es la respuesta por parte de ese objeto, al evento que le está sucediendo.

Esa respuesta, esa forma de Proceder del objeto al evento que le está sucediendo, debemos programarla según nuestras necesidades, es
decir, debemos escribir el código que necesite nuestra aplicación como respuesta al evento que acaba de ocurrir. Posiblemente, no
queramos ninguna respuesta a muchos de los eventos que pueden acaecer a un objeto. Cada objeto tiene muchos eventos y solamente
queremos aprovechar los que nos interesan. Para que un evento no produzca ningún efecto, basta con dejar sin código el procedimiento
correspondiente a ese evento. En los eventos que queramos que realice alguna operación, le escribiremos en su procedimiento el código
necesario para que esa operación se realice. Sin darnos cuenta, hemos comenzado a escribir el código de la aplicación.

Observará que el primer elemento del menú desplegable de la lista de objetos se denomina General. Este no es en realidad ningún objeto,
sino un apartado existente en cada formulario, que, al desplegar su lista de procedimientos tiene la sección de declaraciones, donde
debemos declarar las variables que queremos que afecten a todo el formulario y sus controles, y tendrá además, los nombres de todos los
procedimientos que introduzcamos (véase un poco mas adelante). En este menú desplegable de la lista de procedimientos del General
verá con frecuencia cosas que Vd. no puso allí. Cosas tales como Command1_click, y en la ventana un determinado código. Esto ocurre
cuando se borra algún control que tenía escrito código en alguno de sus procedimientos. Visual Basic sabe lo mucho que cuesta escribir el
código asociado a un control. Si borramos un control de nuestro formulario accidentalmente, después de haber introducido todo el código
asociado a él, Visual Basic nos sorprende con que ese código no lo tira inmediatamente, sino que lo reserva como un procedimiento en ese
apartado General del formulario. Si en realidad queríamos borrar el control y todo su código, debemos quitarlo de ese apartado General de
nuestro formulario, pues en realidad, si no lo queremos, no hará otra cosa que estorbar. Para quitarlo basta con borrar todo el código que
aparece en la ventana de código cuando hacemos click sobre el nombre del control eliminado. Deberemos borrar todo el código, incluida la
cabecera donde figura el nombre del control eliminado, y la parte final, que siempre termina con EndSub.

El primer estorbo lo observará si crea otro control con el mismo nombre, cosa fácil ya que VB da un nombre por defecto a cada control
(Command1, Command2....). El código asociado al control eliminado pasará automáticamente al nuevo control con el mismo nombre.

Una aplicación puede tener todo su código escrito en los sucesivos procedimientos del formulario y de los controles que tenga ese
formulario.
Puede ocurrir que un determinado evento no esté entre los posibles eventos de los controles de nuestra aplicación. Piense por ejemplo, el
evento de que la variable A sea igual a la variable B. No existe en ninguno de los controles ese procedimiento. No se preocupe, puede crear
un procedimiento que se ejecute cuando su programa lo decida. Podemos añadir cuantos procedimientos queramos. Estos procedimientos
se añaden al formulario, y deberán definirse por un nombre que Vd. debe elegir. Para que se ejecuten las instrucciones (código) incluido en
ese procedimiento, basta simplemente con nombrarlo por ese nombre.
Para insertar un procedimiento debe ir a la barra de menú, hacer click sobre Insertar, y en el menú que le desplegará, volver a hacer click
sobre Procedimiento. VB le presentará un cuadro donde le pedirá el nombre, si quiere que sea un procedimiento, una función o una
propiedad. A lo largo del curso irá viendo que es cada cosa.

Escribiendo el código en los sucesivos procedimientos, bien en los propios de cada objeto, bien en los procedimientos que vayamos
creando, es posible completar la aplicación. Pero en una aplicación larga esta forma de escribir el código no sería la mas adecuada. Es
mas, posiblemente sería demasiado engorroso escribirla de esta forma, y muy probablemente deberíamos escribir el mismo código para
varios procedimientos, lo que alargaría inútilmente el programa y el tiempo de desarrollo.

Para disponer de un sitio donde escribir parte (o la mayor parte) de su programa, puede introducir uno o varios módulos. Expliquemos lo
que es un módulo.

Un Módulo es una parte del programa donde solamente puede escribir código. Es igual que un formulario, sin interface gráfica. Un profesor
de Visual Basic lo expresaba diciendo que un Módulo es un Formulario sin cara. En un módulo pueden existir procedimientos al igual que
en los formularios, pero como un módulo no tiene interface gráfica, esos procedimientos debe introducirlos el programador tal y como
explicamos un poco mas atrás. El módulo tiene su propia ventana de código, al igual que un formulario, con un objeto único, el apartado
General. Aquí también tenemos la sección de declaraciones, al igual que los formularios. En esta sección de declaraciones se comporta de
manera similar a la de los formularios, pero permite algo que no nos permite la sección de declaraciones de un formulario  : Declarar
variables que se pueden utilizar en todo el programa. Esto ya lo ha visto mas atrás, con las sentencia de declaración Global y Public.

Los módulos se emplean para la declaración de variables globales, y para escribir el código de la aplicación que sea común a varios
formularios. Esto nos evita tener que repetir código inútilmente. Ese código común se escribirá en un procedimiento que previamente
habremos insertado en este módulo, y lo citaremos por su nombre desde cualquier parte del programa.

¿Cual es el nombre de un procedimiento existente dentro de un módulo ? Depende. Si estamos ejecutando código escrito en otro
procedimiento dentro del mismo módulo, es decir, si estamos dentro de ese mismo módulo, basta con citarlo por su nombre  : p.e., si en el
MóduloA tenemos un procedimiento llamado Procedimiento1, y queremos llamarle desde una línea de código dentro de ese mismo módulo,
basta con referirse a él con :

Procedimiento1

Si la línea de código donde nos vamos a referir a él está fuera de MóduloA, deberemos referirnos a ese procedimiento con :

MóduloA.Procedimiento1

Lo mismo podemos decir para cualquier procedimiento insertado en un formulario. Desde dentro del formulario basta con referirse a él
citándolo por su nombre. Desde fuera de ese formulario deberemos citarle como :

Formulariox.Procedimientoy

donde damos por hecho que Formulariox es el nombre del formulario que lo contiene, y Procedimientoy es el nombre del procedimiento.

Fíjese en el punto usado como separador entre el nombre del formulario y el nombre del procedimiento. VB usa como separador un punto.
Usa el separador para separar el nombre de un control y una de sus propiedades (Label1.Caption), para separar el nombre del formulario
del nombre de uno de sus controles (Formulario1.label1.caption) Se irá familiarizando con la terminología VB según vayamos avanzando
en el curso.

Funciones

Al igual que introducimos Procedimientos, podemos introducir Funciones en nuestra aplicación. Una Función es un Procedimiento al que le
pasamos uno o varios parámetros. (O Ninguno) Verá los Procedimientos y funciones mas adelante (Cap. 15). Al igual que los
Procedimientos, pueden ser públicas (se verán en toda la aplicación) o privadas (se verán solamente en el formulario donde estén.

Main

Merece la pena pararse un poco para estudiar el Procedimiento Main. Para verlo con mas detalle, comentaremos como comienza a
trabajar una aplicación realizada en Visual Basic.

Imaginemos una aplicación que tiene 3 Formularios. En cada uno de ellos tiene código. Logicamente la aplicación tendrá que presentar uno
de ellos en primer lugar. Deberemos decirle a Visual Basic cual es el formulario inicial, y será ese por el que empiece. En ese formulario
dispondremos el código necesario para que la aplicación se ejecute en el orden deseado.

Si hacemos click en la Barra de Menú de Visual Basic, en Herramientas | Opciones obtendremos el siguiente cuadro de diálogo :
Verá que tiene 4 pestañas, y actualmente tiene abierta la pestaña correspondiente a Proyecto, y tiene desplegada una lista donde nos pide
el Formulario Inicial. En esa lista figura también la expresión Sub Main. Si ponemos como formulario inicial uno de los formularios, la
aplicación comenzará por ese formulario. Si en uno de los Módulos existentes en el proyecto, ponemos un procedimiento llamado Main,
podemos comenzar la ejecución de la aplicación justamente por ese procedimiento. En ese procedimiento pondremos el código necesario
para que, posteriormente, se muestre uno de los formularios. Esto es muy practico cuando queremos hacer una función previa a mostrar
cualquier formulario (abrir una base de datos, por ejemplo). Para comenzar la aplicación por Main se elige esa opción en la lista Formulario
Inicial.
¡ Recuerde que Main debe estar en un Módulo !

El cuadro de diálogo anterior sirve además para otras cosas. Entre ellas poner el nombre del proyecto (nombre que no aparecerá por
ninguna parte, solo en los datos internos de la aplicación) y su descripción.
En otra pestaña podemos configurar varias prestaciones del entorno de trabajo :

Guardar la aplicación antes de ejecutar. Esta prestación nos va a evitar muchos disgustos. Es muy práctico guardar la aplicación antes
de ejecutarla, pues de esta forma evitamos que, si nuestra aplicación tiene un error tal que hagamos colgarse a Windows, siempre
tendremos la aplicación metida en el disco duro. Pero también es una pequeña pesadez tener que esperar a que se guarde cada vez que la
ejecutamos.

Si tenemos la activada la casilla Declaración de variables requerida nos pondrá automáticamente Option Explicit en el encabezamiento
de todas las secciones de declaraciones de la aplicación.

Podemos elegir también las ventanas que queremos que estén siempre visibles, y que verifique automáticamente la sintaxis de una
instrucción en el momento de escribirla.
La pestaña de Editor nos permite fundamentalmente 2 cosas :

Ver solamente el código correspondiente al procedimiento que estamos escribiendo ó Ver el código del Módulo (o Formulario) completo. En
este último caso es un poco mas difícil de manejar la ventana de código, sobre todo si el programador no está muy habituado a ello. Le
presenta procedimiento tras procedimiento, separados por una línea. Para seleccionar una u otra opción hay que seleccionar o
deseleccionar la casilla Ver módulo completo.

Cambiar el color de la letra y del fondo del código, según el tipo que sea (código, comentario, error devuelto, etc.). Los alumnos mas
aventajados y con ganas de marear al profesor y, lo que es peor, a sus compañeros, conocen la forma de poner como invisible una parte
del texto del código. Si observa comportamientos raros en el texto donde escribe el código, revise el cuadro de Colores de Código.

FORMULARIO
____________
El primer objeto Visual Basic con que nos encontramos es el FORMULARIO. De hecho, cada vez que iniciamos Visual Basic (VB) nos
presenta en pantalla un nuevo formulario, que tiene por defecto el nombre de Form1

El Formulario es un objeto, que sirve de soporte de otros objetos. El nombre de FORMULARIO lo toma precisamente porque, al igual que
un formulario de papel contiene textos escritos, lugares donde podemos escribir, figuras, cajas donde podemos elegir una u otra opción,
etc., en este cuadro gráfico que llamamos formulario, podemos introducir textos escritos, lugares donde podemos escribir, figuras, cajas
donde podemos elegir una u otra opción ....

En realidad un formulario es lo que normalmente conocemos por VENTANA. El nombre de formulario le viene muy bien cuando ese
formulario es una ventana donde vamos a introducir datos alfanuméricos. Cuando en vez de introducir datos, lo que tenemos es, por
ejemplo, una ventana donde se reproducen exactamente los controles de operación de una máquina, parece en principio que sería mas
correcto el nombre de "ventana". De alguna forma lo hay que llamar, y esa forma es FORMULARIO. Posiblemente a lo largo de estos
apuntes nos referiremos al formulario con el nombre de ventana, o incluso, pantalla. Procuraremos usar el nombre apropiado:
FORMULARIO.

Forma inicial del formulario.


Ejemplo de un formulario para una aplicación industrial. Este formulario reproduce el panel de control de un transmisor - receptor de radio.
En este caso, parece que el nombre de ventana le viene mejor que el de formulario. Observe que dentro del formulario existen gran
cantidad de objetos. Botones, que hacen la misma función que el botón real en el equipo de radio, y un par de displays, que muestran un
texto, en este caso las frecuencias de transmisión y recepción.

Como cualquier objeto Visual Basic, un formulario tiene propiedades y procedimientos:

PROPIEDADES.

Name Nombre
Define al objeto durante la ejecución del programa. Se introduce en tiempo de diseño y no se puede variar durante la ejecución.
Nombre por defecto: Form1 (Form2 y sucesivos) Este nombre por defecto debe cambiarse, (debería cambiarse por norma en el
momento de introducir el formulario), ya que de no hacerlo corremos el riesgo de borrar el código existente de otro formulario del
mismo nombre en el momento de guardar la aplicación.

Caption Título

Es el texto que aparecerá en la barra de Título cada vez que aparezca en pantalla este formulario. No tiene otra función dentro del
programa. El programa no accede a este formulario por el título, sino por el nombre. Puede cambiarse en tiempo de ejecución.

NOTA.- No confundir Nombre (Name) con Título (Caption)

Control Box Control “menos” del Formulario Valor por defecto : True

Propiedad booleana que admite los valores de true (verdadero) o False (Falso). Si esta propiedad es True, aparecerá en la esquina
superior izquierda el "menos" para desplegar el menú de control de este formulario. Si esta propiedad se pone como False, no
existirá dicho "menos" y por tanto no se puede desplegar dicho menú.

MinButton
MaxButton Valor por defecto: True

Botones (flechas) de minimizar y maximizar este formulario. Son igualmente propiedades booleanas, que admiten el valor True o
False. Si están en true, aparecerá la flecha correspondiente. Si están en False, no aparecerá dicha flecha. Deben configurarse de
una u otra forma, dependiendo si se quiere minimizar / maximizar este formulario durante la ejecución.

Nota. En los formularios MDI child, es necesario poner a true las propiedades ControlBox, MinButton y MaxButton para poder
maximizar el formulario hijo. De no ponerlas a true, sí se pretende maximizar el formulario hijo, (Propiedad WindowState=2) el formulario
no aparece.

BorderStyle Tipo de borde

Define el tipo de borde que tendrá el formulario durante la ejecución. No se puede cambiar en tiempo de ejecución,
Admite los siguientes valores:

0 - None El formulario no tiene borde alrededor

1 - Fixed Single
El formulario tendrá un borde fino, y no podrá cambiarse su tamaño durante el tiempo de ejecución. Con este valor,
el formulario puede tener un menú de control, barra de título y botones de maximizar y minimizar. Solo podrá
cambiarse de tamaño utilizando estos botones.
2-Sizable
El formulario tendrá borde grueso, y se podrá cambiar su tamaño en tiempo de ejecución mediante los botones de
maximizar y minimizar, y mediante el arrastre de uno de los bordes con el ratón.

3 - Fixed Dialog
El formulario tendrá borde grueso, y no se podrá redimensionar durante la ejecución. No puede tener los botones
de maximizar ni minimizar.

4 - Fixed ToolWindow
En las versiones de 16 bits de Windows y Windows NT 3.51 y anteriores se comporta como Fixed Single. No puede
cambiar de tamaño. En Windows 95 muestra el botón Cerrar, y el texto de la barra de titulo aparece con un tamaño
de fuente reducido. El formulario no aparece en la barra de tareas de W95.

5 - Sizable ToolWindow
En las versiones de 16 bits se comporta como Sizable. En W95 muestra el botón Cerrar y el texto de la barra de
titulo aparece con un tamaño de fuente reducido. El formulario no aparece en la barra de tareas de W95.

Valor por defecto: 2 . Sizable

Nota: Al cambiar a determinados valores, las propiedades MaxButton y MinButton se ponen a False. Pueden
cambiarse a True posteriormente.

Appearance Apariencia Valor por defecto: 3D

Admite los valores 0 (=Flat, plano) y 1 (=3D) Si tiene el valor 1 (3D), el formulario aparecerá con cierto efecto tridimensional, y los
controles que le introduzcamos a este formulario aparecerán como esculpidos dentro de él. Con valor 0 (Flat) en esta propiedad, el
formulario aparecerá durante la ejecución como una superficie plana. El color de fondo se ve afectado al cambiar esta propiedad. Si
se cambia a 3D, el fondo (Backcolor) toma el color definido en Windows en el Panel de Control. Si se cambia a Flat, toma el color
blanco

Autoredraw Valor por defecto: False

Propiedad booleana. Esta propiedad, estando en True, permite actualizar el contenido del formulario y de sus controles incluso
cuando no están visibles. Imaginemos que en este formulario existe un texto, una etiqueta (Label) o caja de texto (Text Box) cuyo
texto se haya cambiado, bien por programa, bien por una entrada, mientras este formulario no estaba visible. Lo mismo podemos
decir de las propiedades de cualquier otro control. Si esta propiedad Autoredraw está en False, al hacer visible este formulario,
aparecerá igual que cuando se ocultó. Si esta propiedad está en True, aparecerá actualizado.

Backcolor Color del fondo

Establece el color del fondo del formulario. Puede cambiarse en tiempo de ejecución.

Valor por defecto: El establecido en el Panel de Control de Windows.

ClipControls Valor por defecto: False

Propiedad Booleana. Establece si un evento Paint vuelve a dibujar el objeto entero (True) o si solamente dibujan las partes que han sufrido
cambios (False)

DrawMode

Establece un valor que determina el aspecto de la salida de un método gráfico o el aspecto de un control Shape o Line. Verá mas adelante
los efectos de esta propiedad.

DrawStile Valor por defecto : 0

Establece el estilo de línea de la salida de métodos gráficos:

Valores: 0 - Línea continua


1 - Rayas
2 - Puntos
3 - Raya-Punto
4 - Raya - Punto - Punto
5 - Transparente
6 - Continuo interior.

DrawWidth Valor por defecto: 1

Establece el ancho de una línea dibujada. El valor debe expresarse en pixeles.

Enabled Activado Valor por defecto: True

Propiedad booleana. Si está en True, el formulario está activado y se puede interactuar con él. Si está en False, se desactiva el formulario,
impidiendo de esta forma, que se pueda trabajar con él.
ForeColor Valor por defecto: Negro

Establece el color del primer plano del formulario. Es el color que tendrán las letras si escribimos en él, o los dibujos, si lo que hacemos es
dibujar. En tiempo de diseño, determina el color de la rejilla,.

FillStyle Tipo de relleno Valor por defecto: 2

Establece el modo de rellenar controles Shape, o figuras (círculos o cuadrados) creados con los métodos gráficos Circle y Line.

Valores: 0 - Continuo
1 - Transparente
2 - Línea Horizontal
3 - Línea Vertical
4 - Diagonal hacia arriba
5 - Diagonal hacia abajo
6 - Cruzado
7 - Diagonal cruzada

FillColor Color de relleno

Especifica el color del relleno contemplado en FillStyle.

Font Tipo de letra Valor por defecto: El determinado en la personalización.

Especifica el tipo y tamaño de la letra que se usará en el formulario. Al seleccionar esta propiedad en la ventana de propiedades,
aparece un cuadro de dialogo donde se eligen ambos parámetros.
Cuando introduzca nuevos controles en el Formulario, la propiedad Font de estos controles tomará el valor que tenga esta
propiedad en el Formulario. Puede servirle este pequeño truco para utilizar en todos los controles una determinada fuente sin tener
que teclearla para cada control.

FontTranparent Texto Transparente Valor por defecto: True

Establece si el texto o gráfico de fondo del formulario se muestra (True) o no se muestra entre los caracteres de texto escritos en el
propio formulario.

FontSize Tamaño de letra


Establece el tamaño de la letra. Esta propiedad, que puede variarse en tiempo de ejecución, varía solamente el tamaño, y no el tipo
de letra. El tamaño debe expresarse en puntos. Máximo, 2160 puntos.

FontBold, FontItalic, FontStrikethru, FontUnderline

Permiten, en tiempo de ejecución, cambiar un texto a negrita, cursiva, tachado y subrayado. Son propiedades booleanas True /
False

Height Altura Valor por defecto: No existe

Define la altura del formulario. El valor de esta propiedad no se introduce normalmente como un dato numérico, sino que toma el
valor automáticamente, dependiendo de las dimensiones del formulario durante el tiempo de diseño. Puede cambiarse durante el
tiempo de ejecución.

HelpContextID Valor por defecto: 0

Establece un número de contexto asociado para este formulario. Este número se aplica para determinar la ayuda interactiva
asociada a este formulario. Vea mas adelante, el tema Ayuda de Windows.

Puede tomar los siguientes valores : 0 - No se especifica número de contexto


>0 Un entero que especifique un contexto válido.
Icon Icono

Esta propiedad define el icono que va a representar a este formulario cuando esté minimizado. Si el formulario es el formulario
padre o formulario de inicio de una aplicación, este icono es el que toma el Asistente de Instalación para colocarlo como icono de
apertura del programa en el grupo de programas Windows correspondiente. Como valor de esta propiedad se le puede asignar
directamente el icono o el nombre de un archivo (con su path correspondiente) que lo contiene, haciéndolo directamente sobre la
caja de propiedades.

Valor por defecto: el icono que se le haya programado en la personalización.

KeyPreview Valor por defecto: False

Propiedad Booleana. Cuando un formulario tiene dentro de sí varios controles, uno de ellos es el que está activo. En estas condiciones, si
se pulsa una tecla, esa pulsación la recibe en primer lugar el control que esté activo, y si éste no la procesa, pasa esa pulsación al
formulario. Para hacer que esa pulsación pase directamente al formulario, debe ponerse esta propiedad en True.

Left Borde Izquierdo Valor por defecto: No existe


Indica la posición del borde izquierdo del formulario. Normalmente no se introduce como valor numérico, sino que lo toma
automáticamente de la posición que tenga el formulario en el tiempo de diseño. Puede cambiarse en tiempo de ejecución, para
mover el formulario.

LinkMode Valor por defecto: 0

Permite que una aplicación destino inicie una conversación DDE con el formulario (origen de datos). Puede tomar los siguiente
valores:

0 - No hay interacción DDE


1 - Source. Indica que este Formulario es origen de una comunicación DDE. El dato que se va a traspasar en esa
comunicación DDE estará en un TextBox, en un Label o en un PictureBox de este Formulario.

LinkTopic

Establece el tema al que este formulario va a responder a una conversación DDE, cuando funciona como origen. Es por este tema
por el que se debe llamar a este formulario cuando actúa de origen en una conversación DDE

MDIChild Valor por defecto: False

Establece que este formulario es un formulario Hijo dentro de un formulario MDI. No se puede cambiar en tiempo de ejecución. Es
una propiedad booleana
True = es formulario hijo False =No lo es

MouseIcon Valor por defecto: ninguno

Establece un icono personalizado para el puntero del ratón cuando esté encima de este Formulario. Este icono puede ser un bit-
map de los existentes en el directorio Icons de Visual Basic o cualquiera que tengamos. Si se pone 99 como valor de la propiedad
MousePointer (siguiente), cada vez que el puntero del ratón pase por este Formulario, cambiará su forma y adoptará la del icono
elegido.

MousePointer Valor por defecto: flecha

Determina la forma del puntero del ratón cuando se coloca encima del formulario. Puede elegirse uno de los punteros
preestablecidos (15 en total) o el personalizado visto en la propiedad anterior. Para elegir ese icono personalizado, debemos poner
en esta propiedad el valor 99.
Picture Gráfico Valor por defecto: No existe

Mediante esta propiedad podemos poner un gráfico como fondo del formulario. El gráfico puede ser un bit-map o un fichero .ICO

ScaleHeight, ScaleWidth, ScaleMode,

Indican la unidad de medida de dimensión de altura y anchura del Formulario. ScaleMode indica en qué unidades de medida se
van a medir esas dimensiones. Acepta Twips (1), Point(2), Pixel (3), Character (4), Pulgadas (Inch) (5), Milímetros (6), Centímetros
(7). Si colocamos la propiedad ScaleMode en cualquiera de estos valores, las propiedades ScaleHeight y ScaleWidth nos
vendrán dadas automáticamente dependiendo del ancho del Formulario, y no se extrañe si encuentra para estas propiedades
valores tan peregrinos como 4815 y 7423. Al haber elegido la unidad de medida, los valores de ancho (ScaleWidth) y alto
(ScaleHeight) serán los que tengan que ser, medidos en la unidad que hemos elegido. Podemos elegir una cifra para el ancho y el
alto del Formulario de forma que podamos controlar mejor las distintas posiciones que van a ocupar en él los controles, los textos o
los dibujos. Podemos poner, por ejemplo, que el Formulario mida 400 de ancho (ScaleWidth = 400) y 300 de alto (ScaleHeight =
300) forzándole estas propiedades, bien en tiempo de diseño en la caja de propiedades, o en tiempo de ejecución mediante código.
Entonces sabemos que el formulario, independientemente de las dimensiones físicas que tenga sobre la pantalla, medirá 400 de
ancho y 300 de alto, y si en estas condiciones queremos colocar un control o un dibujo justo en el medio del Formulario, sabemos
que tenemos que colocarle en las coordenadas 200, 150. ¿Que unidad de medida estaremos utilizando entonces en el Formulario ?
Unas definidas por el usuario (distintas para el ancho y el alto) que serán las necesarias para que el Formulario mida de ancho lo
que le hayamos puesto en la propiedad ScaleWidth y de alto lo que le hayamos puesto en la propiedad ScaleHeight. Observe que
la propiedad ScaleMode se ha cambiado automáticamente a User (0) al introducir las dimensiones de ancho y alto que nosotros
queremos.

Estas unidades de medida afectarán a los controles que metamos en este Formulario. Se medirán en su ancho y alto con la unidad
de medida definida para el ancho y alto del Formulario. Lógicamente también afectará a las propiedades Left y Top de los
controles, pero estas propiedades se verán afectadas además por las propiedades ScaleLeft y ScaleTop del Formulario que se
verán a continuación.

ScaleLeft, ScaleTop

Estas propiedades, medidas en la unidad de medida elegida para el ancho y alto mediante las propiedades ScaleMode,
ScaleWidth y ScaleHeight anteriores, expresan las coordenadas iniciales de la parte izquierda y de la parte superior
respectivamente del Formulario. Estas propiedades no afectan a la posición del Formulario en la pantalla (Si está maximizado
seguirá ocupando toda la pantalla, si está en “Normal” ocupará el mismo sitio que se dio en tiempo de diseño). Supongamos que
se le asigna a un Formulario, las propiedades ScaleWidth = 400, y ScaleHeight = 300. Si colocamos un control justamente en el
centro del Formulario tendrá sus propiedades Top =150 y Left=200. Si ponemos ahora las propiedades del Formulario ScaleLeft a
30 y ScaleTop a 10, ese control, para seguir en el centro del Formulario deberá tener sus propiedades Top a 160 (150 + 10) y Left
a 230 (200 + 30).
Recuerde que las medidas de un formulario crecen, desde la esquina superior izquierda, según avanzamos hacia abajo y hacia la
derecha.

Como aclaración de las relaciones entre distintas unidades de medida, puede ver en la siguiente table la correspondencia entre
cada una de ellas y la unidad imaginaria Twip.

1 Point=20 Twips  ; 1Pixel=15 Twips : 1 Charecter=240 Twips ; 1 Inch (pulgada) =1440 Twips 1mm=56,52 Twips 1 cm=566 Twips

Tag Valor por defecto: No existe

Esta propiedad no la usa directamente Visual-Basic. Sirve para asociar al formulario información adicional para fines externos a la
programación. Pero también le puede servir para almacenar en ella una variable para que la use un código ajeno al formulario. El
autor de estos apuntes tiene por costumbre utilizar la propiedad Tag del formulario inicial para guardar el parámetro que se le pasa
a algunos programas para acceder a ellos con unos determinados privilegios. Resumiendo, está ahí para lo que el programador
quiere.

Top Posición del borde superior Valor por defecto: No existe

Esta propiedad establece la posición del borde superior del formulario. Normalmente no se introduce como valor numérico sino que
lo toma automáticamente de la posición que tenga el Formulario durante el tiempo de diseño Este valor puede cambiarse durante
la ejecución para, conjuntamente con Left, variar la posición del Formulario. Los valores de Top y Left definen la esquina superior
izquierda del Formulario.

Visible Valor por defecto: True

Propiedad Booleana. Asignándole el valor True la pantalla es visible, y asignándole el valor False, no se ve. Este valor puede
cambiarse durante el tiempo de ejecución para ocultar y hacer visible el formulario.

Width Ancho Valor por defecto: No existe

Define la anchura del formulario. Normalmente no se introduce como valor numérico sino que lo toma automáticamente del tamaño
que tenga el formulario durante el tiempo de diseño. Juntamente con Height define el tamaño del formulario. Puede cambiarse
durante el tiempo de ejecución.

WindowState

Establece el estado en el que aparecerá el formulario cuando se activa y presenta en pantalla. Admite tres opciones:
0 - Normal El formulario recupera la posición y tamaño que tenía en el tiempo de diseño.
1 - Minimizado El formulario aparece minimizado, representado por su icono.
2 - Maximizado El formulario aparece maximizado, ocupando toda la pantalla.

PROCEDIMIENTOS

Activate Activación Click Click


DblClick Doble click Deactivate Desactivación
DragDrop Arrastrar y soltar DragOver Arrastrar por encima
GotFocus Obtener el foco KeyDown Mantener pulsada una tecla
KeyPress Pulsar una tecla KeyUp Soltar una tecla
LinkError Error de enlace LinkExecute Ejecución de un enlace de datos
LinkOpen Romper el enlace Load Cargar el formulario
LostFocus Perder el foco MouseDown Pulsar una tecla del ratón
MouseMove Mover el ratón (Detecta la posición del ratón sobre el formulario)
MouseUp Soltar una tecla del ratón Paint Pintar
QueryUnload Confirmación de descarga Resize Cambio de tamaño
Unload Descargar el formulario

Un Formulario sirve, fundamentalmente, de contenedor de controles. Es la ventana de Windows de nuestra aplicación. Una aplicación
puede tener varios Formularios y dentro de cada uno de ellos, los controles necesarios para cada paso o estado de la aplicación.

Un Formulario puede servir también como soporte de textos o dibujos.

CONTROLES

Una vez introducido un Formulario, se pueden colocar los objetos (controles) que forman parte de la aplicación. Estos controles se irán
viendo en próximos capítulos.

Los controles, lo mismo que el Formulario, tienen Propiedades y Procedimientos.

Las Propiedades definen las características del Control. Los Procedimientos definen la forma de actuar (la forma de proceder) de un
control frente a un evento.

Tanto las propiedades como los procedimientos deben ser definidos por el programador. Las propiedades dejan un pequeño margen de
actuación, los procedimientos son en su totalidad, definidos por el programador. Estos procedimientos forman parte del programa. Podría
incluso hacerse una aplicación que no tuviese mas código que el introducido en los procedimientos.
Para colocar un control en un Formulario, basta con “tomarlo” de la caja de herramientas existente en la parte izquierda de la pantalla de VB
y llevarlo al Formulario. Si no existiese el control deseado en la caja de herramientas, deberemos ir a “cogerlo” a Controles
personalizados que está en el menú desplegable Herramientas de la barra de Menú de VB. Se elige el nuevo control, marcando la caja
de opción a la izquierda de su nombre, y haciendo click en ACEPTAR. Este control ya pasa a la caja de herramientas.

COMMAND BUTTON BOTON DE COMANDO


_______________________________________

El Command Button es un objeto que sirve para introducir datos a través de la pantalla. El Botón de Comando tiene la siguiente forma:

El botón de comando puede usarse para la entrada de datos con el ratón, o para validar cualquier operación. El tamaño puede cambiarse a
voluntad, pero la forma siempre es rectangular. En la figura anterior vemos dos botones de comando, uno de ellos (el Command2) marcado
con unos puntos en su contorno. Estos puntos nos permiten variar su tamaño en tiempo de diseño. También puede cambiarse su tamaño y
posición en tiempo de ejecución.

PROPIEDADES

Name Nombre
Es el nombre que define a este objeto durante la ejecución del programa. No se puede cambiar en tiempo de
ejecución. El nombre por defecto es Command1, Command2, etc. Estos nombres por defecto deberían cambiarse
por otros que nos indiquen algo respecto a este control, aunque en este caso no es tan imprescindible como para
los formularios.

Caption Título
Es el texto que aparece en el botón. Puede cambiarse en tiempo de ejecución. No tiene otra función dentro del
programa.

NOTA.- No confundir Nombre (Name) con Título (Caption)

Appearance Apariencia
Determina la forma del botón. Admite los valores de Flat (Plano) y 3D. No se aprecia en gran medida la
diferencia.
Backcolor Color de fondo
Es el color de un pequeño cuadrado que aparece rodeando el título, NO el color del botón, que es invariable.
Puede cambiarse en tiempo de ejecución.

Cancel
Establece un valor que indica si un botón de comando es el botón Cancelar de un formulario. Es una propiedad
booleana, y admite los valores True o False. Puede utilizar la propiedad Cancel para dar al usuario la opción de
cancelar los cambios que no se han hecho efectivos y devolver el formulario a su estado anterior. En un formulario
sólo puede haber un botón de comando con la propiedad Cancel = True.

Default
Establece un valor que determina el control CommandButton que es el botón de comando predeterminado de un
formulario. Sólo un botón de comando de un formulario puede ser el botón de comando predeterminado. Cuando
Default se define a True para un botón de comando, se define automáticamente a False para el resto de los
botones de comando del formulario. Cuando la propiedad Default del botón de comando está establecida a True y
su formulario primario está activo, el usuario puede elegir el botón de comando (invocando su evento Click)
presionando ENTRAR. Cualquier otro control que tuviera el enfoque no recibe evento de teclado (KeyDown,
KeyPress o KeyUp) de la tecla ENTRAR a menos que el usuario haya movido el enfoque a otro botón de comando
del mismo formulario. En este caso, al presionar ENTRAR se elige el botón de comando que tiene el enfoque en
lugar del botón de comando predeterminado.

DragIcon
Establece el icono que se presenta como puntero en una operación de arrastrar y colocar.

DragMode
Establece un valor que determina si se usa el modo de arrastre manual o automático en una operación de arrastrar
y colocar. Los valores posibles de número son:

0 Manual (Predeterminado)
1 Automático

Enabled Habilitado
Propiedad Booleana que habilita o deshabilita el botón. Cuando está deshabilitado (Enabled = False), el botón no
tiene efecto, y su apariencia varía, presentando un tono pálido tanto en su cuerpo como en su título. Puede variarse
en tiempo de ejecución.
Font Fuente
Es el tipo de letra para el título. Puede cambiarse en tiempo de ejecución.

Height Altura
Establece la altura del botón. Normalmente esta propiedad no se introduce numéricamente, sino que la toma
automáticamente de las dimensiones que se le den al botón en tiempo de diseño. Puede cambiarse, cambiando el
valor a esta propiedad, en tiempo de ejecución.

HelpContextID
Establece un número de contexto asociado para este control. Este número se aplica para determinar la ayuda
interactiva.

Puede tener los siguientes valores:


0 = No se especifica número de contexto
>0 Un entero que especifica un contexto válido.

Index Indice
En el caso de que se tengan varios botones que realicen una función similar (Las teclas numéricas de una
calculadora, p.e.) puede hacerse un array con estos botones de comando. Todos tendrán el mismo nombre, y se
diferencian por un índice. Esta propiedad Index toma el número de ese índice.

Left
Posición de su parte izquierda. Indica la posición del botón, concretamente de la parte izquierda del mismo.
Normalmente esta propiedad no se introduce numéricamente, sino que la toma automáticamente de la posición que
se le de al botón en tiempo de diseño. Puede cambiarse, cambiando el valor a esta propiedad, en tiempo de
ejecución.

MouseIcon Icono para el puntero del ratón


Determina el icono que presenta al puntero del ratón cuando pasa por encima del botón, cuando se especifica en la
propiedad MousePointer que el puntero del ratón es el definido por el usuario. (Custom)

MousePointer Puntero ratón


Determina la forma del puntero del ratón cuando éste pasa por encima del botón. Puede elegirse uno de los
punteros preestablecidos (15) o incluso uno diseñado especialmente. Para especificar que el puntero es uno
diseñado especialmente, hay que poner a esta propiedad el valor 99 (Custom), y en este caso aparecerá el icono
determinado por la propiedad MouseIcon
TabIndex Nº de orden para tabulador
Cuando disponemos de varios controles en un mismo formulario, solamente uno de ellos tiene el foco. Esta
expresión de tener el foco significa que ese control está remarcado y en esa condición, si pulsamos la tecla ENTER
haría el mismo efecto que hacer click con el ratón en ese control. Esto es necesario, ya que existen ordenadores
que no disponen de ratón (típico de algunos portátiles). En estos casos, para elegir uno u otro control debemos
pulsar repetidas veces la tecla TABulador. El foco irá cambiando de uno a otro control (pueden ser controles de
distinto tipo) cada vez que pulsemos la tecla TABulador. Esta propiedad TabIndex marca el orden que seguirá el
foco a través de cada control.

TabStop Sale del control de la tecla TAB


Propiedad booleana. Cuando esta propiedad está a False, el botón no tomará el foco cuando se pulse la tecla del
Tabulador. Sin embargo sigue manteniendo el índice de la propiedad TabIndex descrita anteriormente. Puede
cambiarse en tiempo de ejecución. Esto nos permite descartar algún botón de tomar el foco, cuando por facilidad
para el usuario, sea conveniente en determinados puntos del programa.

Tag
Esta propiedad no la usa directamente Visual-Basic. Sirve para asociar a este control alguna información adicional
para fines externos a la programación. Similar a la del formulario.

Top
Indica la coordenada de la parte superior del control. Puede variarse durante el tiempo de ejecución. Esta
propiedad, juntamente con Left definen la esquina superior izquierda del botón de comando. Normalmente esta
propiedad no se introduce numéricamente, sino que la toma automáticamente de la posición que se le den al botón
en tiempo de diseño. Puede cambiarse, cambiando el valor a esta propiedad, en tiempo de ejecución.

Visible Visible
Propiedad Booleana. Si es true, el botón se ve, si es False el botón no se ve. Puede cambiarse en tiempo de
ejecución. De hecho, es un recurso muy usado para dejar visibles en un formulario, solamente los objetos
(controles) necesarios.

WhatThisHelpID (Propiedad, Windows 95)

Devuelve o establece un número de contexto asociado a un objeto. Se utiliza para dotar a las aplicaciones de
Ayuda interactiva con el menú emergente ¿Qué es esto? de la Ayuda de Windows 95.

Width Ancho
Define el ancho del botón. Con Height determina la dimensión del botón.

PROCEDIMIENTOS DEL BOTON DE COMANDO

Click DragDrop DragOver GotFocus


KeyDown KeyPress KeyUp LostFocus
MouseDown MouseMove MouseUp

¡ El botón de Comando no tiene el procedimiento DbClick  !

LABEL ETIQUETA
____________________

Una etiqueta es un control que nos permite presentar un texto. La etiqueta debe usarse en aquellos casos en los que exista una información
estática o dinámica que no deba ser cambiada por el operador.

Puede adoptar estas formas: con borde tridimensional, borde plano o sin borde, y el texto justificado a la izquierda, a la derecha o
centrado.
Se ha incluido la trama para poder observar los límites de la etiqueta sin borde.

PROPIEDADES

Alignment Justificación
Establece si el texto se justifica a la izquierda, a la derecha, o se centra sobre la etiqueta.

Appearance Apariencia Plana o tridimensional.

Autosize Tamaño
Propiedad booleana. Si se pone a True, el tamaño de la etiqueta se ajusta al texto que contiene.

Backcolor Color de fondo


Es el color de fondo de la etiqueta. Puede cambiarse en tiempo de ejecución.

BackStyle Tipo de fondo


Opaco o transparente. Cuando se selecciona transparente, se ve solamente el texto de la etiqueta. Cuando se
selecciona opaco, este texto se vé sobre un fondo gris.

BorderStyle Tipo de borde


Sin borde o con borde. En caso de haber elegido en la propiedad Appearance el modo tridimensional, y eligiendo
con borde en esta propiedad, el aspecto adopta una forma como incrustada en el formulario.

Caption Título
Es el texto de la etiqueta. Puede cambiarse en tiempo de ejecución, lo que permite usar la etiqueta como
dispositivo de presentación de textos. No se puede cambiar por el procedimiento de arrastrar con el ratón, por lo
que es el control adecuado cuando se quiere presentar un texto que no se pueda cambiar por el operador.

DataField DataSource
Establecen la base de datos y el campo donde está el texto Datos que se llevará a la propiedad Caption. Estas
propiedades permiten presentar los datos de una Base de Datos mediante un procedimiento muy sencillo, con la
ayuda de un control Data (Se verá mas adelante)

DragIcon
Establece el icono que se presenta como puntero en una operación de arrastrar y colocar.
DragMode
Establece un valor que determina si se usa el modo de arrastre manual o automático en una operación de arrastrar
y colocar. Los valores posibles de número son:

0 Manual (Predeterminado)
1 Automático

Enabled Habilitado
Propiedad Booleana que habilita o deshabilita la etiqueta Cuando está deshabilitado (Enabled = False), no tienen
efecto los eventos que se produzcan sobre ella, y su apariencia varía, presentando un tono pálido tanto en su
cuerpo como en su título. Puede variarse en tiempo de ejecución.

Font Fuente
Es el tipo de letra para el título. Puede cambiarse en tiempo de ejecución.

ForeColor
Es el color de la letra de la etiqueta. Puede cambiarse en tiempo de ejecución.

Height Altura
Establece la altura de la etiqueta. Normalmente esta propiedad no se introduce numéricamente, sino que la toma
automáticamente de las dimensiones que se le den a la etiqueta en tiempo de diseño.

Index Indice
En el caso de que se tengan varios etiquetas que realicen una función similar puede hacerse un array con
etiquetas. Todas tendrán el mismo nombre, y se diferencian por un índice. Esta propiedad Index toma el número
de ese índice.

Left Posición de su parte izquierda


Indica la posición de la etiqueta, concretamente de su parte izquierda. Normalmente esta propiedad no se introduce
numéricamente, sino que la toma automáticamente de la posición que ocupaba en tiempo de diseño. Puede
cambiarse, cambiando el valor a esta propiedad, en tiempo de ejecución.

LinkItem LinkMode LinkTimeout LinkTopic


Estas propiedades establecen la forma en que debe llevarse a cabo una conexión DDE con otra aplicación. Se
verán con mas detalle al estudiar los enlaces DDE
MouseIcon Icono del puntero del ratón
MousePointer Puntero ratón
Para estas propiedades es aplicable todo lo dicho para las mismas en el Botón de Comando

Name Nombre
Es el nombre de la etiqueta con el que se le conocerá a lo largo del programa

TabIndex Nº de orden
Al igual que para los botones de comando, la etiqueta tiene propiedad TabIndex. Sin embargo, una etiqueta
NUNCA tomará el foco. Vea la propiedad UseMneumonic mas adelante.

Tag
Esta propiedad no la usa directamente Visual-Basic. Sirve para asociar a este control alguna información adicional
para fines externos a la programación.

Top
Indica la coordenada de la parte superior del control. Puede variarse durante el tiempo de ejecución. Esta
propiedad, juntamente con Left definen la esquina superior izquierda del botón de comando. Normalmente esta
propiedad no se introduce numéricamente, sino que la toma automáticamente de la posición que se le den a la
etiqueta en tiempo de diseño. Puede cambiarse, cambiando el valor a esta propiedad, en tiempo de ejecución.

UseMneumonic
Devuelve o establece un valor que indica si al incluir el signo (&) en el texto de la propiedad Caption del control
Label se define una tecla de acceso. Es una propiedad Booleana.

Los valores que puede tomar son True o False.

True (Predeterminado) Los caracteres (&) que aparezcan en el texto de la propiedad Caption definen al carácter
siguiente como tecla de acceso. El signo (&) no aparece en la interfaz del control Label.
False Los caracteres (&) que aparezcan en el texto de la propiedad Caption aparecen como tales en la interfaz del
control Label.

En tiempo de ejecución, al presionar ALT+ la tecla de acceso definida en la propiedad Caption del control Label, el
enfoque se desplaza al control siguiente al control Label en el orden de tabulación.

Visible Visible
Propiedad Booleana. Si es true, la etiqueta se ve, si es False no se ve. Puede cambiarse en tiempo de ejecución.
WhatThisHelpID (Propiedad, Windows 95)

Devuelve o establece un número de contexto asociado a un objeto. Se utiliza para dotar a las aplicaciones de
Ayuda interactiva con el menú emergente ¿Qué es esto? de la Ayuda de Windows 95.

Width Ancho
Define el ancho de la etiqueta. Con Height determina la dimensión de la misma.

WordWrap
Devuelve o establece un valor que indica si un control Label con el valor True en su propiedad AutoSize se
expande vertical u horizontalmente para adaptarse al texto especificado en su propiedad Caption. Es una
propiedad Booleana.

Esta propiedad puede cambiarse en tiempo de ejecución

True El control Label se expande o contrae horizontal y verticalmente para adaptarse al texto y al tamaño de la
fuente. Contempla para la expansión horizontal la colocación de los espacios del texto.
False (Predeterminado) El texto no se ajusta a la siguiente línea; el control Label se expande o contrae
horizontalmente para adaptarse a la longitud del texto y verticalmente para adaptarse al tamaño de la fuente y al
número de líneas.

Nota Si se establece False en AutoSize, el texto siempre se ajustará a la línea siguiente, independientemente del
tamaño del control Label y del valor de la propiedad WordWrap. Esto puede ocultar parte del texto, ya que el
control Label no se expande en ninguna dirección.

PROCEDIMIENTOS DEL LABEL

Click Change DbClick DragDrop

DragOver LinkClose LinkError LinkNotify

TEXT BOX CAJAS DE TEXTO


_____________________________
Las cajas de texto son los controles en los que Visual Basic presenta o introduce textos. Es por tanto un control bidireccional. Normalmente
se usan para introdución de textos, o para la presentación de aquellos que el operador pueda cambiar. Para cambiar o escribir un texto en
una caja de texto, basta con conseguir que esa caja de texto tenga el foco y teclear el texto en el teclado. Esto se puede lograr, bien
haciendo click con el ratón en esa caja de texto, bien con la tecla TAB, bien por programa.

La caja de texto no se debe usar nunca para presentar textos que el operador de la aplicación no deba cambiar. Úsese para ello la etiqueta,
control no bidireccional, que además tiene la ventaja de ocupar menos memoria de programa.

Las cajas de texto pueden tener una o varias líneas, según esté la propiedad Multiline. La capacidad máxima de una caja de textos es de
64 Kbytes.

La forma de una caja de texto es la siguiente, dependiendo de las propiedades BorderStyle y Appearance:

PROPIEDADES

Alignment Justificación
Establece si el texto se justifica a la izquierda, a la derecha, o se centra sobre la etiqueta. Esta propiedad
solamente tiene efecto cuando la propiedad Multiline está a True, ignorándose en caso contrario. Es decir, permite
colocar el texto justificado a la derecha cuando ese texto puede ser de varias líneas. Para una única línea, se
justifica siempre a la izquierda.
Esta propiedad no puede cambiarse en tiempo de ejecución, pero sí puede leerse en que condición está.

Appearance Apariencia
Plana o tridimensional.
Backcolor Color de fondo
Es el color de fondo de la caja de texto. Puede cambiarse en tiempo de ejecución.

BorderStyle Tipo de borde


Sin borde o con borde. En caso de haber elegido en la propiedad Appearance el modo tridimensional, y eligiendo
con borde en esta propiedad, el aspecto adopta una forma como incrustada en el formulario.

DataField
DataSource Fuente de Datos
Establecen la base de datos y el campo donde está el texto que se llevará a la propiedad Text. Estas propiedades
permiten presentar de una forma muy sencilla datos de una Base de Datos. Se verán cuando se estudie el control
Data y el motor de bases de datos

DragIcon
Establece el icono que se presenta como puntero en una operación de arrastrar y colocar.

DragMode
Establece un valor que determina si se usa el modo de arrastre manual o automático en una operación de arrastrar
y colocar. Los valores posibles de número son:

0 Manual (Predeterminado)
1 Automático

Enabled Habilitado
Propiedad Booleana que habilita o deshabilita la etiqueta Cuando está deshabilitado (Enabled = False), no tienen
efecto los eventos que se produzcan sobre el TextBox. No se puede escribir el él ni pasarle el foco, pero sí se le
puede cambiar el texto mediante el programa. Puede ser una buena alternativa para impedir que el usuario pueda
cambiar un determinado texto. Esta propiedad puede variarse en tiempo de ejecución.

Font Fuente
Es el tipo de letra que se utilizará en el TextBox. Puede cambiarse en tiempo de ejecución.

ForeColor Color de la letra


Determina el color de las letras del texto.
Height Altura
Establece la altura de la caja de texto. Normalmente esta propiedad no se introduce numéricamente, sino que la
toma automáticamente de las dimensiones que se le den a la caja en tiempo de diseño.

HelpContextID
Establece un número de contexto asociado para este control. Este número se aplica para determinar la ayuda
interactiva.

Puede tener los siguientes valores:


0 = No se especifica número de contexto
>0 Un entero que especifica un contexto válido.

Index Indice
En el caso de que se tengan varias cajas de texto que realicen una función similar puede hacerse un array con
ellas. Todas tendrán el mismo nombre, y se diferencian por un índice. Esta propiedad Index toma el número de ese
índice.

Left Posición de su parte izquierda.


Indica la posición de la caja de texto, concretamente de su parte izquierda. Normalmente esta propiedad no se
introduce numéricamente, sino que la toma automáticamente de la posición que ocupaba en tiempo de diseño.
Puede cambiarse, cambiando el valor a esta propiedad, en tiempo de ejecución.

LinkItem LinkMode LinkTimeout LinkTopic


Estas propiedades establecen la forma en que debe llevarse a cabo una conexión DDE con otra aplicación. Se
verán con mas detalle al estudiar los enlaces DDE

Locked
Establece si el texto se puede editar, es decir, cambiar. Cuando se pone esta propiedad a True, el texto existente
en la caja puede resaltarse con el ratón, e incluso copiarlo al portapapeles, pero no puede variarse tecleando un
nuevo texto. Se puede cambiar por programa, cambiando la propiedad Text.
Si está en False, puede cambiarse el texto mediante teclado.

MaxLenght
Indica, si se establece, la longitud máxima del texto.
MouseIcon Puntero del ratón personalizado
MousePointer Puntero ratón
Determina la forma del puntero del ratón cuando éste pasa por encima de la caja de texto. Puede elegirse uno de
los punteros preestablecidos en esta propiedad, (15 en total) e incluso un puntero personalizado en la propiedad
MouseIcon. Para que aparezca este puntero personalizado, MousePointer debe ponerse al valor 99. Lo típico
para esta propiedad es el I-Beam (barra vertical)

Name Nombre
Es el nombre de la caja de texto con el que se le conocerá a lo largo del programa

PasswordChar
En ocasiones, es conveniente que no se pueda leer lo que se escribe en la caja de texto, caso por ejemplo de la
entrada de un password o palabra de paso. Esta propiedad nos permite indicar un carácter que sustituye a
cualquier carácter que tenga la caja de texto. (Típicos el * o ?). El texto que tenga en la propiedad Text no cambia
por el hecho de presentar en pantalla un carácter distinto. Esta propiedad puede cambiarse en tiempo de ejecución.
Para quitar el PasswordChar basta con forzarlo al carácter nulo : Text1.PasswordChar = “”

Esta propiedad se ignora cuando la propiedad Multiline está a True.

ScrollBars
Cuando la propiedad Multiline de la caja de texto está a True, se pueden colocar barras de desplazamiento del
texto hacia arriba y abajo, o hacia los lados. Esto nos permite tener una caja de texto de tamaño reducido y poder
leer en ella un texto mayor que la propia caja. Esta propiedad puede tomar los siguiente valores :

0 - No salen barras
1 - Barras de desplazamiento horizontal
2 - Barras de desplazamiento vertical
3 - Ambas barras.

TabIndex Nº de orden para obtener el foco


Al igual que para los botones de comando, esta propiedad para tabulador marca el orden en el que le llegará el
foco al pulsar la tecla TAB

Tag
Esta propiedad no la usa directamente Visual Basic. Sirve para asociar a este control alguna información adicional
para fines externos a la programación.
Top
Indica la coordenada de la parte superior del control. Puede variarse durante el tiempo de ejecución. Esta
propiedad, juntamente con Left definen la esquina superior izquierda de la caja de texto. Normalmente esta
propiedad no se introduce numéricamente, sino que la toma automáticamente de la posición que se le de en tiempo
de diseño. Puede cambiarse, cambiando el valor a esta propiedad, en tiempo de ejecución.

Visible Visible
Propiedad Booleana. Si es true, la caja de texto se ve, si es False no se ve. Puede cambiarse en tiempo de
ejecución.

WhatThisHelpID (Propiedad, Windows 95)

Devuelve o establece un número de contexto asociado a un objeto. Se utiliza para dotar a las aplicaciones de
Ayuda interactiva con el menú emergente ¿Qué es esto? de la Ayuda de Windows 95.

Width Ancho
Define el ancho de la caja de texto. Con Height determina la dimensión de la misma.

PROCEDIMIENTOS DE LA CAJA DE TEXTO

Click Change DblClick DragDrop DragOver GotFocus

KeyDown KeyPress KeyUp LinkClose

FRAME RECUADRO

Se obtiene directamente de la caja de herramientas


Tiene la siguiente forma :

Un control Frame proporciona un agrupamiento identificable para controles. También puede utilizar un Frame para subdividir un formulario
funcionalmente por ejemplo, para separar grupos de controles OptionButton.

Para agrupar controles, en primer lugar trace el control Frame y, a continuación, meta los controles dentro de Frame. De este modo podrá
mover al mismo tiempo el Frame y los controles que contiene. Si traza un control fuera del Frame y, a continuación, intenta moverlo dentro
de éste, el control se colocará sobre el Frame, pero no pertenecerá a el. Es decir, si es un OptionButton este se comportará como si
estuviese fuera del Frame, aunque físicamente esté dentro de el.

Cuando un control Frame tiene dentro otros controles, y hacemos invisible al Frame, mediante su propiedad Visible = False, los controles
interiores al Frame quedan también invisibles.

PROPIEDADES
Las señaladas con (*) no presentan novedades respecto a las ya comentadas para los controles precedentes.

Appearance (*)
Backcolor (*)

Caption Es el título que aparece en el borde del Frame.

ClipControls
Si esta propiedad está a True, los métodos gráficos en eventos Paint vuelven a dibujar el objeto entero. Antes del
evento Paint se crea una zona de recorte alrededor de los controles no gráficos del formulario. Si esta propiedad
está a False dibujarán solamente las áreas últimamente expuestas. En tiempo de ejecución, esta propiedad es de
sólo lectura.

DragIcon (*)
DragMode (*)

Enabled
Cuando esta propiedad está a False, tanto los procedimientos asociados al propio control Frame como todos los
controles dentro del Frame estarán inhabilitados. Si esta propiedad está a True, todos ellos están habilitados.

Font
En esta propiedad, el tipo de letra afecta solamente al título del Frame, no a los controles internos a el.

ForeColor
Color de las letras del título del Frame.

Height (*)
HelpContextID (*)
Index (*)
Left (*)
MouseIcon (*)
MousePointer (*)
Name (*)
TabIndex (*)
Tag (*)
Top (*)

Visible
Cuando un Frame está con la propiedad Visible = False, tanto el propio Frame como todos los controles interiores
a el serán invisibles.
WhatsThisHelpID (*)
Width (*)

PROCEDIMIENTOS DEL FRAME


Click DblClick DragDrop DragOver MouseDown

MouseMove MouseUp

CHECK BUTTON Y OPTION BUTTON (BOTONES DE ELECCION Y OPCION)

Se obtienen directamente de la caja de herramientas.

Dada la similitud de ambos controles, se comentan conjuntamente.

El control CheckBox, o casilla de verificación, permite elegir una opción (activada/desactivada, True/False) que el usuario puede establecer
o anular haciendo click. Una X en una casilla de verificación indica que está seleccionada, activada, o con valor True. Cada casilla de
verificación es independiente de las demás que puedan existir en el formulario, pudiendo tomar cada una de ellas el valor True o False, a
voluntad del operador.

Un control OptionButton muestra una opción que se puede activar o desactivar, pero con dependencia del estado de otros controles
OptionButton que existan en el formulario.

Generalmente, los controles OptionButton se utilizan en un grupo de opciones para mostrar opciones de las cuales el usuario sólo puede
seleccionar una. Los controles OptionButton se agrupan dibujándolos dentro de un contenedor como un control Frame, un control
PictureBox o un formulario. Para agrupar controles OptionButton en un Frame o PictureBox, dibuje en primer lugar el Frame o
PictureBox y, a continuación, dibuje dentro los controles OptionButton. Todos los controles OptionButton que están dentro del mismo
contenedor actúan como un solo grupo, e independientes de los controles OptionButton de otros grupos distintos.
Aunque puede parecer que los controles OptionButton y CheckBox funcionan de forma similar, hay una diferencia importante: Cuando un
usuario selecciona un OptionButton, los otros controles del mismo grupo OptionButton dejan de estas disponibles automáticamente. Por
contraste, se puede seleccionar cualquier número de controles CheckBox.
En el ejemplo de la figura, existen tres grupos de OptionButton, uno en un PictureBox, que actúa, al tiempo que como cuadro de imagen,
como contenedor de controles OptionButton. Otro grupo está en el interior de un control Frame, y el otro grupo está en el formulario. Los
tres grupos son independientes entre sí, pero interiormente al grupo solamente puede seleccionarse uno de los OptionButton que lo
componen.

En el formulario también existen tres CheckBox, que como puede verse, se pueden seleccionar los que se desee, sin ningún tipo de
exclusión entre ellos.

PROPIEDADES

Las señaladas con (*) son comunes a ambos controles y no presentan novedades respecto a las ya comentadas
para los controles precedentes.

Alignment Común a ambos controles.

Admite los siguientes valores :

0 - Left Justify
1 - Right Justify

Cuando se elige el valor 0, justificado a la izquierda, el título del control aparece a la derecha del botón, pegado a la figura del botón.
Cuando se elige el valor 1, justificado a la derecha, el título (Caption) aparece a la izquierda del botón, comenzando en la parte izquierda
del cuerpo total del control, es decir, no tiene porqué aparecer con su parte derecha pegado al botón, caso que el cuerpo total del control se
haya hecho mas largo que la palabra del título.

Appearance (*)
Backcolor (*)
Caption (*).

DataField DataSource Propiedades del CheckBox solamente.


Establecen la base de datos y el campo donde están los datos (True / False) que se llevarán a la propiedad Value .
Al igual que en los controles Label y TextBox esta propiedad nos permite visualizar datos de una base de datos de
una forma muy sencilla. En este caso, el CheckBox solamente permite presentar (logicamente) datos de tipo
Booleano.

DragIcon (*)
DragMode (*)
Enabled (*)
Font (*)
ForeColor (*)

Height Común a ambos controles.


La altura del control solamente afecta a la colocación del Titulo (Puede ponerse un título largo en varias líneas), no
al tamaño del botón, que es invariable.

HelpContextID (*)
Index (*)
Left (*)
MouseIcon (*)
MousePointer (*)
Name (*)
TabIndex (*)
TabStop (*)
Tag (*)
Top (*)
Value Común a ambos controles
El valor de esta propiedad indica si el control está seleccionado (Value = 1) o no seleccionado (Value = 0 ó Value
= False). Esta propiedad puede cambiarse en tiempo de ejecución. Mediante esta propiedad, podemos tanto forzar
el valor como leerlo.

Atención. Presenta una diferencia entre uno y otro control respecto a la forma de expresarse respecto a su valor
cuando está seleccionado. Para forzar que el control NO esté seleccionado, o para leer el Value cuando no está
seleccionado, podemos utilizar tanto Value = 0 como Value = False. Sin embargo, cuando lo que se quiere es
poner la propiedad a True hay una diferencia entre ambos controles.
Para el OptionButton podemos utilizar indistintamente las siguiente formas :

Option1.Value = True Option1.Value = 1

Con cualquiera de ellas seleccionaremos ese control por programa.


Para el CheckBox solamente se podrá usar para este propósito la instrucción :

Check1.value = 1

El poner como Value el valor True nos dará en este control un error.

Para la lectura del Value, existe una diferencia entre el valor devuelto por el CheckBox y el devuelto por el
OptionButton.

Para leer el dato existente en un CheckBox es necesario utilizar la forma :

variable = Check1.Value donde variable tomará el valor 1 (no True)

Para el control OptionButton emplearemos una instrucción igual :

variable = Option1.Value donde variable tomará el valor True (no 1)

Visible (*)
WhatsThisHelpID (*)
Width (*)

PROCEDIMIENTOS
Click DblClick (Solo OptionButton) DragDrop DragOver GotFocus

KeyDown KeyPress KeyUp LostFocus

LIST BOX Y COMBO BOX

Estos dos controles, debido a su similitud, se estudian conjuntamente.

Se obtienen directamente de la caja de herramientas :

Un control ListBox muestra una lista de elementos en la que el usuario puede seleccionar uno o más. Si el número de elementos supera el
número que puede mostrarse, se agregará automáticamente una barra de desplazamiento al control ListBox.

Un control ComboBox combina las características de un control TextBox y un control ListBox. Los usuarios pueden introducir información
en la parte del cuadro de texto y seleccionar un elemento en la parte de cuadro de lista del control. En resumen, un ComboBox es la
combinación de un ListBox, que se comporta como si de un ListBox se tratase, y de un TextBox, con comportamiento análogo a un
TextBox sencillo, con la particularidad aquí de que el texto se le puede introducir por teclado, o elegir uno de los que figuran en la parte
ListBox del Combo.

Estos controles toman la siguiente forma :


Puede verse en la figura un ejemplo de presentación de un ListBox (izquierda), un ComboBox con la lista desplegada (Centro) y un
ComboBox con la lista sin desplegar (Combo2 a la derecha).

La lista tiene varios elementos. Cada línea de esta lísta es un elemento de la lista. Como el número de elementos de la lista tiene mas
elementos de los que le podían caber, generó automáticamente la barra de desplazamiento vertical.

El ComboBox está normalmente sin desplegar. Se despliega cuando se hace click con el ratón en la flecha que tiene en su parte derecha
(véase fig. Anterior). Al desplegarse, muestra la lista con todos sus elementos. Haciendo click con el ratón en cualquiera de sus elementos,
el elemento elegido pasa a la parte TextBox del Combo y la lista vuelve a replegar.

El ListBox (y por tanto el ComboBox) tiene unas propiedades y métodos particulares que solamente se pueden aplicar durante el tiempo
de ejecución :

ListCount - Indica el número de elementos que tiene la lista


ListIndex - Indica el número de orden del elemento seleccionado dentro de la lista.
AddItem - Añade un elemento a la lista.
RemoveItem - Elimina un elemento de la lista.
Text - Obtiene el elemento seleccionado.
List (n) - Obtiene el elemento cuyo orden dentro de la lista es n.

ListCount valdrá 0 si la lista no tiene ningún elemento, y n si tiene n elementos.

Para seleccionar un elemento de la lista, basta con hacer click con el ratón sobre él. Ese elemento se resaltará con fondo en azul. Una vez
seleccionado un elemento, la propiedad ListIndex tomará el valor del número de orden que ocupa ese elemento en la lista, comenzando
por el 0 para el elemento que ocupa el primer lugar. Si no se selecciona ningún elemento, el valor de la propiedad ListIndex será -1. El
primer elemento de la lista es ListIndex 0, y el valor de la propiedad ListCount siempre es uno más que el valor mayor de ListIndex.
En el ComboBox la propiedad Text contiene el texto que contenga la parte TextBox del Combo, bien haya sido introducida desde teclado
o mediante la recuperación de un elemento la parte ListBox del mismo.

Ejemplos

Supongamos que tenemos un ListBox llamado List1, y un ComboBox llamado Combo1. Se enumeran distintas formas de obtener
información de ellos.

Variable = List1.Listcount
Variable contendrá un número con el número total de elementos de la lista List1.

Variable = List1.ListIndex
Variable contendrá un número con el número de orden del elemento de la lista seleccionado en ese momento.

List1.AddItem “ELEMENTO NUEVO”


Añade un elemento a List1. En este caso, el elemento añadido es la palabra ELEMENTO NUEVO.

Variable = “VISUALBASIC”
List1.AddItem Variable
Añade un elemento a List1. En este caso, el elemento añadido es la palabra VISUALBASIC.

Variable = List1.Text
Variable contendrá el elemento que estaba seleccionado en List1. (Variable será una cadena de caracteres)

Variable = List1.List (n)


Variable contendrá el elemento que ocupa el número de orden n dentro de la lista.

Variable = List1.List (List1.ListIndex)


Variable contendrá el elemento que estaba seleccionado en List1. Se ha utilizado la propiedad List para obtener el
elemento, y en vez de introducir un número para definir el elemento que se desea, se introdujo el valor ListIndex de List1,
que es concretamente, el número de orden del elemento seleccionado en ese momento. Observe que poner List1.List
(List1.ListIndex) es idéntico a poner List1.Text.

List1.RemoveItem (n)
Elimina el elemento n de List1.
List1.RemoveItem (List1.ListIndex)
Elimina el elemento que estaba seleccionado en ese momento.

List1.listIndex = n
Selecciona el elemento n de List1 (Se resalta en azul el elemento n)

PROPIEDADES DE ListBox y de ComboBox

Las señaladas con (*) son comunes a ambos controles y no presentan novedades respecto a las ya comentadas para los controles
precedentes.

Appearance (*)
Backcolor (*)
Columns Propiedad de ListBox solamente.

Determina si los elementos se presentan en una sola columna o en varias columnas, y la forma de presentar los elementos en el ListBox. Si
esta propiedad se pone a 0 la lista tendrá solamente una columna, y presentará los elementos uno debajo de otro. Cuando los elementos
sean mas que los que se pueden presentar en la lista, aparecen automáticamente unas barras de desplazamiento vertical.
Si la propiedad se pone a un número distinto a 0, el ListBox es de tipo multicolumna, presentará en cada columna los elementos que le
quepan dependiendo de su dimensión vertical, y tendrá tantas columnas como sea necesario para albergar el número de elementos que
tenga. Presentará en su cuadro tantas columnas como se le indique en el valor de esta propiedad, y si no puede presentar todos los
elementos en las columnas que muestra, le aparecerán barras de desplazamiento horizontales para poder movernos por todas las
columnas que tenga.
Recuerde : El número que se le asigna a la propiedad Columns no indica el número de columnas que tendrá el ListBox sino el número de
columnas que presenta.

Esta propiedad puede asignarse en diseño, mediante la caja de propiedades, o en tiempo de ejecución mediante una instrucción como
esta :

Nombrelista.Columns = número
.
Esta propiedad no puede definirse a 0 o cambiada desde 0 en tiempo de ejecuciones decir, no se puede convertir en tiempo de ejecución
un ListBox de múltiples columnas en un ListBox de columna única o un ListBox de columna única en un ListBox de múltiples columnas. Sin
embargo, sí es posible cambiar durante la ejecución el número de columnas de un ListBox de múltiples columnas.
DataField DataSource .
Establecen la base de datos y el campo donde están los datos que se llevarán al TextBox o ComboBox para
presentar datos procedentes de una Base de Datos.

DragIcon (*)
DragMode (*)
Enabled (*)
Font (*)
ForeColor (*)
Height (*)
HelpContextID (*)
Index (*)
IntegralHeight No aplicable a ListBox o ComboBox
ItemData Propiedad muy importante.

Devuelve o establece un número específico para cada elemento de un control ComboBox o ListBox.

Sintaxis
objeto.ItemData(índice) [= número]

La sintaxis de la propiedad ItemData tiene las siguientes partes:

objeto Nombre del ListBox o ComboBox.


índice El número de un elemento concreto del objeto.
número El número que se asocia con el elemento especificado.

Comentarios

La propiedad ItemData es una matriz de valores enteros largos cuyo número de elementos es el valor de la propiedad ListCount del control.
Los números asociados con cada elemento se pueden usar para cualquier fin. Por ejemplo, se puede usar en la confección de una lista de
teléfonos, el número de identificación de un empleado, etc. Cuando se rellena el ListBox, también se rellena los elementos
correspondientes de la matriz ItemData con los números correspondientes.
La propiedad ItemData se usa a menudo como índice de una matriz de estructuras de datos asociados con los elementos de un control
ListBox.

Nota Cuando se inserta un elemento en una lista con el método AddItem, el elemento también se inserta automáticamente en la matriz
ItemData. Sin embargo, el valor no se reinicializa a cero; retiene el valor que estaba en esa posición antes agregar el elemento a la lista.
Cuando se usa la propiedad ItemData, asegúrese de establecer su valor al agregar nuevos elementos a la lista.

Left (*)

List Es el contenido de la lista.


Si la lista de elementos es corta e invariable, pueden introducirse los elementos en el cuadro de propiedades durante el diseño.

MouseIcon (*)
MousePointer (*)
Name (*)

Sorted

Establece o devuelve un valor que indica si los elementos de un ListBox o ComboBox se colocan automáticamente en orden
alfabético. Los valores que puede adoptar son True o False.

True Los elementos de la lista se ordenan alfabéticamente (sin distinguir entre mayúsculas y minúsculas).
False (Predeterminado) Los elementos de la lista no se ordenan alfabéticamente.

Cuando esta propiedad tiene el valor True, Visual Basic se encarga de casi todo el procesamiento de cadenas necesario para
mantener el orden alfabético, incluyendo el cambio de los números de índice cuando se agregan o eliminan elementos.

Nota El uso del método AddItem para agregar un elemento en una posición específica de la lista puede romper el orden
alfabético, y los elementos agregados con posterioridad pueden no ordenarse correctamente.

TabIndex (*)
TabStop (*)
Tag (*)
Top (*)
Visible (*)
WhatsThisHelpID (*)
Width (*)

PROCEDIMIENTOS
Click Change (Solo ComboBox) DblClick DragDrop DragOver

DropDown (Solo ComboBox) GotFocus KeyDown KeyPress

KeyUp LostFocus MouseDown (Solo ListBox) MouseMove (Solo ListBox)

MouseUp (Solo ListBox)

NOTA MUY IMPORTANTE

El procedimiento Change del ComboBox solamente se efectúa cuando el cambio se produce mediante la entrada de un texto DESDE EL
TECLADO, no por un cambio en la parte Text de este control, producido al llevar un elemento desde la parte List a la parte Text.

CONTROLES HScrollBar y VScrollBar

Son dos controles similares, para introducir un dato cuasi-analógico en una aplicación. Se toman directamente de la caja de herramientas, y
tienen un aspecto parecido al de un control de volumen de un equipo de música. El HScrollBar está en posición horizontal, y el VScrollBar
en posición vertical.

Mediante estos controles se pueden introducir datos variando la posición del cursor.

PROPIEDADES de HScrollBar y VScrollBar

Las señaladas con (*) son comunes a ambos controles y no presentan novedades respecto a las ya comentadas para los controles
precedentes.

DragIcon (*)
DragMode (*)
Enabled (*)
Height (*)
HelpContextID (*)
Index (*)

LargeChange
Esta propiedad establece la variación de la propiedad Value cada vez que se hace click en el interior de la barra de
desplazamiento, en la parte por donde pasa el cursor.

Left (*)

Max
Esta propiedad establece el valor máximo para la propiedad Value, es decir, el valor de esta propiedad cuando el cursor
está en su parte máxima. (Recuerde que el cursor está en el máximo, cuando está mas a la derecha, caso del HScrollBar,
o cuando está en la parte mas baja, caso del HScrollBar.

Min
Esta propiedad establece el valor mínimo para la propiedad Value, es decir, el valor de esta propiedad cuando el cursor
está en su parte mínima. (Recuerde que el cursor está en el mínimo, cuando está mas a la izquierda, caso del HScrollBar,
o cuando está en la parte mas alta, caso del HScrollBar.

MouseIcon (*)
MousePointer (*)
Name (*)

SmallChange
Esta propiedad establece la variación de la propiedad Value cada vez que se hace click en las flechas superior o inferior de
la barra de desplazamiento.
TabIndex (*)
TabStop (*)
Tag (*)
Top (*)
Value
Esta propiedad lee o establece el valor dado por la posición del cursor. Este valor tiene un mínimo, establecido por Min y
un máximo, establecido por Max. Esta propiedad es la que se debe leer para conocer la posición del cursor.

Visible (*)
WhatsThisHelpID (*)
Width (*)

PROCEDIMIENTOS DE HScrollBar y VScrollBar

Change DragDrop DragOver GotFocus KeyDown KeyPress

KeyUp LostFocus Scroll

Comentario El Procedimiento Change se produce cuando, tras mover el cursor, se suelta el botón del ratón. Esto produce el efecto de
que el cambio que se tenga que producir con el movimiento del cursor no se realiza de una manera continua. El procedimiento Scroll se
realiza en el instante que se está moviendo el cursor. Por lo tanto, es este procedimiento el que se debe usar para conseguir el efecto de un
cambio continuo mientras se está moviendo el cursor.

TIMER TEMPORIZADOR

Este objeto permite establecer temporizaciones. Presenta una novedad respecto a los controles estudiados hasta ahora. El control Timer
solamente se ve durante el tiempo de diseño. En tiempo de ejecución, el control permanece invisible.

La temporización producida por el Timer es independiente de la velocidad de trabajo del ordenador. (Casi independiente. El timer no es un
reloj exacto, pero se le parece)

Se toma directamente de la caja de herramientas, y tiene el aspecto siguiente :


PROPIEDADES

Enabled (*)
Index (*)
Interval
El valor de esta propiedad nos dará el intervalo de tiempo (en milisegundos) en que se producirá un evento Timer y consecuentemente,
realizará el procedimiento asociado a este evento. Si el valor de la propiedad Interval está a 0 (Predeterminado), no se produce el evento
Timer. (El control Timer está deshabilitado cuando se pone la propiedad Interval = 0)

Left (*)
Name (*)
Tag (*)
Top (*)

PROCEDIMIENTOS

Timer

Se produce cada vez que se cumple un intervalo completo.

SHAPE

Se toma directamente de la caja de herramientas :

Shape es un control gráfico que se muestra como un rectángulo, un cuadrado, una elipse, un círculo, un rectángulo redondeado o un
cuadrado redondeado.
Utilice controles Shape en tiempo de diseño en lugar o además de invocar los métodos Circle y Line en tiempo de ejecución. Puede dibujar
un control Shape en un contenedor, pero no puede actuar como contenedor. (Esto quiere decir que un control Shape nunca le servirá, por
ejemplo, para albergar varios OptionButton y pretender que sean independientes de otros controles OptionButton que se encuentren
fuera del control Shape.

Este control no tiene Procedimientos. En realidad, solamente sirve para mostrar un determinado gráfico, envolver gráficamente a otros
controles, pero no tiene ninguna aplicación en cuanto a programa. Es un “adorno” para sus aplicaciones.

PROPIEDADES

Backcolor (*)

BackStyle
Esta propiedad establece si Shape permite ver a su través (Transparent) o n lo permite (Opaque)
BorderColor
Establece el color del borde.
BorderStyle
Establece el tipo de borde. Puede ser : Transparent, (No se ve el borde), Solid, (Borde de línea continua),Dash, (línea a
rayas), Dot, (línea a puntos), Dash-Dot, (línea de raya - punto), dash-Dot-Dot, (línea de raya - punto - punto), InsideSolid,
(raya continua)

El efecto de establecer la propiedad BorderStyle depende del valor de la propiedad BorderWidth. Si BorderWidth no es 1 y
BorderStyle no es 0 o 6, BorderStyle se establece como 1.

BorderWidth
Establece el ancho de la línea.

DrawMode (*)
FillColor (*)
FillStyle (*)
Height (*)
Index (*)
Left (*)
Name (*)

Shape
Establece la forma del control. Puede ser : Rectangular, cuadrado, redondo, ovalado, cuadrado con esquinas redondeadas
y rectangular con esquinas redondeadas.

Tag (*)
Top (*)
Visible (*)
Width (*)

PROCEDIMIENTOS No tiene.

.LINE

Se toma directamente de la caja de herramientas

Line, al igual que Shape, es un control gráfico que solamente sirve para poner una línea en un formulario. Del mismo modo, no tiene
procedimientos, por lo que no sirve para aportar código al programa. Solo sirve para aportar una característica gráfica, es un adorno.

PROPIEDADES

BorderColor
Establece el color de la línea.
BorderStyle
Establece el tipo de línea : Puede ser : Transparent, (No se ve la línea), Solid, (Línea continua),Dash, (línea a rayas), Dot,
(línea a puntos), Dash-Dot, (línea de raya - punto), dash-Dot-Dot, (línea de raya - punto - punto), InsideSolid, (raya
continua)

BorderWidth
Establece el ancho de la línea.
DrawMode (*)
Index (*)
Left (*)
Name (*)

Tag (*)
Visible (*)
X1, X2 Establece las coordenadas x del inicio y final.
Y1, Y2 Establece las coordenadas y del inicio y final

PROCEDIMIENTOS No tiene.

CONTROL GAUGE

Este control presenta una información numérica de forma gráfica, bien como un display lineal (típico por ejemplo en ecualizadores de
audio ), o como una aguja. No está normalmente en la caja de herramientas, por lo que hay que traerla desde los Controles Personalizados
(Menú desplegable de Herramientas). Se denomina MicroHelp Gauge Control. El archivo que lo contiene se denomina GAUGE16.OCX,
(Ver. 16 bits) GAUGE32.OCX (Ver. 32 bits)

Mediante este control, podemos presentar una magnitud numérica de una forma cuasi-analógica. Podríamos decir que es un control similar
al HScrollBar, que en vez de meter información a la aplicación, la presenta.

Este control puede servir, por ejemplo, para presentar el tanto por ciento de ejecución de una tarea, como elemento tranquilizante. Puede
presentar el nivel de un depósito de agua, etc.

Presenta las dos formas siguientes :


En la figura puede verse un Gauge de aguja, uno de barra horizontal y otro de barra vertical. Para mejorar la presentación, el Gauge
permite poner un gráfico como fondo, cambiar el color de la barra, color de fondo, etc.
El control Gauge crea medidores definidos por el usuario, que puede elegir entre los estilos lineales (relleno) o de aguja.

Nota para la distribución Cuando cree y distribuya aplicaciones con controles Gauge, tendrá que instalar el archivo apropiado en el
subdirectorio SYSTEM de Windows del cliente. El Kit para instalación que incluye Visual Basic, le proporciona herramientas para escribir los
programas que instalan las aplicaciones correctamente.

PROPIEDADES

Autosize, Backcolor, DragIcon, DragMode, Enabled, ForeColor, Height, HelpContextID,


Index, InnerBottom, InnerLeft, InnerRight, InnerTop, Left, Max, Min, MouseIcon, MousePointer, Name, NeedleWidth, Picture, Style,
TabIndex, Tabstop, Tag, Top, Value, Visible, WhatsThisHelpID, Width.

Son destacables por nuevas o particulares, las siguientes propiedades :

ForeColor Color de la barra


InnerBottom Distancia entre la parte baja del control y el comienzo de la barra o aguja.
InnerLeft, InnerRight, InnerTop. Idéntico al anterior, respecto a otros lados.
Max Valor de la propiedad Value a fondo de escala
Min Valor de la propiedad Value para indicación cero.
NeedleWidth Ancho de la aguja
Style Tipo de marcador. Puede tomar los siguientes valores :
0 = de barra, horizontal.
1 = de barra, vertical.
2 = de aguja, de 180 grados
3 = de aguja, de 360 grados.
Value
Valor numérico a presentar. Debe ser igual o menor que la propiedad Max, e igual o mayor que la propiedad Min.

PROCEDIMIENTOS

Change DblClick DragDrop DragOver GotFocus KeyDown

KeyPress KeyUp LostFocus MouseDown MouseMove MouseUp

Controles (Continuación) El CommonDialog

El CommonDialog es un control del que se libran muy pocas aplicaciones. Dada la importancia de este control, se le dedica un capitulo
único en esta Guía del Estudiante.

CUADRO DE DIALOGO CommonDialog

Normalmente se encuentra en la caja de herramientas

Este control no se presenta en tiempo de diseño mas que con un simple icono :
El cuadro de diálogo, CommonDialog se utiliza para varias funciones :

 Abrir Ficheros
 Guardar Ficheros
 Elegir colores
 Seleccionar Impresora
 Seleccionar Fuentes
 Mostrar el fichero de Ayuda

En realidad el cuadro de diálogo permite conocer datos con los cuales, y mediante el código adecuado, abriremos o guardaremos ficheros,
elegiremos colores o seleccionaremos fuentes. Es decir, el CommonDialog NO realiza mas funciones que mostrar ficheros existentes,
fuentes disponibles, colores, para que, mediante código, abramos esos ficheros o usemos una determinada fuente.

Dependiendo de la aplicación para la que vaya a usarse se deberá activar de distintas formas. Si el cuadro de diálogo se va a usar para
seleccionar la impresora y para otras aplicaciones, es recomendable usar uno exclusivamente para seleccionar la impresora.
Esta última recomendación se debe a que, para el control de la impresora, el CommonDialog SI realiza las funciones de selección de
impresora predeterminada. Esta diferencia operativa hace que si usamos el mismo CommonDialog para seleccionar impresora y abrir
ficheros, por ejemplo, se “cuelgue” el CommonDialog.

El control CommonDialog es un control personalizado (Microsoft CommonDialog Control COMDLG16.OCX / COMDLG32.OCX), y como
casi todos los controles personalizados presenta un asistente de propiedades propio. Puede accederse a las propiedades mediante el
cuadro de propiedades típico de otros controles, o mediante el asistente, pulsando el botón derecho del ratón con el puntero colocado
encima del icono del cuadro de diálogo.

Analizando las propiedades, vemos que tiene gran cantidad de ellas. Esto es porque agrupa todas las propiedades correspondientes a la
cinco funciones que puede desarrollar. Se detalla a continuación la forma de usar el CommonDialog para cada aplicación.

Se entiende que el nombre - Name - que se ha puesto para el cuadro de diálogo en todos los ejemplos es CD1)

FUENTES

Para mostrar el cuadro de diálogo correspondiente a Tipos de Letra ( Fonts ), debe ejecutarse la instrucción:

CD1.ShowFont

y haber puesto, en la propiedad Flags del cuadro de diálogo, el valor de 1, 2 ó 3, correspondiente respectivamente a los tipos de letra de la
pantalla, de la impresora o ambos. (Véase la propiedad Flags mas adelante) Si no pone uno de estos valores, le dirá que no tiene fuentes
instaladas.

El cuadro de diálogo que se presenta es el siguiente:

Los valores que se pueden obtener de este cuadro de dialogo son:

CD1.FontName Indica el nombre de la fuente


CD1.FontSize Indica el tamaño de la fuente
CD1.Color Indica el color de la fuente (Abrir con Flags=256+1, 2 ó 3)
CD1.FontBold = (True / False) Si es True, se ha elegido "Negrita"
CD1.FontItalic = (True / False) Si es True, se ha elegido "Cursiva"
CD1.FontStrikethru = (True / False) Si es True, se ha elegido "Tachada "
CD1.FontUnderline = (True / False) Si es True, se ha elegido "Subrayada"
Si se elige una versión Negrita Cursiva serían True las opciones FontBold y FontItalic

El objeto Font no puede aplicarse al CommonDialog. Es decir, no podemos poner :


Variable = CD1.Font.Size sino Variable = CD1.Fontsize

En el ejemplo que acompaña a este capítulo, puede ver como se introducen las características de una determinada fuente elegida en un
cuadro de texto.

COLOR

Para mostrar el cuadro de diálogo correspondiente al color, se deberá ejecutar la instrucción:

CD1.ShowColor

El cuadro de diálogo presentado tiene esta forma:

(La parte derecha del cuadro puede no salir. Depende del valor de la propiedad Flags. Se saca haciendo click en Definir colores
personalizados, si está activado. También depende de la propiedad Flags)
El número correspondiente al color elegido se puede conocer analizando la propiedad color de cuadro de diálogo. En nuestro ejemplo, lo
obtendríamos con

Variablecolor = CD1.Color

donde Variablecolor contendrá un número correspondiente al color elegido.

Nota acerca del número del color.

Para establecer un color por medio de código, se pondrá un valor de color a la propiedad correspondiente de ese objeto. El valor del color
puede establecerse de tres formas que se comentan a continuación.

Colores en Visual Basic.

Visual Basic acepta para especificar un color, tres procedimientos: Mediante el número de color, mediante la sentencia RGB ( rojo, verde,
azul ) o mediante la función QBColor.

Por número

El número que representa el color en VB está formado por la suma de la componente roja, la componente verde y la componente azul.
Podríamos verlo muy bien en numeración Hexadecimal:

Color = Hex XX YY ZZ

Donde ZZ es un número Hexadecimal que representa la cantidad del color rojo. El mínimo estaría en 0 (H00) y el máximo en 255 (HFF)

YY representaría la cantidad de color verde y XX la de color azul, ambos con los mismos límites explicados para el rojo.

Por ejemplo: el rojo puro sería: Hex(0000FF) = 255


el verde puro sería: Hex(00FF00) = 652280
el azul puro sería: Hex(FF0000) = 16711680

Una mezcla de un poco de rojo (HB1), otro poco de verde (H56) y otro poco de azul (H1F) daría el siguiente número:

Hex(1F56B1) = 2053809
El número de color puede estar comprendido entre 0 (correspondiente al negro) y el 16777215 (correspondiente al blanco. Observe que
esa cantidad, 16.777.215 (FFFFFF en hexadecimal) corresponde a los famosos 16 millones de colores de las tarjetas gráficas.

Si queremos poner el color de fondo a un control Label, usaremos la propiedad Backcolor. Si el Label se llama Label1, pondríamos la
instrucción

Label1.Backcolor = 12345678

Por la sentencia RGB

Se puede expresar el color, poniendo simplemente RGB (rojo, verde, azul), donde rojo es un número entre 0 y 255 que indica la cantidad de
color rojo que se aporta al color, verde un número comprendido entre 0 y 255 indicando la cantidad de verde, y lo mismo para azul.
Esta es la forma mas sencilla de poner la propiedad color, y con la que mejor controlaremos el mismo.

Si queremos poner al Label anterior un color mediante la sentencia RGB, ejecutaríamos la sentencia :

Label1.Backcolor = RGB (128, 30, 100)

Mediante la Función QBColor

Esta función se ha puesto en Visual Basic para compatibilidad con los colores que se usan en Quick-Basic y Qbasic. Mediante esta función
se obtienen solamente 16 colores.

Sintaxis Objeto.QBColor(color)

El argumento color es un número entero entre 0 a 15, según la siguiente lista:

Número Color Número Color

0 Negro 8 Gris
1 Azul 9 Azul claro
2 Verde 10 Verde claro
3 Aguamarina 11 Aguamarina claro
4 Rojo 12 Rojo claro
5 Fucsia 13 Fucsia claro
6 Amarillo 14 Amarillo claro
7 Blanco 15 Blanco brillante
Para el mismo Label anterior, usaríamos la sentencia :

Label1.Backcolor = QBColor (12)

Fin de la nota acerca del número del color

IMPRESORAS

Nota: Si utiliza un CommonDialog para impresoras y otras aplicaciones, puede tener problemas. Utilice un CommonDialog
exclusivamente para impresoras.

Para presentar el cuadro de elección de impresora, ejecute la instrucción:

CD2.ShowPrinter

(A este cuadro de dialogo le hemos llamado CD2 para evitar los problemas referidos en la nota).

Aparecerá el siguiente cuadro de diálogo:


La impresora elegida puede conocerla llamando a la propiedad DeviceName de un objeto que aún no hemos visto: el objeto Printer. Este
objeto es el encargado de pasar al Administrador de Impresión todos los trabajos de impresión que generen las aplicaciones Visual Basic:

Nombredelaimpresora = Printer.DeviceName

Para que la impresora quede como impresora por defecto de Windows, debe tener a True la propiedad PrinterDefault del cuadro de
diálogo.

En este cuadro puede observarse, que además de los botones de ACEPTAR y CANCELAR, existe otro, INSTALAR. Haciendo click en este,
podemos cambiar la impresora por cualquier otra que tenga instalada.

ABRIR Y GUARDAR ARCHIVOS

Posiblemente las opciones mas usadas del cuadro de diálogo. Para presentar el cuadro de diálogo correspondiente a Abrir Archivo, debe
ejecutar la instrucción:

CD1.ShowOpen

Si lo que necesita es abrir el cuadro de diálogo para guardar un fichero, debe ejecutar la instrucción :
CD1.ShowSave

pero antes deberá introducir el filtro o filtros de archivos que necesite. Ojo, ¡ ANTES !
Un filtro sirve para que en el cuadro de diálogo se presenten solamente los ficheros de nuestro interés. Se pueden seleccionar por el
nombre, la extensión o las dos cosas. La sintaxis para introducir un filtro es la siguiente:

CD1.Filter = "Descripción del fichero|nombre.extensión"

donde "nombre" puede ser un nombre o usar caracteres comodín. Lo mismo para "extensión"

Por ejemplo, para buscar archivos ejecutables, con cualquier nombre y extensión .EXE

CD1.Filter = "Ficheros ejecutables |*.exe"

Observe el carácter separador entre la descripción de los ficheros (Ficheros ejecutables) y el parámetro de busca (*.EXE). No ponga
ningún espacio entre el separador y los caracteres de busca. El separador es el carácter ASCII 124.
Puede buscar varios tipos de ficheros, separando los caracteres de busca por medio del carácter punto y coma (;)

CD1.Filter = "Ficheros ejecutables |*.EXE;*.COM;*.BAT"

Puede también introducir dos filtros, separados por el separador | (En una línea solamente).

CD1.Filter=”Ficheros de un tipo |*.EXE |Ficheros de otro |*.COM |Otros ficheros |*.BAT”

Por ejemplo : CD1.Filter = "Ficheros Word |*.DOC|Ficheros Write |*.WRI"

¡ No se pueden poner dos líneas con filtros, se quedaría solamente con la última !

En este caso, cuando se presente el cuadro de diálogo, solamente presentará uno de los filtros, y deberá seleccionar manualmente el otro
en un cuadro situado en la parte inferior izquierda del cuadro de diálogo. Para predeterminar cuál de los dos filtros saldrá sin tener que
seleccionarlo, deberá ejecutar esta instrucción, ANTES de invocar el cuadro de diálogo

CD1.FilterIndex = 2

En este caso, aparecerá por defecto el filtro escrito en segundo lugar. El orden de los filtros comienza por 1.

El cuadro de diálogo deberá presentar un directorio. Este directorio con el que, por defecto, aparece el cuadro de diálogo, se puede
introducir mediante la propiedad InitDir, que deberá contener el nombre del directorio y su path. Si no se especifica, comenzará por el
directorio actual.

Para conocer el nombre del fichero elegido, se emplea la propiedad FileName :

Nombrefichero= CD1.filename

El nombre del fichero, Nombrefichero en la sentencia anterior, viene con su path, es decir, nombre y dirección completa, por lo que puede
emplearse directamente la salida del CommonDialog para abrir un fichero.

El cuadro de diálogo de abrir o cerrar tiene esta forma :


El cuadro de guardar es similar. Observe que en este caso hemos desplegado la segunda opción de filtro de ficheros :
Como ve ambos cuadros son prácticamente iguales. Solamente se difieren en que uno pone Abrir y el otro Guardar como en su barra de
título. También en que el cuadro Guardar como presenta los nombres de los ficheros con un tono apagado. Funcionalmente difieren. Por
ejemplo, si quiere guardar un fichero con un nombre ya existente, y dependiendo de la propiedad Flags que verá mas adelante, le
aparecerá la siguiente advertencia :

Si desea otra leyenda en la barra de título, puede cambiarla usando el asistente de propiedades, que lo obtendrá colocando el cursor del
ratón sobre el icono del CommonDialog y pulsando el botón derecho. Haga click sobre Propiedades en el popmenú que se presenta.
Aparecerá esto :
PRESENTAR AYUDAS

Mediante el CommonDialog se puede presentar un fichero de ayuda. (Ficheros del tipo .HLP de Windows)

Pese a que se pueden presentar estos ficheros basándonos en el CommonDialog, es preferible usar directamente el programa
WinHelp.Exe, que puede ejecutarlo mediante la función Shell :

VariableID = Shell (“WinHelp.Exe FicheroAyuda.hlp”,1)

Para mostrar el fichero de ayuda debe poner el nombre (y Path) del fichero de ayuda en la propiedad HelpFile del CommonDialog

CD1.HelpFile = "C:\MiCarpeta\MiFicheroAyuda.HLP"

Puede mostrar el índice, o una página concreta de ese fichero. Para ello debe jugar con la propiedad HelpCommand, que le va a indicar al
CommonDialog qué ayuda debe mostrar.

CD1.HelpCommand =Valor
Las opciones para valor son:

1 &H1 cdlContext
Muestra la Ayuda de un contexto determinado. Cuando se usa esta valor, también se debe especificar un contexto con la propiedad
HelpContext.
2 &H2 cdlQuit
Notifica a la aplicación Ayuda que el archivo de Ayuda especificado ya no se está utilizando.
3 &H3 cdlContents
Muestra el tema de contenido de ayuda, definido con la opción Contents de la sección [OPTION] del archivo .HPJ.
3 &H3 cdlIndex
Muestra el índice del archivo de Ayuda especificado. Las aplicaciones sólo deben utilizar este valor para un archivo de Ayuda con
índice único.
4 &H4 cdlHelpOnHelp
Muestra la Ayuda para utilizar la propia aplicación Ayuda.
5 &H5 cdlSetContents
Determina el tema de contenido a mostrar cuando el usuario presiona la tecla F1.
5 &H5 cdlSetIndex
Establece el contexto especificado en la propiedad HelpContext como índice actual para el archivo especificado en la propiedad
HelpFile. Este índice seguirá siendo el actual hasta que el usuario acceda a un archivo de Ayuda distinto. Utilice este valor sólo
para los archivos de Ayuda con más de un índice.
8 &H8 cdlContextPopup
Muestra en una ventana emergente un tema de Ayuda determinado, identificado por un número de contexto definido en la sección
[MAP] del archivo .HPJ.
9 &H9 cdlForceFile
Asegura que WinHelp muestre el archivo de Ayuda correcto. Si se muestra el archivo correcto, no sucede nada. Si se muestra un
archivo incorrecto, WinHelp abrirá el correcto.
257 &H101 cdlKey
Muestra la Ayuda sobre una palabra reservada determinada. Al usar esta opción, deberá especificar también una palabra reservada
con la propiedad HelpKey.
258 &H102 cdlCommand
Ejecuta una macro de Ayuda.
261 &H105 cdlPartialKey
Muestra el tema de la lista de palabras claves que coincide con la palabra pasada en el parámetro dwData, si sólo se encuentra
uno. Si se encuentra más de uno, aparecerá el cuadro de diálogo Buscar mostrando los temas encontrados en el cuadro de lista Ir
a. Si no se encuentra ninguno, se mostrará el cuadro de diálogo Buscar. Para que aparezca el cuadro de diálogo Buscar sin pasar
una palabra reservada, utilice un puntero largo a una cadena vacía.
Si queremos que se muestre el índice de la ayuda, pondríamos esta propiedad de la forma :

CD1.HelpCommand = cdlHelpIndex

Para mostrar la página que se ha puesto en el fichero de ayuda como Contexto 2 (En Sección [MAP] del fichero .HPJ (Vea Creación de
Ficheros de Ayuda),

CD1.HelpCommand = cdlHelpContext
CD1.HelpContext = 2

Para mostrar la Ayuda de la Ayuda de Windows :

CD1.HelpCommand = cdlHelpHelpOnHelp

Una vez establecidas estas propiedades, mostraremos la ayuda con el Método ShowHelp

CD1.ShowHelp

Repitiéndole que no se debe usar el CommonDialog para mostrar ayudas, pero para cumplir el objetivo de plasmar en este texto la mayor
información acerca de cada control, se enumeran a continuación el resto de propiedades que afectan a la presentación de ayuda :

HelpFile
HelpContext
HelpKey

PROPIEDADES DEL CommonDialog

La Propiedad Action

La propiedad Action se incluye en la versión 4 de VB solamente por motivos de compatibilidad con anteriores versiones. Realiza las mismas
funciones que ShowFont, ShowColor, ShowPrinter, ShowOpen y ShowSave. No debe usarse esta propiedad, sino los equivalentes
citados, en previsión de que pueda ser eliminada en futuras versiones.

La sintaxis de Action es : Nombre.Action [= valor]


Valor Descripción

0 Ninguna acción.
1 Muestra el cuadro de diálogo Abrir.
2 Muestra el cuadro de diálogo Guardar como.
3 Muestra el cuadro de diálogo Color.
4 Muestra el cuadro de diálogo Fuente.
5 Muestra el cuadro de diálogo Impresora.
6 Ejecuta WINHELP.EXE.

NO utilice la propiedad Action. Utilice en su lugar ShowFont, ShowPrinter, ShowSave, ShowOpen , ShowColor y ShowHelp

CancelError

Devuelve o establece un valor que indica si se genera un error cuando el usuario elige el botón Cancelar.

Sintaxis: objeto.CancelError = (True / False)

True Se genera un error.


False (Predeterminado) No se genera ningún error.

Cuando se establece True en esta propiedad, se producirá el error número 32755 (cdlCancel) cada vez que el usuario elija el botón
Cancelar.

Debe poner esta propiedad a true cuando quiera detectar que se ha pulsado el botón CANCELAR. Luego, debe detectar con la
rutina de detección de errores adecuada, si el error producido ha sido el 32755. De ser así, es que han pulsado ese botón, y Vd.
procederá en consecuencia.

Color
Esta propiedad es de lectura / escritura
De escritura :Establece el color predeterminado con que aparecerá el CD para elegir
color. Puede introducirse como RGB o numéricamente, como se explicó mas atrás. Para que aparezca este color predeterminado,
debe poner la propiedad Flags a 1.
De lectura : Entrega el color elegido, bien en el cuadro de elección de color, bien en el
cuadro de elección de fuente.
Copies
Establece el valor predeterminado para número de copias que aparecerá en el CD cuando se abra para elegir impresora.

DefaultExt
Devuelve o establece la extensión de archivo predeterminada para el cuadro de diálogo.

Sintaxis objeto.DefaultExt [= cadena]

Puede utilizar esta propiedad para especificar una extensión de archivo predeterminada, como por ejemplo .TXT o .DOC.
Importante para el CommonDialog de Guardar: Cuando se guarde un archivo sin extensión, se le agregará automáticamente la
especificada en esta propiedad.

DialogTitle
Devuelve o establece la cadena mostrada en la barra de título del cuadro de diálogo.

Sintaxis Nombre.DialogTitle [= título]

Esta propiedad puede introducirse en la ventana de propiedades, o por programa. Puede utilizar esa propiedad para mostrar el
nombre del cuadro de diálogo en la barra de título.

Nota El control CommonDialog ignora el valor de la propiedad DialogTitle cuando muestra los cuadros de diálogo Color o Fuente.

El título predeterminado para un cuadro de diálogo Abrir es Abrir, y para un cuadro de diálogo Guardar como es Guardar como.

FileName
Devuelve o establece la ruta y el nombre de archivo de un archivo seleccionado. La lectura de esta propiedad devuelve el nombre
del archivo seleccionado actualmente en la lista. Si no hay ningún archivo seleccionado, FileName devuelve una cadena vacía.

Filter
(Explicada mas atrás)

Devuelve o establece los filtros que aparecen en el cuadro de lista Tipo de un cuadro de diálogo.

Sintaxis CD1.Filter [= descripción1 |filtro1 |descripción2 |filtro2...]

Utilice el símbolo de canalización ( | , (ASCII 124) ) para separar los valores de descripción y de filtro. No incluya espacios antes ni
después del símbolo de canalización, pues aparecerían en los valores de descripción y valor.
Al especificar más de un filtro en un cuadro de diálogo, utilice la propiedad FilterIndex para especificar el filtro predeterminado.

Nota para los que no tiene teclado de 102 teclas. Para obtener el carácter ASCII 124, pulse la tecla ALT y, sin dejar de pulsarla, teclee 124
en el teclado numérico.

FilterIndex
Devuelve o establece un filtro predeterminado para un cuadro de diálogo Abrir o Guardar Como.

Sintaxis CD1.FilterIndex [= número]

Esta propiedad indica el filtro predeterminado cuando se han especificado varios filtros para un cuadro de diálogo Abrir o Guardar.
El índice del primer filtro definido es 1.

Flags Propiedad que tiene distintos significados para cada tipo de cuadro de diálogo.
Tiene la misma sintaxis para todos los cuadros.

Sintaxis CD1.Flags [= valor]

El parámetro valor establece distintas alternativas, dependiendo de cada cuadro.

Para el cuadro de diálogo Color

Las opciones para valor son:

1 &H1& cdlRGBInit
Establece como valor de color inicial para el cuadro de diálogo el indicado en su propiedad Color.

2 &H2& cdlFullOpen
Hace que el cuadro de diálogo se muestre completo al crearlo, incluyendo la sección que permite al usuario crear colores
personalizados. Sin esta opción, el usuario debe elegir el botón de comando Definir colores personalizados para mostrar tal
sección.

4 &H4& cdlPreventFullOpen
Desactiva el botón de comando Definir colores personalizados, evitando que el usuario defina colores.
8 &H8& cdlShowHelp
Hace que el cuadro de diálogo muestre un botón Ayuda.

Se pueden poner varias de estas condiciones, poniendo como valor Flags la suma de los valores de cada una de las condiciones a poner.

Para los cuadros Abrir y Guardar

Las opciones para valor son:

1 &H1& cdlReadOnly
Hace que la casilla de verificación Sólo lectura aparezca marcada inicialmente al crear el cuadro de diálogo. Este indicador también
señala el estado de la casilla Sólo lectura cuando el cuadro de diálogo está cerrado.
2 &H2& cdlOverwritePrompt
Hace que el cuadro de diálogo Guardar como genere un cuadro de mensaje si el archivo seleccionado ya existe. El usuario deberá
confirmar que desea sobrescribir el archivo.
4 &H4& cdlHideReadOnly
Oculta la casilla de verificación Sólo lectura.
8 &H8& cdlNoChangeDir
Hace que el cuadro de diálogo restablezca como directorio actual el que lo era en el momento de abrirse.
16 &H10& cdlShowHelp
Hace que el cuadro de diálogo muestre el botón Ayuda.
256 &H100& cdlNoValidate
Especifica que el cuadro de diálogo común permita caracteres no válidos en el nombre de archivo devuelto. Funciona tanto con el
cuadro de Abrir como con el de Cerrar. Tenga cuidado a la hora de crear un archivo con nombre no válido !
512 &H200& cdlAllowMultiselect
Especifica que el cuadro de lista Nombre de archivo admita selecciones múltiples. El usuario puede seleccionar más de un archivo
en tiempo de ejecución presionando la tecla MAYÚS y utilizando las teclas FLECHA ARRIBA y FLECHA ABAJO para seleccionar
los archivos deseados. Al hacerlo, la propiedad FileName devolverá una cadena con los nombres de todos los archivos
seleccionados. Los nombres están delimitados en la cadena con espacios.
1024 &H400& cdlExtensionDifferent
Indica que la extensión del nombre de archivo devuelto es distinta de la especificada en la propiedad DefaultExt. Este indicador no
estará activado si la propiedad DefaultExt es Null, si las extensiones coinciden, o si el archivo no tiene extensión. El valor de este
indicador puede comprobarse al cerrar el cuadro de diálogo.
2048 &H800& cdlPathMustExist
Especifica que el usuario sólo pueda introducir una ruta de acceso válida. Si se establece este indicador y el usuario introduce una
ruta no válida, aparecerá un mensaje de advertencia.
4096 &H1000& cdlFileMustExist
Especifica, para el cuadro de Abrir, que el usuario sólo pueda escribir en el cuadro de texto Nombre de archivo nombres de
archivos existentes. Si este indicador está activado y el usuario introduce un nombre de archivo no válido, aparecerá una
advertencia. Este indicador activa automáticamente cdlPathMustExist.
8192 &H2000& cdlCreatePrompt
Especifica, para el cuadro de diálogo de abrir, que si no existe el fichero consulte al usuario antes de crear un archivo que no existe
actualmente. Esta advertencia dice : Este Archivo no existe ¿desea crearlo ? y aparecen los botones de ACEPTAR y CANCELAR.
Si el usuario pulsa aceptar el CommonDialog se cierra normalmente, si se le pulsa CANCELAR desaparece esta advertencia y el
CommonDialog espera a que se le escriba o seleccione otro fichero. Este indicador establece automáticamente los indicadores
cdlPathMustExist y cdlFileMustExist.
16384 &H4000& cdlShareAware
Especifica que se ignoren los errores al compartir archivos.

32768 &H8000& cdlNoReadOnlyReturn


Especifica que el archivo devuelto no tenga el atributo de Sólo lectura ni esté en un directorio protegido contra escritura. Presenta
un aviso (tanto en el cuadro de abrir como en el cerrar) que impide elegir un fichero de estas características.

Se pueden poner varias de estas condiciones, poniendo como valor Flags la suma de los valores de cada una de las condiciones a poner.

Para el cuadro Mostrar Fuentes:

Las opciones para valor son:

1 &H1& cdlScreenFonts
Hace que el cuadro de diálogo muestre solamente las fuentes de pantalla que admite el sistema.
2 &H2& cdlPrinterFonts
Hace que el cuadro de diálogo muestre solamente las fuentes que admite la impresora, especificadas por la propiedad hDC.

3 &H3& cdlBoth
Hace que el cuadro de diálogo muestre las fuentes de impresora y de pantalla disponibles. La propiedad hDC identifica el contexto
de dispositivo asociado a la impresora
4 &H4& cdlShowHelp
Hace que el cuadro de diálogo muestre un botón Ayuda.
256 &H100& cdlEffects
Especifica que el cuadro de diálogo permita efectos de tachado, subrayado y color.
1024 &H400& cdlANSIOnly
Especifica que el cuadro de diálogo sólo permita seleccionar las fuentes que utilizan el juego de caracteres de Windows. Si se
establece este indicador, el usuario no podrá seleccionar una fuente que sólo contenga símbolos.
2048 &H800& cdlNoVectorFonts
Especifica que el cuadro de diálogo no permita seleccionar fuentes vectoriales.

4096 &H1000& cdlNoSimulations


Especifica que el cuadro de diálogo no permita simulaciones de fuente de interfaz de dispositivo gráfico (GDI).

8192 &H2000& cdlLimitSize


Especifica que el cuadro de diálogo seleccione sólo los tamaños de fuente comprendidos en el rango especificado por las
propiedades Min y Max.

16384 &H4000& cdlFixedPitchOnly


Especifica que el cuadro de diálogo seleccione sólo fuentes de espaciado fijo.
32768 &H8000& cdlWYSIWYG
Especifica que el cuadro de diálogo permita seleccionar solamente fuentes disponibles al la vez en la pantalla y en la impresora. Si
se establece este indicador, también deben establecerse cdlBoth (sume 3 a este número) y cdlScalableOnly (sume 131072 a este
número)

65536 &H10000& cdlForceFontExist


Especifica que aparezca un cuadro de mensaje cuando el usuario intente seleccionar una fuente o un estilo que no existan.
131072 &H20000& cdlScalableOnly
Especifica que el cuadro de diálogo permita seleccionar solamente fuentes escalables.

262144 &H40000& cdlTTOnly


Especifica que el cuadro de diálogo permita seleccionar solamente fuentes TrueType.

Nota Antes de mostrar el cuadro de diálogo Fuentes, debe establecer cdlScreenFonts,


cdlPrinterFonts o cdlBoth en la propiedad Flags. En caso contrario, se producirá el error No hay fuentes. (O dicho de otra forma, Flags=1, 2
ó 3)

Se pueden poner varias de estas condiciones, poniendo como valor Flags la suma de los valores de cada una de las condiciones a poner.

Para el Cuadro de Diálogo Imprimir

(Observará seguramente que lo que se describe a continuación no se cumple siempre. Depende de las impresoras que tenga Vd.
instaladas)
Las opciones para valor son:

0 &H0& cdlAllPages
Devuelve o establece el estado del botón de opción Todas las páginas.
1 &H1& cdlSelection
Devuelve o establece el estado del botón de opción Selección. Si no se especifica cdlPageNums ni cdlSelection, el botón
de opción Todas estará seleccionado.
2 &H2& cdlPageNums
Devuelve o establece el estado del botón de opción Páginas.
4 &H4& cdlNoSelection
Desactiva el botón de opción Selección.
8 &H8& cdlNoPageNums
Desactiva el botón de opción Páginas y el control de edición asociado.
16 &H10& cdlCollate
Devuelve o establece el estado de la casilla de verificación Intercalar.
32 &H20& cdlPrintToFile
Devuelve o establece el estado de la casilla de verificación Imprimir a un archivo.
64 &H40& cdlPrintSetup
Hace que el sistema muestre el cuadro de diálogo Configurar impresora en lugar de Imprimir. Use este Flag cuando lo que
desea es cambiar la impresora predeterminada.
128 &H80& cdlNoWarning
Evita que aparezca una advertencia cuando no hay una impresora predeterminada.

256 &H100& cdlReturnDC


Devuelve un contexto de dispositivo para la impresora seleccionada en el cuadro de diálogo. El contexto se devuelve en la
propiedad hDC del cuadro de diálogo.
512 &H200& cdlReturnIC
Devuelve un contexto de información para la impresora seleccionada en el cuadro de diálogo. Un contexto de información
proporciona un método rápido de obtener información sobre el dispositivo sin crear un contexto de dispositivo. El contexto
de información se devuelve en la propiedad hDC del cuadro de diálogo.
2048 &H800& cdlShowHelp
Hace que el cuadro de diálogo muestre el botón Ayuda
262144 &H40000& cdlUseDevModeCopies
Si un controlador de impresora no admite copias múltiples, al establecer este indicador se desactiva el control de edición de
número de copias. Si el controlador sí admite múltiples copias, al establecer este indicador el cuadro de diálogo almacenará
el número de copias solicitado en la propiedad Copies.
524288 &H80000& cdlDisablePrintToFile
Desactiva la casilla de verificación Imprimir a un archivo.
1048576 &H100000& cdlHidePrintToFile
Oculta la casilla de verificación Imprimir a un archivo.

Propiedades que afectan al tipo de letra.

Las seis propiedades siguientes nos dan las características especiales de la fuente elegida (negrita, cursiva, etc.). Una vez seleccionado el
tipo de letra, el valor de estas propiedades contiene la opción elegida para la letra (si FontBold=True es que hemos elegido negrita, etc.)

FontBold
Propiedad Booleana que establece o devuelve que el tipo de letra usado es Negrita.

Sintaxis Variable = CD1.FontBold

Los valores de Variable son:

True Se ha elegido negrita False (Predeterminado) No se ha elegido negrita.

FontItalic
Propiedad Booleana que establece o devuelve que el tipo de letra usado es Cursiva.

Sintaxis Variable = CD1. FontItalic

Los valores de Variable son:

True si se ha elegido cursiva, False (Predeterminado) en caso contrario.

FontStrikethru
Propiedad Booleana que establece o devuelve que el tipo de letra usado es Tachada.

Sintaxis Variable = CD1. FontStrikethru

Los valores de Variable son:

True si se ha elegido tachado, False (Predeterminado) en caso contrario.


FontUnderline
Propiedad Booleana que establece o devuelve que el tipo de letra usado es Subrayado.

Sintaxis Variable = CD1.FontUnderline

Los valores de Variable son:

True, si se ha elegido subrayado, False (Predeterminado) en caso contrario

FontName

Devuelve el nombre de la fuente elegida. Es una variable tipo String

Sintaxis Variable = CD1.FontName

(Variable toma el valor del nombre de la fuente. Por ejemplo, Variable = “Arial”

En general, deberá modificar FontName antes de establecer los atributos de tamaño y estilo con las propiedades FontSize,
FontBold, FontItalic, FontStrikethru y FontUnderline.

Nota En tiempo de ejecución puede obtener información sobre las fuentes disponibles a través de las propiedades FontCount y
Fonts. Lo verá mas adelante

FontSize

Devuelve de la fuente elegida. Debe ser una variable tipo Integer o Long

Sintaxis Variable = CD1.FontSize

donde Variable será una expresión numérica que especifica el tamaño de fuente a utilizar, en puntos.

Nota Las fuentes disponibles en Visual Basic varían dependiendo de la configuración del sistema y de los dispositivos de
presentación e impresión. En las propiedades relacionadas con las fuentes sólo pueden establecerse valores para los que exista
una fuente.

En general, deberá modificar FontName antes de establecer los atributos de tamaño y estilo con las propiedades FontSize,
FontBold, FontItalic, FontStrikethru y FontUnderline. Sin embargo, cuando especifique un tamaño inferior a 8 puntos para una
fuente TrueType, primero deberá establecer el tamaño en puntos con la propiedad FontSize, luego especificar la propiedad
FontName y después establecer de nuevo el tamaño con FontSize. El entorno operativo Microsoft Windows utiliza una fuente
distinta para las fuentes TrueType con un tamaño inferior a 8 puntos.

Index

Igual que el ya estudiado para otros controles.

InitDir
Devuelve o establece el directorio de archivos inicial.

Sintaxis objeto.InitDir [= cadena]

La sintaxis de la propiedad InitDir consta de las siguientes partes:

objeto Nombre que define al CommonDialog


cadena Expresión de cadena que especifica el directorio de archivos inicial.

Si no se especifica esta propiedad, se utilizará el directorio actual.

Left y Top

Estas propiedades solamente afectan a la colocación del icono en el formulario. No afectan a la colocación del CommonDialog
durante la ejecución. La posición del CommonDialog en tiempo de ejecución no puede controlarse.

Esta afirmación de que la posición del CommonDialog no es controlable es válida para sistemas a 32 bytes. En VB 4 de 16 bits, el
CommonDialog aparece aproximadamente en la parte superior izquierda del formulario que lo contiene. Algunos programadores
han optado por poner un formulario para contener solamente al CommonDialog, y así, controlando la posición de ese formulario,
poder controlar la posición (aproximada) en la que aparece el CD.

Esto no ocurre para sistemas a 32 bytes, en los que el CD aparece siempre en la parte superior izquierda de la pantalla,
independientemente de donde esté el formulario que lo contiene.

MaxFileSize
Devuelve o establece el tamaño máximo del nombre de archivo abierto con el control CommonDialog.

Sintaxis objeto.MaxFileSize [= valor]

La sintaxis de la propiedad MaxFileSize consta de las siguientes partes:

objeto = Nombre que define al CommonDialog


valor = Número entero que especifica el tamaño máximo del nombre de archivo en bytes. El rango de esta propiedad es 132KB. El
valor predeterminado es 256.

Name
Nombre que define al CommonDialog

PrinterDefault

Devuelve o establece una opción que determina si la configuración elegida por el usuario en el cuadro de diálogo Imprimir se utiliza
para modificar la configuración predeterminada de impresora del sistema.

Sintaxis objeto.PrinterDefault [= valor]

objeto = Nombre que define al CommonDialog


valor = Expresión booleana que especifica si lo seleccionado por el usuario se utiliza para modificar la configuración de impresora
predeterminada del sistema, según se indica en Configuración.

Las opciones para valor son:

True Las opciones que elija el usuario en el apartado Configurar del cuadro de diálogo Imprimir (selección de la impresora,
orientación, etcétera) se utilizan para modificar la configuración de impresora en el archivo WIN.INI del usuario. (En el sistema
operativo Windows NT, esta información se almacena en el Registro).
False Las opciones que elija el usuario no se utilizan para modificar la configuración de impresora predeterminada del sistema.

Utilice esta propiedad, que por defecto está a True, para poner o no poner como impresora predeterminada, la impresora
seleccionada con el CommonDialog. Puede por ejemplo, querer imprimir un texto en una impresora determinada, pero solo ese
texto, y no quiere cambiar la impresora predeterminada por el hecho de haber seleccionado en este momento otra impresora.
Ponga esta propiedad a False (recuerde que por defecto está a True) para que la impresora seleccionada no se quede como
impresora por defecto.
Tag
Lo mismo que se ha explicado para otros controles.

CONTROLES PARA MOSTRAR IMAGENES


_____________________________________

Una imagen representa una figura, bien natural (tipo fotografía) o sintética. Para presentar una imagen es necesario hacerlo sobre un objeto
que la admita. Los objetos que admiten una imagen son:

 Formularios
 PictureBox
 Image

Existen mas controles gráficos que se irán viendo a lo largo del curso. Estos tres son los mas usados y con los que comenzaremos a
trabajar.

Para mostrar una imagen en cualquiera de estos objetos, es necesario especificarlo en su propiedad Picture. La forma de especificarle al
objeto la imagen que debe presentar puede hacerse de dos formas:

 En la caja de propiedades, si no se va a variar la imagen durante la aplicación.


 Mediante una instrucción para cambiar esta propiedad. La instrucción es la siguiente:

Nombreobjeto.Picture = LoadPicture (Path, Fichero)

Por ejemplo, si tenemos un formulario llamado Form1 y queremos rellenarlo con una imagen contenida en el fichero de Windows metafile
DOLLAR.WMF que se encuentra en el directorio C:\VB\METAFILE\BUSINESS, deberemos ejecutar la instrucción:

Form1.Picture = LoadPicture (“C:\VB\METAFILE\BUSINESS\DOLLAR.WMF”)

Para "descargar" esa imagen de ese formulario, basta con ejecutar la misma instrucción sin fichero alguno:

Form1.Picture = LoadPicture ( )

También pueden tomar la imagen desde otro control de imagen, mediante un procedimiento de Intercambio Dinámico de Datos (DDE)
(Solo el PictureBox)
Puede también meter una imagen en una variable, y luego poner en uno de los controles citados anteriormente la imagen guardada en la
variable. Este método es muy rápido, ya que no necesita acceder al disco para buscar una imagen, pero emplea mucha memoria RAM, ya
que la variable )o variables conteniendo la(s) imágenes están en la RAM.

Para ello debemos declarar una o varias variables tipo Picture, y meter en ellas una imagen mediante el método LoadPicture. Vea en el
capitulo 7 (Métodos Gráficos - Método LoadPicture) un ejemplo muy ilustrativo.

EL FORMULARIO
Ya hemos visto lo que es el Formulario. Simplemente podemos añadir a lo ya dicho, que un formulario tiene la propiedad Picture, con lo que
podemos poner como fondo un bit-map, un fichero de icono ( .ICO) o un Metarchivo (.WMF). Un fondo gráfico sobre el Formulario puede
convertir una aplicación de buena a excelente. No intente nunca mejorar una aplicación mediocre con un fondo artístico en un Formulario.

CONTROL PICTURE BOX

Este objeto se encuentra en la caja de herramientas estándar:

Este objeto permite presentar todo tipo de ficheros gráficos (.BMP, WMF, .ICO, .CUR)

Las dimensiones del PictureBox se establecen en el diseño o mediante programa, variando las propiedades Height y Width. También
puede cambiarse su posición mediante las propiedades Top y Left. Dispone de una propiedad, Align que permite colocarlo adosado a uno
de los lados del formulario que lo contiene.

El Control PictureBox puede ser destino de los datos de un enlace DDE. (Los datos serán, lógicamente, gráficos. Por ello, tiene las
propiedades LinkMode, LinkItem, LinkTimeout y LinkTopic.

También puede tomar el dato del gráfico de una Base de Datos. (A través de un control Data o un objeto Recordset)

Las propiedades de un PictureBox son:

Align Appearance Autoredraw Autosize Backcolor BorderStyle


ClipControls DataField DataSource DragIcon DragMode DrawStile
DrawWidth Enabled FillColor FiilStyle Font Fontransparent
ForeColor Height HelpContextID Index Left LinkItem
LinkMode LinkTimeout LinkTopic MouseIcon MousePointer Name
Negotiate Picture ScaleHeight ScaleLeft ScaleMode ScaleTop
ScaleWidth TabIndex TabStop Tag Top Visible
WhatThisHelp Width

Un PictureBox puede disponer de los siguientes procedimientos :

Click Change DblClick DragDrop DragOver GotFocus


KeyDown KeyPress

CONTROL IMAGE

Este control se encuentra en la caja de herramientas estándar:

Este control permite presentar todo tipo de ficheros gráficos (.BMP, WMF, .ICO, .CUR)

El control Image no puede ser destino de una comunicación DDE. Puede tomar la imagen de una base de datos, bien a través de un control
Data o a través de un objeto Recordset.

El control Image utiliza menos recursos del sistema y repinta con más rapidez que un control PictureBox, pero sólo admite una parte de las
propiedades, los eventos y los métodos de PictureBox. Use la propiedad Stretch para determinar si el gráfico se escala para que se ajuste
al control o viceversa. Poniendo esta propiedad a True el gráfico se adaptará a las dimensiones del control Image. Si se pone a False, el
control Image tomará las medidas del gráfico que contenga. Si el gráfico es un bit-map (Fichero .BMP), con la propiedad Stretch a True
podemos variar el tamaño del bit-map, variando las propiedades Width y Height del control Image, propiedades que se pueden cambiar en
tiempo de ejecución. Si esta propiedad está a False, el tamaño del bit-map no cambiará, presentándose solamente una porción del bit-map,
caso que el control Image sea menor que el tamaño del bit-map, o sobrará espacio en el control, en caso contrario. Aunque puede colocar
un control Image en un contenedor, un control Image no puede actuar como contenedor. Esto se entiende mejor con un ejemplo. Prepare
un formulario con un PictureBox y con un control Image. Introduzca dos OptionButton en cada uno de ellos, y otro en otra parte del
formulario, fuera de ambos. Ejecute la aplicación. Los OptionButton colocados dentro del PictureBox se comportan entre ellos
independientes de los otros tres OptionButton presentes en el formulario, exactamente igual que si se les hubiera introducido en un Frame.
Los controles colocados dentro del control Image cambian formando conjunto con el que se colocó en el formulario, fuera de los dos
controles. El PictureBox funciona como un contenedor de esos dos OptionButton que tiene en su interior, mientras que el control Image,
no. (Vea el ejemplo del capítulo 2, Oficina de cambio de divisas)

Un Image es transparente, es decir, deja ver el fondo del formulario en las partes no ocupadas por su gráfico. Por lo tanto, no tendrían
sentido en este control propiedades como Backcolor, FillColor, o FillStyle.

Las propiedades de un Image son:

Appearance BorderStyle Datafield DataSource DragIcon DragMode


Enabled Height Index Left MouseIcon MousePointer Name Picture Stretch
Tag Top Visible
WhatThisHelp Width

Un Image puede disponer de los siguientes procedimientos :

Click DblClick DragDrop DragOver GotFocus MouseDown


MouseMove MouseUp

PROPIEDADES DE LOS CONTROLES PictureBox e Image

Align (PictureBox solamente)

Permite colocar el control en el borde superior (Align Top), en el inferior (Align Bottom), en el izquierdo (Align Left) o en el
derecho (Align Right) del formulario que lo contiene. Para no alinearlo con ningún borde basta con poner la propiedad Align a
0-None.

Cuando se adosa a uno de los bordes, el tamaño del control se ajusta automáticamente a la anchura o altura del formulario.

Sintaxis
NombrePictureBox.Align [= número]
número Un entero que especifica cómo se presenta el control. Puede tomar los siguientes valores :

0-None (Predeterminado cuando el control se coloca en un formulario no MDI). Con este valor, el
control mantiene el tamaño y la posición asignada en tiempo de diseño.
1-Top (Predeterminado cuando el control se coloca en formularios MDI) El control se coloca en la parte
superior del formulario y su anchura es igual a la anchura del formulario.
2-Bottom El control se coloca en la parte inferior del formulario y su anchura es igual a la anchura del
formulario.
3-Left El control se coloca en la parte izquierda del formulario y su altura es igual a la altura del
formulario.
4-Right El control se coloca en la parte derecha del formulario y su altura es igual a la altura del
formulario.

Se puede usar propiedad Align para crear rápidamente una barra de herramientas o una barra de estado en la parte superior o
inferior de un formulario. Cuando un usuario cambie el tamaño del formulario, un control con la propiedad Align establecida a 1
ó 2 modificará su tamaño de forma automática para ajustarse a la anchura del formulario.

De la misma forma se puede crear barras de herramientas a los lados izquierdo o derecho de un formulario. Si en un formulario
hay dos barras de herramientas, una en la parte superior (o inferior) y otra en un lateral, la de la parte superior o inferior es la
que se extiende hasta la esquina, teniendo preferencia sobre las colocadas verticalmente a la izquierda o a la derecha.

Al ser el PictureBox un contenedor, puede poner un PictureBox en la parte superior de un Formulario, y colocar en este
PictureBox varios controles Image, a los que se les puede poner un icono. De esta forma realizamos una barra de
herramientas.

Negotiate (PictureBox solamente)

Establece un valor que determina si se muestra un control que puede alinearse cuando un objeto activo del formulario muestra
una o más barras de herramientas. No está disponible en tiempo de ejecución.

La propiedad Negotiate puede tener los valores True o False:

True Si el control se alinea en el formulario (la propiedad Align se establece como un valor no cero), el control
permanecerá visible cuando un objeto activo del formulario muestre una barra de herramientas.
False (Predeterminado) El control no se muestra cuando un objeto activo del formulario muestra una barra de
herramientas. La barra de herramientas del objeto activo se muestra en lugar del control.
Appearance (PictureBox e Image) 3D o Flat, como en otros controles

Autoredraw (PictureBox solamente)

Permite que el Formulario o PictureBox (El control Image no tiene esta propiedad), mantenga siempre la imagen presente. Si
Autoredraw está a False, el control no presentará las imágenes que no se hayan dibujado realmente (caso por ejemplo de un
formulario minimizado) o que se hayan borrado por haber sido puestas tras otro control.

Sintaxis objeto.AutoRedraw [= valor]

Los valores posibles de valor son:

True Activa el redibujado automático de un control PictureBox. Los gráficos y el texto se escriben en la pantalla y en una
imagen almacenada en memoria. El control no recibe eventos Paint; se vuelve a dibujar cuando es necesario, usando la imagen
almacenada en memoria.

False (Predeterminado) Desactiva el redibujado automático de un control y escribe los gráficos y el texto solamente en la
pantalla. Visual Basic invoca el evento Paint del control cuando se necesita volver a dibujar dicho control.

Autosize (PictureBox solamente)

Devuelve o establece un valor que determina si el tamaño de un control se cambia automáticamente para presentar su
contenido completo.

Sintaxis objeto.AutoSize [= valor]

Los valores posibles de valor son:

True El tamaño se cambia automáticamente para presentar el contenido completo.


False (Predeterminado) Mantiene constante el tamaño del control. El contenido se recorta cuando excede el área del
control.

BackColor (PictureBox solamente)

Color de fondo. Igual que otros controles

BorderStyle (PictureBox e Image)


Tipo de borde. Ninguno o fijo. Igual que otros controles.

ClipControls (PictureBox solamente)

Devuelve o establece un valor que determina si los métodos gráficos en eventos Paint vuelven a dibujar el objeto entero o
solamente las áreas últimamente expuestas. También determina si el entorno operativo Microsoft Windows crea una zona de
recorte que excluya los controles no gráficos contenidos en el objeto. En tiempo de ejecución es de sólo lectura.

Sintaxis objeto.ClipControls [= booleano]

Los valores posibles de booleano son:

True (Predeterminado) Los métodos gráficos de los eventos Paint vuelven a dibujar completamente el objeto. Antes del
evento Paint se crea una zona de recorte alrededor de los controles no gráficos del formulario.
False Los métodos gráficos de los eventos Paint solamente vuelven a dibujar las partes recién expuestas. Antes del
evento Paint no se crea una zona de recorte alrededor de los controles no gráficos. Los formularios complejos se cargan
normalmente más rápido cuando ClipControls está establecido a False.

DataField (PictureBox e Image)

Devuelve o establece un valor que indica el nombre del campo de una Base de datos de donde se tomará la imagen a
presentar. (Vea controles enlazados a datos)

Sintaxis objeto.DataField =NombredelCampo

Para poder presentar una imagen contenida en una base de datos, el control
PictureBox o Image deben estar enlazados a una base de datos mediante un control
Data.

DataSource (PictureBox e Image)

Establece un valor que especifica el control Data a través del cual el control Picture ó Image se enlaza a una base de datos. No
está disponible en tiempo de ejecución.

Verá esto con mas detalles cuando estudie los Objetos enlazados a Datos.

DragIcon
DragMode (PictureBox e Image) Igual que otros controles
DrawMode (PictureBox solamente)

Devuelve o establece un valor que determina el aspecto de la salida de un método gráfico.

DrawStyle (PictureBox solamente)

Devuelve o establece un valor que determina el estilo de línea de la salida de métodos gráficos.

Sintaxis objeto.DrawStyle [= número]

Los valores posibles de número son: 0 (Predeterminado) Continuo.


1 Rayas.
2 Puntos.
3 Raya-punto.
4 Raya-punto-punto.
5 Transparente.
6 Continuo interior.

DrawWidth (PictureBox solamente)

Devuelve o establece la anchura de línea de lo dibujado con los métodos gráficos.

Sintaxis NombredelPictureBox.DrawWidth [= tamaño]

tamaño Expresión numérica comprendida entre 1 y 32.767 que representa la anchura de la línea en pixeles. El valor
predeterminado es 1, es decir, un píxel de ancho.

Enabled (PictureBox e Image)

Habilitado. Igual que otros controles.

FillColor, FillStyle, Font, Fontransparent, ForeColor (PictureBox solamente)

Igual que otros controles.

Height, Width , Left, Top (PictureBox e Image)


Definen el tamaño y la posición del control. En el control Image el tamaño puede depender del gráfico que se introduzca y del
valor de la propiedad Stretch.

HelpContextID (PictureBox solamente) Igual que otros controles

Index (PictureBox e Image) Igual que otros controles

LinkItem, LinkMode, LinkTimeout, LinkTopic (PictureBox solamente)

Propiedades que afectan al comportamiento de este control como DESTINO de una conversación DDE. Se estudiará con mas
detalles al estudiar el Intercambio Dinámico de Datos.

MouseIcon, MousePointer (PictureBox e Image)

MouseIcon Establece un icono de mouse personalizado.

(Una vez que comenzamos a estudiar las propiedades gráficas, se comenta cómo se puede cambiar el icono de la propiedad MouseIcon de
todos los controles)

Sintaxis
objeto.MouseIcon = LoadPicture(ruta) ó
objeto.MouseIcon = imagen

donde :
objeto Nombre del objeto PictureBox o Image
ruta Expresión de cadena que especifica la ruta y el nombre del archivo que contiene el icono personalizado. Así
podemos cargar un icono de los existentes en el disco. Ej. Image1.MouseIcon =
LoadPicture("C:\vb\icons\computer\disk05.ico")

imagen Propiedad Picture de un objeto Form, de un control PictureBox o de un control Image, o nombre de una variable tipo
Picture. De esta forma podemos cargar como un icono el gráfico que tengamos en otro objeto o en una variable tipo Picture.
Ej. Image1.MouseIcon = Picture1.picture

La propiedad MouseIcon proporciona un icono de mouse personalizado que se utiliza cuando el valor de la propiedad
MousePointer es 99.

MousePointer devuelve o establece un valor que indica el tipo de puntero de mouse que aparece cuando se pasa el puntero
del ratón por encima de un objeto en tiempo de ejecución.
Sintaxis objeto.MousePointer [= valor]

objeto Nombre del objeto PictureBox o Image


valor Número entero que especifica el tipo de puntero de mouse que aparece, según se describe mas adelante.

Las opciones para valor son:

0 (Predeterminado) Forma que determine el objeto.


1 Flecha.
2 Cruz (puntero en forma de cruz).
3 Forma de I.
4 Icono (pequeño cuadrado dentro de otro cuadrado).
5 Tamaño (flecha de cuatro puntas: norte, sur, este y oeste).
6 Tamaño NE SO (flecha doble apuntando al nordeste y al sudoeste).
7 Tamaño N S (flecha doble apuntando al norte y al sur).
8 Tamaño NO SE (flecha doble apuntando al noroeste y al sudeste).
9 Tamaño O E (flecha doble apuntando al oeste y al este).
10 Flecha hacia arriba.
11 Reloj de arena (espera).
12 No soltar.
13 Flecha y reloj de arena.
14 Flecha e interrogación.
15 Tamaño de todo (personalizable en Microsoft Windows NT 3.51)
99 Icono personalizado especificado en la propiedad MouseIcon explicada anteriormente.

Name (PictureBox e Image) Nombre del control

Picture (PictureBox e Image)

Devuelve o establece un gráfico mostrado en un control.


Ya se ha estudiado mas atrás como cambiar la propiedad Picture.

ScaleHeight, ScaleWidth, ScaleLeft, ScaleTop, ScaleMode


Propiedades del PictureBox solamente.

¡Todas las propiedades Scale ? ? ? ? afectan a las coordenadas, no a la escala !


IMAGE LIST

Este control no está normalmente en la caja de herramientas. Solamente está disponible en la versión de 32 bits. Hay que introducirlo
mediante los Herramientas | Controles Personalizados y pertenece al grupo Microsoft Windows Common Controls
(COMCTL32.OCX) (Vea Nota 1)

Este control nos permite almacenar varias imágenes. Es, tal como indica su nombre, como un ListBox pero que en vez de contener textos,
contiene imágenes.
La utilidad de este control es para almacenar en él distintas imágenes, y servirlas desde él a otro control, un PictureBox o un control Image,
sin necesidad de tener que acceder a leerlas en el disco, que conllevaría una importante pérdida de tiempo si el cambio de imágenes debe
ser rápido.
Este control es necesario para almacenar las imágenes que se mostrarán en los iconos de la barra de herramientas. Verá mas adelante
como se realiza una barra de herramientas (La barra de herramientas solo está disponible para la versión de 32 Bits)

Un ImageList permite tener varias imágenes dentro de él, pero este control no las presenta. Solamente sirve de “almacén” para pasarlas
rápidamente a otro control (PictureBox, p.e.) que será el que las presenta en pantalla.

En la siguiente figura, pueden verse las propiedades de un ImageList con varias imágenes cargadas.
Nota 1. El grupo de controles Microsoft Windows Common Controls (COMCTL32.OCX) incluye además de este los controles TabStrip,
Toolbar, StatusBar, ProgressBar, TreeView, ListView y Slider.

Para introducir imágenes en el control ImageList deberemos acceder a sus propiedades, bien mediante F4 y luego haciendo click sobre
Personalizado, bien pulsando el botón derecho del ratón sobre el icono del control. Aparecerá un cuadro donde podemos insertar imágenes
El tipo de imágenes pueden ser mapas de bits :BMP o iconos .ICO

El control ImageList tiene una colección llamada ListImages. Esta colección contiene todas las imágenes introducidas en el ImageList y
las propiedades de cada imagen. Como toda colección, será un array donde podemos elegir uno de sus elementos designándolo por su
nombre seguido de su número (Index) encerrado entre paréntesis. Así la imagen número 3 será :

ImageList1.Listimages (3)

Si tenemos un control Picture llamado Picture1 y queremos poner en su propiedad Picture la imagen cargada en el ImageList1, en su
posición 3, usaríamos la expresión :

Set Picture1.Picture = ImageList1.ListImages (3) . Picture

Observe que tras ListImages ( ) es necesario poner la propiedad Picture, ya que Picture es una propiedad de la colección ListImages

Como cualquier colección, ListImages tiene la propiedad Count, que nos servirá para contar el número de imágenes que guarda.
Numerodeimágenes = ImageList1. ListImages.Count

Dado que al guardar imágenes en un ImageList, estas imágenes están guardadas en la memoria RAM, es fácil realizar una animación.
Para ello necesitamos varias imágenes que poniendo una tras otra, dé la sensación de movimiento. Imaginemos un número indeterminado
de imágenes dentro de un ImageList, y un control Picture llamado Picture1 donde queremos presentar la animación. En el procedimiento
Timer de un Timer pondríamos

Static pepe As Integer


pepe = pepe + 1
If pepe > ImageList1.ListImages.Count Then pepe = 1
Set Picture1.Picture = ImageList1.ListImages(pepe).Picture

Una de las mayores aplicaciones del ImageList es proporcionar imágenes para otros controles. Entre ellos el TOOLBAR

Barra de Herramientas. Control Toolbar

Este control permite realizar una barra de herramientas. La barra de herramientas es, como ya conocerá, una barra donde existen varios
iconos. Estos iconos realizan una determinada función. Normalmente se ponen en la barra de herramientas los iconos que representan las
acciones mas frecuentes de una aplicación. Esto facilita la operación al no tener que desplegar menús para buscar la operación a realizar.

Como el espacio que ocupan los iconos es grande, es también bastante normal que no estén representados en la barra de herramientas
todas las funciones posibles de la aplicación, sino como decíamos, solamente las mas frecuentes. Pero ocurre que la función que para un
usuario es muy frecuente, para otro no lo es, por lo que también es habitual poder programar los iconos que aparecen en la barra de
herramientas.

Todo ello lo puede hacer el control Toolbar.

Para introducir el Toolbar es necesario que esté presente en la caja de herramientas el control personalizado Microsoft Windows Common
Controls (COMCTL32.OCX).

El control Toolbar es un contenedor de un array de iconos. Estos iconos forman botones sobre los que se puede insertar código en sus
procedimientos. A cada botón se le denomina Button y a la colección de botones se le denomina Buttons. Cada Button es un elemento
de la colección Buttons y por lo tanto podemos referirnos a cada uno de ellos por el índice que tiene dentro de la colección.

Los iconos de cada uno de los botones del Toolbar debe introducirse previamente en un control ImageList. Como se recordará, un control
ImageList es un almacén de imágenes, que podemos usar en cualquier parte de la aplicación. Una de esas partes es la confección de la
barra de herramientas. Por lo tanto, es necesario introducir un control ImageList en cualquier aplicación que use un control Toolbar. Todas
las imágenes del Toolbar deben estar en un único ImageList. Y este ImageList debe estar en el mismo formulario que el Toolbar
La barra de herramientas puede realizarse en tiempo de diseño (este sería el caso para cuando no existiese variación ni elección de
botones a lo largo de la ejecución de la aplicación)
o en tiempo de ejecución (caso que correspondería con una aplicación que tuviese una barra de menú programable o que variase esta
barra de menú dependiendo de cada operación que se esté ejecutando en la aplicación).

Para realizar la barra de herramientas en tiempo de diseño, basta con visualizar el cuadro de propiedades que aparece pulsando el botón
derecho del ratón sobre el control Toolbar. Aparecerá un cuadro de diálogo como este :

Puede ver que en el cuadro ImageList aparece el nombre de un ImageList. Al desplegar la lista aparecerán todos los ImageList que existan
en el formulario. El ImageList debe estar en el mismo formulario que el Toolbar. Deberá elegirse el ImageList que contenga las imágenes de
los iconos que queremos introducir en el Toolbar.

Este cuadro nos permite también introducir la forma que adoptará el puntero del ratón cuando entre en el Toolbar (MousePointer), si el
Toolbar aparece por defecto habilitado o deshabilitado (Enabled) y si muestra o no un rótulo programable al pasar el ratón por encima de
cada botón del Toolbar. (ShowTips). (El uso de estos pequeños rótulos pueden hacer una aplicación muy bonita) La propiedad
AllowCustomize permite, si es True, cambiar el orden de los botones e introducir separadores (vea evento DobleClick).

En el cuadro botones podemos introducir los datos deseados para cada uno de los botones que compondrán la colección Buttons.
Para insertar un nuevo botón hay que hacer click sobre Insertar botón e insertará un nuevo botón inmediatamente después del que figura
en la propiedad Index (en la figura del ejemplo, lo insertaría en segundo lugar, no en el último lugar como podría creerse). También
podemos eliminar un botón haciendo click sobre Eliminar botón.

El Caption (opcional) es la palabra que figurará debajo del icono del botón.

Un botón se identifica por su índice. ( Toolbar1.buttons(1) )

La propiedad Key es un nombre que se puede añadir a cada botón. Esta propiedad sirve para identificar el botón que se ha pulsado, pero
no para nombrar al botón.

La propiedad Value es el valor por defecto, con el que aparecerá el botón al comienzo de la aplicación. (Unpressed, no pulsado, Pressed,
pulsado).

La propiedad Style define el tipo de botón :

0 - Default Botón monostable. (Se pulsa, pero no se mantiene pulsado)


1 - Check Botón Biestable. (Se mantiene pulsado y se levanta con otro click)
2 - Button Group Solo uno de los botones del grupo puede estar pulsado. Esta
propiedad lleva implícito que los botones que forman un grupo son biestables. Pueden hacerse varios
grupos independientes introduciendo un botón que no pertenezca a un grupo (tipos 0, 1, 3 ó 4) entre los dos
grupos que se independientes que se pretenden formar
3 - Separator El botón se convierte en un separador de anchura fija.
4 - PlaceHolder El botón se convierte en un separador de anchura variable.

ToolTipText es el texto que aparecerá al lado del botón cada vez que se ponga el cursor del ratón sobre el botón. Para que aparezca debe
estar habilitada la propiedad ShowTips.

Image es el número de la imagen en el ImageList.

El control Toolbar también puede realizarse en tiempo de ejecución. Para introducir u botón en el Toolbar hay que crear el botón y añadirlo
a la colección Buttons de Toolbar. Podemos hacerlo en una sola instrucción :

Set NombreBotón = NombreToolbar.Buttons.add ( [Indice], [Key], [Caption], [Style], [Imagen])

NombreBotón puede ser cualquier nombre (es el nombre del objeto botón)
NombreToolbar es el nombre del Toolbar
Indice es el número de orden de ese botón dentro del Toolbar
Key es el valor de la propiedad Key del botón. Este valor debe ser único para cada botón.
Style es un número del 0 al 4 con el tipo de botón. Vea lista mas arriba
Imagen es el número de la imagen para ese botón, dentro del ImageList que las contiene.

Los botones pueden habilitarse y deshabilitarse usando la propiedad Enabled (True / False). Recuerde que los botones se identifican por su
índice :

Toolbar1.Buttons(Indice).Enabled = False

Para saber que botón se ha pulsado, puede leerse la propiedad Key :

Text1.Text = Button.Key presenta en Text1 el texto introducido en la propiedad


Key del último botón pulsado.

Con la lectura de la propiedad Key, y la sentencia Case o If ... Then podemos iniciar la parte de la aplicación asociada a cada botón.

El control Toolbar tiene los siguientes eventos :

ButtonClick
Este evento se produce cada vez que se hace click sobre un botón del Toolbar. Pasa como parámetro el índice del botón pulsado.
Podremos saber que botón se ha pulsado mediante sentencias condicionales :

Private Sub Toolbar1_ButtonClick(ByVal Button As Button)

If Button.Index = 1 Then . . . .
If Button.Index = 2 Then . . . .

También podríamos usar la propiedad Key como se dijo mas atrás.

Click

Este evento se produce cuando se hace click sobre cualquier botón del Toolbar, pero no pasa parámetros. (No distingue sobre que botón
se ha hecho click) Podemos utilizarlo cuando se quiera realizar una operación común para todos los botones (Que suene un Beep, por
ejemplo)

DobleClick

Este evento solamente se produce cuando se hace doble click en la parte del Toolbar donde no hay botones, y la propiedad
AllowCustomize esté a True. Si se hace doble click sobre un botón se produce solamente el evento click (dos veces). Haciendo doble
click en una zona libre de botones, con la propiedad AllowCustomize = True nos permite cambiar el orden de los botones e introducir
separadores.

Change

Se produce solamente cuando se ha realizado algún cambio del orden por el procedimiento anterior.

DragDrop, DragOver

Igual que cualquier control.

MouseMove, MouseUp, MouseDown

Igual que el resto de los controles Pasa como parámetro el índice del botón, la tecla de mayúsculas, y las posiciones x e y del ratón.

Private Sub Toolbar_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)


Este control solamente funciona en la versión de VB de 32 Bits. Pero para 16 bits puede hacerse una cosa parecida (y mas sencilla)
utilizando un control Picture como contenedor de tantos controles Image como necesitemos. Dado que el control Picture dispone de
propiedad Align y puede servir como contenedor de otros controles, puede realizarse una barra de herramientas similar a esta, y
posiblemente de forma mas sencilla.

¡ El control Toolbar NO sirve de contenedor de otros controles, a excepción de sus botones ! ! !

LA BARRA DE ESTADO

Este control es muy parecido a la barra de herramientas, y suele usarse, colocándolo en la parte inferior de la ventana, para indicar el
proceso que está en curso en la aplicación. La barra de estado, control StatusBar se introduce en la caja de herramientas al mismo tiempo
que el control Toolbar, mediante el control personalizado múltiple Microsoft Windows Common Controls (COMCTL32.OCX).

La barra de estado puede albergar hasta 16 paneles, que pueden contener texto o gráficos. También pueden contener información del
Hardware, tal como el estado de la tecla Bloqueo de Mayúsculas, Bloqueo del teclado numérico, tecla Insert activada, tecla Scroll
Lock activada, o mostrar la fecha y la hora

La barra de estado puede configurarse como de un solo panel o de múltiples paneles. (Propiedad Style. 0=múltiples paneles, 1= panel
único)

Las dimensiones de cada panel pueden configurarse como fijas o ajustadas al tamaño del texto o imagen que presentan.

Las propiedades pueden establecerse en tiempo de diseño, mediante el siguiente cuadro.


En este control las imágenes no es necesario introducirlas previamente en un ImageList. Pueden introducirse directamente sobre el cuadro
de diálogo que sale pulsando el botón derecho del ratón - propiedades - en la ventana correspondiente a paneles. Acepta imágenes tipo Bit-
map o .ICO. Los paneles pueden combinar una gráfico y un texto.

La barra de estado puede realizarse en tiempo de diseño o en tiempo de ejecución. Para realizarla en tiempo de ejecución basta con
visualizar la ventana de propiedades, muy similar a la del control Toolbar.

Para añadir un panel en tiempo de ejecución basta con añadirlo a la colección Panels del control StatusBar mediante la sentencia :

Set PanelNuevo = Nombrebarraestado.Panels.Add.( [índice],[key],[Text],[estilo],[gráfico]

Donde PanelNuevo es el nombre con el que se va a conocer ese panel que acabamos de crear. PanelNuevo debe declararse como variable
objeto Panel donde sea necesario según el ámbito que le queramos dar. De esta forma, una vez creado, nos podremos referir a ese panel
simplemente citándolo por su nombre (En este caso, PanelNuevo)
Los términos [índice],[key],[Text],[estilo],[gráfico] que entran a formar parte en la sintaxis de creación del panel se explican a
continuación.

Indice - Necesario. Es el índice que define al panel dentro del StatusBar.


Key - Opcional. Es la propiedad Key de ese panel (El contenido de esta propiedad lo podemos
leer desde cada panel
Variable = statusbar1.Panels(Panel.Index).Key
Text - El texto que queremos figure en el panel (Solo si la propiedad Estilo está en sbrText
Estilo - Propiedad estilo del panel.
0 - sbrText El panel mostrará el Texto de la propiedad Text de ese panel
1 - sbrCaps El panel muestra el estado de la tecla Bloqueo Mayúsculas
2 - sbrNum El panel muestra el estado de la tecla Bloq. Números
3 - sbrIns El panel muestra el estado de la tecla Insert
4 - sbrScrl El panel muestra el estado de la tecla Scroll / Lock
5 - sbrTime El panel muestra la hora
6 - sbrDate El panel muestra la fecha
Gráfico - Es el gráfico que va a tener el panel. Este gráfico puede obtenerse desde un ImageList,
ImageList1.ListImages(n).Picture - o directamente desde el disco duro, mediante el
método LoadPicture - LoadPicture("C:\vb\icons\comm\net09a.ico") -

Si no se pone alguna de las propiedades opcionales intermedias, deben mantenerse las comas separadoras.

Como ejemplo, podemos añadir varios paneles de la siguiente forma :

Dim PanelNuevo As Panel ‘Donde deba declararse a efectos del ámbito


Dim pepe As Integer

Set PanelNuevo = statusbar1.Panels.Add(pepe, "Contenido del Key " & Str(pepe), "Texto " & Str(pepe), ,
LoadPicture("C:\vb\icons\comm\net09a.ico"))

Estos son los controles gráficos mas importantes. Verá a lo largo del curso que existen otros, y más que podrá encontrar entre diferentes
suministradores de controles, ya que VB ha dejado una puerta abierta para realizar controles a medida. Existen varias empresas de software
dedicadas a la fabricación de controles personalizados, y en el aspecto de controles gráficos, podrá encontrar una amplia gama de
fabricantes y controles. Puede obtener muchos controles en el CD-ROM que acompaña a varias revistas especializadas en programación
VB, y a través de la red Internet.
INTERCAMBO DINAMICO DE DATOS
EL CONTROL PERSONALIZADO MICROSOFT COMM

INTERCAMBO DINAMICO DE DATOS (Dinamic Data Exchange) DDE

El intercambio dinámico de datos es una utilidad de Windows que utiliza Visual Basic, y nos permite crear aplicaciones que tomen datos
una de otras.

Para pasar datos de una aplicación a otra se necesitan al menos, dos aplicaciones (lógico), una que se deje leer, y la otra (u otras), que
quieran leer la información en aquella.

Puede darse el caso que una aplicación esté recibiendo datos de otra aplicación, y a su vez envíe datos a una tercera.

A la aplicación que envía la información se le llama aplicación servidor, y a la que la recibe, aplicación cliente.

La aplicación servidor debe estar funcionando antes de que la aplicación cliente le pida la información. Si no es así, se generará un error.

Los datos a traspasar de una aplicación a otra pueden ser :

*0 Textos, de un Label o un TextBox.


*1 Imágenes, de un PictureBox.

El origen de un intercambio DDE siempre es un formulario. Dentro de este formulario origen estará el Label, TextBox o PictureBox que
contiene la información a enviar.

Para indicar que un formulario es origen de información para un intercambio DDE debemos decírselo en sus propiedades LinkMode y
LinkTopic.

El destino de un texto ha de ser necesariamente un Label, un TextBox, y el destino de un gráfico debe ser un PictureBox.

Cuando queremos que uno de estos controles sea el destino de un intercambio DDE debemos indicarlo en sus propiedades LinkMode,
LinkTopic, LinkItem, e indicarle el tiempo de espera para un intercambio en la propiedad LinkTimeout.

Propiedad LinkMode

Tiene distinta forma si se trata de un control (Label, TextBox y PictureBox) ó un formulario.

Para un formulario tiene dos valores posibles :


0 = None No puede existir comunicación DDE con ese formulario
1= Source El formulario permite que exista una comunicación DLL entre uno de
sus controles y otra aplicación.

Si se establece el valor de esta propiedad a 0 en tiempo de diseño, no podrá cambiarse en tiempo de ejecución. Si se establece a 1 en
tiempo de diseño, se podrá cambiar a 0 y volver a ponerla a 1 en tiempo de ejecución.

Para un control, la propiedad LinkMode le permite que inicie una conversación DDE con una aplicación servidor, (origen), y cómo iniciarla.
Tiene 4 valores posibles :

0=None. No existe comunicación DDE con ese control

1=Automático Los datos se traspasarán desde la aplicación servidor a este control de


la aplicación cliente cada vez que cambie el dato en la aplicación
servidor (origen)

2=Manual Los datos se traspasarán cuando lo pida la aplicación cliente (destino),


mediante la orden LinkRequest.

3=Notify Cuando existe un cambio en los datos de la aplicación origen, ésta


notifica a la aplicación destino que el dato ha cambiado, pero no le envía el dato nuevo. En el control de la
aplicación destino donde debe llevarse la información, se genera el evento LinkNotify, en cuyo procedimiento
podremos escribir el código necesario dependiendo de nuestra aplicación. Para traer la información, debe
ejecutarse la orden LinkRequest. (Véase mas adelante)

En tiempo de ejecución, para un control, esta propiedad es de lectura y escritura, es decir, se puede usar para saber que valor tiene esta
propiedad en un determinado control, o para forzar esa propiedad a un determinado valor.

La sintaxis de esta propiedad es :

objeto.LinkMode [= número]

donde número es un entero que especifica el tipo de conexión. (0, 1, 2 ó 3 según se ha visto)
y objeto es el nombre del control.

Propiedad LinkTopic
Esta propiedad es de lectura y escritura, tanto para los controles como para los formularios.

Cuando un control destino quiere establecer una comunicación DDE “llama” a la aplicación origen, y dentro de ella, al formulario que
contiene el control cuya información debe ser traspasada. (Nótese que la aplicación origen puede tener varios formularios). Al ese
formulario podría llamarle por su nombre, (por su Name), pero no lo hace así. Le llama por un nombre que le debemos poner al formulario
en su propiedad LinkTopic. A este nombre se le denomina Tema.

La propiedad LinkTopic, para un formulario de origen, devuelve o establece el tema al que el formulario “responde” en una conversación
DDE.

Sintaxis nombredelformulario.LinkTopic [= tema]

Para un control destino, La propiedad LinkTopic contiene el nombre de la aplicación y el tema, ambos separados mediante el carácter |
(carácter 124)

Sintaxis nombredelcontrol.LinkTopic [= aplicacionorigen|tema]

El nombre de la aplicación origen será el nombre del de proyecto de Visual Basic sin la extensión .VBP (si la aplicación se está ejecutando
en el entorno de desarrollo de Visual Basic), o el nombre de la aplicación de Visual Basic sin la extensión .EXE (si se ejecuta como un
archivo ejecutable independiente).

El tema será el mismo al que “responde” el formulario donde se encuentra el control que contiene la información a traspasar.

( DDE es una utilidad de Windows. Windows establece que el estándar de un vinculo DDE es Aplicación | Tema  ! elemento. Véase para
mas detalles el manual de Windows, enlaces DDE)

Propiedad LinkItem

La propiedad LinkItem solamente la tiene el control destino de la información. No la tiene el formulario origen. En esta propiedad deberá
expresarse el nombre del control origen de la información.

Esta propiedad es de lectura y escritura, es decir, tanto sirve para saber el nombre del control origen de los datos, como para establecerlo
en tiempo de ejecución.

Sintaxis objeto.LinkItem [= cadena]

donde cadena es el nombre del control origen que tiene los datos y objeto es el nombre del control al que le estamos poniendo la propiedad
LinkItem.
Propiedad LinkTimeout

Devuelve o establece la cantidad de tiempo que un control espera una respuesta a un mensaje DDE.

Sintaxis objeto.LinkTimeout [= número]

donde número es una expresión numérica que especifica el tiempo de espera en décimas de segundo.
El tiempo de respuesta DDE desde aplicaciones origen varía. Use esta propiedad para ajustar el tiempo que un control destino espera la
respuesta de una aplicación origen. Si se usa LinkTimeout de forma correcta se puede evitar la generación de un error por Visual Basic si
una aplicación origen tarda mucho en responder.

Nota La plazo mayor de tiempo que un control puede esperar es 65.535 décimas de segundo, es decir, sobre 1 hora y 49 minutos. Al
establecer LinkTimeout a 1 se indica al control que espere la respuesta en una conversación DDE durante el mayor plazo de tiempo. El
usuario puede forzar que el control deje de esperar presionando la tecla ESC..

Evento LinkNotify

Ocurre cuando el origen ha cambiado el dato definido por el vínculo DDE si la propiedad LinkMode del control destino está establecido a 3
(Notificar).

Private Sub objeto_LinkNotify([índice As Integer])

End Sub

En este procedimiento se puede escribir el código necesario para nuestra aplicación, a sabiendas de que este evento se produce cuando
cambia la información en origen. Posiblemente no quiera depositarlo de inmediato en el control destino, puesto que si fuese así habría
puesto la propiedad LinkMode a 1. Cuando quiera colocar el dato en el control destino, puede utilizar el método LinkRequest para obtener el
nuevo dato de la fuente.

Método LinkRequest

Pide a la aplicación origen de una conversación DDE que actualice el contenido de un control Label, PictureBox o TextBox.

Sintaxis objeto.LinkRequest
Siendo objeto el nombre del control destino de la aplicación.

Objeto es el nombre de un control Label, PictureBox o TextBox involucrado en una conversación DDE como destino. LinkRequest provoca
que la aplicación origen envíe los datos actuales al objeto, actualizando la propiedad Caption si objeto es un control Label, la propiedad
Picture si objeto es un control PictureBox o la propiedad Text si objeto es un control TextBox.
Si la propiedad LinkMode del objeto está definida como 1 (Automático), la aplicación origen actualiza objeto automáticamente y
LinkRequest no es necesario. Si la propiedad LinkMode del objeto está definida como 2 (Manual) , la aplicación origen actualiza objeto sólo
cuando se usa LinkRequest.
Si la propiedad LinkMode del objeto está definida como 3 (Notify), el origen notifica al destino que los datos han cambiado invocando el
método LinkNotify. El destino debe entonces usar el método LinkRequest para actualizar los datos.

Método LinkSend

Transfiere el contenido de un control PictureBox a la aplicación destino de una conversación DDE.

Sintaxis objeto.LinkSend

Objeto debe ser un control PictureBox de un objeto Form que sea origen de una conversación DDE.
Cuando otras aplicaciones establecen vínculos automáticos con un objeto Form de su aplicación, Visual Basic las notifica cuando el
contenido de un control TextBox o Label origen cambia. Sin embargo, Visual Basic no notifica automáticamente a una aplicación destino
DDE cuando el valor de la propiedad Picture de un control PictureBox origen cambia. Como la cantidad de datos de un gráfico pueden ser
muy grande y como no tiene sentido actualizar la aplicación destino por cada cambio de píxel de la imagen, Visual Basic requiere el uso del
método LinkSend para notificar explícitamente a las aplicaciones destino DDE cuándo cambia el contenido de un control PictureBox.

Método LinkPoke

Transfiere el contenido de un control Label, PictureBox o TextBox a la aplicación origen de una conversación DDE.

Sintaxis objeto.LinkPoke

Objeto es el nombre del control Label, PictureBox o TextBox involucrado en la conversación DDE como destino. Si objeto es un control
Label, LinkPoke transfiere el contenido de la propiedad Caption al origen. Si objeto es un control PictureBox, LinkPoke transfiere el
contenido de la propiedad Picture al origen. Si objeto es un control TextBox, LinkPoke transfiere el contenido de la propiedad Text al origen.
Normalmente, en una conversación DDE la información fluye de origen a destino. Sin embargo, LinkPoke permite que un objeto destino
suministre datos al origen. No todas las aplicaciones origen aceptan información de esta forma; si la aplicación origen no acepta los datos,
se produce un error.

PROTOTIPOS: PROGRAMACION .NET

Algunas de las ventajas e inconvenientes de la plataforma .Net.

A continuación se resumen las ventajas más importantes que proporciona .Net Framework:
 Código administrado: El CLR realiza un control automático del código para que este sea seguro, es decir,
controla los recursos del sistema para que la aplicación se ejecute correctamente.
 Interoperabilidad multilenguaje: El código puede ser escrito en cualquier lenguaje compatible con .Net ya
que siempre se compila en código intermedio (MSIL).
 Compilación just-in-time: El compilador JIT incluido en el Framework compila el código intermedio (MSIL)
generando el código máquina propio de la plataforma. Se aumenta así el rendimiento de la aplicación al ser
específico para cada plataforma.
 Garbage collector: El CLR proporciona un sistema automático de administración de memoria denominado
recolector de basura (garbage collector). El CLR detecta cuándo el programa deja de utilizar la memoria y la
libera automáticamente. De esta forma el programador no tiene por que liberar la memoria de forma explícita
aunque también sea posible hacerlo manualmente (mediante el método disponse() liberamos el objeto para
que el recolector de basura lo elimine de memoria).
 Seguridad de acceso al código: Se puede especificar que una pieza de código tenga permisos de lectura
de archivos pero no de escritura. Es posible aplicar distintos niveles de seguridad al código, de forma que se
puede ejecutar código procedente del Web sin tener que preocuparse si esto va a estropear el sistema.
 Despliegue: Por medio de los ensamblados resulta mucho más fácil el desarrollo de aplicaciones distribuidas
y el mantenimiento de las mismas. El Framework realiza esta tarea de forma automática mejorando el
rendimiento y asegurando el funcionamiento correcto de todas las aplicaciones.

¿Todo son ventajas? 

Procesos como la recolección de basura de .Net o la administración de código introducen factores de sobrecarga
que repercuten en la demanda de más requisitos del sistema. 

El código administrado proporciona una mayor velocidad de desarrollo y mayor seguridad de que el código sea
bueno. En contrapartida el consumo de recursos durante la ejecución es mucho mayor, aunque con los
procesadores actuales esto cada vez es menos inconveniente.

El nivel de administración del código dependerá en gran medida del lenguaje que utilicemos para programar. Por
ejemplo, mientras que Visual Basic .Net es un lenguaje totalmente administrado, C Sharp permite la administración
de código de forma manual, siendo por defecto también un lenguaje administrado. Mientras que C++ es un lenguaje
no administrado en el que se tiene un control mucho mayor del uso de la memoria que hace la aplicación.

Arquitectura básica de la plataforma .Net. Descripción del Framework y sus principales componentes:
Lenguajes, biblioteca de clases y CLR.

La nueva tecnología de Microsoft ofrece soluciones a los problemas de programación actuales, como son la
administración de código o la programación para Internet. Para aprovechar al máximo las características de .Net es
necesario entender la arquitectura básica en la que esta implementada esta tecnología y así beneficiarse de todas
las características que ofrece esta nueva plataforma. 
El Framework de .Net es una infraestructura sobre la que se reúne todo un conjunto de lenguajes y servicios que
simplifican enormemente el desarrollo de aplicaciones. Mediante esta herramienta se ofrece un entorno de ejecución
altamente distribuido, que permite crear aplicaciones robustas y escalables. Los principales componentes de este
entorno son:
 Lenguajes de compilación
 Biblioteca de clases de .Net
 CLR (Common Language Runtime)

Actualmente, el Framework de .Net es una plataforma no incluida en los diferentes sistemas operativos distribuidos
por Microsoft, por lo que es necesaria su instalación previa a la ejecución de programas creados mediante .Net. El
Framework se puede descargar gratuitamente desde la web oficial de Microsoft (ver link de descarga en los
recursos del final). 
.Net Framework soporta múltiples lenguajes de programación y aunque cada lenguaje tiene sus características
propias, es posible desarrollar cualquier tipo de aplicación con cualquiera de estos lenguajes. Existen más de 30
lenguajes adaptados a .Net, desde los más conocidos como C# (C Sharp), Visual Basic o C++ hasta otros lenguajes
menos conocidos como Perl o Cobol. 

Common Language Runtime (CLR) 

El CLR es el verdadero núcleo del Framework de .Net, ya que es el entorno de ejecución en el que se cargan las
aplicaciones desarrolladas en los distintos lenguajes, ampliando el conjunto de servicios que ofrece el sistema
operativo estándar Win32. 

La herramienta de desarrollo compila el código fuente de cualquiera de los lenguajes soportados por .Net en un
mismo código, denominado código intermedio (MSIL, Microsoft Intermediate Lenguaje). Para generar dicho código
el compilador se basa en el Common Language Specification (CLS) que determina las reglas necesarias para crear
código MSIL compatible con el CLR. 

De esta forma, indistintamente de la herramienta de desarrollo utilizada y del lenguaje elegido, el código generado
es siempre el mismo, ya que el MSIL es el único lenguaje que entiende directamente el CLR. Este código es
transparente al desarrollo de la aplicación ya que lo genera automáticamente el compilador. 

Sin embargo, el código generado en MSIL no es código máquina y por tanto no puede ejecutarse directamente. Se
necesita un segundo paso en el que una herramienta denominada compilador JIT (Just-In-Time) genera el código
máquina real que se ejecuta en la plataforma que tenga la computadora. 
De esta forma se consigue con .Net cierta independencia de la plataforma, ya que cada plataforma puede tener su
compilador JIT y crear su propio código máquina a partir del código MSIL. 

La compilación JIT la realiza el CLR a medida que se invocan los métodos en el programa y, el código ejecutable
obtenido, se almacena en la memoria caché de la computadora, siendo recompilado sólo cuando se produce algún
cambio en el código fuente. 

Biblioteca de clases de .Net 

Cuando se está programando una aplicación muchas veces se necesitan realizar acciones como manipulación de
archivos, acceso a datos, conocer el estado del sistema, implementar seguridad, etc. El Framework organiza toda la
funcionalidad del sistema operativo en un espacio de nombres jerárquico de forma que a la hora de programar
resulta bastante sencillo encontrar lo que se necesita. 

Para ello, el Framework posee un sistema de tipos universal, denominado Common Type System (CTS). Este
sistema permite que el programador pueda interactuar los tipos que se incluyen en el propio Framework (biblioteca
de clases de .Net) con los creados por él mismo (clases). De esta forma se aprovechan las ventajas propias de la
programación orientada a objetos, como la herencia de clases predefinidas para crear nuevas clases, o el
polimorfismo de clases para modificar o ampliar funcionalidades de clases ya existentes. 
La biblioteca de clases de .Net Framework incluye, entre otros, tres componentes clave:
 ASP.NET para construir aplicaciones y servicios Web.
 Windows Forms para desarrollar interfaces de usuario.
 ADO.NET para conectar las aplicaciones a bases de datos.

La forma de organizar la biblioteca de clases de .Net dentro del código es a través de los espacios de nombres
(namespaces), donde cada clase está organizada en espacios de nombres según su funcionalidad. Por ejemplo,
para manejar ficheros se utiliza el espacio de nombres System.IO y si lo que se quiere es obtener información de
una fuente de datos se utilizará el espacio de nombres System.Data. 

La principal ventaja de los espacios de nombres de .Net es que de esta forma se tiene toda la bliblioteca de clases
de .Net centralizada bajo el mismo espacio de nombres (System). Además, desde cualquier lenguaje se usa la
misma sintaxis de invocación, ya que a todos los lenguajes se aplica la misma biblioteca de clases. 

Ensamblados 

Uno de los mayores problemas de las aplicaciones actuales es que en muchos casos tienen que tratar con
diferentes archivos binarios (DLL´s), elementos de registro, conectividad abierta a bases de datos (ODBC), etc. 

Para solucionarlo el Framework de .Net maneja un nuevo concepto denominado ensamblado. Los ensamblados son
ficheros con forma de EXE o DLL que contienen toda la funcionalidad de la aplicación de forma encapsulada. Por
tanto la solución al problema puede ser tan fácil como copiar todos los ensamblados en el directorio de la
aplicación. 

Con los ensamblados ya no es necesario registrar los componentes de la aplicación. Esto se debe a que los
ensamblados almacenan dentro de si mismos toda la información necesaria en lo que se denomina el manifiesto del
ensamblado. El manifiesto recoge todos los métodos y propiedades en forma de meta-datos junto con otra
información descriptiva, como permisos, dependencias, etc. 

Para gestionar el uso que hacen la aplicaciones de los ensamblados .Net utiliza la llamada caché global de
ensamblados (GAC, Global Assembly Cache). Así, .Net Framework puede albergar en el GAC los ensamblados que
puedan ser usados por varias aplicaciones e incluso distintas versiones de un mismo ensamblado, algo que no era
posible con el anterior modelo COM. 

Recursos: 
Página oficial de .Net Framework 
http://msdn.microsoft.com/netframework/ 

Descarga de .Net Framework 


http://msdn.microsoft.com/netframework/howtoget/default.aspx

Un entorno de desarrollo gratuito para tus creaciones ASP.NET, que además ofrece componentes adicionales de
fácil instalación como el .NET Framework o la base de datos SQL Server Express.
 http://www.microsoft.com/spanish/msdn/vstudio/express/VWD/default.mspx

Comentamos un programa que ha presentado recientemente Microsoft para facilitar el acceso a su tecnología de
desarrollo ASP.NET. El programa en concreto es Visual Web Developer Express Edition, un IDE (Entorno de
desarrollo) para programar fácilmente en ASP.NET, pero que además proporciona otras herramientas útiles o
imprescindibles para realizar nuestros proyectos.

el programa se encuentra en su versión "Beta 2", que es la que hemos instalado y probado. Se puede descargar
gratuitamente desde la web de Microsoft. La versión publicada gratuitamente se puede utilizar sin limitaciones
durante 30 días. En adelante, si se desea continuar su uso, se debe registrar, también gratis, desde el mismo
ordenador donde se ha instalado y ello nos dará acceso a nuevos beneficios, como documentación adicional.

http://www.microsoft.com/spanish/msdn/vstudio/express/VWD/default.mspx

La primera impresión sobre este programa es muy buena. Muchos de nosotros hemos podido tener problemas para
acceder fácilmente a la nueva tecnología .NET de Microsoft y con esta herramienta finalizan en parte esas
dificultades. Ello es debido a que, no sólo proporciona un programa con el que aumentar la productividad de los
programadores al escribir código ASP.NET, sino que además incluye el .NET Framework, un servidor donde
ejecutar las aplicaciones creadas en .NET. Por tanto, en pocos minutos podremos empezar a realizar nuestras
primeras incursiones en .NET.

Instalación

Durante la instalación se eligen los componentes que se desean poner en nuestro ordenador. El propio programa de
instalación se conectará a Internet para recibir aquellos componentes que deseemos. Entre los componentes
opcionales se encuentran:

- Microsoft MDSN Express Library 


Si necesitamos documentación sobre .NET, con la MSDN tendremos acceso a gran cantidad de información y
ayuda.

- Microsoft SQL Server 2005 Express Edition 


Una versión reducida de SQL Server, pero que nos servirá para nuestras tareas de desarrollo. Debemos instalar
este componente porque, por poco que deseemos hacer, necesitaremos una base de datos.
El proceso de instalación continúa solicitando el directorio donde se va a instalar el programa y además mostrando
los componentes adicionales que se van a incorporar a nuestro sistema. Entre otros componentes adicionales se
encuentran paquetes de idioma y el mencionado .NET Framework, que necesitaremos para ejecutar nuestras
aplicaciones ASP.NET.
Una vez dentro del programa

El programa comienza mostrando una página de inicio con las acciones típicas que puede necesitar una persona
que acaba de empezar a utilizar Visual Web Developer. Entre otras, podemos realizar acciones como crear un sitio
personal, crear un sitio web, crear un servicio web, nuevas descargas, recursos, tutoriales para manejar el
programa, etc.
Nosotros, para empezar, creamos un sitio web personal, pulsando tan sólo un botón y nos mostró en pocos
segundos una pantalla de bienvenida comentando las características de la página personal. Pulsando CTRL.+F5 se
puso en marcha el sitio web sin problemas. (Eso si, hay que tener instalado el SQL Server Express... y el .NET
Framework, claro. Pero como dijimos, todo lo necesario se puede obtener durante la instalación.)

Trabajar en ASP.NET resulta más complicado que el otros lenguajes para hacer páginas lado del servidor, como
ASP o PHP. Aunque como ventaja hay que remarcar que podrá aumentar sustancialmente nuestra productividad,
dado que ofrece muchas ayudas a los desarrolladores como la programación visual. Por todo ello, sin duda,
necesitaremos cierta experiencia para sacar provecho de este programa. Aunque los programadores de sistemas
Microsoft tendrán mucho de su parte, ya que el entorno y las herramientas son muy similares a los de otros
productos de la compañía.
Para adquirir esos conocimientos sobre .NET, si nos registramos como usuarios de Visual Web Developer Express,
obtendremos acceso, entre otros, a un completo libro para aprender ASP.NET de la editorial Microsoft Press,

Introducción a la programación orientada a objetos, utilizada en la tecnología .Net.


La programación orientada a objetos es una evolución de la programación procedural basada en funciones. La
POO nos permite agrupar secciones de código con funcionalidades comunes. 

Una de las principales desventajas de la programación procedural basada en funciones es su construcción, cuando
una aplicación bajo este tipo de programación crece, la modificación del código se hace muy trabajosa y difícil
debido a que el cambio de una sola línea en una función, puede acarrear la modificación de muchas otras líneas de
código pertenecientes a otras funciones que estén relacionadas. 

Con la programación orientada a objetos se pretende agrupar el código encapsulándolo y haciéndolo independiente,
de manera que una modificación debida al crecimiento de la aplicación solo afecte a unas pocas líneas. 

La organización de una aplicación en POO se realiza mediante estructuras de código, también llamados objetos.
Estos objetos contienen una serie de procedimientos e información destinados a resolver un grupo de tareas con un
denominador común. Un procedimiento que este situado en un objeto no podrá ser usado por otro procedimiento
perteneciente a otro objeto, si no es bajo una serie de reglas. Los datos que mantenga el objeto, permanecerán
aislados del exterior y sólo se podrá acceder a ellos siguiendo ciertas normas. 

El objetivo de POO es catalogar y diferenciar el código, en base a estructuras jerárquicas dependientes, al estilo de
un árbol genealógico. 

Los objetos se crean a partir de una serie de especificaciones o normas que definen como va a ser el objeto, esto es
lo que en POO se conoce como una clase. 

Las clases definen la estructura que van a tener los objetos que se creen a partir de ella, indicando que propiedades
y métodos tendrán los objetos. 

Las propiedades definen los datos o información del objeto, permitiendo modificar o consultar su estado, mientras
que los métodos son las rutinas que definen el comportamiento del objeto. Es necesario tener muy clara cual es la
diferencia entre un objeto y una clase, a este respecto podemos decir que una clase constituye la representación
abstracta de algo mientras que un objeto constituye la representación concreta de lo que la clase define.
Imaginemos los planos de una casa diseñados por un arquitecto, en ellos encontramos el esquema de la casa, las
medidas, los materiales etc... Una vez construida la casa podremos comprobar que cumple todo lo que los planos
determinaban, de esta manera podemos comparar los planos de la casa con las clases en POO, y la casa en si con
un objeto creado a partir de una clase. Se debe destacar también que con los mismos planos se pueden crear
muchas casas iguales, lo mismo ocurre en POO, a partir de una clase se pueden crear muchos objetos iguales. 

La creación de un objeto a partir de una clase se conoce como instanciación de un objeto.

tipos de datos para la plataforma .NET, con sus correspondencias tanto en VB.NET y C#.

Todos los lenguajes de programación que cumplen las normas de .NET tienen muchas cosas en común, una de
ellas es el conjunto de tipos de datos. Hay que destacar que estos tipos de datos están implementados como clases,
de manera que una variable declarada de un tipo determinado, tendrá la capacidad de usar tanto los métodos como
las propiedades que pertenezcan a la clase del tipo de dato. 

VB.NET
Dim Cadena As String 
Dim Longitud As Integer 
Cadena = "Datos" 
Longitud = Cadena.Length()

C#
String Cadena; 
Int Longitud; 
Cadena = "Datos"; 
Longitud = Cadena.Length();

En el ejemplo anterior declaramos una variable de tipo String (Cadena de caracteres), y podemos ver como esta
variable posee una serie de propiedades y métodos que pueden ser invocados, en este caso usamos la propiedad
Length() para obtener el numero de caracteres de la variable Cadena y asignarlo a la variable Longitud, que pasaría
a tener el valor 5. 

En la siguiente tabla se muestra una relación de los tipos de datos de .NET Framework y su correspondencia en
VB.NET y C#. 

Nombre deTipo de datoTipo de dato


Descripción
la clase en VB.NET en C#

Byte Byte Byte Entero sin signo de 8 bit.

Sbyte Sbyte (Nosbyte Entero sin signo de 8bit (Tipo no acorde con el CLS)
nativo)

Int16 Short short Entero con signo de 16 bit.

Int32 Integer int Entero con signo de 32 bit.

Int64 Long long Entero con signo de 64 bit.

Uint16 UInt16 (Noushort Entero sin signo de 16 bit. (Tipo no acorde con el CLS)
nativo)
Uint32 Uint32 (Nouint Entero sin signo de 32 bit. (Tipo no acorde con el CLS)
nativo)

Uint64 Uint64 (Noulong Entero sin signo de 64 bit. (Tipo no acorde con el CLS)
nativo)

Single Single float Numero con coma flotante de precisión simple, de 32 bit.

Double Double double Numero con coma flotante de precisión doble, de 64 bit.

Boolean Boolean bool Valor logico

Char Char char Carácter unicode de 16 bit.

Decimal Decimal decimal Valor decimal de 96 bit.

IntPtr IntPtr (No-- Entero con signo cuyo tamaño depende de la plataforma: 32 bit en
nativo) plataformas de 32 bit y 64 bit en plataformas de 64 bit. (Tipo no acorde
con el CLS)

UintPtr UintPtr (No-- Entero sin signo cuyo tamaño depende de la plataforma: 32 bit en
nativo) plataformas de 32 bit y 64 bit en plataformas de 64 bit. (Tipo no acorde
con el CLS)

String String string Cadena de caracteres.

Según el modo en el que se almacenan y manipulan estos tipos de datos se pueden dividir en dos categorías.
Podemos almacenar variables por valor y por referencia. Explicamos lo que significa cada uno y las maneras que
.NET realiza este almacenamiento.

Tipos por valor: los tipos por valor almacenan datos a los que se puede acceder de forma directa, a su vez dentro
de esta categoría encontramos mas subcategorías como los tipos nativos de .NET, los tipos de datos creados por el
programador y los enumerados. Los tipos por valor no pueden tener valores nulos. 

Tipos por referencia: Los tipos creados por referencia almacenan la dirección de memoria en la que se encuentra
un dato determinado de manera que usaremos esa dirección de memoria para acceder de forma indirecta al dato.
Los tipos por referencia se dividen en varios subgrupos como son las clases propias de la plataforma, interfaces,
clases creadas por el programador, etc. 
Cuando ejecutamos una aplicación es necesario que los datos se sitúen en la memoria del ordenador, la cual esta
divida en dos partes, una llamada Stack, de pequeño tamaño pero de un acceso muy rápido y otra llamada Heap
que cuenta con un mayor tamaño pero con una velocidad de acceso inferior. 

Cuando creamos tipos por valor, el valor de la variable de este tipo se almacena en el Stack, si asignamos una
variable de estas características a otra, se crea una copia en el Stack. Al destruir un tipo por valor, se destruye
también el valor que se guardo en el Stack. 
Cuando creamos un tipo por referencia, en realidad lo que guardamos en el Heap es una dirección de memoria que
apunta a un valor, pero no al valor en si mismo. Si asignamos una variable que contiene un tipo por referencia a otra
variable, se dice que ambas se refieren al mismo valor. Los tipos por referencia si pueden contener valores nulos.

Explicación de la creación de clases y objetos en los dos principales lenguajes de la plataforma .Net.

Para explicar la creación de clases usaremos un ejemplo sencillo basado en una clase principal "bicicleta". 

Para crear una clase debemos definir sus propiedades y sus métodos, en este ejemplo se usan los siguientes
términos como propiedades de la clase bicicleta: Modelo, Precio, NumeroDeVelocidades y Velocidad; como
métodos de la clase se usan: Acelerar(km) , Frenar() y ConsultarVelocidad(). 

VB.NET
Public Class Bicicleta 
    Public Modelo as String 
    Public Precio as Double 
    Public NumeroDeVelocidades as Integer 
    Private Velocidad as Integer 
    Public Sub Acelerar(ByVal km As Integer) 
       Velocidad = Velocidad + km 
    End Sub 

    Public Sub Frenar() 


       If Velocidad > 0 Then 
          Velocidad = Velocidad -1 
       End If 
    End Sub 

    Public Function ConsutarVelocidad() As Integer 


       Return Velocidad 
    End Function 
End Class

C#
Class Bicicleta 

    public string Modelo; 
    public double Precio; 
    public int NumeroDeVelocidades 
    private int Velocidad 

    public void Acelerar(int km) 


    { 
       Velocidad = Velocidad + km; 
    } 

    public void Frenar() 


    { 
       if (Velocidad > 0) 
       { 
          Velocidad = Velocidad - 1; 
       } 
    } 

    public int ConsultarVelocidad() 


    { 
       return Velocidad; 
    } 
}

Nuestra clase bicicleta consta de varias propiedades y métodos, las palabras Private y Public definen la
accesibilidad de las propiedades, funciones o subrutinas. La definición de una propiedad o método de tipo privado
indica que sólo podrá ser usada dentro del código de la misma clase, si creásemos un objeto de tipo bicicleta, las
especificaciones de la clase no nos permitirían acceder a la propiedad velocidad para consultarla o modificarla, ya
que esta definida como privada. En cambio se pueden usar las subrutinas Acelerar() y Frenar() ya que son de tipo
Public, y desde dentro de ellas se interactua con las propiedades privadas, con esto conseguimos encapsular el
código y hacer accesible solo aquello que queramos. 

Una vez está construida la clase ya se pueden instanciar objetos de la misma. 

VB.NET
Dim objBicicleta as Bicicleta = New Bicicleta 

Dim VelocidadActual as Integer 


objBicileta.Modelo = "Montaña" 
objBicicleta.Precio = 200 
objBicicleta.NumeroDeVelocidades = 21 

objBicicleta.Acelerar(5) 
objBicicleta.Frenar() 

VelocidadActual = objBicicleta.ConsultarVelocidad

C#
Bicicleta objBicicleta = new Bicicleta(); 

int VelocidadActual; 

objBicicleta.Modelo = "Montaña"; 
objBicicleta.Precio = 200; 
objBicicleta.NumeroDeVelocidades = 21; 

objBicicleta.Acelerar(5); 
objBicicleta.Frenar(); 

VelocidadActual = objBicicleta.ConsultarVelocidad(); 

Tras la creación del objeto objBicicleta a partir de la clase, se pueden modificar los valores de las propiedades de
tipo Public, y llamar a los métodos de tipo Public. 

En el ejemplo se llama a los métodos Acelerar(5), pasándole el numero de km que queremos acelerar a través del
parámetro "km" que está definido en la subrutina. 
Luego se llama al método Frenar() que decrementa en una unidad el valor de la propiedad Velocidad. 

Por último se usa la función ConsultarVelocidad(), que retorna el valor de la propiedad Velocidad para introducirlo en
la variable VelocidadActual.

primer programa en .NET, utilizando la consola, que utiliza un formato de salida y entrada de datos en modo
texto.

Se puede definir una aplicación de consola como aquella que se ejecuta en una ventana de MS-DOS, es decir, en
línea de comandos. 

Lo más común dentro del desarrollo bajo la plataforma .Net es la creación de aplicaciones Web o aplicaciones
Windows sin embargo la mejor forma de sentar unas bases firmes acerca de la programación orientada a objetos es
comenzar construyendo aplicaciones sencillas de consola. 

El primer ejemplo de aplicación de consola es un sencillo programa que pide al usuario 2 números y le pregunta si
desea sumarlos o restarlos. 

Antes de comenzar a desarrollar la aplicación se ha de conocer la clase principal que interactúa con la consola de
MS-DOS, la clase Console. 

Mediante esta clase se consigue mostrar información en la pantalla así como capturar la información que introduzca
el usuario, cabe destacar que los métodos de la clase Console son de tipo Shared, esto significa que no es
necesario crear un objeto a partir de la clase para invocar a sus métodos, es posible hacerlo indicando el nombre de
la clase seguido de un punto y el nombre del método. 

El método WriteLine() 

Este método es el que se usa para mostrar texto en la consola, el método escribe en la pantalla el valor que le
pasemos como parámetro. 

El parámetro que recibe el método puede ser de varios tipos, ya sea una cadena de caracteres, un número entero,
una línea en blanco, etc... 

VB.NET

    Module Module1 


    Sub Main() 
       'Escribimos una cadena de caracteres. 
       Console.WriteLine("Escribiendo una línea en la consola") 
       'Escribimos un numero entero 
       Console.WriteLine(23) 
       'Escribimos una comparación lógica 
       Console.WriteLine(3 > 1) 
       Console.ReadLine() 
    End Sub 
End Module

C#
using System; 

namespace ConsoleApplication2 

    class Class1 
    { 
       [STAThread] 
       static void Main(string[] args) 
       { 
       //Escribimos una cadena de caracteres. 
       Console.WriteLine("Escribiendo una línea en la consola"); 
       //Escribimos un numero entero 
       Console.WriteLine(23); 
       //Escribimos una comparación lógica 
       Console.WriteLine(3 > 1); 
       Console.ReadLine(); 
       } 
    } 
}

Es importante destacar que este método añade automáticamente el salto de carro al final de la línea, esto significa
que la siguiente llamada a Console.WriteLine() escribe en la siguiente línea. 

La última línea en la que realizamos una llamada al método ReadLine() se utiliza para evitar que la pantalla se cierre
automáticamente. 
 
Fig1: Ejemplo del método WriteLine()

El método ReadLine() 

Este método se usa para recoger la información que el usuario introduce cuando la aplicación así lo requiera.
Cuando invocamos al método Console.ReadLine() el sistema queda en espera hasta que el usuario pulsa la tecla
Intro. 

Si se asigna la llamada a Console.ReadLine() a una variable se consigue capturar el dato introducido por el usuario,
para después poder operar con él. 

VB.NET

       'Declaramos una variable de tipo cadena de caracteres 


       Dim cadena As String 
       'Mostramos un mensaje al usuario 
       Console.WriteLine("Por favor, introduzca su nombre:") 
       'Capturamos el dato introducido por el usuario 
       cadena = Console.ReadLine() 
       'Operamos con el dato 
       cadena = "El nombre introducido es: " & cadena 
       'Mostramos la cadena 
       Console.WriteLine(cadena) 
       Console.ReadLine() 

C#

       //Declaramos una variable de tipo cadena de caracteres 


       string cadena; 
       //Mostramos un mensaje al usuario 
       Console.WriteLine("Por favor, introduzca su nombre:"); 
       //Capturamos el dato introducido por el usuario 
       cadena = Console.ReadLine(); 
       //Operamos con el dato 
       cadena = "El nombre introducido es: " + cadena; 
       //Mostramos la cadena 
       Console.WriteLine(cadena); 
       Console.ReadLine();

 
Fig2: WriteLine() y ReadLine()

El método Read() 
Este es otro método que permite capturar información que proviene del usuario. La diferencia con el anterior es que
Read() no espera a que el usuario pulse intro para capturar el dato introducido, sino que lo hace tras la pulsación de
cualquier tecla, capturando el valor de la tecla pulsada en código ASCII.

Una vez que hemos aprendido a usar la clase consola, vamos a realizar una aplicación de consola.

Ahora que se conoce un poco mejor la clase Console, se dará comienzo a la aplicación, los lenguajes usados para
este ejemplo son Visual Basic.Net y C#. 

Lo primero que se debe hacer después de arrancar Visual Studio.Net, es escoger la opción "Aplicación de consola"
(Fig1), tras este paso Visual Studio genera las siguientes líneas: 
 
Fig3: Creación de una aplicación de consola.

VB.NET
Module Module1 
    Sub Main() 

    End Sub 


End Module

C#
using System; 

namespace ConsoleApplication3 

    class Class1 
    { 
       [STAThread] 
       static void Main(string[] args) 
       { 
          // 
          // TODO: Add code to start application here 
          // 
       } 
    } 
}

Dentro del procedimiento Main(), se introduce el código que se quiere ejecutar. Lo primero que hay que hacer es
declarar las variables que se van a usar, para este ejemplo se usan 2 variables de tipo entero para recoger los
valores de los números que introduzca el usuario: 

VB.NET
Module Module1 
    Sub Main() 
       Dim Numero1 As Integer 
       Dim NUmero2 As Integer 
    End Sub 
End Module 

C#
using System; 

namespace ConsoleApplication3 

    class Class1 
    { 
       [STAThread] 
       static void Main(string[] args) 
       { 
          int Numero1; 
          int Numero2; 
       } 
    } 
}

Una vez están declaradas las variables, se solicitan ambos números al usuario y se introducen sus valores en las
dos variables, a continuación se pide que se seleccione una de las opciones posibles, sumar o restar. 

VB.NET
Module Module1 
    Sub Main() 
       Dim Numero1 As Integer 
       Dim Numero2 As Integer 

       Console.WriteLine("Introduzca el primer número") 


       Numero1 = Console.ReadLine() 

       Console.WriteLine("Introduzca el segundo número") 


       Numero2 = Console.ReadLine() 

       Console.WriteLine("Escoja una opción: 1 - Sumar / 2 - Restar") 


       If (Console.ReadLine = 1) Then 
          Console.WriteLine("El resultado de la suma es: " & Numero1 + Numero2) 
          Console.ReadLine() 
       ElseIf (Console.ReadLine = 2) Then 
          Console.WriteLine("El resultado de la resta es: " & Numero1 - Numero2) 
          Console.ReadLine() 
       Else 
          Console.WriteLine("Opción Incorrecta") 
       End If 
    End Sub 
End Module

C#
using System; 

namespace ConsoleApplication2 

    class Class1 
    { 
       [STAThread] 
       static void Main(string[] args) 
       { 
          int Numero1; 
          int Numero2; 
          int opcion; 

          Console.WriteLine("Introduzca el primer número"); 


          Numero1 = Int32.Parse(Console.ReadLine()); 

          Console.WriteLine("Introduzca el segundo número"); 


          Numero2 =Int32.Parse(Console.ReadLine()); 

          Console.WriteLine("Escoja una opción: 1 - Sumar / 2 - Restar"); 


          opcion = Int32.Parse(Console.ReadLine()); 
          if (opcion == 1) 
          { 
             Console.WriteLine("El resultado de la suma es: " + (Numero1 + Numero2)); 
          } 
          else if (opcion == 2) 
          { 
             Console.WriteLine("El resultado de la resta es: " + (Numero1 - Numero2)); 
          } 
          else 
          { 
          Console.WriteLine("Opción Incorrecta"); 
          } 
          Console.ReadLine(); 
       } 
    } 
}

Siguiendo el flujo de la aplicación se puede ver que después de que el usuario selecciona una de las 2 opciones, se
muestra el resultado de la operación por pantalla. 

Si lo que se desea es encapsular el código en la medida de lo posible se pueden construir 2 funciones que realicen
las operaciones de sumar y restar y que escriben el resultado en la pantalla, el código quedaría de la siguiente
manera: 

VB.NET
Module Module1 
    Sub Main() 
       Dim Numero1 As Integer 
       Dim Numero2 As Integer 

       Console.WriteLine("Introduzca el primer número") 


       Numero1 = Console.ReadLine() 

       Console.WriteLine("Introduzca el segundo número") 


       Numero2 = Console.ReadLine() 

       Console.WriteLine("Escoja una opción: 1 - Sumar / 2 - Restar") 


       If (Console.Readline = 1) Then 
          Sumar(Numero1, Numero2) 
       ElseIf (Console.ReadLine = 2) Then 
          Restar(Numero1, Numero2) 
       Else 
          Console.WriteLine("Opción Incorrecta") 
       End If 
    End Sub 

    Sub Sumar(ByVal Numero1, ByVal Numero2) 


       Console.WriteLine("El resultado de la suma es: " & Numero1 + Numero2) 
       Console.ReadLine() 
    End Sub 

    Sub Restar(ByVal Numero1, ByVal Numero2) 


       Console.WriteLine("El resultado de la resta es: " & Numero1 - Numero2) 
       Console.ReadLine() 
    End Sub 
End Module

C#
using System; 

namespace ConsoleApplication2 

    class Class1 
    { 
       [STAThread] 
       static void Main(string[] args) 
       { 
          int Numero1; 
          int Numero2; 
          int opcion; 

          Console.WriteLine("Introduzca el primer número"); 


          Numero1 = Int32.Parse(Console.ReadLine()); 

          Console.WriteLine("Introduzca el segundo número"); 


          Numero2 =Int32.Parse(Console.ReadLine()); 

          Console.WriteLine("Escoja una opción: 1 - Sumar / 2 - Restar"); 


          opcion = Int32.Parse(Console.ReadLine()); 
          if (opcion == 1) 
          { 
             Sumar(Numero1, Numero2); 
          } 
          else if (opcion == 2) 
          { 
             Restar(Numero1, Numero2); 
          } 
          else 
          { 
             Console.WriteLine("Opción Incorrecta"); 
          } 
          Console.ReadLine(); 
       } 
       static void Sumar (int Numero1, int Numero2) 
       { 
          Console.WriteLine("El resultado de la suma es: " + (Numero1 + Numero2)); 
          Console.ReadLine(); 
       } 

       static void Restar (int Numero1, int Numero2) 


       { 
          Console.WriteLine("El resultado de la resta es: " + (Numero1 - Numero2)); 
          Console.ReadLine(); 
       } 
    } 
}

De esta manera se consigue encapsular funcionalidades dentro de la aplicación, asignando las tareas de Sumar y
Restar a dos subrutinas, la principal ventaja es que una vez hayamos asegurado que ambas subrutinas funcionan,
podremos olvidarnos de ellas y continuar con el desarrollo de la aplicación. 

El resultado de la ejecución de cualquiera de los 2 códigos anteriores es el siguiente: 

 
Fig4: Resultado del ejemplo.
creación en .NET de aplicaciones en entorno de ventanas, llamadas generalmente aplicaciones Windows.

La creación de aplicaciones Windows ha resultado siempre una tarea compleja debido a la dificultad de tener que
crear una interfaz gráfica que interactúe con el usuario. Los Formularios de Windows (Windows Forms) de .Net
permiten la creación de aplicaciones de interfaz gráfica de forma sencilla. .Net proporciona un amplio conjunto de
controles como botones, cajas de texto, etiquetas, etc. que, unidos a la completa biblioteca de clases de .Net, hace
posible el desarrollo de aplicaciones en poco tiempo. 

En los siguientes ejemplos se ha usado Visual Studio.Net, no obstante, es posible crear aplicaciones Windows con
un simple editor de texto y una herramienta de compilación compatible con el CLR de .Net Framework. Visual
Studio.Net admite diseñar la aplicación de forma visual, permitiendo en cada momento acceder al código generado y
sirviendo además como herramienta de compilación y depuración. 

Para comenzar una nueva aplicación, se ejecuta Visual Studio y se selecciona Nuevo Proyecto, donde aparecen los
distintos tipos de aplicaciones que se pueden realizar con cada lenguaje, seleccionando en este caso Aplicación
para Windows. Una vez introducido el nombre de la aplicación y la ruta donde se ubicará se pulsa Aceptar. 
 
Fig 1. Ventana de creación de nuevo proyecto.

En los siguientes ejemplos se muestra como crear una aplicación basada en formularios en los dos lenguajes más
comunes, tanto para Visual Basic .Net como para C#, dejando al lector la elección del lenguaje que le resulte más
cercano. 

Después de haber creado el proyecto, se dispone de una aplicación completa que puede ser ejecutada. Esto se
puede realizar en el menú Depurar pulsando en el elemento Iniciar (Tecla F5) lo que ejecutará directamente la
aplicación dentro de Visual Studio.Net. Véase el código creado hasta ahora: 
VB.NET
Public Class Form1 
      nbsp;   Inherits System.Windows.Forms.Form 

      + " Código generado por el Diseñador de Windows Forms " 

      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles


MyBase.Load 

      'escriba aquí su código. 

      End Sub 

End Class

Si se ha optado por C# se puede comprobar que el código es muy similar, aunque algo más extenso ya que la
inicialización por defecto esta situada fuera de la región del código que va generando automáticamente el
diseñador. 

En el código generado, el formulario 'Form1' es una clase que proviene mediante la palabra clave inherits (heredar)
del espacio de nombres System.Windows.Forms.Form perteneciente a la biblioteca de clases de .Net. Las
aplicaciones desarrolladas con .Net utilizan la biblioteca de clases incluida en el Framework de .Net que
proporcionan un conjunto de funcionalidades prefabricadas que facilitan el desarrollo. Está biblioteca de clases está
organizada en espacios de nombres dependiendo de su funcionalidad. 

Todos los lenguajes incluidos en .Net están orientados a objetos, siguiendo esta metodología el formulario 'Form1'
se declara como una clase. Como se verá más adelante esto facilita el acceso a los métodos y propiedades del
formulario y de los controles que se incluyan al tratar a cada elemento como objetos independientes.
proceso de insertar controles en una aplicación Windows. Los controles son elementos que podemos
colocar en una aplicación para interactuar con el usuario o visualizar los resultados del programa.

Los controles simplifican la creación del interfaz facilitando además la interacción ordenada del usuario con la
aplicación y la visualización de los resultados. Dentro de la región denominada "Código generado por el Diseñador
de Windows Forms", el diseñador crea automáticamente el código correspondiente a cada control según se van
añadiendo estos desde la pantalla de diseño visual. Por tanto, para insertar un nuevo control basta con arrastrarlo
desde el cuadro de herramientas al formulario de la aplicación. 

Arrastrando un control de tipo botón a nuestro formulario y analizando el código generado se observa lo
siguiente:

VB.NET
Me.Button1 = New System.Windows.Forms.Button() 

'Button1 

Me.Button1.Location = New System.Drawing.Point(184, 64) 
Me.Button1.Name = "Button1" 
Me.Button1.TabIndex = 0 
Me.Button1.Text = "Button1"

C#
this.button1 = new System.Windows.Forms.Button(); 
// 
// button1 
// 
this.button1.Location = new System.Drawing.Point(184, 88); 
this.button1.Name = "button1"; 
this.button1.TabIndex = 0; 
this.button1.Text = "button1";

Al introducir un control de tipo botón se genera en el código un objeto llamado 'button1' perteneciente a la clase
System.Windows.Forms.Button y se establecen las propiedades por defecto para ese objeto. Estas propiedades se
pueden modificar desde la vista de diseño pulsando sobre el control 'button1' y seleccionado el panel de
propiedades (Tecla F4). 

Otra forma de cambiar las propiedades de un control es modificando el código generado automáticamente por el
diseñador. A continuación se muestra un sencillo ejemplo donde se que modifica el literal de texto que aparece
sobre el botón 'button1': 

VB.NET
'load de la clase Form1 
Button1.Text = "Pulsa aquí"

C#
//load de la clase Form1 
button1.Text="Pulsa aquí";

Los eventos son llamadas al código que se producen cuando el usuario realiza una acción. Aprendemos a
utilizarlos en .NET
Los eventos son llamadas al código que se producen cuando el usuario realiza una acción como, por ejemplo,
pulsar un botón o seleccionar un elemento de una lista. Los eventos responden a la acción del usuario sobre un
control ejecutando una función situada en el código. 

A continuación se muestra un sencillo ejemplo en el que se introducen una serie de controles en la vista de diseño
modificando las propiedades tal como aparecen en la imagen. 

Al pulsar dos veces sobre el botón 'btnBoton' se crea automáticamente en el código del formulario el evento que se
corresponde con la pulsación del botón. La función creada se denomina por defecto 'btnBoton_Click' y responde al
evento btnBoton.Click que se indica por medio de la palabra clave handles (manejador). Seguidamente se muestra
el código en el evento que interactúa con el resto de controles: 

VB.NET
Private Sub btnBoton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
btnBoton.Click 

      lblResultado.Text = "Hola " & txtNombre.Text 

End Sub

C#
private void btnBoton_Click(object sender, System.EventArgs e) 
       { 
      lblResultado.Text = "Hola " + txtNombre.Text; 
       }

Cada control tiene su propia colección de eventos. Para crear un nuevo evento se utiliza el menú desplegable de
clases y su correspondiente menú de métodos situados en la parte superior del código. 

Las aplicaciones .NET utilizan objetos que podemos programar nosotros mismos. Aprendemos a trabajar
conjuntamente con los controles de las aplicaciones Windows y los objetos que podamos haber
programado.

La programación orientada a objetos proporciona un mejor ordenamiento y claridad del código. La forma de
programar consiste en dividir el código en clases de objetos que posteriormente pueden ser reutilizados. Para más
información se recomienda leer el artículo de 'Programación orientada a objetos, introducción' incluido en esta
sección. 
Al arrancar la aplicación, el punto de inicio del código se sitúa por defecto en el evento 'Load' de la clase 'Form1', si
bien se puede cambiar dentro de las propiedades del proyecto desde el explorador de soluciones. El evento 'Load'
es una subrutina que no devuelve ningún valor. En ella se pueden instanciar objetos de otras clases para ser
utilizados posteriormente. El siguiente ejemplo muestra como crear una clase propia y la instanciación de un objeto
de dicha clase: 

VB.NET
Public Class MiClaseSumar 

   Public resultado As Integer 

   Public Function sumar(ByVal NumSuma1 As Integer, ByVal NumSuma2 As Integer) As Integer 

          Return NumSuma1 + NumSuma2 

       End Function 

End Class

C#
public class MiClaseSumar 
    { 
    public int resultado; 

    public int sumar(int NumSuma1, int NumSuma2) 


       { 
       return NumSuma1 + NumSuma2; 
       }
    }
En el evento load de Form1 se crea un objeto de la clase y se llama al método sumar. 

VB.NET
'load de la clase Form1 
Me.Text = " Mi primera Aplicación con Windows Forms" 

Dim objetoSuma As New MiClaseSumar() 


objetoSuma.resultado = objetoSuma.sumar (10, 5) 'resultado = 15 

lblResultado.Text = objetoSuma.resultado

C#
//load de la clase Form1 
this.Text = " Mi primera Aplicación con Windows Forms"; 

MiClaseSumar objetoSuma = new WindowsApplication2.MiClaseSumar(); 


objetoSuma.resultado = objetoSuma.sumar(10,5); //resultado = 15 

lblResultado.Text = objetoSuma.resultado.ToString();

Se puede observar como en C# es necesario convertir previamente el resultado. Esto se debe a que el resultado de
la suma es de tipo numérico y no se puede asignar directamente al texto de la etiqueta, por lo que se debe convertir
previamente a tipo texto. Esto no es necesario en Visual Basic .Net, donde la conversión de tipos no es obligatoria,
aunque es recomendable para obtener un código más óptimo. 

Con la programación orientada a objetos resulta más fácil programar aplicaciones ya que el código está mejor
estructurado y resulta más sencillo de leer y modificar. Además, Visual Studio .Net facilita en gran medida la
creación de aplicaciones con interfaz gráfico al generar automáticamente el código encargado de visualizar
formularios y controles. 

Recursos: 

101 Visual Basic and C# Code Samples 


http://www.microsoft.com/downloads/details.aspx?FamilyID=08e3d5f8-033d-420b-a3b1-
3074505c03f3&DisplayLang=en

Una aplicación de ASP.NET tiene opciones de configuración y administración. Aquí se verá como configurar
y ejecutar una aplicación web de ASP.NET a partir de servidores web como Internet Information Server.

Existen diversos elementos de configuración y administración en una aplicación Web de ASP.Net. Este tipo de
aplicaciones se compone de un conjunto de ficheros almacenados en una carpeta dentro del servidor Web. 

Para ejecutar una aplicación Web de ASP.Net se necesita que el servidor Web sea compatible con ASP.Net. En
este caso se va a utilizar IIS 5.0 (Internet Information Server) como servidor Web. El IIS es un componente de
Windows incluido en las versiones profesionales de Windows 2000 y XP. Si no se tiene este componente, se debe
proceder a su instalación mediante el icono de 'Agregar o quitar programas' en el panel de control y seleccionando
'Agregar o quitar componentes de Windows' en donde aparecerá el IIS para su instalación. El acceso al IIS se
realiza mediante el icono de 'Servicios de Internet Information Server' situado en las 'Herramientas administrativas'
dentro del panel de control. 

El servidor Web IIS permite administrar las aplicaciones Web y comunicarse con los navegadores cliente mediante
protocolo http (protocolo de transferencia de hipertexto). El IIS también ofrece otros servicios de protocolo, como
transferencia de archivos (FTP), servicio de correo electrónico (SMTP) y servicio de noticias (NNTP).  

Con el clásico ASP 3.0 era suficiente con tener el IIS instalado en el servidor Web, ya que era el IIS el que
directamente interpretaba el código ASP y enviaba la respuesta al cliente. Sin embargo, en ASP.Net se necesita que
el servidor Web tenga instalado .Net Framework para poder procesar código de ASP.Net, como ocurre con cualquier
otra aplicación de .Net. Es importante decir que los navegadores cliente que accedan a la aplicación Web no
necesitan tener instalado IIS ni tampoco .Net Framework ya que es el servidor Web el que tiene que saber
interpretar el código de ASP.Net. 

Cuando se solicita una página de tipo .aspx (página de ASP.Net) el servidor Web de IIS envía la solicitud a .Net
Framework que es quien realmente procesa la petición de la página. De esta forma, las aplicaciones Web de
ASP.Net se benefician de todas la ventajas de ejecución de código en .Net Framework, ya que el código es
compilado y ejecutado por .Net Framework y devuelto al IIS para que éste a su vez lo envíe al cliente.  

Con ASP.Net también es posible tener código de ASP 3.0 dentro de páginas de ASP.Net, con la ventaja de que el
código de ASP 3.0 también se compila junto con el código de ASP.Net aumentando el rendimiento del servidor Web.

A continuación, se muestra un ejemplo de los distintos ficheros que pueden existir en una aplicación Web de
ASP.Net.
Fig. Aplicación Web de ASP.Net

Una vez creada la aplicación, el código de servidor se ensambla en un fichero .dll situado en la carpeta Bin de la
aplicación Web. Por tanto, una vez realizada la compilación, los ficheros de código (.vb ó .cs) ya no son necesarios
para la ejecución de la aplicación ya que están ensamblados en la dll y es aconsejable quitarlos del servidor para
que no se pueda acceder desde el exterior a su contenido. 
En resumen, para que funcione una aplicación Web de ASP.Net se debe tener en el Servidor Web lo siguiente:
 Tener instalado IIS 5.0 ó superior en el servidor Web y configurar un directorio virtual asociado a la aplicación
Web.
 Tener instalado en el servidor Web .Net Framework.
 Los archivos .aspx correspondientes a las páginas Web.
 Un archivo de ensamblado (DLL) situado en la carpeta Bin de la aplicación Web, que contiene el código de
servidor que necesitan las páginas aspx.
 Un archivo llamado Global.asax que sirve para el control general de la aplicación durante su ejecución.
 Un archivo llamado Web.config donde se establece la configuración de la aplicación. Aunque este fichero es
opcional se necesita cuando se quieren establecer parámetros de configuración que no sean los de por
defecto.
 De manera adicional también puede aparecer en la carpeta Web otro tipo de archivos como:
o Archivos .ascx (controles personalizados de usuario de ASP.Net)
o Archivos .asmx (servicios Web XML de ASP.Net).
o Páginas .htm ó .html (páginas Web estáticas)
o Páginas .asp (páginas activas de servidor)
o Archivos .css (hojas de estilo CSS, Cascade Style Sheet).
o Documentos, imágenes, etc...

Para terminar, se va a crear una aplicación Web de tipo ASP.Net y a instalarla en un servidor Web con IIS. El primer
paso es crear la aplicación Web, para ello se entra en Visual Studio .Net y en el menú 'Archivo' se selecciona 'Nuevo
proyecto'. Aquí se debe elegir uno de los lenguajes disponibles y seleccionar 'Aplicación Web ASP.Net'. 
Fig. Creación de una aplicación Web de ASP.Net

De forma automática, al crear un nuevo proyecto Web, Visual Studio .Net crea un directorio virtual en el IIS y lo
asocia con la aplicación Web. Si se ha instalado IIS con la configuración por defecto, el sitio Web predeterminado
(localhost) será 'c:\inetpub\wwwroot'. 

En el caso de que se tuviera una aplicación Web de ASP.Net ya creada y se desee instalar en un servidor Web, se
debe copiar la carpeta con la aplicación en el servidor Web y asociarla manualmente a un directorio virtual. Para
ello, dentro de IIS se selecciona el elemento de 'Sitio Web predeterminado' y pulsando con el botón derecho se
selecciona la opción: 'Nuevo' > 'Directorio virtual' donde mediante un asistente se asocia la carpeta de la aplicación
Web a un directorio virtual en el servidor.

Fig. Creación de un directorio virtual en IIS

Para probar que la aplicación Web funciona correctamente se debe compilar primero en Visual Studio .Net y
posteriormente acceder a la aplicación mediante el navegador: 

http://[Nombre_del_servidor]/[directorio_virtual]/[página] 

Por ejemplo, http://localhost/MiWeb/webform1.aspx


novedades que se presentan en Visual Basic 2010.

Confluencia y evolución conjunta de VB y C#

Antes de comenzar con las novedades del lenguaje, queremos mencionar un hecho especialmente destacable: la
evolución paralela de funcionalidades que a partir de Visual Studio 2010 experimentarán y ofrecerán los dos
principales lenguajes de la plataforma: Visual Basic y C#. 
Desde la primera versión de .NET Framework, los equipos de desarrollo de estos dos lenguajes han procurado
marcar algunas diferencias entre ambos, siendo su intención la de hacer de Visual Basic un lenguaje más atractivo
al desarrollador de aplicaciones de gestión, mientras que C# se pretendía dirigir a los programadores más
orientados hacia el desarrollo a más “bajo nivel”: componentes, servicios, etc. Scott Wiltamuth, uno de los directores
de la división de lenguajes de Visual Studio, menciona que llevar estos objetivos a la práctica resultó más
complicado de lo esperado, debido a la presencia de lo que él denomina “poderosas fuerzas de unificación” que han
propiciado un cambio de orientación hacia el desarrollo en paralelo de funcionalidades para los dos lenguajes,
como:
 La existencia de un entorno de desarrollo integrado y bloques de construcción de aplicaciones comunes a
ambos lenguajes.
 La naturaleza orientada a objetos y el sistema de tipos común a los dos lenguajes.
 El hecho de que las principales áreas de innovación presente y futura en el desarrollo de los lenguajes se
reflejan en partes “exteriores” de los mismos, como ocurre en el caso de LINQ.

A los elementos anteriores hay que añadir las demandas de las comunidades de desarrolladores, ya que los
programadores de VB querían aquellas funcionalidades disponibles en C# de las que VB carecía, y viceversa.
Todo ello ha propiciado el cambio de estrategia que acabamos de mencionar, que tiene el claro objetivo de que,
independientemente del lenguaje que utilicemos, podamos aprovechar toda la potencia que .NET Framework pone a
nuestra disposición.

Propiedades auto-implementadas

Antes de la llegada de Visual Basic 2010 (o Visual Basic 10, como también se denomina), cada vez que en una
clase se definía una propiedad, estábamos obligados a codificar por completo sus bloques de acceso/asignación
(Get/Set), aún cuando la propiedad no necesitara una lógica especial para dichas operaciones. A partir de esta
nueva versión, es posible crear propiedades auto-implementadas, que se declaran en una simple línea de código sin
necesidad de especificar los bloques Get/Set; con la ventaja adicional de poder asignar al mismo tiempo un valor
predeterminado

Al crear una propiedad de este modo, el compilador genera internamente un campo de respaldo con ámbito de
clase, cuyo nombre se compone de un guión bajo y el nombre de la propiedad. Dicho campo es perfectamente
accesible desde el código de la clase, aunque no es expuesto a través de IntelliSense.

Las propiedades auto implementadas sufren algunas restricciones: no pueden ser declaradas con los
modificadores ReadOnly ni WriteOnly, y en el caso de que la propiedad vaya a contener un array, no
podemos especificar la dimensión del mismo en la declaración, aunque sí es posible inicializarlo, como
vemos en los ejemplos del listado 1.

Inicializadores de colecciones

La manera que hasta ahora teníamos de inicializar una colección con un conjunto de valores consistía en llamar
sucesivamente a su método Add, pero Visual Basic 2010 aporta una nueva sintaxis más sucinta para esta tarea,
consistente en utilizar la palabra clave From en el momento de crear la colección, seguida de una lista con los
valores de inicialización encerrados entre llaves; internamente, el compilador generará una llamada al método Add
de la colección por cada uno de los elementos existentes en la lista. El listado 2 presenta un ejemplo basado en la
clase Libro del listado 1.

Listado 1. Propiedades auto-implementadas 


Public Class Libro 
Public Property Título As String 
Public Property Autor As String 
Public Property Precio As Decimal 
Public Property Editorial 

As String = "Netalia" 

' La siguiente línea produce un error de compilación: 


' Public Property Distribuidores Varios(10) As String 

' La siguiente línea es correcta para crear una 


' propiedad que contenga un array: 

Public Property Distribuidores 


As String() = New String() { 
"Distribuidor01", "Distribuidor02" } 
Public Sub VerCamposRespaldo() 
Console.WriteLine(_Título) 
Console.WriteLine(_Autor) 
Console.WriteLine(_Precio) 
Console.WriteLine(_Editorial) 
Console.ReadLine() 

End Sub 
End Class

Listado 2. Inicializadores de colecciones

Dim lstLibros1 As List(Of Libro) = New List(Of Libro) From { 

New Libro() With { 

.Título = "El camino", .Autor = "Miguel Delibes", 

.Precio = 18.00D, .Editorial = "Ediciones Destino" 

}, 

New Libro() With { 


.Título = "El caballero de Olmedo", .Autor = "Lope de Vega", 

.Precio = 11.50D, .Editorial = "Vicens-Vives" 

Listado 3 

Dim lstLibros2 As New List(Of Libro) From { 

{"El camino", "Miguel Delibes", 18.00D, "Ediciones Destino"}, 

{"El caballero de Olmedo", "Lope de Vega", 11.50D, "Vicens-Vives"} } 

'------------------------------------------------------

<Extension()> 

Public Sub Add(ByVal lstLibros As List(Of Libro), 

ByVal sTítulo As String, 


ByVal sAutor As String, 

ByVal dPrecio As Decimal, 

ByVal sEditorial As String) 

lstLibros.Add(New Libro() With { .Título = sTítulo, .Autor = sAutor, 

.Precio = dPrecio, .Editorial = sEditorial }) 

End Sub

Pero, al inicializar colecciones como la del listado 2, ¿no sería estupendo poder pasar solamente los valores para
las propiedades de cada objeto de la colección, y que ésta se encargara de instanciar los objetos? Esto es
perfectamente posible creando un método de extensión con el nombre Add para la colección List(OfLibro), lo que
hará posible utilizar una sintaxis de inicialización mucho más simple, como muestra el listado 3.

En el caso de que estemos desarrollando una colección propia en la que deseemos que esté disponible esta sintaxis
de inicialización, es preciso implementar la interfaz IEnumerable, o al menos cumplir con el patrón IEnumerable, es
decir, implementar métodos GetEnumeratory Add. Con respecto al método Add, podemos crear una sobrecarga que
facilite la sintaxis de inicialización para nuestra colección, o bien un método de extensión como en el caso anterior.
En el listado 4 vemos un ejemplo.

Continuación de línea implícita


Suponemos que para la inmensa mayoría de aquellos que programan con Visual Basic siempre ha resultado un
fastidio tener que utilizar el carácter de guión bajo (subrayado) para separar en varias líneas físicas una misma línea
lógica de código. Gracias a la nueva característica de continuación de línea implícita en Visual Basic 2010, ahora
será posible obviar el guión bajo al continuar una instrucción en la línea siguiente en una gran cantidad de lugares
de nuestro código. 
La especificación del lenguaje [3] detalla todas las situaciones en las que el carácter de continuación puede omitirse.
Los listados 1-4 incluyen múltiples ejemplos de continuaciones de línea implícitas.

Listado 4 
Dim colBiblioteca1 As New Biblioteca() From { 

New Libro() With { 


.Título = "El camino", .Autor = "Miguel Delibes", 
.Precio = 18.00D, .Editorial = "Ediciones Destino" }, 

New Libro() With { 


.Título = "El caballero de Olmedo", .Autor = "Lope de Vega", 
.Precio = 11.50D, .Editorial = "Vicens-Vives" } 

Dim colBiblioteca2 As New Biblioteca() From { 


{"El camino", "Miguel Delibes", 18.00D, "Ediciones Destino"}, 
{"El caballero de Olmedo", "Lope de Vega", 11.50D, "Vicens-Vives"} } 

'-----------------------------------

Public Class Biblioteca 


Implements IEnumerable(Of Libro) 
Private lstLibros As List(Of Libro) 

Public Sub New() 


Me.lstLibros = New List(Of Libro) 
End Sub 

Public Sub Add(ByVal oLibro As Libro) 


lstLibros.Add(oLibro) 

End Sub 

Public Sub Add(ByVal sTítulo As String, 


ByVal sAutor As String, 
ByVal dPrecio As Integer 
ByVal sEditorial As String) 
lstLibros.Add(New Libro() With { 
.Título = sTítulo, .Autor = sAutor, 
.Precio = dPrecio, .Editorial = sEditorial }) 

End Sub 

Public Function GetEnumerator() 


As System.Collections.Generic.IEnumerator(Of Libro) 
Implements System.Collections.Generic.IEnumerable(Of Libro).GetEnumerator 

Return lstLibros.GetEnumerator() 
End Function 
End Class

Expresiones lambda

Las expresiones lambda fueron introducidas en Visual Basic 2008, pero entonces solo podían constar de una única
línea de código, siendo también obligatorio que la expresión devolviera un valor. Esta restricción ha sido superada
en Visual Basic 2010, donde podemos escribir expresiones lambda compuestas por varias líneas de código. Como
novedad adicional, además de crear expresiones que devuelvan un valor (comportamiento habitual), podemos crear
otras que no devuelvan resultado alguno (al estilo de un procedimiento Sub) utilizando un delegado de tipo Action(Of
T), como se muestra en el listado 5.
Covarianza y contravarianza

Cuando trabajamos con tipos genéricos que mantienen una relación de herencia, debemos tener en cuenta ciertas
restricciones impuestas por la plataforma de las que a priori podemos no ser conscientes, ya que asumimos que
deberían funcionar por una simple cuestión de principios lógicos en los que se basa la OOP. Tomemos como
ejemplo el listado 6.

Listado 5 
Dim Lambda01 As Func(Of Integer, String) = 

Function(nNumero As Integer) 
Dim nNuevoNumero As Integer 
Dim sResultado As String 
nNuevoNumero = nNumero * 7 
sResultado = "El resultado es: " & nNuevoNumero.ToString() 
Return sResultado 

End Function 

Console.WriteLine(Lambda01(123)) 

Dim Lambda02 = 

Function(nDiasAgregar As Double) As DateTime 


Dim dtFechaActual As DateTime = DateTime.Today 
Dim dtFechaNueva As DateTime = 

dtFechaActual.AddDays(nDiasAgregar) 
Return dtFechaNueva 
End Function 

Console.WriteLine(Lambda02(5).ToString("dd-MMMM-yyyy")) 

' Expresión lambda de tipo Sub 

Dim Lambda03 = 
Sub(sNombre As String, dtFechaNacimiento As DateTime) 

Dim sMensajeCompleto As String = sNombre & 


" nacido en " & 
dtFechaNacimiento.ToString("yyyy") 

Console.WriteLine(sMensajeCompleto) 

End Sub 
Lambda03("Ernesto Naranjo", New DateTime(1970, 10, 18)) 
' Expresión lambda de tipo Sub con declaración estricta 
' usando Action(Of T) 

Dim Lambda04 As Action(Of String) = 


Sub(sMensaje) 
Console.WriteLine(sMensaje) 

End Sub 

Lambda04("Hola mundo!")

Listado 6 
Public Class Documento 
Public Property Texto As String 
Public Property Autor As String 

End Class 

Public Class Carta 


Inherits Documento 
Public Property Destinatario As String 

End Class 

Public Class Acta 


Inherits Documento 
Public Property DepartamentoEmisor As String 
Public Property Fecha As DateTime 

End Class 

'---------------------------------------

Dim ilstCartas As IList(Of Carta) = New List(Of Carta) From { 


New Carta() With {.Texto = "AAA", .Autor = "Bea", 
.Destinatario = "Tom"}, 
New Carta() With {.Texto = "BBB", .Autor = "María", 
.Destinatario = "Ana"} 

' error de ejecución 

Dim ilstDocumentos As IList(Of Documento) = ilstCartas

Si el intento de asignación de un objeto del tipo IList(Of Carta)a una variable del tipo IList(Of Documento) no
produjera un error en tiempo de ejecución, podríamos reasignar a uno de los elementos de IList(OfDocumento)un
tipo Actae intentar seguidamente extraerlo como un tipo Carta, como vemos en el listado 7, lo que provocaría una
ruptura en el sistema de seguridad de tipos de la plataforma.
Listado 7 
ilstDocumentos(1) = New Acta() With { 

.Texto = "cccc", .Autor = "Ignacio", 

.DepartamentoEmisor = "Contabilidad", 

.Fecha = DateTime.Today } 

Dim oCarta As Carta = ilstCartas(1)

La versión 4 de .NET Framework levanta en ciertos casos estas restricciones, permitiendo la conversión implícita o
varianza entre ciertos tipos de interfaces en dos modalidades diferentes: covarianza y contravarianza. 
La covarianza permite asignar a un tipo como IEnumerable(Of T), en el que T esté situado en un nivel superior de la
jerarquía, un valor de tipo IEnumerable(Of T) cuyo T sea un descendiente, sin que se produzca error. El compilador
acepta esto debido a que dicha interfaz está definida dentro de la plataforma como IEnumerable(Of Out T), lo que
indica que el tipo T solamente podrá ser manipulado en operaciones “de salida”. De esta manera, es posible escribir
el código del listado 8.

Por otra parte, la contravarianza produce, en cierto sentido, un efecto opuesto al anterior, ya que permite, por
ejemplo, que en un tipo derivado T del que hemos creado una colección List(Of T), una operación/ método como
Sort sea llevada a cabo por un tipo superior en la jerarquía de clases de T mediante la interfaz IComparer( Of T).
Ello es posible porque la interfaz está definida dentro de la plataforma como IComparer(Of In T), lo que indica que T
solamente podrá ser manipulado en operaciones “de entrada”. El listado 9 muestra un ejemplo de este caso.
Listado 8 
Dim ienumCarta As IEnumerable(Of Carta) = New List(Of Carta) From { 
New Carta() With {.Texto = "AAA", .Autor = "Bea", .Destinatario = "Tom"}, 
New Carta() With {.Texto = "BBB", .Autor = "María", .Destinatario = "Ana"} 


Dim ienumDocumento As IEnumerable(Of Documento) = ienumCarta

Listado 9 
Public Class ComparadorDocumentos 
Implements IComparer(Of Documento) 
Public Function Compare(ByVal x As Documento, ByVal y As Documento) As Integer 
Implements System.Collections.Generic.IComparer(Of Documento).Compare 

'.... 

End Function 
End Class 

'-------------------------------- 

Dim lstCartas As List(Of Carta) = New List(Of Carta) From { 


New Carta With {.Texto = "XXX", .Autor = "Sole", .Destinatario = "Bob"}, 
New Carta With {.Texto = "YYY", .Autor = "Ana", .Destinatario = "Alex"}, 
New Carta With {.Texto = "ZZZ", .Autor = "Marta", .Destinatario = "David"} 


Dim icompDocumentos As IComparer(Of Documento) = New ComparadorDocumentos() 
lstCartas.Sort(icompDocumentos)

Para una descripción en mayor profundidad de esta nueva característica de Visual Basic, también presente en C#,
recomendamos la consulta del artículo sobre este tema que publicó recientemente dotNetManía [2].

Otras novedades adicionales

Otras novedades adicionales que incorpora Visual Basic 2010 son las siguientes:
 La opción /langversion del compilador nos permite especificar la versión del lenguaje con la que se compilará
nuestro código.
 Haciendo uso del enlace tardío del que siempre ha gozado Visual Basic, ahora es posible acceder a objetos
creados en lenguajes dinámicos como Iron Python e Iron Ruby.
 Al desarrollar aplicaciones que acceden a objetos COM, tales como los componentes de Office, ahora es
posible incrustar directamente en nuestro ensamblado la información de tipos asociada a los objetos COM, en
lugar de tener que importarla desde el ensamblado PIA suministrado por el fabricante.

En el centro de recursos del lenguaje [3], encontrará información ampliada y todo tipo de recursos para sacarle el
mayor partido a todas las nuevas características.
Con toda seguridad, la oferta de funcionalidades del nuevo Visual Basic 2010 será bien recibida por todos los
desarrolladores que utilizan este lenguaje. Esperamos que este rápido repaso sirva para conseguir una mejor toma
de contacto con las novedades aquí presentadas.

Microsoft nos tiene preparadas para la próxima versión de Workflow Foundation, que vendrá de la mano de
la versión 4.0 de .NET Framework y de Visual Studio 2010.

Como todos los desarrolladores de software sabemos, crear programas es una actividad gratificante y que impone
una enorme cantidad de retos. Desde el principio de los tiempos, los programadores siempre andamos buscando y
creando herramientas, librerías, marcos de trabajo, etc. que nos simplifiquen la solución de las tareas y nos faciliten
el desarrollo de las aplicaciones y servicios que nuestros clientes y jefes necesitan.

La mayoría de las complejidades de una aplicación no se ven a simple vista en el software que habitualmente
creamos. Me refiero a cosas como la ejecución en paralelo, la sincronización de procesos, las llamadas a
procedimientos remotos, etc. Detalles que tendríamos que ir resolviendo en cada desarrollo específico si no
contásemos con herramientas como a las que me refería anteriormente.

Workflow Foundation provee al desarrollador de una caja de herramientas que permite abstraernos de muchos de
esos detalles y centrarnos en los aspectos importantes del negocio de la mano que nos da de comer: mejorar
procesos y herramientas para aumentar la productividad y reducir costes; permitiendo que el desarrollador sea más
productivo, que las aplicaciones sean más sencillas de modificar y más fácilmente actualizables.

Si queréis saber más sobre los conceptos que se esconden detrás de Workflow Foundation, os recomiendo que le
echéis un vistazo a "The Workflow Way"
Nuevas características

Para esta nueva versión de .NET Framework, se han introducidos grandes cambios en la versión correspondiente
de Workflow Foundation, que llamaremos WF4, con respecto a las versiones incluidas en .NET 3.0 y 3.5 (a las que
nos referiremos por WF3). El equipo ha revisado el núcleo del modelo de programación, el runtime y las
herramientas, y ha reestructurado cada uno de ellos para mejorar el rendimiento y la productividad, así como para
añadir algunas de las propuestas más importantes recibidas a través del feedback de los usuarios actuales.

La gran mayoría de los cambios que encontrarán los desarrolladores en WF4 con respecto a WF3 han sido
necesarios para mejorar la experiencia de utilización de Workflow Foundation y hacer de él cada vez más una pieza
fundamental en el desarrollo de aplicaciones .NET. Es importante destacar que todos esos cambios se han
realizado manteniendo la compatibilidad hacia atrás. Los nuevos componentes del framework están localizados en
un nuevo ensamblado llamado System. Activities.dll, mientras que los componentes compatibles con versiones
anteriores se encuentran en System.Workflow.dll, de manera que podemos migrar sin tocar nada de código las
aplicaciones que ya tengamos desarrolladas con WF3.

Nota: En esta nueva versión se han revisado el núcleo del modelo de programación, el runtime y las herramientas.

Diseñadores 
El diseñador de workflows es la parte más visible de Workflow Foundation, y para el equipo de Visual Studio 2010
los objetivos principales en este sentido han sido la usabilidad y el rendimiento. Los diseñadores de actividades
están basados en Windows Presentation Foundation (WPF), aprovechando todas las capacidades que éste aporta.
A partir de ahora, podremos definir en XAML nuestras actividades, para luego verlas e interactuar con ellas. Una
novedad muy interesante es la posibilidad de alojar (host) el diseñador en nuestras aplicaciones, de forma que
nuestros los usuarios puedan interactuar con los flujos de trabajo de una manera mucho más fácil y natural.
Flujo de datos 
En WF3, el flujo de datos dentro de un workflow era algo oscuro. WF4 nos ofrece un modelo de flujo de datos
mucho más claro y conciso en el uso de parámetros y variables. Estos conceptos, que son familiares a los
desarrolladores, simplifican tanto la definición del almacén de datos como su viaje a través de flujos y actividades.
Este nuevo modelo, a la vez, hace más obvias las entradas y salidas esperadas de una actividad, y mejora el
rendimiento del runtime en la medida en que los datos son administrados con más eficiencia.

Diagramas de flujo 
En WF4 aparece una nueva actividad de control de flujo llamada Flow- Chart, de manera que los desarrolladores
puedan definir un workflow usando el modelo de diagramas de flujo, algo mucho más similar y cercano a los
conceptos que muchos analistas y desarrolladores manejan habitualmente cuando crean soluciones o diseñan
procesos de negocio, por lo que tenía sentido proveer de una actividad que hiciese más sencillo modelar este
concepto. Este nuevo control permite trabajar con operaciones como volver a pasos anteriores, dividir la lógica en
base a una condición, etc.

Modelo de programación 
En WF4, se renueva el modelo de programación de Workflow Foundation para hacerlo más simple y más robusto.
La clase base en este modelo de programación es WorkflowElement, que sirve para representar tanto workflows
como actividades. Además, ya no necesitamos crear un Workflow- Runtime para invocar a un workflow; tan solo
necesitamos crear una instancia del flujo y ejecutarla, lo que simplifica la creación de tests unitarios y elimina la
necesidad de crear un entorno apropiado cada vez que queremos instanciar un flujo.

Integración con WCF 


Las ventajas que ofrece Workflow Foundation se aplican tanto a crear servicios y consumirlos como a coordinarlos.
Para WF4, se ha hecho un gran esfuerzo en la integración de WCF y WF, y el resultado de ello se traducirá en
nuevas actividades de mensajería, coordinación de mensajes y un soporte para alojar servicios mejorados, junto a
una forma de definir declarativamente esos servicios.

Plantillas de flujos y el diseñador 


WF4 incorpora muchas actividades, y Visual Studio 2010 incluye dos plantillas para definir workflows: secuencial
(sequential) y de diagrama de flujo (flowchart). Aunque cualquier objeto WorkflowElement puede ser ejecutado como
un workflow, estas dos plantillas nos ofrecen los patrones de diseño más comunes a la hora de definir la lógica de
negocio. En la figura 1 vemos un ejemplo de flujo de trabajo secuencial que define lo que ocurre cuando se recibe
un pedido: se guarda y se notifica a otros servicios.
Por su parte, los flujos de tipo flowchart se han introducido en WF4 a petición de un montón de desarrolladores que
desean trabajar en base a paradigmas más parecidos a aquellos con los que suelen razonar. Por ejemplo,
imaginemos un escenario en el que entran en juego parámetros de un usuario en nuestra aplicación. Como
respuesta a los datos introducidos, nuestro sistema debería continuar con el proceso o volver a un paso anterior
para que el usuario vuelva a introducirlos. En un flujo secuencial, esto se modelaría mediante algo parecido a la
figura 2, donde la actividad DoWhile se usa para continuar procesando hasta que se cumpla una cierta condición.
La figura 2 es muy correcta; pero como desarrolladores o analistas, esta figura no nos dice gran cosa. Sin embargo,
el diagrama de flujo que se muestra en la figura 3, que hace exactamente lo mismo, es mucho más parecido a lo
que estábamos pensando cuando lo definimos.
Actividades de flowchart 
Cuando diseñemos flujos de tipo flowchart, podremos usar muchas más actividades para controlar el flujo de
ejecución de nuestros workflows. Estas actividades nos aportan pasos simples, o puntos de decisión basados en
una condición o un switch. El poder real de los diagramas de flujo reside en la posibilidad de conectar estos tipos de
nodos para conformar los flujos deseados.

 Flowchart. Es un contenedor de pasos del workflow. Cada paso puede ser una actividad o cualquiera de los
siguientes elementos de esta lista, que para ser ejecutados deberán estar conectados dentro del flowchart.
 FlowDecision. Es un bifurcador lógico basado en una condición.
 FlowSwitch. Permite varias ramas de ejecución basadas en una expresión.
 FlowStep. Representa un paso en el flujo de ejecución, con la posibilidad de estar conectado a otros pasos.

Es importante darse cuenta de que, mientras que hay actividades específicas para este modelo de flowchart,
podemos usar otras actividades en el workflow. Una actividad de tipo flowchart se puede añadir a otra actividad para
que aporte la semántica de ejecución y diseño de un diagrama de flujo. Es decir, podemos tener una secuencia con
muchas actividades y un flowchart justo en el medio.

La actividad Interop 
Para aquellos que tenemos workflows y actividades ya definidos en WF3, la actividad Interop puede sernos muy útil
para reusar lo que ya tenemos hecho. Esta actividad nos permite incorporar a un modelo de WF4 las actividades
que ya tengamos definidas bajo un modelo WF3, mapeando las propiedades que tengamos como parámetros en el
modelo de WF4. Al ser estas propiedades parámetros, podremos utilizar expresiones para definir valores. En la
figura 4 se muestra la configuración de una actividad Interop que llama a una actividad de WF3. Los parámetros son
definidos a través de referencias a variables definidas en el workflow.
Actividades de "mensajería" 
Uno de los puntos más importantes en WF4 es la mejora en la integración de WF y WCF. Desde el punto de vista de
los workflows, esto se traduce en tener actividades que modelen diferentes operaciones de "mensajería", tales como
enviar o recibir mensajes. Actualmente hay varias actividades para ello, cada una con una funcionalidad y sentido
algo diferentes:
 Send/Receive. Actividades de un solo sentido para enviar o recibir mensajes. Estas actividades se componen
de interacciones petición/respuesta.
 ReceiveAndSendReply. Modela una operación que recibe un mensaje y devuelve una respuesta.
 SendAndReceiveReply. Invoca a un servicio y recibe la respuesta.
 SendParameters/ReceiveParameters. Invoca o implementa una operación de servicio usando varios
parámetros.

Para hacer una llamada a un método de un servicio desde un workflow, seguiremos los pasos normales de
añadir una referencia al servicio a nuestro proyecto de Workflow Foundation. Visual Studio creará una actividad
personalizada para cada método que se encuentre en el contrato del servicio. Podéis pensar en esto como algo
similar a un proxy WCF para WF. Por ejemplo, si disponemos de un servicio que busca reservas de hoteles con
el contrato que se muestra en el listado 1, al añadir una referencia a él nos aparecerá una actividad
personalizada como la de la figura 5.

[ServiceContract]
public interface ISearchHotels
{
[OperationContract]
List<HotelSearchResult> SearchHotels( HotelSearchRequest
requestDetails);
}

Todo lo anterior y mucho más nos espera a partir del próximo abril; un sinfín de mejoras en cuanto a rendimiento,
productividad y facilidades a la hora de definir la lógica de negocio. Si quiere tener una visión más detallada de las
características que hemos presentado aquí, así como de algunas otras que se nos han quedado en el tintero, visite 
Workflow Foundation 4 Beta 1.

InstallShield es una aplicación que permite generar instaladores de aplicaciones desde hace aproximadamente 20
años.

Hasta la versión 2008 de Visual Studio, existían plantillas propias de Instalador además de la posibilidad de publicar
las aplicaciones a través de ClickOnce.

Con Visual Studio 2010, se introdujo una versión Limitada de InstallShield dando a los desarrolladores nuevas
posibilidades, sin quitar las ya existentes.

Para poder comenzar a utilizar este tipo de proyecto, vamos a necesitar:

 Registrarnos en la página propietaria de Installshield . Lo cual lo podremos realizar desde el propio Visual
Studio
 Descargar el paquete de InstallShield
 Una vez descargado, será necesario reiniciar Visual Studio.
 A continuación al agregar un nuevo proyecto de tipo InstallShield nos dará la posibilidad de Activar la Edición
Limitada con el Serial que habrá llegado al email que utilizamos a la hora de realizar el registro.

Para comenzar a utilizar el setup, vamos a definir una solución en Visual Studio con un proyecto simple en el
lenguaje que deseéis, donde vamos a definir un botón, con un MessageBox.

A nuestra solución en Visual Studio, agregaremos un nuevo proyecto de tipo “InstallShield Limited Edition Project”.
Al agregar este nuevo proyecto, vamos a poder observar por un lado un asistente que nos permitirá definir el Setup,
y en el “Explorador de Soluciones”, en el proyecto que acabamos de crear aparecerá la estructura del Setup, la cual
detallaremos más adelante.

El asistente de Installshield

El asistente se va a mostrar en VS con una pantalla representativa de los pasos de un Setup.

Dentro de esta pantalla podremos encontrarnos con una barra de botones que nos van a permitir, a lo largo de los
distintos pasos del asistente, por cada etapa, así como ir a un paso concreto, o volver a la pantalla de inicio del
asistente.
A continuación vamos a tratar cada uno de los pasos de manera individual:

Application Information (Información de la Aplicación): 


Durante esta etapa, definiremos características generales de la aplicación:

 Nombre de la Empresa.
 Nombre de la Aplicación.
 Versión de la Aplicación.
 Página WEB de la empresa.

Además de lo indicado, podremos indicar el icono que se visualizará en el Panel de Control a la hora de agregar y
quitar programas. También podremos cambiar el directorio de Instalación por defecto.

Más adelante veremos más opciones configurables desde el explorador de Soluciones.

Installation Requeriments (Prerrequisitos)


El siguiente paso del asistente va a permitir definir los prerrequisitos de instalación de nuestra Aplicación.

Podemos especificar si la aplicación necesita algún Sistema Operativo concreto para funcionar, o si necesitamos
algún Software para que funcione.

En el caso de necesitar un Software distinto, podemos especificar el mensaje de error que aparecerá durante la
instalación.
También podremos definir acciones personalizadas como son:

 Entradas en el Registro de Windows


 Buscar un fichero o Carpeta en el Equipo de Destino de la instalación.
 Buscar un valor en un fichero INI…

Installation Architecture (Arquitectura de la Instalación)

Este paso no se encuentra disponible para la Edición Limitada de Installshield para Visual Studio.

Application Files(Ficheros)

Esta etapa del asistente nos permitirá establecer los ficheros de nuestra aplicación que se van a guardar en cada
directorio:
 Directorio de la aplicación.
 Carpeta de datos comunes.
 Datos de aplicación.
 Directorio Temporal.
 …
Tendremos la opción de elegir los ficheros de manera manual, añadir carpetas, o elegir que nos copie el resultado
de otro proyecto.

Application ShortCuts(Accesos Directos a la Aplicación)

A través de este paso, podremos especificar los accesos directos que queremos que se generen a la hora de
instalar la aplicación.
Para ello, será necesario que indiquemos el fichero Ejecutable al cual se va a acceder. Vamos a disponer de la
posibilidad de agregar un Acceso Directo al Escritorio o al menú inicio de la aplicación. Además de ello, podremos
modificar el Icono del Acceso directo, e incluso asociar una extensión para que por defecto se habrá con nuestra
aplicación.

Como complemento, también se puede agregar un acceso directo al Desinstalador de la Aplicación.

Application Registry(Uso del Registro) 


Si la aplicación que se va a instalar necesita la definición de claves en el registro de Windows se puede realizar de
manera muy sencilla.

Para ello, necesitaremos realizar las siguientes acciones:

 Indicar que la aplicación hace uso del Registro de Windows.


 Indicar el fichero ejecutable de la aplicación.
 Crear las claves y valores necesarios.

Installation Interview(Opciones para la Instalación) 


A través del último paso del asistente, podremos definir algunas características adicionales a nuestro instalador:

 Mostrar una Licencia


 Permitir introducir usuario y compañía a la persona que va a instalar la aplicación.
 Permitir al usuario modificar la ruta por defecto de instalación de la aplicación.
 Ejecución Automática cuando finalice la instalación.
 Cambiar las imágenes de cada uno de los pasos del asistente del Setup.
Una vez seguidos los pasos del asistente y configurado las opciones requeridas, podremos generar el fichero de
Instalación, para poder instalar la aplicación en otros equipos.

¿Más necesidades o posibilidades?

El asistente nos va a facilitar mucho el trabajo a la hora de definir nuestro instalador pero podemos agregar otras
características que no se observan con el asistente.

Como indicaba al principio, en el explorador de soluciones de Visual Studio, vamos a poder observar el proyecto de
tipo “InstallShield”, con una estructura como la que se puede observar en la imagen:
El proyecto va a constar de los siguientes 6 apartados:

1 Organize Your Setup (Organización del Setup) 


Además de las características generales definidas en la primera etapa del asistente vamos a tener la posibilidad de
indicar características adicionales:

 Características generales del Setup:


o Fuente de los cuadros del setup
o Código del producto
o Crear log del instalador
o Permitir o no botones de eliminar, cambiar o reparar del panel de control
o Añadir un fichero Readme.
o Requerir privilegios de administrador para instalarlo.
o …
 Actualizaciones:
o Condicionar la instalación de actualizaciones.

2 Specify Application Data (Especificación Ficheros de la Aplicación) 


En este apartado podremos definir la estructura que va a generar el instalador en el equipo cliente.

Podremos indicar directorios donde se van a almacenar los ficheros ejecutables, DLL, Base de Datos… Además de
ello, dispondremos de la opción de indicar los ficheros redistribuibles que se van a instalar con el Setup, así como el
orden de instalación de los mismos. 3 Configure Target System (Configuración del equipo de Destino) 
En esta sección se van a poder definir las siguientes características con respecto del equipo del usuario:

 Accesos Directos a la aplicación.


 Tareas relacionadas con el Registro de Windows.
 Uso de Ficheros INI.
 Definición de Variables de Entorno.
 Asociación de extensiones con nuestra aplicación.
 Configuración del Servicio de Información de Internet (IIS).

4 Customize Setup Appearance (Configuración de la apariencia del Setup) 


Vamos a poder llevar a cabo una personalización de las siguientes características del instalador:
 Agregar o Quitar Pasos del setup (Ventana de inicio, Ventana de selección de directorio…)
 Podremos configurar fuentes y literales de los mensajes y botones del asistente.
5 Define Setup Requirements and Actions (Definición de prerrequisitos y acciones) 
En este apartado, vamos a poder definir que prerrequisitos tienen que darse para que nuestra aplicación funcione de
manera satisfactoria.

Podremos agregar algunas acciones personalizadas para la instalación, mantenimiento o desinstalación de la


aplicación, como podrían ser:

 Ejecutar un Fichero Excel, un script VB o JScript después de iniciar el Setup.


 Ejecutar un Fichero Excel, un script VB o JScript después de iniciar el mantenimiento.
 …

6 Prepare for Release (Preparando la Entrega) 


InstallShield nos brinda la posibilidad de generar entregables en 3 formatos:
 CDROM
 DVD-5
 Imagen

Nos va a facilitar un poco el trabajo al predefinir estos formatos a la hora de realizar nuestras entregas.

creo que es un acierto por parte de Microsoft la inclusión de este tipo de instalador dentro de Visual Studio.

Es una gran alternativa a los proyectos de instalación que ya brindaba Visual Studio, que podían quedarse algo
cortos para determinadas circunstancias.
El hecho de ser una edición limitada, va a provocar que algunas características que podrían ser de utilidad no estén
disponibles.

6.2.3 Lecturas Requeridas.

 LECTURA No. 1: programación OO

En este documento se observa de manera adecuada la conformación de los lenguajes de programación


orientados A objetos, como funcionan de manera integral características y diferencias entres los diferentes con
otros lengiuajes.

http://www.programasprogramacion.com/
.
http://www.programas-gratis.net/descargar-bajar/manuales-tutoriales-programacion

http://www.iworld.com.mx/iw_specialreport_read.asp?iwid=5428&back=1
http://www.monografias.com/trabajos/objetos/objetos.shtml
http://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_objetos
C++ y Java como programar, Deitel & Deitel, edición 4.
Programación orientada a objetos, Luis Joyanes Aguilar, edición 1

 LECTURA No. 2: programación dinamica

En este documento se detalla los diferentes herramientas de programación dinámica tales como ASP,PHP,
JAVASCRIPT otros, sus características y funciones primarias. Así mismo ejemplos practicos de asociación e
integridad hompogenea.

http://forum.wordreference.com/showthread.php?t=16428
http://www.itcio.es/desarrollo-personal/analisis/1000598004202/trasfondo-curso-estrategico.2.html
http://www.itcio.es/desarrollo-personal/analisis/1000598004202/trasfondo-curso-estrategico.2.html
http://candadodigital.blogspot.com/2007/10/la-funcin-de-seguridad-informtica-en-la.html

6.2.4 Material complementario.

 LECTURA No. 1: programación a nivel de servidor y cliente

Describe de manera practica la programacon orientada a objetos y la rpgramacion dinámica enfocada a nivel de
servidor y a nivel de cliente.

http://www.mailxmail.com/cursos-programacion

http://www.gratisprogramas.org/descargar/50-libros-de-programacion/

 VIDEO No. 1: programación java

El video describe la operatividad de los lenguajes orientados objetos

http://www.descargarte.net/search/curso+programacion+en+java/

 VIDEO No. 2: programación PHP y ASP

El video describe la funcionanlidad de los lenguajes dinamicos


http://www.enlared.biz/editores-programacion-multilenguaje.html
6.2.5 Actividades de aprendizaje unidad No. 2.

6.2.5.1 Actividades autónomas:

 Nombre de la actividad. Programación abierta.


 Nombre del recurso a utilizar. Correo electrónico.
 Indicaciones pasó a paso. Cada uno de los participantes debe leer detalladamente las lecturas requeridas No.
1, 2, lectura complementaria, y adicionalmente observar y analizar los videos 1, 2..

Realizado lo anterior, debe realizar los talleres que se encuentran en la plataforma, escritos en letra arial 12,
sobre los talleres 1, 2,3,4,5,6.estos deberán ser enviados al tutor a más tardar el último día de la sexta semana
del desarrollo del módulo, a través del correo electrónico.
 Actividades previas. Desarrollar las lecturas requeridas, complementarias y observar los videos.
 Competencias o indicador de competencias. Conocer el funcionamiento de los diferentes lenguajes de
programación.
 Producto a entregar. Taller 1: java; taller 2: C++; taller 3: ASP; taller 4: PHP; taller 5: javascript; taller 6:
VBscript.

Actividades sobre talleres.

El estudiante deberá implementar en cada uno de los programas propuestos, un programa que permita
leer su nombre y apellido; cedula identificación; sueldo básico y descuentos.
Cada taller debe guardarse con el nombre del programa utilizado.
 Fecha de inicio y limite.
Fecha inicio: Primer día de la tercera semana
Fecha entrega: Último día de la sexta semana
 Porcentaje de valoración. 40%

6.2.5.2 Actividades colaborativas y de acompañamiento tutorial:

 Nombre de la actividad. Foro programación dinámica.


 Nombre del recurso a utilizar. Foro en plataforma.
 Indicaciones pasó a paso. Los participantes previamente a la realización del trabajo en grupo, deberán realizar
las lecturas requeridas y adicionalmente observar y analizar el video No. 2. Cada participante debe realizar una
consulta sobre las aplicaciones web los participantes deberán realizar el siguiente cuestionario:
o Dos diferencias primarias de los lenguajes de programación.
o Como se comportan los tipos de datos en la programación dinámica
o Cual es la acción primaria de los constructores y destructores en los lenguajes OO.

Una vez resuelto el cuestionario, cada uno de los participantes deberá participar en uno de los grupos
conformados por el tutor. En cada grupo los participantes socializaran el cuestionario anterior, unificaran criterios
y elaboraran un documento con respuestas comunes a cada pregunta la cual se publicará en el foro para ser
socializado.
 Actividades previas. Desarrollar las lecturas requeridas, complementarias y observación de los videos.
 Competencias o indicador de competencias. Utilizar las herramientas de la programación OO y dinámica para
implementar aplicaciones de entorno empresarial.Utilizar las aplicaciones necesarias para mejorar el rendimiento
de los equipos de cómputo. Compartir el desarrollo del trabajo. Participar activamente y tratar con respeto las
opiniones y posturas de los demás participantes.
 Producto a entregar. El documento publicado en la plataforma (foro) con las respuestas.
 Fecha de inicio y limite.
Fecha inicio: Primer día de la semana siete
Fecha final: Último día de la semana diez
 Porcentaje de valoración. 20%

6.2.6 Resultados del aprendizaje.

Clasificación Técnicas Recursos Estrategia


Evidencias Estrategias de la e de
estrategia instrumentos tecnológicos mejoramiento
Desarrollo Argument Actividad Elaboración Correo
del taller 1, ación y autónoma de talleres electrónico
taller 2, sustentaci
Conocimiento taller 3taller ón de
4,taller 5 planteami
taller6. entos

Identifique
las
necesidade
s de la
empresa
Conozca las Participaci Actividad Consulta Plataforma,
funciones ón de la autónoma y individual chat y blog
de los actividad colaborativa
diferentes en el foro
sistemas
operativos
Desempeño
Expone las
funcionalida
des de
herramienta
s de
escritorio,
aplicaciones
específicas
y utilitarios
Talleres Document Actividad Elaboración Documento
Producto o escrito Colabora del para
Documento tiva y cuestionario participar en
con Acompa en grupo el foro e
respuestas ñamiento plataforma
del del tutor
cuestionario

6.2.7 Valoración de evidencias.

I NIVEL II NIVEL III NIVEL


INTERPRETATIVA ARGUMENTATIVA PROPOSITIVA

• Operar los recursos - Implementar sesiones de - Identificar los datos


tecnológicos de oficina de la usuario que contribuyan al involucrados en el proceso.
unidad administrativa de mantenimiento de la - Establecer prioridades para
acuerdocon los manuales de integridad de los sistemas de el procesamiento de los
operación. hardware y software de la datos.
- Instalar recursos Unidad Administrativa. - Interpretar políticas de
tecnológicos de oficina, - Realizar instalaciones de trazabilidad.
aplicando el manual de los controladores de - Probar el funcionamiento de
operación, las dispositivos. la Base de Datos.
normas legales, de seguridad - Registrar el sistema - Corregir inconsistencias de
y salud ocupacional operativo. funcionamiento.
requeridas. • Verificar el funcionamiento - Aplicar de manera
- Instalar sistemas operativos de los recursos tecnológicos sistemática los conocimientos
- Brindar soporte técnico y de oficina de acuerdo con los en el modelo E-R.
operativo a los usuarios de procedimientos de seguridad, para el diseño adecuado de
los recursos tecnológicos de las normas de gestión de la las clases de datos.
oficina de la Unidad calidad y el manual del - Implementar procesos de
Administrativa. usuario. normalización de estructuras
- Utilizar el sistema operativo - Coordinar un esquema de en las bases de datos,
de acuerdo con los contingencia para alcanzando como mínimo la
requerimientos de los contrarrestar los riesgos. tercera forma normal.
procesos y - Ejecutar software de - Investigar y proponer
procedimientos de la Unidad protección contra virus estrategias y métodos para
Administrativa. informáticos y malware. alcanzar formas normales
- Emplear paquetes - Actualizar el software de más
integrados de oficina de protección y antispyware. elevadas.
acuerdo con el manual de - Fijar normas de uso de los - Construir y diseñar GUI
operaciones y recursos tecnológicos de (Graphic User Interface/
políticas de la Organización. oficina. Interfaces Gráficas de
• Coordinar la utilización de - Controlar el inventario de Usuario) para
los recursos tecnológicos de los recursos tecnológicos. la gestión y mantenimiento
oficina de la Unidad - Asignar las prioridades, de las bases de datos y su
Administrativa, de acuerdo derechos y restricciones a los utilización.
con las políticas de la usuarios - Documentar el proceso de
Organización y la gestión de diseño, construcción y
la utilización de las bases de
calidad. datos y
sus respectivas GUI.

6.2.8 Evaluación de aprendizajes.

EVALUACIÓN DE APRENDIZAJES

Actividades individuales  Conocer las diferencias y


funcionalidades de los lenguajes
denprogramacion.
 Identificar la funcionalidad y
utilización de herramientas de cada
uno de los programas integrados a
la programación de propósito
general o especifico, teniendo en
cuentas lecturas requeridas,
complementarias y observación de
videos.

 Consulta sobre las nuevas


propuestas en el campo de la
programación..
Propósitos de la formación
Criterios de evaluación  Análisis de lecturas requeridas y
complementarias y observación de
videos.
 Calidad de los argumentos y
sustentación.
 Cumplimiento en los tiempos
estipulados.
 Respeto a los derechos de autor en
la información consultada
Ponderación 20%
Actividades Colaborativas y de Trabajo para socializar en el foro los
acompañamiento tutorial temas sobre: antecedentes, lenguajes
OO, lenguajes dinamicas y prototipos.s.
Propósitos de la formación  Conocer las ventajas de trabajar con
una u otra herramienta de escritorio.
 Establecer criterios para trabajar con
las aplicaciones específicas
requeridas por la empresa.
Criterios de evaluación  Calidad y pertinencia de las
respuestas
 Respeto a los derechos de autor en
la información consultada
 Respeto y buen trato a los
compañeros de grupo y
participantes del foro
Ponderación 25%
Autoevaluación En el proceso de autoevaluación se
debe tener en cuenta los siguiente

 Calidad y presentación de los


trabajos.
 Puntualidad en la entrega individual
y grupal.
 Respeto por los compañeros
 Participación activa en el foro
 Trabajo en grupo.
Ponderación 5%

Lenguajes de programacion
Unidad II
Horas trabajo Horas
Actividad de de trabajo
acompañamiento autónomo
Lectura comprensiva de los
documentos.
Observación de los cuatro videos.
Elaboración de taller 1, taller 2 y 6 8
taller 3.
Trabajo en grupo 3

Participación en foro programación


dinamica 7

7. GLOSARIO

Programación: Acción y efecto de programar.

Programar: dar instrucciones a un computador para conseguir un resultado deseado.

Web: red informática


Servidor: En Internet, un servidor es un ordenador remoto que provee los datos solicitados por parte de los
navegadores de otras computadoras.

En redes locales se entiende como el software que configura un PC como servidor para facilitar el acceso a la red y
sus recursos.

Los Servidores almacenan información en forma de páginas web y a través del protocolo HTTP lo entregan a
petición de los clientes (navegadores web) en formato HTML.

Diccionario en línea masadelante.com. Consultado el 14 de enero de 2011. Disponible en


http://www.masadelante.com/faqs/servidorLenguaje de programación: idioma artificial para darle ordenes a un
computador

Enfoque orientado a objetos: visualizar la programación como objetos

Interacción: Acción que se ejerce recíprocamente entre dos o más objetos, agentes, fuerzas, funciones

Diccionario de la lengua española, (2011). (Vigésima segunda edición). Consultado el 14 de enero de 2011.
Disponible en http://buscon.rae.es/draeI/..

Dato: cualquier valor

Información: organización de los datos

Aplicativo: programa de computador

Requerimiento: necesidad o solicitud

Informática: ciencia que estudia el tratamiento informático de la computación.

Tecnología: conjunto de técnicas, procesos y conocimientos


Sistémico: De la totalidad de un sistema o relativo a ella.

Diccionario de la lengua española. Wordreference.com. Consultado el 14 de enero de 2011. Disponible en


http://www.wordreference.com/definicion/sist%C3%A9mico .

Computador: máquina electrónica programable

Algoritmo: conjunto de instrucciones que realizan un proceso especifico

lenguaje de programación: medio por el cual se programa


asembler: lenguaje de programación de más bajo nivel

Programación orientada a objetos: programación usando el enfoque orientado a objetos.

Sistema: conjunto de partes interrelacionadas entre sí y con un objetivo común

PHP: lenguaje de programación web.

C++: lenguaje de programación orientado a objetos

Multiusuario: También llamado multipuesto. Es un tipo de configuración que permite soportar a varios usuarios o
puestos de trabajo al mismo tiempo, de forma que el sistema operativo gestiona la simultaneidad, otorgando a cada
usuario todos los recursos necesarios.

Diccionario en línea mastermagazine.info. Consultado el 14 de enero de 2011. Disponible en


http://www.mastermagazine.info/termino/6043.php .

Operador: Se denomina operario a las personas, hombres o mujeres que realizan una tarea determinada,
generalmente de carácter técnico y que es recompensada mediante el pago de un salario.
Enciclopedia libre wikipedia. Consultado el 14 de enero de 2011. Disponible en http://es.wikipedia.org/wiki/Operario.

Periférico: En informática, se denomina periféricos a los aparatos o dispositivos auxiliares e independientes


conectados a la unidad central de procesamiento de una computadora.

Se consideran periféricos tanto a las unidades o dispositivos a través de los cuales la computadora se comunica con
el mundo exterior, como a los sistemas que almacenan o archivan la información, sirviendo de memoria auxiliar de
la memoria principal.

Se entenderá por periférico al conjunto de dispositivos que, sin pertenecer al núcleo fundamental de la computadora,
formado por la CPU y la memoria central, permitan realizar operaciones de entrada/salida (E/S) complementarias al
proceso de datos que realiza la CPU. Estas tres unidades básicas en un computador, CPU, memoria central y el
subsistema de E/S, están comunicadas entre sí por tres buses o canales de comunicación.

Enciclopedia libre wikipedia. Consultado el 14 de enero de 2011. Disponible en http://es.wikipedia.org/wiki/Perif


%C3%A9rico.

8. BIBLIOGRAFIA

KERNIGHAN B. RITCHIE D. “El lenguaje de programación C”. Ed. Prentice Hall.

JOYANES L. CASTAN H. “C++”. Ed. Mc Graw Hill.

SCHILDT H. “C Manual de Referencia”. Ed. Mc


SANCHEZ, Vidales Miguel Angel. (2001). Introducción a la informática: Hardware, software y teleinformática (1era
Edición). Universidad Pontificia de Salamanca.
NORTON, Peter Norton. (2000). Introducción a la computación (3 ª Edición).Mexico: Editorial Mc Graw-Hill.

Ingeniería del software, Iann Sommerville, séptima edición, capitulo 23


Aplicaciones distribuidas en java con tecnología RMI, Santi Caballe, edición 1.
C++ y Java como programar, Deitel & Deitel, edición 4.
Programación orientada a objetos, Luis Joyanes Aguilar, edición 1
Fundamentos de programación piensa en C, CAIRO, OSVALDO, Edición 1, 2006
Programación orientada a objetos con JAVA, David J Barnes, edición 3
Técnicas cuantitativas para la gestión en la ingeniería del software, Javier Tuya, Edición 1, 2007, Cap. 3

Aplicaciones distribuidas en java con tecnología RMI, Santi Caballe, edición 1

PARSONS, Jamrich, OJA Dan. (1999).Conceptos Básicos de computación (2da edición). International Thomson
Editores.
Hardware y software sistema informático. Disponible en http://pdf.rincondelvago.com/hardware-y-
software_sistema-informatico.html (Consultado el 28/12/2010).

Hardware. Disponible en http://es.wikipedia.org/wiki/Hardware (Consultado el 28/12/2010).

Definición de Software y Hardware. Disponible en http://www.masadelante.com/faqs/software-hardware (Consultado


el 2. 28/12/2010).

COMMN, Craft, Explicando el software / hardware de las computadoras. Disponible en


http://www.arturogoga.com/2009/03/31/explicando-el-software-hardware-de-las-computadoras-subtitulos-en-espaol/ .
(Consultado el 28/12/2010).

IES Pedro Espinosa, Antequera. Video sobre la historia del hardware. Disponible en
http://aulasimm.wordpress.com/2008/11/05/video-sobre-la-historia-del-hardware/. (Consultado el 28/12/2010).
Hardware y software sistema informático. Disponible en http://pdf.rincondelvago.com/hardware-y-
software_sistema-informatico.html (Consultado el 28/12/2010).

Sistema operativo. Disponible en http://es.wikipedia.org/wiki/Sistema_operativo. (Consultado el 28/12/2010).

Funciones del sistema operativo. Disponible en http://es.kioskea.net/contents/systemes/sysintro.php3 . (Consultado


el 28/12/2010).

Comandos para administrar un sistema Linux. Disponible en


http://www.webtutoriales.com/tutoriales/linux/comandos-linux.23.html. (Consultado el 28/12/2010).

Rendimiento de los sistemas operativos. Disponible en http://www.angelfire.com/ex/martin1/Resumenx3.htm.


(Consultado el 28/12/2010).

La Red Martínez, David Luis, UNIVERSIDAD NACIONAL DEL NORDESTE


U.N.N.E. – ARGENTINA, Sistemas operativos. Disponible en
http://exa.unne.edu.ar/depar/areas/informatica/SistemasOperativos/SO0.htm. (Consultado el 28/210/2010).

P., Hernández S,José, Análisis de Desempeño de 3 Sistemas Operativos1 en un computador personal con recursos
de hardware limitados (marzo de 2009). Disponible en http://www.linux-
magazine.es/Readers/white_papers/Comparativa_SOs_Mac_OSX_Ubuntu_Windows_7.pdf . (Consultado el
28/12/2010).

Aplicación informática. Disponible en http://es.wikipedia.org/wiki/Aplicaci%C3%B3n_inform%C3%A1tica,


(Consultado el 28/12/2010).

Aplicaciones informáticas. Disponible en http://www.articuloz.com/informatica-y-tecnologia-articulos/aplicaciones-


informaticas-3753302.html. (Consultado el 28/10/2010).

Recursos informáticos. Disponible en http://www.uhu.es/cine.educacion/didactica/0067recursosinformaticos.htm.


(Consultado el 28/12/2010)
Programa informático. Disponible en http://es.wikipedia.org/wiki/Programa_inform%C3%A1tico. (Consultado el
28/12/2010).

Menus ocultos del sistema operativo Windows xp. Disponible en http://www.hispazone.com/Articulo/122/Menus-


ocultos-del-sistema-operativo-Windows-XP.html. (Consultado el 28/12/2010).

Reportaje sistemas operativos. Disponible en http://www.youtube.com/watch?v=-TYWetXTDOw. (Consultado el


28/12/2010).

Tipos de sistemas operativos. Disponible en http://www.youtube.com/watch?v=BiznImTMkSE&feature=related.


(Consultado el 28/12/2010).

Historia de los sistemas operativos y diferencias entre sistemas operativos. Disponible


http://www.youtube.com/watch?v=sz6MOWPhCXo&feature=related.
(Consultado el 28/12/2010)

Instituto tecnológico de tuxtepec, Desempeño y seguridad de los sistemas operativos. Disponible en


http://www.slideshare.net/martincitomvc/desempeo-y-seguridad-2661270 . (Consultado el 28/12/2010)

Seguridad informática: Hackers. Disponible en http://www.monografias.com/trabajos/hackers/hackers.shtml .


(Consultado el 28/12/2010).

Seguridad informática, ¿Que, por qué y para qué?. Disponible en


http://www.inegi.gob.mx/inegi/contenidos/espanol/ciberhabitat/museo/cerquita/redes/seguridad/intro.htm .
(Consultado el 28/10/2010).

FERRER, Jorge, Fernández Sanguino, Javier, Hispalinux, seguridad informática y software libre. Disponible en
http://lucas.hispalinux.es/Informes/informe-seguridad-SL/informe-seguridad-SL.pdf. (Consultado el 28/12/2010).

Sistemas de información. Disponible en http://www.monografias.com/trabajos7/sisinf/sisinf.shtml . (Consultado el


28/12/2010).
Funciones de los sistemas de información. Disponible en
http://help.sap.com/saphelp_40b/helpdata/es/c1/3754ea449a11d188fe0000e8322f96/content.htm . (Consultado el
28/12/2010).

Herramientas para el desarrollo de sistemas de información. Disponible en


http://www.alipso.com/monografias/desarrollo_de_sistemas_de_informacion/ . (Consultado el 28/12/2010)

Seguridad informática. Disponible en http://www.youtube.com/watch?v=6ihTC8up2eM. (Consultado el 28/12/2010).

Hackers, seguridad de la información. Disponible en http://www.youtube.com/watch?v=0w5-


92Tvzt4&feature=related. (Consultado el 28/12/2010).

Historia secreta de los hackers informáticos. Disponible en http://www.youtube.com/watch?


v=KIEr4NY5ItI&feature=related. (Consultado el 28/12/2010).

Seguridad informática. Disponible en http://www.youtube.com/watch?v=SvB-LND8K_U&feature=related .


(Consultado el 28/12/2010).

Sistemas y tecnologías de la información para la gestión empresarial. Disponible en http://www.youtube.com/watch?


v=el5mX_0BFL4. (Consultado el 28/12/2010).
La revolución de las tecnologías de la información. Disponible en http://www.youtube.com/watch?
v=8jR8DukPXwg&feature=related. (Consultado el 28/12/2010).

Las tecnologías de la información y la comunicación. Disponible en http://www.youtube.com/watch?v=U4D-E1o-


PxE&feature=related. (Consultado el 28/12/2010).

Anda mungkin juga menyukai