Détecter un retour à la ligne automatique.

mromain

XLDnaute Barbatruc
Bonjour le forum,


Suite à cette discussion, j'ai effectué quelques recherches afin de savoir comment détecter les retours à la ligne automatique du texte dans une cellule.
Malheureusement, je n'ai pas réussi à trouver une solution...

Si vous en avez une, je suis preneur :).

A+
 

mromain

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Hello James ;)


Non, je ne parle pas de ça (du moins, je pense).
Je parle des retours à la ligne automatique : quand une chaine de caractère (ne contenant pas de vbCr, ni de vbLf) est sur plusieurs lignes en fonction de la largeur de colonne (quand on coche Retour à la ligne automatique dans le format de cellule).

Je mets un petit fichier exemple (j'aurais du le faire à mon premier post...).

En tous cas, merci pour ta réponse :).

a+
 

Pièces jointes

  • Book1.xls
    12.5 KB · Affichages: 151
  • Book1.xls
    12.5 KB · Affichages: 174
  • Book1.xls
    12.5 KB · Affichages: 174

James007

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Re,
Si je comprends mieux, tu veux capter :
Range("A1").WrapText = True ' or False
Mais la largeur de la cellule va automatiquement modifier le nombre de lignes,
que tu cherches à déterminer ...

A +
 

mromain

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Re,

C'est exactement ça.
Ce que je souhaiterai, c'est une boucle sur chaque caractère du texte, et pouvoir dire pour chacun d'eux à quelle ligne il appartient.

Donc si ensuite on modifie la largeur de cellule et on relance la macro, le résultat sera différent.

a+
 

James007

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Re,

Le problème que je vois, c'est qu'à l'affichage, l'utilisateur voit plusieurs lignes dans la cellule ...
mais pour VBA, il n'y a pas de VbLf ou de VbNewLine à capturer ... donc comment faire ?
Je vais essayer de creuser plus avant ...

A +
 

mromain

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Re,

Le problème que je vois, c'est qu'à l'affichage, l'utilisateur voit plusieurs lignes dans la cellule ...
mais pour VBA, il n'y a pas de VbLf ou de VbNewLine à capturer ... donc comment faire ?
Je vais essayer de creuser plus avant ...

A +

C'est exactement le problème sur lequel je m'arrache les cheveux depuis ce matin...
Je continue à creuser de mon coté ;)

a+
 

tototiti2008

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Bonjour mromain, Bonjour James,

Après avoir essayé différents trucs, je crois que je vais abandonner....
La seule possibilité que je vois encore, ça serait d'estimer la largeur de chaque caractère (en fonction de la taille et de la police) pour la comparer à la largeur de la cellule, et là je crois que ça dépasse mes capacités (ou mon courage;))
 

ROGER2327

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Bonjour à tous
En utilisant une fonte non proportionnelle comme Courier New ou Lucida Console, il y a peut-être moyen de faire. Par exemple, en corps 8, zoom 100%, on peut estimer la largeur de colonne l en fonction du nombre de caractères n comme suit :
l=(n+1)*7
(En espérant que ça ne dépende pas en plus de la carte graphique, du moniteur et de l'âge du capitaine…)
ROGER2327
#4722


Mardi 10 Sable 138 (Exaltation de Ubu Roi (Ubu d'hiver), SPs)
20 Frimaire An CCXIX
2010-W49-5T16:06:52Z

 

James007

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Bonjour le fil ....

Merci ROGER2327 ...
mais je m'arrache les cheveux, entre les polices, les points pour le nombre de caractères ..., la largeur de la colonne, la hauteur de la ligne ... je vais essayer d'aller creuser la documentation Microsoft ...

A +
 

mromain

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Re bonjour James, Tototiti,
Bonjour Roger,

Tout d'abord, merci pour vos contributions.
En surfant sur internet, j'ai lu que quelques polices de caractères avaient "la même taille, quelque soit le caractère". Il doit s'agir des polices dont tu parles Roger.
Sinon, ce n'est pas du tout vital.
Je continue à creuser de mon coté, si je trouve, je vous tiendrai bien évidemment au courant.

a+ :)
 

mromain

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Bonsoir à tous,

Du coup, en fouinant, j'ai trouvé une fonction ici (et la valeur des constantes là et ) qui est sensée renvoyer la taille d'une chaine de caractère en pixels, en fonction de sa police, de sa taille et de si le texte est es gras.

Voici la fonction :
Code:
Public Type POINTAPI
    X As Long
    Y As Long
End Type
 
Public Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
 
Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
Declare Function CreateFont Lib "gdi32" Alias "CreateFontA" (ByVal nHeight As Long, ByVal nWidth As Long, ByVal nEscapement As Long, ByVal nOrientation As Long, ByVal fnWeight As Long, ByVal fdwItalic As Boolean, ByVal fdwUnderline As Boolean, ByVal fdwStrikeOut As Boolean, ByVal fdwCharSet As Long, ByVal fdwOutputPrecision As Long, ByVal fdwClipPrecision As Long, ByVal fdwQuality As Long, ByVal fdwPitchAndFamily As Long, ByVal lpszFace As String) As Long
Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Declare Function GetTextExtentPoint32 Lib "gdi32" Alias "GetTextExtentPoint32A" (ByVal hdc As Long, ByVal lpsz As String, ByVal cbString As Long, lpSize As POINTAPI) As Long
Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long

Private Const FW_NORMAL = 400
Private Const FW_BOLD = 700
Private Const DEFAULT_CHARSET As Byte = 1
Private Const OUT_DEFAULT_PRECIS = 0
Private Const CLIP_DEFAULT_PRECIS = 0
Private Const PROOF_QUALITY = 2
Private Const DEFAULT_PITCH = 0


Public Function TailleChaineEcran(ByVal sChaine As String, ByVal sPolice As String, ByVal iTaille As Integer, Optional ByVal bBold As Boolean = False) As POINTAPI
    Dim pt As POINTAPI, mWnd As Long, WR As RECT, nDC As Long
    Dim TextSize As POINTAPI, CX As Long, CY As Long
    Dim sNomChamp As String
    Dim hEnCours As Long
     
    ' position curseur
    GetCursorPos pt
    ' handle fenetre sous le curseur
    mWnd = WindowFromPoint(pt.X, pt.Y)
    ' device context de la fenetre
    nDC = GetWindowDC(mWnd)
     
    Dim hFont As Long
    hFont = CreateMyFont(sPolice, iTaille, bBold)
    hEnCours = SelectObject(nDC, hFont)
 
    ' dimensions du texte dans sChaine
    GetTextExtentPoint32 nDC, sChaine, Len(sChaine), TextSize
    TailleChaineEcran.X = TextSize.X
    TailleChaineEcran.Y = TextSize.Y
 
    SelectObject nDC, hEnCours
    hEnCours = ReleaseDC(mWnd, nDC)
 
End Function
 
Function CreateMyFont(sPolice As String, nSize As Integer, Optional bBold As Boolean = False) As Long
    'Créer la police spécifique
    CreateMyFont = CreateFont(-nSize, 0, 0, 0, FW_NORMAL + IIf(bBold, FW_BOLD, 0), False, False, False, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, sPolice)
End Function
Et une macro pour l'utiliser :
Code:
Sub Test()
Dim taille As POINTAPI, laCell As Range, texte As String

    Set laCell = ActiveSheet.Range("A1")
    
    With laCell
        taille = TailleChaineEcran(" " & .Text & "  ", .Font.Name, .Font.Size, .Font.Bold)
        
        texte = "Cellule : " & .Address(0, 0) & vbNewLine
        texte = texte & "Chaine de caractère : """ & .Text & """" & vbNewLine
        texte = texte & "Police : " & .Font.Name & vbNewLine
        texte = texte & "Taille du texte : " & .Font.Size & vbNewLine
        texte = texte & "Gras : " & IIf(.Font.Bold, "OUI", "NON") & vbNewLine & vbNewLine
        texte = texte & "  --> " & taille.X & " pixels"
    End With
    
    MsgBox texte
End Sub
Par contre, chez moi, elle ne semble pas donner de bons résultats (par rapport au nombre de pixels de la largeur de colonne). Les résultats renvoyés semblent être inférieurs (à ce qui est affiché).

Pouvez-vous l'essayer chez vous afin de voir si vous avez le même soucis ?

Merci

a+
 

job75

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Bonjour le fil, le forum,

J'ai cherché de mon coté.

Le problème que je n'ai pu résoudre, c'est celui des espaces qui entrainent un retour à la ligne.

L'"espace" de code 160, lui, n'entraine pas de retour à la ligne.

Cette solution (fichier joint) fonctionne donc car le caractère de code 160 remplace l'espace de code 32.

Noter que L'ASTUCE consiste à augmenter provisoirement de 0.3 la largeur de la cellule :

Code:
Sub LettreLigne()
Dim cel As Range, hauteur#, largeur#, txt$, h#, lig%, n%, i%, der$, tablo()
Application.ScreenUpdating = False
For Each cel In Range("A2", Range("A65536").End(xlUp))
  hauteur = cel.RowHeight
  largeur = cel.ColumnWidth
  txt = Replace(cel, " ", Chr(160)) 'avec des espaces "normaux" ça ne marche pas...
  cel.EntireRow.ClearContents
  If txt <> "" Then cel = "A"
  cel.Rows.AutoFit
  cel.ColumnWidth = largeur + 0.3 'VOILA L'ASTUCE : on augmente la largeur
  h = cel.RowHeight
  lig = 1
  n = 0
  For i = 1 To Len(txt)
    cel = Left(txt, i)
    der = Right(cel, 1)
    If cel.RowHeight > h Then 'si changement de hauteur de la ligne
      h = cel.RowHeight
      lig = lig + 1
      If der <> Chr(10) Then
        ReDim Preserve tablo(n)
        tablo(n) = Chr(10)
        n = n + 1
      End If
    End If
    ReDim Preserve tablo(n)
    tablo(n) = IIf(der = Chr(160), "<Espace>", der) & IIf(der = Chr(10), "", lig)
    n = n + 1
  Next i
  cel.RowHeight = hauteur
  cel.ColumnWidth = largeur
  Set cel = cel.Offset(, 1) 'pour le résultat
  If n Then cel = Join(tablo) 'concaténation
  cel = Replace(cel, " " & Chr(10) & " ", Chr(10))
Next cel
End Sub

Edit : parfois le W pose problème...

A+
 

Pièces jointes

  • LettreLigne(1).xls
    44.5 KB · Affichages: 114
Dernière édition:

Coco-31

XLDnaute Junior
Re : Détecter un retour à la ligne automatique.

Bonsoir le fil,

Merci Mromain de m'avoir signalé cette discussion qui prolonge naturellement la mienne et reprend la question que j'avais posé. je suis avec attention ce fil.
Merci encore à tous ceux qui nous aident

Coco
 

job75

XLDnaute Barbatruc
Re : Détecter un retour à la ligne automatique.

Bonjour le fil, le forum,

On préfèrera peut-être ce type de restitution des résultats.

A+
 

Pièces jointes

  • RetourLigne(1).xls
    44 KB · Affichages: 160
  • RetourLigne(1).xls
    44 KB · Affichages: 167
  • RetourLigne(1).xls
    44 KB · Affichages: 168

Discussions similaires

Réponses
8
Affichages
234

Statistiques des forums

Discussions
312 216
Messages
2 086 351
Membres
103 195
dernier inscrit
martel.jg