TextBox Multiligne - Sélection & insertion de données
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 2024
-
8 juin 2015 à 13:05
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 2024
-
11 juin 2015 à 10:37
Bonjour CodeS SourceS,
Je rencontre une difficulté assez curieuse.
Tout d'abord le but de ce code : faire en sorte de "formater" le contenu d'un textbox MultiLine pour l'affichage dans une cellule Excel.
Il s'agit d'ajouter donc des "balises" dans le texte du textbox pour que lors de la restitution dans la cellule, le texte puisse être formaté (couleur de texte, gras, souligne...).
Le code fonctionne bien si le texte sélectionné est, au maximum, sur une seule ligne. Par contre, lors de la sélection de plusieurs lignes de texte, les balises ne se placent pas dans le textbox. La curiosité tiens dans le fait que la variable Par les contient bien ces balises...
Grrr!
Voici le code, en trois étapes :
Module de l'userform :
Option Explicit
Private Sub UserForm_Initialize()
Dim monTxtBox As TextBoxFormat
Dim Obj As Object
Dim Defaut_txt$
Dim Cpt%
Set CollectTxt = New Collection
Defaut_txt = "Bonjour," & vbCrLf & _
"Merci de ne sélectionner qu'une partie du texte, choisir les différents formats (disponibles lors d'un clic droit) en cliquant sur les boutons et VALIDER!" & vbCrLf & _
"Vous pourrez ainsi visualiser le résultat du formatage dans le textbox et dans la cellule active." & vbCrLf & _
"Les différents codes fonctionnent pour une sélection d'une ligne maxi." & vbCrLf & _
"Pour une sélection de plusieurs lignes les balises ne s'affichent pas!"
For Cpt = 1 To 4
Set Obj = Me.Controls.Add("forms.TextBox.1")
With Obj
.Move 24, 6 + (75 * (Cpt - 1)), 480, 70
.MultiLine = True
.Name = TXTBOXNAME & Cpt
.Value = Defaut_txt
.WordWrap = True
End With
Set monTxtBox = New TextBoxFormat
Set monTxtBox.TxtF = Me.Controls(TXTBOXNAME & Cpt)
CollectTxt.Add monTxtBox
Next Cpt
Me.Move Me.Left, Me.Top, 544, 411
End Sub
Module "standard" :
Option Explicit
Public Nom_Tb$
Public CollectTxt As Collection
Public Const TXTBOXNAME$ = "F_TextBox"
Public Const PARAM$ = "Noir;Blanc;Rouge;Vert;Bleu;Jaune;Gras;Italic;Souligne"
Public Const BALISES$ = "N;W;R;V;B;Y;G;I;S"
Public Sub Format_Txt(Balise As String)
Dim Valeur$, S%, L%, Quoi$, Par$
With UserForm1.Controls(Nom_Tb)
Valeur = .Value
S = .SelStart
L = .SelLength
Quoi = .SelText
Par = "<" & Balise & ">" & .SelText & "</" & Balise & ">"
'On VOIT ICI que Par contient bien les balises "<X>" & "</X>"...
'Debug.Print Par
.Value = Replace(Valeur, Quoi, Par)
End With
End Sub
Module de classe nommé : TextBoxFormat
Option Explicit
Public WithEvents TxtF As MSForms.TextBox
Private Sub TxtF_MouseUp(ByVal Button%, ByVal Shift%, ByVal X!, ByVal Y!)
Select Case Button
Case XlMouseButton.xlSecondaryButton
With TxtF
If .SelText = "" Then
MsgBox "Veuillez sélectionner le texte à formater."
Exit Sub
End If
Nom_Tb = .Name
End With
CreerMenu
Application.CommandBars("Menu").ShowPopup
End Select
End Sub
Public Sub CreerMenu()
Dim cBar As CommandBar, i%, Bal$, Texto$
Const NOMB As String = "Menu"
On Error Resume Next
Application.CommandBars(NOMB).Delete
On Error GoTo 0
Set cBar = Application.CommandBars.Add(Name:=NOMB, Position:=msoBarPopup, temporary:=True)
For i = 0 To UBound(Split(BALISES, ";"))
Texto = Split(PARAM, ";")(i)
Bal = Split(BALISES, ";")(i)
With Application.CommandBars(NOMB).Controls.Add(Type:=msoControlButton)
.Caption = Texto
.OnAction = "'Format_Txt """ & Bal & """'"
End With
Next i
Set cBar = Nothing
End Sub
ucfoutu
Messages postés18038Date d'inscriptionlundi 7 décembre 2009StatutModérateurDernière intervention11 avril 2018211 Modifié par ucfoutu le 8/06/2015 à 15:47
Bonjour, Franck,
Ton problème résulte des vbxcrl présents et qui se font des croche-pieds entre l'aller et le retour.
On pourrait bien sûr suivre ta logique et "formater" chaque sous-chaîne issue d'un split sur les retours à la ligne.
Mais pourquoi s'embarrasser, alors que la propriété seltext est déjà le texte sélectionné et qu'elle est en lecture/écriture. Sers-t'en et affranchis toi au passage du Replace, du Selstart, du Sellength, de la variable valeur, de la variable Par et de la variable quoi ===>>>
Public Sub Format_Txt(Balise As String) With UserForm1.Controls(Nom_Tb) .SelText = "<" & Balise & ">" & .SelText & "</" & Balise & ">" End With End Sub
________________________
Nul ne saurait valablement coder ce qu'il ne saurait exposer clairement.
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 202414 8 juin 2015 à 15:48
Bonjour Jacques,
J'avais réussit à pointer du doigt le souci (vbcrlf), mais n'ai trouvé aucune explication à ce sujet.
Merci pour la réponse en tout cas.
Je vais tester sur le champs.
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 202414 9 juin 2015 à 09:40
Bonjour,
Je rouvre ce sujet afin de comprendre certains "détails".
La saisie de caractères (Via Chr(CodeAscii)) dans le textbox entraine des réactions assez "particulières".
C'est le cas pour VbCrlf qui nous empêche, par exemple, d'utiliser la fonction Replace dans mon exemple.
C'est également le cas d'autres caractères.
Affiche, dans le textbox, un "grand" espace avant la balise "ouvre" et après la balise "ferme", mais n'affiche rien avant la balise "ouvre" et après la balise "ferme" dans la fenêtre d'exécution...
Efface la sélection dans le textbox et affiche dans la fenêtre d'exécution un espace avant la balise "ouvre" et après la balise "ferme".
Je n'ai pas, de fait, testé tous les Chr() possibles, mais y a t'il un endroit, un site ou se renseigner sur ces particularités?
Pourquoi ces "réactions" particulières? sont-elles explicables?
[Oui, il y a une explication à chacune de ces particularités. Mais qu'elle est-elle???]
S'il n'en existe pas, est-il opportun de créer un tutoriel à ce sujet?
Merci par avance.
Vous n’avez pas trouvé la réponse que vous recherchez ?
ucfoutu
Messages postés18038Date d'inscriptionlundi 7 décembre 2009StatutModérateurDernière intervention11 avril 2018211 9 juin 2015 à 11:28
Je vais commencer par le chr(0), qui est très particulier ===>>>
Le caractère 0 est un caractère nul de terminaison.
Il n'est pas lu au Debug Print, d'une part et, d'autre part, le debug print ne lit pas au delà de ce caractère
Idem avec une msgbox, d'ailleurs (et pour la même raison)
Fais l'expérience ===>>
toto = "aaa" & Chr(0) & "bbb" MsgBox toto
L'affichage n'ira pas au delà de "aaa", bien que la chaîne soit plus longue ===>>>
Msgbox len(toto)
t'affichera bien 7
et pour cause, car le caractère 0 a bel et bien été pris en compte et le voilà :
Dim titi() As Byte titi = StrConv(toto, vbFromUnicode) For i = 0 To UBound(titi) MsgBox titi(i) Next
Mais termine la "lecture".
Regarde maintenant :
MsgBox Left(toto, 3) & Right(toto, 3)
tu vois bien, que le "bbb" est bien là, mais que le chr(0) a interrompu la lecture de la chaîne (c'est sa vocation, d'ailleurs).
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 202414 9 juin 2015 à 11:48
Bonjour Jacques,
Et une fois de plus, merci.
Ok. J'ai bien saisi la vocation du Chr(0).
Le but était, mais je penses que tu t'en doutes, de "préparer" la restitution du contenu du textbox dans la cellule, afin que le formatage se fasse sans souci.
Pour cela, j'aurais utilisé un simple Split(montext, Chr(0)).
Mais si l'affichage ne peut se faire, cela ne m'arrange pas.
Je cherchais un caractère "invisible" pour indiquer les débuts et fins de balise.
J'ai également testé Chr(2) et Chr(3) mais ces caractères ne sont pas "invisibles" à l'affichage...
Je vais continuer à explorer d'autres possibilités.
ucfoutu
Messages postés18038Date d'inscriptionlundi 7 décembre 2009StatutModérateurDernière intervention11 avril 2018211 9 juin 2015 à 23:29
Ah ...
Tu veux le beurre et l'argent du beurre (des balises, mais invisibles)
Pourquoi ne pas alors utiliser une RichtextBox, ce qui te permettrait de formater ton texte comme tu l'entends, sans aucune balise ?
La "récupération", ensuite, du format pourra se faire sans problème caractère par caractère (une simple boucle).
Et tu pourras (toujours sans aucune balise apparente) "conjuguer" à ton aise (la taille, le style, la couleur, etc ...)
Oui, je veux le beurre, son argent et ... la crémière (tu va comprendre pourquoi)...
1- je ne veux pas utiliser le Contrôle RichTextBox car cela obligerait les utilisateurs du fichier à tous l'installer sur leur machine. (ici, tu comprends bien que ce fichier n'est pas pour moi, mais pour un forumeur)
2- Je ne souhaites pas que mes balises (<N>, <W>, <B> etc) soient invisibles car l'utilisateur s'en sert pour visualiser la mise en forme qu'il est en train d'effectuer.
3- Je souhaitais ajouter de part et d'autres de ces balises, un caractère invisible (dans mon exemple prenons Chr(0) même s'il ne convient pas) afin de pourvoir restituer le plus facilement du monde :
Ainsi, pour la restitution, je n'avais qu'à faire un Split :
Tb() = Split(TextBox.Value, Chr(0))
pour obtenir quelque chose comme ceci :
Tb(1) => <B>
Tb(2) => Bonjour,
Tb(3) => </B>
Tb(4) => <N>
Tb(5) => Comment allez-vous par ici?
Tb(6) => </N>
etc...
EDIT : ps : tu dois te demander : "pourquoi ne pas faire la mise en forme directement dans la cellule?"
En effet, c'est comme cela que je ferais. Mais bon, à ce moment là, pourquoi créer un Userform pour saisir dans une cellule? Aucun intérêt non plus.
Je respecte seulement les consignes...
ucfoutu
Messages postés18038Date d'inscriptionlundi 7 décembre 2009StatutModérateurDernière intervention11 avril 2018211 11 juin 2015 à 07:16
L'inconvénient majeur de ces "balises" incluses directement dans le texte de la textbox est qu'elles sont dépendantes des gestes (tous) de l'utilisateur et donc extrêmement vulnérables.
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 202414 11 juin 2015 à 10:37
Bonjour,
Effectivement, je n'ai pas pensé à cet aspect...
Si l'utilisateur, dans un mauvais geste supprime un < ou un > ou encore /... ça risque de planter toute restitution.
Pour moi, cela semble sans issue.
Les deux seules raisonnables solutions étant :
- Le contrôle RichTextBox
- formater le texte directement dans la cellule.
Je vais toutefois reposer le problème posément, on ne sait jamais.
Encore merci pour ton intervention.
A++