Curso Básico de Programación
en Visual Basic

 

Entrega Treinta y una: 30/Jun/99
por Guillermo "guille" Som

Si quieres linkar con las otras entregas, desde el índice lo puedes hacer

 

Menús (el resto) y los diálogos comunes

Nos quedamos pendientes de codificar las opciones del menú de ficheros.

Las opciones que tenemos son:

Nuevo
---
Abrir...
Guardar
Guardar como...
---
Imprimir...
    Seleccionar impresora...
    Imprimir
---
Salir

 

Pero vamos a añadir otra: Mezclar

Esta opción insértala entre abrir y guardar, el nombre del menú es mnuFicMezclar y la letra M es la que debe estar subrayada (escribe &Mezclar en el caption)

¿Para que sirve mezclar?
Para intercalar otro fichero en el texto actual; ahora vamos a ver qué necesitamos para escribir el código de estas opciones.
Cuando se pulsa Abrir…, (o en cualquiera de las opciones en las que se necesite el nombre de un fichero), lo que el usuario espera es que se le pregunte el fichero a editar. Se puede hacer de forma simple, usando el InputBox o un formulario de nuestra cosecha que simplemente pregunte un nombre de fichero, pero… eso no es lo que estamos acostumbrados a ver… lo que necesitamos es poder mostrar un:

Cuadro de diálogos comunes

Es decir, un cuadro de diálogo, (no se porqué lo llaman de diálogo, ya que no habla…), con el que poder seleccionar un fichero de cualquier directorio o unidad de disco. El VB incluye un control para hacer esto. Pero para poder usarlo, primero tiene que estar disponible.
Para ello, en el menú proyecto, selecciona componentes… y te mostrará un cuadro de diálogo con los controles que tenemos registrados en el sistema, selecciona: Microsoft Common Dialog Control (ComDlg32.ocx, control de diálogos comunes) y pulsa aceptar.

En la barra de herramientas, (la que está a la izquierda), verás que hay un icono como este:
Muestra el formulario y haz doble clic en ese icono, y se insertará en el formulario, desde este momento ya está disponible, el nombre por defecto de este control es: CommonDialog1, por tanto para acceder a las propiedades y métodos tendremos que usar, como es costumbre en todos los controles, ese nombre seguido de un punto y después la propiedad o método.

Por ejemplo para abrir:

With CommonDialog1
    .DialogTitle = "Seleccionar un fichero para abrirlo"
    .ShowOpen
    NombreFichero = .FileName
End With

Ahora que "sabemos" cómo se usa este control, vamos a usarlo "correctamente" y no es porque lo otra forma no sea correcta, que lo es, me refiero a que nos sea "útil" en nuestro proyecto.

Bien, estamos dispuestos a entrar de lleno en lo que es la codificación del programa; ya hemos visto otros "listados", pero este es algo más complicado... aunque no tiene porqué serlo...

Revisemos lo que tenemos y, sobre todo, que utilidad tendrá todo este tinglado, sé que después de dos entregas ya se tendría que saber pero...

-La intención es crear un formulario con una serie de menús, una caja de texto en la que poder escribir y poder manipular el texto escrito, pudiendo guardarlo en el fichero de texto y permitirnos asignar el texto contenido en cualquier otro fichero, además de realizar ciertas tareas de "edición" en el texto contenido en esa caja de texto.

Pero nos falta un pequeño detalle: cómo saber el nombre del fichero con el que queremos "nombrar" lo que hemos escrito o como saber el nombre del fichero que usamos para asignarlo al textbox, es decir necesitamos una variable para guardar un nombre de fichero.

Ahora hay otro pequeño detalle: ¿dónde necesitamos usarla?

Me explico: ¿necesitamos una variable local a un solo procedimiento? o ¿ necesitamos una variable que pueda ser "vista" en todos los procedimientos?

¿Recuerdas lo dicho en la entrega 26?

Creo que nuestra variable para almacenar el nombre del fichero debe tener una "cobertura" a nivel de módulo, ya que se usará tanto en los procedimientos de abrir como en los de guardar. Por tanto declárala en la sección general del formulario:

Private NombreFichero As String

Y ahora te tendría que seguir mostrando código, pero, creo que parte de lo que hay que hacer ya lo hemos hecho... voy a comprobarlo y te lo digo... ¡vuelvo enseguida!

Si se ha hecho, en la entrega quince para más señas, así que solo te diré "lo nuevo", pero el resto tendrás que hacerlo por tu cuenta, aunque te diré que es lo que debes hacer y dónde; de esta forma tendrás ejercicios obligatorios... si no los resuelves, no tienes programa, je, je.

Antes de ver el código de este mini-editor, vamos a ver un nuevo sistema de nombrar constantes:

Enum

Nota: esto sólo existe en la versión 5 o superior.

La enumeración se usa para constantes de forma correlativa, aunque eso puede cambiarse.

Por ejemplo:

Enum eEdicion
    Deshacer
    Sep1
    Cortar
    Copiar
End Enum

Según esto, Deshacer vale 0, Sep1=1, Cortar=2, etc.

Osea el primer nombre de constante valdrá cero y las demás irán incrementando el valor de uno en uno.

Si no queremos que se comporte de esta forma, es decir que empiece con cero, podemos asignar el valor que queramos:

Enum ePrueba
    Primero = -1
    Segundo
    Tercero
End Enum

Ahora los valores son: Primero= -1, Segundo= 0, Tercero= 1

También podemos asignar los que queramos:

Enum ePrueba2
    Uno = 1
    Dos     '2
    Tres    '3
    Nulo = 0
    Cuatro = 4
    Cinco   '5
End Enum

Fíjate que al indicarle Uno=1, se empieza por uno y el siguiente valor será dos, etc., hasta que volvamos a asignar un nuevo valor, en este caso Nulo=0, Cuatro vale 4 y los siguientes, si no se le indica lo contrario, van aumentando de uno en uno.

Otra cosa que se suele hacer con esto de las enumeraciones, siempre que los valores asignados sean correlativos, es indicar cual es el valor menor y cual el mayor; así se pueden usar en ciertos bucles y para ciertas comprobaciones en las que necesitemos que un valor determinado esté entre los dos valores indicados:

Enum eEdicion
    edPrimero
    edDeshacer = edPrimero
    edSep1
    edCortar
    edCopiar
    edPegar
    edSep2
    edSeleccionarTodo
    edSep3
    edBuscar
    edBuscarSig
    edReemplazar
    edUltimo = edReemplazar
End Enum

En este caso, se asignan dos constantes: edPrimero y edUltimo para indicar los valores mínimo y máximo del rango de las constantes. Recuerda que cada vez que se asigna un valor a una constante de una enumeración, si en la siguiente no se le indica explícitamente un valor, se incrementa el valor anterior en uno. Por tanto, edPrimero y edDeshacer valdrán cero, edSep1 vale 1, edCortar vale dos y así sucesivamente.

Otra cosa a saber sobre las enumeraciones, es que los valores siempre son numéricos del tipo long.

Cuando creamos una enumeración, estamos creando un nuevo tipo de variable... o casi, lo importante es que podemos crear variables de la enumeración:

Dim miVarEnum As ePrueba

Al asignar un valor a una variable declarada de esta forma, el Visual Basic nos indicará los nombres (o valores posibles)

Por ejemplo: 

es decir, nos muestra una lista despegable con los valores posibles.

También podemos usar esos nombres de forma independiente, sin necesidad de crear una variable especial:

Dim x As Long

x = Primero

 Es decir, se asignará a la variable x lo que vale la constante Primero (-1)

Un dato importante: no deberías usar el mismo nombre de constante en diferentes enumeraciones, ya que el Visual Basic podría confundirse... aunque te avisará de que hay un "conflicto".

Si tenemos estas dos enumeraciones:

Enum ePrueba
    Primero = -1
    Segundo
    Tercero
End Enum

Enum ePrueba1
    Primero = -1
    Otro = Primero
    Siguiente
    Ultimo = Siguiente
End Enum

Y asignamos x = Primero, nuestro querido Visual Basic nos dirá que se ha detectado un nombre ambiguo, tal como nos muestra este mensaje:

Para solucionarlo podemos hacer dos cosas:

---Usar nombres diferentes en las constantes enumeradas, (lo más recomendable).
---Indicar el nombre de la enumeración: x = ePrueba1.Primero

Para terminar esto, decirte que puedes usar nombres de constantes con espacios, aunque esto es algo que está bien cuando creamos "controles", para que los nombres de las constantes de las propiedades sean descriptivas:

Enum ePrueba3
    [Fecha Actual]
    [Fecha Anterior]
End Enum

Fíjate en el uso de corchetes.
Cuando se usan estos valores, el propio Visual Basic se encarga de asignarlo con los corchetes:

unaFecha = [Fecha Actual]

Y si los asignamos nosotros directamente, hay que poner el nombre de la "constante" dentro de los corchetes, sino el Visual Basic entenderá que son dos nombres diferentes sin ningún tipo de operación de por medio... lo cual se convertirá en un "bonito" error...

El único "defectillo" que tienen las constantes de las enumeraciones, es que los nombres usados no mantienen el estado de mayúsculas / minúsculas, es decir que si declaramos Primero en un Enum y después escribimos ese nombre en minúsculas se cambiará la declaración a minúsculas:

x = primero

Pero aún así, si tenemos Option Explicit podemos detectar valores no "creados"; aunque para mi gusto, se debería "respetar" el estado de mayúsculas/minúsculas de la declaración.

Un último comentario y ya termino..., al igual que ocurre con los procedimientos en los que no se indica "explícitamente" que es privado, serán públicos por defecto. Así que, si no tienes intención de hacer públicas las enumeraciones, decláralas como Private.

Ahora veamos parte del código nuevo, el resto será el que se mostró en la entrega anterior.

Los valores de las constantes para el menú de edición las vamos a tener en una enumeración. Por tanto si la versión que estás usando es anterior a la 5, tendrás que declararlas como constantes normales, (tal y como se mostró en la entrega 30).

En la parte de las declaraciones del formulario:

' Constantes para el menú de Edición.
' Los valores se corresponden con el índice de mnuEditor
Private Enum eEdicion
    cedPrimero
    cedDeshacer = cedPrimero
    cedSep1
    cedCortar
    cedCopiar
    cedPegar
    cedSep2
    cedSeleccionarTodo
    cedSep3
    cedBuscar
    cedBuscarSig
    cedReemplazar
    cedUltimo = cedReemplazar
End Enum

Private NombreFichero As String     ' Nombre del fichero
Private Modificado As Boolean       ' Para indicar si se ha cambiado el texto

Al iniciarse el formulario asignaremos los filtros para la selección del tipo de ficheros en el cuadro de diálogo.
El filtro se asigna a la propiedad Filter del CommonDialog y el formato a usar será: descripción del tipo, el tipo, descripción, tipo, etc. cada uno de estos "datos" estará separado por el signo | (ALT+124) o Alt Gr y 1.

Private Sub Form_Load()
    ' Asignar el filtro para el diálogo común
    CommonDialog1.Filter = "Textos (*.txt)|*.txt|Todos (*.*)|*.*"

End Sub

Cada vez que escribamos algo en el textbox habrá que indicarle a nuestro programa de que se ha cambiado, por tanto asignaremos True a la variable Modificado:

Private Sub txtEditor_Change()
    Modificado = True
End Sub

Ahora veremos el código de algunas de las opciones del menú de ficheros, el resto lo veremos en la siguiente entrega, junto con todo el código...

Private Sub mnuFicAbrir_Click()
    ' Comprobar si el texto se ha modificado
    ' si es así, guardarlo o no, según la respuesta del usuario
    ' ***ejercicio***

    With CommonDialog1
        .DialogTitle = "Seleccionar un fichero para abrilo"
        .FileName = NombreFichero
        .ShowOpen
        If Len(.FileName) Then
            NombreFichero = .FileName

            ' Abrir el fichero y asignarlo al textbox
            ' ***ejercicio***

            Modificado = False
        End If
    End With
End Sub


Private Sub mnuFicGuardar_Click()
    ' Si no se ha asignado el nombre al fichero, preguntar por él
    If Len(NombreFichero) = 0 Then
        mnuFicGuardarComo_Click
    Else
        GuardarFichero
    End If
End Sub


Private Sub mnuFicGuardarComo_Click()
    ' Preguntar el nombre del fichero y guardarlo
    With CommonDialog1
        .DialogTitle = "Guardar el fichero"
        .FileName = NombreFichero
        .ShowSave
        If Len(.FileName) Then
            NombreFichero = .FileName
            GuardarFichero
        End If
    End With
End Sub


Private Sub mnuFicMezclar_Click()
    ' Preguntar el nombre del fichero a mezclar
    With CommonDialog1
        .DialogTitle = "Fichero a mezclar"
        .ShowOpen
        If Len(.FileName) Then
            ' Leer el fichero y guardarlo en una variable
            Dim nFic As Long
            Dim sMerge As String
            Dim sTmp1 As String, sTmp2 As String

            nFic = FreeFile
            Open .FileName For Input As nFic
            sMerge = input$(LOF(nFic), nFic)
            Close nFic

            ' Tomar lo que hay hasta la posición del cursor
            With txtEditor
                sTmp1 = Left$(.Text, .SelStart)
                sTmp2 = Mid$(.Text, .SelStart + 1)
                .Text = sTmp1 & sMerge & vbCrLf & sTmp2
            End With
        End If
    End With
End Sub


Private Sub mnuFicNuevo_Click()
    ' Comprobar si se ha modificado el fichero actual
    ' ***ejercicio***

    txtEditor = ""
    Modificado = False
End Sub


Private Sub GuardarFichero()
    ' Guardar el contenido del textbox en NombreFichero
    ' ***ejercicio***

    Modificado = False
End Sub

Como te imaginarás donde pone ***ejercicio*** es lo que tienes que hacer, ya sabes que en la entrega quince se hizo algo parecido.

Por lo demás, nos queda la parte de: seleccionar impresora, imprimir, buscar y reemplazar, pero eso lo dejaremos para otra ocasión... aunque si no quieres esperar, pásate por la sección "Mis Utilidades" y busca la entrada que dice "Un procedimiento genérico para imprimir"

En la próxima entrega también veremos algo sobre el control de errores... cosa que será necesaria "controlar" para los casos en que se pulse "Cancelar" en el cuadro de diálogo de selección del nombre del fichero.

Así que, paciencia... y a esperar... si puedes... y si no puedes... pues eso...

Hasta la próxima

Nos vemos
Guillermo


 
entrega anterior ir al índice siguiente entrega

Ir al índice principal del Guille