Solved Detect the change of a control from the main form to the subform, and vice versa (2 Viewers)

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
I had thought about adding to that loop that it only adds the events in which the rich text is active.

My goal was what I said before, but I wanted to achieve it through a class module. I know that I have things to learn, that's why I am open to other proposals that go along the path by which I want to achieve it. Which is why I ask you how you suggest I put it and why, doing it this way, it doesn't work for me in the "FPreciosAlmazara" form.

Thanks.
 

Josef P.

Well-known member
Local time
Today, 14:51
Joined
Feb 2, 2023
Messages
826
I do not understand this code:
Code:
Private Sub mTextbox_Enter()
    If mTextbox.TextFormat = acTextFormatHTMLRichText Then
        mForm.ScrollBars = 0
        Dim txt As TextBox
        Set txt = Screen.ActiveControl
        If txt.TextFormat = acTextFormatHTMLRichText Then
            If Not mForm.ActiveControl.Parent.Name = mForm.Name Then
                mForm.Parent.RibbonName = "RichText"
            End If
            mForm.RibbonName = "RichText"
        End If
    End If
End Sub
mTextbox and txt should always be the same textbox, right?

Attached is your sample file with the EventCollector shown in #15.
Whether I meet your intention with it, I do not know. I don't understand your code enough. ;)
 

Attachments

  • Detectar cambios entre formulario principal y subformulario.zip
    61.7 KB · Views: 51

Edgar_

Active member
Local time
Today, 07:51
Joined
Jul 8, 2023
Messages
430
you can only react to the events of a single textbox in the class
The last one in the loop

@zelarra821 The reason the class works with the sample form and not with your production form is that in the sample, your rich textbox is indeed the last in the loop, but in your production form, the last textbox is TxtFechaFinal in FPreciosAlmazaraSubformularioPreciosAceite and Maquila in FPreciosAlmazaraSubformularioPreciosAlmazara, so this code:
Code:
    For Each ctrl In mForm.Controls
        Debug.Print mForm.Name, TypeName(ctrl), ctrl.Name 'this line will tell me the order
        If TypeName(ctrl) = "TextBox" Then
            Set mTextbox = ctrl
           
            mTextbox.OnEnter = "[Event Procedure]"
            mTextbox.OnExit = "[Event Procedure]"
        End If
    Next ctrl

Which basically is doing this:
For each control in the collection of controls of the form assigned to mForm:
if the type of control of the current control is "textbox", then do these things:
1. set my variable mTextbox to it
2. write "[Event Procedure]" on its event expression box for OnEnter and OnExit
Go to the next control and do exactly the same and, as you can see, that includes setting mTextbox again to a different control.

Can be changed with this:
Rich (BB code):
    Dim ctrl As Object
    For Each ctrl In mForm.Controls
'        Debug.Print mForm.Name, TypeName(ctrl), ctrl.Name
        If TypeName(ctrl) = "TextBox" Then
            If ctrl.TextFormat = acTextFormatHTMLRichText Then
                Set mTextbox = ctrl
               
                mTextbox.OnEnter = "[Event Procedure]"
                mTextbox.OnExit = "[Event Procedure]"
            End If
        End If
    Next ctrl

And it will work if you only have one rich textbox in the form.
 

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
Hello.

Thank you so much Joseph and Edgar.

I have reviewed the behavior of what was proposed in post number 15, and what I have published does the same, but in a simpler way. Furthermore, I have corrected and added what Edgar proposed.

My idea is to create a class module that does the following:

1. When you enter a text box with rich text, you need to hide the form's scroll bars and show one of the ribbons you created called RichText.

2. When you exit a text box with rich text, you need to display the form's scroll bars and display another of the ribbons you created called Database.

3. When you click on the Header or Detail of the form, you have to make the two changes from point 2.

4. These three points must be able to be reproduced with simple forms, or forms with subforms (one, two, three...) in each of them.

With the code that you can find in the example that I attach now (corrected according to what Joseph and Edgar pointed out), I can do points 1, 2 and 4. The only thing left for me to achieve is point 3.
 

Attachments

  • Detectar cambios entre formulario principal y subformulario.accdb
    2.3 MB · Views: 51

Josef P.

Well-known member
Local time
Today, 14:51
Joined
Feb 2, 2023
Messages
826
That's too easy for point 3, isn't it?
Code:
Private Sub EncabezadoDelFormulario_Click()
    Me.IdAlmazara.SetFocus
End Sub
 

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
Edgar, what if I wanted to add the two events (Enter and Exit) to more than one textbox with rich text?

Thank you so much.
 

Edgar_

Active member
Local time
Today, 07:51
Joined
Jul 8, 2023
Messages
430
1. When you enter a text box with rich text, you need to hide the form's scroll bars and show one of the ribbons you created called RichText.

2. When you exit a text box with rich text, you need to display the form's scroll bars and display another of the ribbons you created called Database.

3. When you click on the Header or Detail of the form, you have to make the two changes from point 2.

4. These three points must be able to be reproduced with simple forms, or forms with subforms (one, two, three...) in each of them.

With the code that you can find in the example that I attach now (corrected according to what Joseph and Edgar pointed out), I can do points 1, 2 and 4. The only thing left for me to achieve is point 3.
Your production form has everything inside the header. There's nothing in the detail section, I don't think you need to check which scrollbars setting you have for that setting to work, just use this
Code:
Private Sub mHeader_Click()
    mForm.ScrollBars = 2 'or whatever of the settings you need
    mForm.RibbonName = "Database"
End Sub
After you put something in the detail section, you can then expect some behavior for the detail click event.

Edgar, what if I wanted to add the two events (Enter and Exit) to more than one textbox with rich text?
The same way we targetted the textbox with rich text, if you find a way to differentiate them, but you will need to have one variable for each like mTextBox1, mTextBox2, ... mTextBoxN. And in order to set those textboxes to any of these variables, you should have a way to identify them during the loop, either via a control name, or any other property. You could use the tag property, for example. That would work. HOWEVER! you will be told that this is a bad usage for a class, because classes are meant to be reused. BUT YOU CAN DO IT, if you want. For example, make another form, add a rich textbox and add something to its tag property (the "Información adicional" property located in the "Otras" tab of your properties pane), something like "rich1", then add another rich textbox and type "rich2". And in the loop:
Rich (BB code):
    Dim ctrl As Object
    For Each ctrl In mForm.Controls
        If TypeName(ctrl) = "TextBox" Then
            If ctrl.TextFormat = acTextFormatHTMLRichText Then
                if ctrl.Tag = "Rich1" Then
                    Set mTextbox1 = ctrl
                elseif ctrl.Tag = "Rich2" Then
                    Set mTextbox2 = ctrl
                end if
                ctrl.OnEnter = "[Event Procedure]"
                ctrl.OnExit = "[Event Procedure]"
            End If
        End If
    Next ctrl
It's not great for a class, but you can do it. After all, you're experimenting. So try it.

Since it's not a great use for a class, that's why I was using an external module in my initial snippets. That way I don't have to set an event from the class and I directly have the module figure that out.
 

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
Hello.

I have looked at what you have proposed. For that, I prefer how I had it before, and that is that I add an optional parameter to the function that starts the class module to put the textbox that interests me. This way, I can add as many as I want more easily and in the form in question, and not touch the class module.

---------------------------------------------------------------------------------------------------------------------------------------------------------------

On the other hand, regarding the proposal to place the focus on a field. Yes, I already knew that's what had to be done. Now what I want is to not have to touch the class module code.

Therefore, I have created a procedure to obtain the field whose tabindex is 0 and place the focus on it. However, I am not able to achieve it.

I attach the database.

Thanks.
 

Attachments

  • Detectar cambios entre formulario principal y subformulario.accdb
    2.3 MB · Views: 58

Edgar_

Active member
Local time
Today, 07:51
Joined
Jul 8, 2023
Messages
430
I downloaded your file and noticed that your GetFirstControl loops over all your controls and tries to find the control with tabindex = 0, but not all controls have this property, so it throws an error when the current object in the loop is a label. You're trapping this error with your error handling, that's why you couldn't know. So trap that error or modify your procedure however you see fit.

You still have everything inside the header section. Your detail section has nothing.
 

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
I have made the proposed changes: differentiate header from detail and correct the error.

With those corrections, it now works for me in a form when I am in the text box with rich text and click on the detail of one of the forms, but not in the other, and I don't know why.

Thank you so much.
 

Attachments

  • Detectar cambios entre formulario principal y subformulario.accdb
    2.3 MB · Views: 58

Edgar_

Active member
Local time
Today, 07:51
Joined
Jul 8, 2023
Messages
430
it now works for me in a form when I am in the text box with rich text and click on the detail of one of the forms, but not in the other, and I don't know why.
You have three forms and all of them have header and detail section. If you add this to your class module:
Rich (BB code):
Private Sub mHeader_Click()
    If Not mForm.ScrollBars = 2 Then
        mForm.ScrollBars = 2
    End If
    GetFirstControl
    mForm.RibbonName = "Database"
    MsgBox "header"
End Sub

Private Sub mDetail_Click()
    If Not mForm.ScrollBars = 2 Then
        mForm.ScrollBars = 2
    End If
    GetFirstControl
    mForm.RibbonName = "Database"
    MsgBox "detail"
End Sub

You will see that those sections are indeed recognized by your class. So I'm not sure what's not working for you. We both speak spanish, so you could explain in much more detail if that's comfortable for you.
 

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
Hola, Edgar. Lo único que se me ocurre es añadir un parámetro opcional en Inicializar para poner el subform, de tal forma que pueda añadir el evento al salir, y quitar el sub para situar el foco.

He probado a añadir un encabezado en los dos subformularios que no funcionaba. También he comparado el nombre del Header y el Detail de los subform entre los formularios en que funciona y el que no. Nada.

Muchas gracias.
 

Edgar_

Active member
Local time
Today, 07:51
Joined
Jul 8, 2023
Messages
430
Hice visibles los bordes de los controles de tus formularios y le di color a tus headers para diferenciarlos de tus secciones detail. Además, puse en el código de tu clase unos message box que se ejecutan al hacer click en secciones header y detail, respectivamente. Si tú haces click sobre las zonas grises, que son encabezados, notarás que se ejecuta perfectamente el message box de encabezado. Cosa similar ocurre con el detail.

No es lo mismo hacer click sobre el "fondo" del encabezado que sobre los controles que se ubican en este. Por esto, si lo que quieres es que se ejecute un código sobre cualquier cosa que se encuentre en tu header, incluyendo los controles, tendrás que tomar en cuenta esos controles en tu código. Pero dime si lo que acabo de describir es o no lo que necesitas, porque no estoy entendiendo.

I made the borders of your form controls visible and gave color to your headers to differentiate them from your detail sections. Additionally, I put in the code of your class some message boxes that are executed when clicking on the header and detail sections, respectively. If you click on the gray areas, which are headers, you will notice that the header message box is executed perfectly. A similar thing happens with the detail.

Clicking on the "background" of the header is not the same as clicking on the controls located in it. Therefore, if what you want is for code to be executed on anything that is in your header, including the controls, you will have to take those controls into account in your code. But tell me whether or not what I just described is what you need, because I'm not understanding.
 

Attachments

  • Detectar cambios entre formulario principal y subformulario3.accdb
    856 KB · Views: 54

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
Luego lo veo. Ahora estoy en el trabajo. Muchas gracias.
 

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
Hola, Edgar. Gracias por contestar. El problema no es que no detecte el hacer click en el header o en el Detail, sino que, al hacer click en esas secciones, debe mandar el foco del campo del subform con texto enriquecido a uno que no tenga texto enriquecido dentro del propio Subform.

Por eso motivo he puesto el último Sub, para intentar lograr eso, pero no consigo hacer que funcione.

 

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
¿Podrías echarle un vistazo a ver si tú eres capaz de lograr que funcione el procedimiento? Básicamente, debe hacer referencia al campo del subformulario desde el formulario principal, pero no sé hacerlo. Muchas gracias.
 

Edgar_

Active member
Local time
Today, 07:51
Joined
Jul 8, 2023
Messages
430
¿Podrías echarle un vistazo a ver si tú eres capaz de lograr que funcione el procedimiento? Básicamente, debe hacer referencia al campo del subformulario desde el formulario principal, pero no sé hacerlo. Muchas gracias.
Code:
Public Sub GetFirstControl()

    Dim ctrl As Object
    Dim Form As Form
  
    For Each ctrl In mForm.Controls
        Select Case ctrl.ControlType
            Case acCheckBox, acComboBox, acCommandButton, acImage, acSubform, acTextBox
                If ctrl.TabIndex = 0 Then
                    ctrl.SetFocus
                    Exit Sub
                End If
        End Select
    Next ctrl

End Sub

Esto hace que, dependiendo de en qué formulario hagas click, si haces click en una sección detail o header, hará foco en el control cuyo tabindex sea 0. En el caso del formulario principal, el control con tabindex = 0 es el botón "Volver", pero en los subformularios, que también tienen un header y un detail section, si haces click en esas secciones de los subformularios, te elegirán el control con tabindex 0, que en ambos casos es la Fecha de inicio.

Eso necesitas? o tal vez necesitas que, al hacer click en el encabezado o detalle del formulario principal, se vaya y haga foco en el primer subformulario y a su vez en el primer control?
 
Last edited:

zelarra821

Registered User.
Local time
Today, 14:51
Joined
Jan 14, 2019
Messages
813
Hola, Edgar. Te he grabado un vídeo explicando lo que quiero conseguir, pues veo que con palabras no lo logro. Espero tu respuesta. Muchas gracias.
 

Attachments

  • Video.zip
    1.7 MB · Views: 47

Edgar_

Active member
Local time
Today, 07:51
Joined
Jul 8, 2023
Messages
430
Qué tal, Zelarra,

En tu video, en que haces la prueba del código propuesto en el formulario de muestra, haces click afuera y se queda con foco el campo de texto enriquecido. Pero si haces la prueba sobre el otro formulario, el que es para producción, podrás ver que sí funciona ahí.

¿Qué es lo que esta pasando? En el archivo adjunto, agregué una línea al código propuesto para que sepas a qué control del formulario se está yendo el foco cuando haces click sobre el detalle o el encabezado. Debe de ir al control que tenga el tabindex en 0.

La razón por la que el comportamiento que deseas ocurre correctamente en el formulario de producción pero no en el de muestra, es porque:
- en el formulario de producción, el control con tabindex = 0 es el botón "Volver".
- en el formulario de muestra, el control con tabindex = 0 es el subformulario

Cuando pasas de un formulario principal a un subformulario, el subformulario se te enfocará automáticamente sobre el control que ya tenía enfoque. En el caso que mostraste en el video, el subformulario ya tenia enfocado el cuadro de texto enriquecido, por lo cual no se movió. ¿Sí me explico?
 

Attachments

  • Detectar cambios entre formulario principal y subformulario3.accdb
    904 KB · Views: 49

Users who are viewing this thread

Top Bottom