Codificación: Manipulación de controles en frmPedidos

Creado por David Miralpeix, Modificado el Fri, 16 Feb 2024 a las 12:28 PM por David Miralpeix

< Codificación: Manipulación de controles en frmEmpleados 


Planteamiento inicial

En este punto veremos como crear o modificar controles de distintos formularios y la programación de sus eventos, todo mediante código VBScript.


Formulario de Pedidos


Grupo de validación

En el ejemplo anterior hemos creado mediante la configuración dos campos nuevos y ocultado uno existente. Necesitamos crear un campo de tipo "combo" para poder elegir entre los grupos de seguridad existentes y debe ser obligatorio. Este campo vamos a crearlo mediante código.


Lo primero es entrar en el configurador de la pantalla. El campo que hemos hecho invisible antes, "Inmovilizado", nos ha dejado un hueco donde colocaremos nuestro control. Necesitamos saber el contenedor de dicho control porque el campo que vamos a crear tendrá que tener el mismo. Tenemos varias formas de hacer esto pero por ahora lo haremos de la forma más simple; asignaremos el contenedor del campo que hemos ocultado.


Necesitamos elegir en qué evento crearemos el campo. Para más información sobre los eventos del formulario consultar los artículos sobre Show e Initialize.


IMPORTANTE: Si creamos campos que queremos sean leídos por el propio objeto debemos crearlo forzosamente en el evento Initialize. Si creamos un campo en el evento Show y le asignamos la propiedad ObjPOrigen no será leído hasta que se cree el control, lo cual será ya demasiado tarde para que se muestre en la apertura del objeto.


Para este ejemplo lo crearemos en el evento Initialize. Lo primero que necesitamos es referenciar el control "Inmovilizado" porque queremos usar algunas de sus propiedades, como la posición X e Y o el contenedor.


Para referenciar un objeto lo haremos de la siguiente forma:


Set lControlInmovilizado = gForm.Controls("Inmovilizado")

NOTA: Para trabajar con un control podemos referenciarlo asignándolo a una variable o llamarlo de forma estándar, por ejemplo la instrucción "Msgbox lControlInmovilizado.Value" es exactamente igual a "Msgbox gForm.Controls("Inmovilizado").Value".


Creamos el combo de forma estándar. Para información detallada sobre la creación de dicho campo consultar su artículo. Si necesitan revisar sus propiedades pueden consultar las del control TextBox puesto que son las mismas.


El código de creación resultante:

Set lControlInmovilizado = gForm.Controls("Inmovilizado")
  Set lControl = gForm.Controls.Add("AhoraOCX.ComboUsuario", "Pers_GrupoFirma", lControlInmovilizado.Container)
  With lControl 
     .C1Nombre = "Descrip"
     .C1TipoDato = 8          ' Texto
     .C1Anchura = 2500
     .C2Nombre = "IdGrupoFirma"
     .C2TipoDato = 2          ' Int
     .C2Anchura = 300
     .CActiva = 2
     .NColumnas=2
     .Descripcion="SELECT Descrip, IdGrupoFirma FROM Pers_Grupos_Firmas"
     .Formato = "Mayusculas y Minusculas"
     .TipoDato = "Long"
     .ObjOrigen = "EObjeto"
     .ObjPOrigen = "Pers_IdGrupoFirma"
     .visible = True
     .CaptionVisible = True
     .CaptionControl = "Grupo Val."
     .CaptionWidth = 1800
     .Enabled = True
     .CaptionLink = True
     .Move lControlInmovilizado.Left,lControlInmovilizado.Top,5000,300
     .AplicaEstilo 
     .TabStop=True
     .TabIndex = 25
     .Necesario = True
     .ActivarScripts = True
  End With

Veamos las propiedades más importantes en la creación de dicho campo:


CX... - Estas propiedades determinan el nombre, tipo de dato y anchura de las columnas que definamos en la consulta sql del combo. El objeto admite un máximo de tres columnas.

CActiva - Determina la columna cuyo valor se guardará en el campo. En este ejemplo mostramos dos columnas, una con la descripción y otra con la Id pero únicamente guardamos la Id.

ObjOrigen / ObjPOrigen - Estas propiedades son comunes a todos los controles que creemos y sirven de enlace con la información que guardaremos directamente en la tabla Conf. Equivalen a "EObjeto Origen" y "EObjeto Propiedad" vistos en el documento anterior.

CaptionLink - Activar esta propiedad habilita el que podamos hacer click en la etiqueta y nos cargue un asistente que se forma con los datos por defecto del combo. Para más información del captionlink revisar el siguiente enlace.

Move - Usar este método nos ahorra tener que establecer manualmente las propiedades Left, Top, Width y Height del control, a las que hace referencia secuencialmente. Nótese que para los valores X e Y (Left y Top en las propiedades del objeto) usamos las mismas que el control de inmovilizado que hemos referenciado antes.

Necesario - Puesto que en los requerimientos hemos considerado que la elección del grupo de validadores es esencial en la creación de todo pedido activamos esta propiedad para que, al crear uno nuevo, nos de error al guardar si no está activo.

ActivarScripts - Activar esta propiedad en cualquier control es esencial si necesitamos trabajar con sus eventos (si no lo activáramos no podríamos, por ejemplo, capturar su evento "CaptionLink").


Botón de validación

Siguiendo los requerimientos de la solución es necesario crear un botón para validar. Ahora únicamente vamos a centrarnos en crearlo in darle ninguna funcionalidad.


Seguimos este documento y obtenemos el código de creación que introduciremos en el evento Initialize:

  gForm.Botonera.ActivarScripts = True
  gForm.Botonera.BotonAdd "Validar", "Pers_ValidarPedido", , 0, True, 123
  gForm.Botonera.HabilitaBotones

El botón que hemos creado ahora mismo no tiene ninguna funcionalidad y aparece a todos los usuarios. Volveremos a esta pantalla a terminar estos puntos en otro documento.


Ocultación de pestaña Conf.

En los objetos del ERP a los que añadimos campos configurables se crea automáticamente una pestaña con los campos configurables en su formulario para su rápida edición.

En este formulario, teniendo en cuenta la naturaleza de los campos que hemos añadido, queremos ocultar dicha pestaña para que nadie pueda modificar estos valores.


Seguimos los pasos indicados en este documento y obtenemos el siguiente código:


gForm.Controls("TabDatos").item(3).Visible = False


Creación de nueva pestaña

Crearemos una nueva pestaña que albergará el histórico solicitado siguiendo los pasos del siguiente documento.


El código resultante es el siguiente:


  '    Creación de panel
  Set lPnl = gForm.Controls.Add("Threed.SSPanel", "Pers_panelHco")
  lPnl.Visible=True
  lPnl.autosize = 3
  lPnl.Object.Caption = ""
  '    Creación de la pestaña en sí
  gform.controls("TabDatos").InsertItem 100, "Hco. Firmas", lPnl.Hwnd, 1

Podemos comprobar como es necesario crear primero un panel que asignaremos a la nueva pestaña. Actualmente la pestaña está vacía y no tiene funcionalidad ninguna, en siguientes artículos añadiremos el grid correspondiente.


Ocultación de menú "Albarán"

Siguiendo las especificaciones de la solución debemos ocultar dicho menú y condicionar su visibilidad a que la propiedad Pers_Validado del pedido esté activa.


Aquí será necesario primero ocultarlo al entrar en el formulario y, posteriormente, trabajar el evento de la carga del objeto para, si procede, hacerlo visible. Podríamos hacer exactamente lo mismo si quisiéramos dejarlo inactivo cambiando su propiedad correspondiente. Para el siguiente ejemplo simplemente lo ocultaremos.


Primero en el evento Initialize lo ocultamos, siguiendo los pasos indicados en el siguiente documento.

gForm.Controls("mnuMain").Tools("mnuAlbaran").visible = False

El nombre del menú lo hemos consultado en la opción correspondiente del Admon, tal como puede verse en el siguiente enlace. Al seleccionar la librería y el formulario puedo ver todos sus menús y obtener sus nombres.


Ahora es necesario mostrarlo cuando se cumpla la condición de que esté totalmente validado. Recordemos que dicha validación, la de la cabecera del pedido, se realizará en un proceso independiente que lo marcará como tal una vez todas sus líneas hayan sido validadas.

Necesitamos añadir la visibilidad del mismo en un evento que se ejecute cada vez que cargamos un objeto. ¿Porqué no sirve en el Show o Initialize? Dentro de un objeto tenemos flechas de navegación entre registros, si no controláramos esta condición cada vez que cargamos un objeto serviría únicamente en la apertura de un único objeto y, lo que es peor, si lo dejáramos activo al navegar entre los mismos tendríamos el menú visible cuando no debiera estarlo.

Para ello usaremos el evento CargaObjeto, accesible mediante el control EnlaceObjeto.



Para ello simplemente leeremos la propiedad Value del campo que hemos añadido, "Validado", para mostrarlo u ocultarlo en función de su valor. Si hacemos click en el control nos dirá el nombre que se le ha asignado dentro del formulario:


Como este nombre es muy poco descriptivo lo renombraremos a algo que nos resulte más legible, con la opción del menú contextual Renombrar:


Nos solicitará el nuevo nombre (para este ejemplo le asignamos Pers_Validado) y, tras salir y volver a entrar de la pantalla, podremos ver el nuevo nombre aplicado:



Ahora que ya podemos trabajar con el campo añadiremos la funcionalidad básica inversa que antes hemos aplicado, siendo el código resultante el siguiente:


Sub CargaObjeto
  If gForm.Controls("Pers_Validado").Value Then
    gForm.Controls("mnuMain").Tools("mnuAlbaran").visible = True
  Else
    gForm.Controls("mnuMain").Tools("mnuAlbaran").visible = False
  End If
End Sub

Como está en el evento CargaObjeto se oculta o se muestra en función del valor que tenga el control Pers_Validado que anteriormente hemos renombrado.


NOTA: En nuestro ejemplo la ocultación del menú en el evento Initialize es redundante puesto que lo ocultamos en el evento de carga del objeto. Lo eliminamos para evitar código innecesario.


Modificación del campo Pedido Cli.

Uno de los requerimientos es rellenar automáticamente el campo Pedido Cli. con un valor determinado compuesto por la serie seleccionada y uno de los campos de la tabla Series_Facturacion. Tenemos varias formas de afrontar esto pero optaremos por modificar el campo en cuestión una vez modifiquemos el campo "Serie" del que depende.


Dado que tenemos que capturar el evento AfterUpdate del control SeriePedido tenemos que marcar su activación de scripts en el evento Initialize.


gForm.Controls("SeriePedido").ActivarScripts = True


Ahora tenemos que modificar el evento AfterUpdate para capturar su valor. Para más información consultar el siguiente enlace.


  If aCombo.Name = "SeriePedido" Then
    If aCombo.Value <> "" Then
      lCodSerie = gcn.DameValorCampo("SELECT CodSerie FROM Series_Facturacion WHERE SerieFactura = " & aCombo.Value)
      If lCodSerie <> "" Then
        gForm.Controls("IdPedidoCli").Text = CStr(aCombo.Value) & " - " & CStr(lCodSerie)
      End If
    End If
  End If

Hemos hecho la primera referencia al control gCn. Recomendamos encarecidamente la lectura del siguiente artículo que lo explica en profundidad puesto que nos resultará de la máxima utilidad a la hora de hacer nuestras modificaciones.


Si bien esta modificación modificará el campo una vez hayamos cambiado el valor necesitamos una forma de rellenarlo automáticamente en los pedidos que creemos. Anteriormente hemos usado el evento CargaObjeto. Haremos lo mismo con el evento NuevoObjeto.

Sub NuevoObjeto
  lSerieFacturacion = gForm.Controls("SeriePedido").Value
  lCodSerie = gcn.DameValorCampo("SELECT CodSerie FROM Series_Facturacion WHERE SerieFactura = " & lSerieFacturacion)
  If lCodSerie <> "" Then
    gForm.Controls("IdPedidoCli").Text = CStr(lSerieFacturacion) & " - " & CStr(lCodSerie)
  End If
End Sub

Para asegurar así mismo que no se nos escapa ningún evento "Nuevo", en CargaObjeto añadimos un control extra para que actualice el campo siempre que el control NumPedido sea 0 (al guardarlo siempre se le asigna un valor). Aprovechamos y, ya que tenemos el código y lo llamamos desde dos sitios, creamos una subrutina para ello:


Sub AsignacionValorPedCli()
  lSerieFacturacion = gForm.Controls("SeriePedido").Value
  lCodSerie = gcn.DameValorCampo("SELECT CodSerie FROM Series_Facturacion WHERE SerieFactura = " & lSerieFacturacion)
  If lCodSerie <> "" Then
    gForm.Controls("IdPedidoCli").Text = CStr(lSerieFacturacion) & " - " & CStr(lCodSerie)
  End If
End Sub


Llamamos a dicha subrutina en los sitios que corresponda con una simple instrucción.


AsignacionValorPedCli()


Modificación de observaciones (tras modificar Origen)

Necesitamos rellenar automáticamente el campo Observaciones cuando se modifique el valor del campo Origen. La captura del campo, también de tipo Combo, se realizará en el mismo evento que acabamos de modificar, AfterUpdate. En esta ocasión simplemente comprobaremos que el valor corresponda con el que necesitamos y modificaremos el control Observaciones, sin olvidarnos que si no rellenamos su propiedad ActivarScripts no podremos capturar su evento.


gForm.Controls("Origen").ActivarScripts = True


If aCombo.Name = "Origen" Then
    If aCombo.Value = "SubCanal 0" Then
      If gForm.Controls("Observaciones").Text = "" Then
        gForm.Controls("Observaciones").Text = "TEXTO MODIFICADO POR Origen"
      Else
        gForm.Controls("Observaciones").Text = gForm.Controls("Observaciones").Text & VbCrlf & "TEXTO MODIFICADO POR Origen"
      End If
    End If
  End If

Añadimos una simple comprobación para evitar introducir una línea en blanco antes del texto para respetar lo que hubiera podido estar introducido en el control.


Modificación de observaciones (tras modificar SeriePedido)

Esta modificación se basa exactamente en lo mismo que las anteriores con la particularidad que vamos a tratar el campo en el evento AfterUpdate de un campo de texto, no de un combo, aunque su funcionamiento es exactamente el mismo.


  If aTexto.Name = "IdPedidoCli" Then
    lSerieFacturacion = gForm.Controls("SeriePedido").Value
    lCodSerie = gcn.DameValorCampo("SELECT CodSerie FROM Series_Facturacion WHERE SerieFactura = " & lSerieFacturacion)
    lValorTeorico = lSerieFacturacion & " - " & lCodSerie
    If lValorTeorico <> aTexto.Text Then
      lTextoObs = "Se ha modificado el valor de Pedido Cli"
      If gForm.Controls("Observaciones").Text = "" Then
        gForm.Controls("Observaciones").Text = CStr(lTextoObs)
      Else
        gForm.Controls("Observaciones").Text = gForm.Controls("Observaciones").Text & VbCrlf & CStr(lTextoObs)
      End If
    End If
  End If




Tenemos pendiente el desarrollo de la parte funcional de la misma y habilitar el botón para validar las líneas. Volveremos más adelante a ella para terminarla.

El código completo hasta el momento de este formulario se puede ver en el fichero adjunto frmPedidos_1.txt.


Codificación: Manipulación de grids en frmEmpleados >

¿Le ha sido útil este artículo?

¡Qué bien!

Gracias por sus comentarios

¡Sentimos mucho no haber sido de ayuda!

Gracias por sus comentarios

¡Háganos saber cómo podemos mejorar este artículo!

Seleccione al menos una de las razones
Se requiere la verificación del CAPTCHA.

Sus comentarios se han enviado

Agradecemos su esfuerzo e intentaremos corregir el artículo