Autor Tema: Abrir copias de formulario  (Leído 2489 veces)

Desconectado xavi

  • Administrador
  • Habitual
  • *****
  • Mensajes: 214
Abrir copias de formulario
« en: Abril 20, 2012, 06:38:18 pm »
Palabras clave: abrir, copia, instancia, formulario
Autor: Eduardo Olaz
Extraído de: La web del Búho

Pregunta
Se puede abrir el mismo formulario 2,3 o mas veces a la vez??
Como se hace???


Cita de: Eduardo Olaz
Un formulario es un objeto, con su módulo de clase asociado. Además es un tipo de objeto del que se puede crear múltiples instancias, es decir se pueden crear varios ejemplares de la clase correspondiente al formulario, y por ejemplo, añadirlas a una colección de formularios. Además, podemos variar las propiedades de cada ejemplar de la clase, por ejemplo el texto de la barra de títulos.

En un formulario he puesto el botón cmdNuevoFormulario y un botón llamado cmdVaciarColeccion.
Al apretar el botón cmdNuevoFormulario crea  una instanica del formulario FormularioMultiple, y lo añade a la colección colFormularios.
Cuando se aprieta el botón, descarga uno a uno los elementos de la colección formularios, con lo que se descargarán, excepto el último cargado porque todavía está instanciado por la variable frmFormulario. Para descargarlo hacemos:
    set frmFormulario = Nothing
Si cerramos el formulario de los botones, sin descargar la colección, también desaparecerán los fomularios al destruirse la colección de forma implícita.

Código: [Seleccionar]
Option Explicit

Dim colFormularios As New Collection
Dim frmFormulario As Form
Dim lngFormulario As Long

Private Sub cmdNuevoFormulario_Click()
    Set frmFormulario = New Form_FormularioMultiple
    lngFormulario = lngFormulario + 1
    colFormularios.Add frmFormulario
    With frmFormulario
        .Caption = " Formulario " & .Name & " nº " & Format(lngFormulario,"000")
        .Visible = True
    End With
End Sub

Private Sub cmdVaciarColeccion_Click()
    VaciarColeccion colFormularios
    ' Para que desaparezca el último formulario cargado
    ' ponemos frmFormulario a Nothing
    Set frmFormulario = Nothing
End Sub

Private Sub VaciarColeccion(Coleccion As Collection)
    Dim i As Long
    ' Vaciamos la colección de formularios
    With Coleccion
        For i = .Count To 1 Step -1
            .Remove (i)
        Next i
    End With
End Sub
« Última modificación: Septiembre 24, 2019, 06:00:56 pm por xavi »

Desconectado xavi

  • Administrador
  • Habitual
  • *****
  • Mensajes: 214
Re:Abrir copias de formulario
« Respuesta #1 en: Julio 04, 2023, 01:55:01 pm »
Actualización tomando la info de Allen Browne Hay un ejemplo en esa URL

Para evitar problemas, utiliza una colección pública y un código en un módulo independiente.
El ejemplo de Allen toma un formulario llamado frmClient

Código: [Seleccionar]
Public clnClient As New Collection    'Instances of frmClient.
Function OpenAClient()
    'Purpose:    Open an independent instance of form frmClient.
    Dim frm As Form

    'Open a new instance, show it, and set a caption.
    Set frm = New Form_frmClient
    frm.Visible = True
    frm.Caption = frm.Hwnd & ", opened " & Now()

    'Append it to our collection.
    clnClient.Add Item:=frm, Key:=CStr(frm.Hwnd)

    Set frm = Nothing
End Function

Function CloseAllClients()
    'Purpose: Close all instances in the clnClient collection.
    'Note: Leaves the copy opened directly from database window/nav pane.
    Dim lngKt As Long
    Dim lngI As Long

    lngKt = clnClient.Count
    For lngI = 1 To lngKt
        clnClient.Remove 1
    Next
End Function

La segunda función CloseAllClients() muestra cómo cerrar estas instancias eliminándolas de nuestra colección. Pero si el usuario cierra una instancia con la interfaz normal, debemos eliminar esa instancia de nuestra colección. Eso se hace en el evento Cerrar del formulario frmClient de esta manera:

Código: [Seleccionar]
Private Sub Form_Close()
    'Purpose: Remove this instance from clnClient collection.
    Dim obj As Object        'Object in clnClient

    Dim blnRemove As Boolean  'Flag to remove it.

    'Check if this instance is in the collection.
    For Each obj In clnClient
        If obj.Hwnd = Me.Hwnd Then
            blnRemove = True
            Exit For
        End If
    Next

    'Deassign the object and remove from collection.
    Set obj = Nothing
    If blnRemove Then
        clnClient.Remove CStr(Me.Hwnd)
    End If
End Sub