XL 2019 séparer le nom et le numéro de chambre

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

escudo

XLDnaute Junior
Bonsoir à tous,


J'ai un problème avec un code VBA qui fonctionne très bien pour l'extraction des données, mais j'aimerais qu'il sépare le nom et le numéro de chambre. Le nom devrait être placé dans la colonne A et le numéro de chambre dans la colonne B.


Merci d'avance pour votre aide !
 

Pièces jointes

Solution
Bonjour escudo, le forum,

Ce n'était pas fini, marquez plutôt ce post comme solution, la macro s'exécute en 1,4 seconde chez moi :
VB:
Sub Extraction()
Dim DL&, tablo, a(), i&, n&, sejour As Range, x$, y As Variant, s, ub%, hTVA As Variant, b, ii&, jj%, j%
With Sheets("FACTURES")
    DL = .Cells(.Rows.Count, 1).End(xlUp).Row 'dernière ligne
    tablo = .Range("A1:A" & DL + 1) 'matrice, plus rapide, au moins 2 éléments
    ReDim a(1 To DL, 1 To 7)
    For i = 1 To DL
        If UCase(Left(tablo(i, 1), 6)) = "SEJOUR" Then
            n = n + 1
            Set sejour = .Cells(i, 1)
            x = tablo(i, 1) & "/"
            a(n, 1) = Trim(Mid(x, 9, InStr(x, "/") - 9)) 'nom
            x = "/ CHB"
            y =...
Bonjour @escudo🙂,

Remplacez les lignes :
VB:
                ' Enregistrer dans la feuille de résultats
                wsResult.Cells(resultRow, 1).Value = clientName ' Nom du Client
                wsResult.Cells(resultRow, 2).Value = roomNumber ' Numéro de Chambre

Par les lignes :
VB:
                ' Enregistrer dans la feuille de résultats
                S = Split(Replace(clientName & "//", "CHB:", ""), "/")
                wsResult.Cells(resultRow, 1).Value = Trim(S(0))      ' Nom du Client
                wsResult.Cells(resultRow, 2).Value = Trim(S(1))      ' Numéro de Chambre

nota : n'oubliez pas de rajouter en début de code la déclaration : Dim S
 
Bonjour escudo, mapomme,

Ou en utilisant les InStr comme vous avez essayé de le faire :
VB:
    ' Parcourir les lignes de la feuille d'origine
    For i = 2 To lastRow
        ' Récupérer le contenu des cellules A et B
        cellContent = ws.Cells(i, 1) & ws.Cells(i, 2) & "/"
        
        ' Extraire le nom du client et le numéro de chambre si dans la colonne A
        If InStr(cellContent, "SEJOUR :") Then
            Dim pos1, num: pos1 = InStr(cellContent, "CHB:")
            If pos1 Then num = Val(Mid(cellContent, pos1 + 4)): roomNumber = "CHB : " & IIf(num, num, "")
            Dim pos2: pos2 = InStr(cellContent, "/")
            clientName = Application.Trim(Mid(cellContent, 9, pos2 - 9))
        End If
Et attention, dans la restitution vous aviez utilisé roomNumbert au lieu de roomNumber !!!

A+
 

Pièces jointes

Je reviens vers vous une nouvelle fois pour résoudre un petit problème Les dates de départ n'ont pas été extraites.
De plus, si la feuille source contient un grand nombre de données, l'extraction se limite à un petit nombre de lignes.
 

Pièces jointes

Dernière édition:
Je reviens vers vous une nouvelle fois pour résoudre un petit problème Les dates de départ n'ont pas été extraites.
De plus, si la feuille source contient un grand nombre de données, l'extraction se limite à un petit nombre de lignes.
Salut,
je n'ai pas compris cette ligne :
VB:
cellContent = ws.Cells(i, 1) & ws.Cells(i, 2)  & "/"
pourquoi le & "/" à la fin ? si on enlève ce code, les dates de départ sont extraites.
pour l'extraction limitée à un petit nombre de lignes , vérifier que la valeur de lastRow est bonne (debug.Print lastRow)

Nullosse.
 
Bonsoir les amis, j'ai une difficulté à extraire toutes les données, surtout lorsqu'il y a un grand nombre d'éléments à traiter. En effet, la macro semble se limiter à quelques lignes seulement j'ai colorer en jaune les données qui n'ont pas été extraites. Un autre problème est que les numéros de chambre peuvent se trouver dans les colonnes A, B ou C de la feuille source je veux aussi extraire les numéros de facture.
 

Pièces jointes

Bonsoir les amis, j'ai une difficulté à extraire toutes les données, surtout lorsqu'il y a un grand nombre d'éléments à traiter. En effet, la macro semble se limiter à quelques lignes seulement j'ai colorer en jaune les données qui n'ont pas été extraites. Un autre problème est que les numéros de chambre peuvent se trouver dans les colonnes A, B ou C de la feuille source je veux aussi extraire les numéros de facture.
Salut,
le souci c'est que quand le numéro de chambre est en colonne C les montants de la facture sont décalés d'une colonne alors il suffit d' introduire une nouvelle variable Decalage qui prend en compte ce décalage :
VB:
Sub ExtraireResultats()
    Dim ws As Worksheet, wsResult As Worksheet
    Dim lastRow As Long, resultRow As Long, i As Long
    Dim clientName As String, roomNumber As String
    Dim dateArrivee As Variant, dateDepart As Variant
    Dim montantPaiement As Double, modePaiement As String
    Dim cellContent As String, dates() As String
    Dim startPos As Long, endPos As Long
    Dim Decalage As Integer, Facture, NumFacture
 
    ' Définir la feuille active et la feuille de résultats
    Set ws = ThisWorkbook.Sheets(1) ' Ajustez le numéro de la feuille si nécessaire
    On Error Resume Next
    Set wsResult = ThisWorkbook.Sheets("Résultat")
    On Error GoTo 0
   
    ' Créer la feuille "Résultat" si elle n'existe pas
    If wsResult Is Nothing Then
        Set wsResult = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
        wsResult.Name = "Résultat"
    End If
   
    ' Effacer les anciennes données dans la feuille Résultat
    wsResult.Cells.Clear
   
    ' En-têtes de la feuille Résultat
    wsResult.Cells(1, 1).Value = "Nom du Client"
    wsResult.Cells(1, 2).Value = "Numéro de Chambre"
    wsResult.Cells(1, 3).Value = "Date d'Arrivée"
    wsResult.Cells(1, 4).Value = "Date de Départ"
    wsResult.Cells(1, 5).Value = "N° Facture"
    wsResult.Cells(1, 6).Value = "Montant Paiement"
    wsResult.Cells(1, 7).Value = "Mode de Paiement"
   
    ' Déterminer la dernière ligne des données dans la feuille d'origine
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
   
    ' Initialiser la ligne pour les résultats
    resultRow = 2
    ' Parcourir les lignes de la feuille d'origine
    For i = 2 To lastRow
        cellContent = ws.Cells(i, 1)
       
        If InStr(cellContent, "SEJOUR :") > 0 Then
           Dim pos1 As Long, pos2 As Long, pos3 As Long
           Dim tempName As String
           ' Récupérer le contenu des cellules A et B et C
           cellContent = ws.Cells(i, 1) & ws.Cells(i, 2) & ws.Cells(i, 3)
           'Regarder si il y a quelque chose en colonne C
           If Not IsEmpty(ws.Cells(i, 3)) Then Decalage = 1 Else Decalage = 0
           ' Trouver la position de "SEJOUR :" et "CHB:"
           pos1 = InStr(cellContent, "SEJOUR :") + 8 ' Position après "SEJOUR :"
           pos2 = InStr(cellContent, "/") ' Trouver la position du "/"
           pos3 = InStr(cellContent, "CHB:") + 4 ' Position après "CHB:"
   
           ' Extraire le nom du client entre "SEJOUR :" et "/"
           If pos1 > 0 And pos2 > 0 Then
              tempName = Trim(Mid(cellContent, pos1, pos2 - pos1)) ' Extraire le nom du client
           Else
              tempName = "" ' Si le format est incorrect, laisser le nom vide
           End If
   
           ' Extraire le numéro de chambre après "CHB:"
           If pos3 > 0 Then
              roomNumber = Trim(Mid(cellContent, pos3)) ' Extraire le numéro de chambre
           Else
              roomNumber = "" ' Si "CHB:" est absent, laisser le numéro de chambre vide
           End If
   
           ' Assignation des résultats
           clientName = tempName
        End If
        ' Extraire le numéro de facture
        If InStr(cellContent, "FACTURE No : ") > 0 Then
             Facture = Split(cellContent, ":")
             NumFacture = Trim(Facture(1))
        End If

        ' Extraire les dates de la colonne A (format "DU xx.xx.xxxx AU xx.xx.xxxx")
        If InStr(cellContent, "DU") > 0 And InStr(cellContent, "AU") > 0 Then
            dates = Split(cellContent, "AU")
           
            ' Extraire la date d'arrivée après "DU"
            dateArrivee = Trim(Mid(dates(0), InStr(dates(0), "DU") + 3)) ' Extraire la date après "DU"
            ' Extraire la date de départ après "AU"
            dateDepart = Trim(dates(1))
           
            ' Convertir les dates au format DateValue, en remplaçant les points par des slashes pour qu'Excel puisse les interpréter
            On Error Resume Next
            dateArrivee = DateValue(Replace(dateArrivee, ".", "/")) ' Convertir la date d'arrivée en Date
            If Err.Number <> 0 Then
                dateArrivee = "" ' Si erreur de conversion, mettre une date vide
                Err.Clear
            End If
            dateDepart = DateValue(Replace(dateDepart, ".", "/")) ' Convertir la date de départ en Date
            If Err.Number <> 0 Then
                dateDepart = "" ' Si erreur de conversion, mettre une date vide
                Err.Clear
            End If
            On Error GoTo 0
        End If
        montantPaiement = 0
        ' Vérifier si le montant du paiement dans la colonne F ou E est numérique et s'il est négatif
        If IsNumeric(ws.Cells(i, 5 + Decalage).Value) Then
            montantPaiement = ws.Cells(i, 5 + Decalage).Value
            If montantPaiement < 0 Then
                ' Extraire le mode de paiement (colonne B)
                modePaiement = ws.Cells(i, 2).Value
                ' Enregistrer dans la feuille de résultats
                wsResult.Cells(resultRow, 1).Value = clientName ' Nom du Client
                wsResult.Cells(resultRow, 2).Value = roomNumber ' Numéro de Chambre
                wsResult.Cells(resultRow, 3).Value = dateArrivee ' Date d'Arrivée
                wsResult.Cells(resultRow, 4).Value = dateDepart ' Date de Départ
                wsResult.Cells(resultRow, 5).Value = NumFacture ' Numéro de facture
                wsResult.Cells(resultRow, 6).Value = montantPaiement ' Montant Paiement
                wsResult.Cells(resultRow, 7).Value = modePaiement ' Mode de Paiement
                resultRow = resultRow + 1
            End If
        End If
    Next i
    ' Message de fin d'exécution
    MsgBox "Extraction terminée!"
End Sub

Factures.png



Nullosse.
 
Bonjour le Fil,
Escudo
Tu dis : "Un autre problème est que les numéros de chambre peuvent se trouver dans les colonnes A, B ou C de la feuille source"
Comment ce peut il que ces numéro soient un peu partout ,pourquoi pas en colonne "D" ? Lol
Bonne journée
Jean marie
 
Bonjour le Fil,
Escudo
Tu dis : "Un autre problème est que les numéros de chambre peuvent se trouver dans les colonnes A, B ou C de la feuille source"
Comment ce peut il que ces numéro soient un peu partout ,pourquoi pas en colonne "D" ? Lol
Bonne journée
Jean marie
Les données sources sont au format PDF et, lorsqu'elles sont converties en Excel, un décalage apparaît.
 
Salut,
le souci c'est que quand le numéro de chambre est en colonne C les montants de la facture sont décalés d'une colonne alors il suffit d' introduire une nouvelle variable Decalage qui prend en compte ce décalage :
VB:
Sub ExtraireResultats()
    Dim ws As Worksheet, wsResult As Worksheet
    Dim lastRow As Long, resultRow As Long, i As Long
    Dim clientName As String, roomNumber As String
    Dim dateArrivee As Variant, dateDepart As Variant
    Dim montantPaiement As Double, modePaiement As String
    Dim cellContent As String, dates() As String
    Dim startPos As Long, endPos As Long
    Dim Decalage As Integer, Facture, NumFacture
 
    ' Définir la feuille active et la feuille de résultats
    Set ws = ThisWorkbook.Sheets(1) ' Ajustez le numéro de la feuille si nécessaire
    On Error Resume Next
    Set wsResult = ThisWorkbook.Sheets("Résultat")
    On Error GoTo 0
  
    ' Créer la feuille "Résultat" si elle n'existe pas
    If wsResult Is Nothing Then
        Set wsResult = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
        wsResult.Name = "Résultat"
    End If
  
    ' Effacer les anciennes données dans la feuille Résultat
    wsResult.Cells.Clear
  
    ' En-têtes de la feuille Résultat
    wsResult.Cells(1, 1).Value = "Nom du Client"
    wsResult.Cells(1, 2).Value = "Numéro de Chambre"
    wsResult.Cells(1, 3).Value = "Date d'Arrivée"
    wsResult.Cells(1, 4).Value = "Date de Départ"
    wsResult.Cells(1, 5).Value = "N° Facture"
    wsResult.Cells(1, 6).Value = "Montant Paiement"
    wsResult.Cells(1, 7).Value = "Mode de Paiement"
  
    ' Déterminer la dernière ligne des données dans la feuille d'origine
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
  
    ' Initialiser la ligne pour les résultats
    resultRow = 2
    ' Parcourir les lignes de la feuille d'origine
    For i = 2 To lastRow
        cellContent = ws.Cells(i, 1)
      
        If InStr(cellContent, "SEJOUR :") > 0 Then
           Dim pos1 As Long, pos2 As Long, pos3 As Long
           Dim tempName As String
           ' Récupérer le contenu des cellules A et B et C
           cellContent = ws.Cells(i, 1) & ws.Cells(i, 2) & ws.Cells(i, 3)
           'Regarder si il y a quelque chose en colonne C
           If Not IsEmpty(ws.Cells(i, 3)) Then Decalage = 1 Else Decalage = 0
           ' Trouver la position de "SEJOUR :" et "CHB:"
           pos1 = InStr(cellContent, "SEJOUR :") + 8 ' Position après "SEJOUR :"
           pos2 = InStr(cellContent, "/") ' Trouver la position du "/"
           pos3 = InStr(cellContent, "CHB:") + 4 ' Position après "CHB:"
  
           ' Extraire le nom du client entre "SEJOUR :" et "/"
           If pos1 > 0 And pos2 > 0 Then
              tempName = Trim(Mid(cellContent, pos1, pos2 - pos1)) ' Extraire le nom du client
           Else
              tempName = "" ' Si le format est incorrect, laisser le nom vide
           End If
  
           ' Extraire le numéro de chambre après "CHB:"
           If pos3 > 0 Then
              roomNumber = Trim(Mid(cellContent, pos3)) ' Extraire le numéro de chambre
           Else
              roomNumber = "" ' Si "CHB:" est absent, laisser le numéro de chambre vide
           End If
  
           ' Assignation des résultats
           clientName = tempName
        End If
        ' Extraire le numéro de facture
        If InStr(cellContent, "FACTURE No : ") > 0 Then
             Facture = Split(cellContent, ":")
             NumFacture = Trim(Facture(1))
        End If

        ' Extraire les dates de la colonne A (format "DU xx.xx.xxxx AU xx.xx.xxxx")
        If InStr(cellContent, "DU") > 0 And InStr(cellContent, "AU") > 0 Then
            dates = Split(cellContent, "AU")
          
            ' Extraire la date d'arrivée après "DU"
            dateArrivee = Trim(Mid(dates(0), InStr(dates(0), "DU") + 3)) ' Extraire la date après "DU"
            ' Extraire la date de départ après "AU"
            dateDepart = Trim(dates(1))
          
            ' Convertir les dates au format DateValue, en remplaçant les points par des slashes pour qu'Excel puisse les interpréter
            On Error Resume Next
            dateArrivee = DateValue(Replace(dateArrivee, ".", "/")) ' Convertir la date d'arrivée en Date
            If Err.Number <> 0 Then
                dateArrivee = "" ' Si erreur de conversion, mettre une date vide
                Err.Clear
            End If
            dateDepart = DateValue(Replace(dateDepart, ".", "/")) ' Convertir la date de départ en Date
            If Err.Number <> 0 Then
                dateDepart = "" ' Si erreur de conversion, mettre une date vide
                Err.Clear
            End If
            On Error GoTo 0
        End If
        montantPaiement = 0
        ' Vérifier si le montant du paiement dans la colonne F ou E est numérique et s'il est négatif
        If IsNumeric(ws.Cells(i, 5 + Decalage).Value) Then
            montantPaiement = ws.Cells(i, 5 + Decalage).Value
            If montantPaiement < 0 Then
                ' Extraire le mode de paiement (colonne B)
                modePaiement = ws.Cells(i, 2).Value
                ' Enregistrer dans la feuille de résultats
                wsResult.Cells(resultRow, 1).Value = clientName ' Nom du Client
                wsResult.Cells(resultRow, 2).Value = roomNumber ' Numéro de Chambre
                wsResult.Cells(resultRow, 3).Value = dateArrivee ' Date d'Arrivée
                wsResult.Cells(resultRow, 4).Value = dateDepart ' Date de Départ
                wsResult.Cells(resultRow, 5).Value = NumFacture ' Numéro de facture
                wsResult.Cells(resultRow, 6).Value = montantPaiement ' Montant Paiement
                wsResult.Cells(resultRow, 7).Value = modePaiement ' Mode de Paiement
                resultRow = resultRow + 1
            End If
        End If
    Next i
    ' Message de fin d'exécution
    MsgBox "Extraction terminée!"
End Sub

Regarde la pièce jointe 1220058


Nullosse.
Merci beaucoup pour ton aide, ton code fonctionne parfaitement !
 
Bonsoir le forum,

Dans le fichier du post #9 les données de la dernière facture n'étaient pas correctement placées, je les ai corrigées.

Voici une manière de faire plus simple et plus "ramassée" :
VB:
Sub Extraction()
Dim F As Worksheet, lig&, sejour As Range, ligdeb&, x$, a(1 To 7), c As Range, s, ub%
Application.ScreenUpdating = False
Set F = Sheets("Résultat")
F.Rows("2:" & Rows.Count).ClearContents 'RAZ
lig = 2 '1ère ligne de destination
With Sheets("FACTURES")
    Set sejour = .Cells(Rows.Count, 1)
    Do
        Set sejour = .Columns(1).Find("SEJOUR", sejour, xlValues, xlPart)
        If sejour.Row = ligdeb Then Exit Do
        If ligdeb = 0 Then ligdeb = sejour.Row
        x = sejour & "/"
        Erase a 'efface le tableau a
        a(1) = Trim(Mid(x, 9, InStr(x, "/") - 9)) 'nom
        x = "/ CHB"
        Set c = sejour.EntireRow.Find(x)
        If Not c Is Nothing Then a(2) = Mid(c, InStr(c, x) + 2) 'chambre
        x = Replace(Replace(UCase(sejour(4)), ".", "/"), "DU", "")
        s = Split(x, "AU"): ub = UBound(s)
        If ub > -1 Then If IsDate(s(0)) Then a(3) = CDate(s(0)) 'date arrivée
        If ub > 0 Then If IsDate(s(1)) Then a(4) = CDate(s(1)) 'date départ
        x = sejour(2)
        a(5) = Trim(Mid(x, InStr(x, ":") + 1)) 'facture n°
        For Each c In sejour.CurrentRegion.Columns(5).Resize(, 2).Cells 'colonnes E ou F
            If c < 0 Then
                a(6) = c: a(7) = .Cells(c.Row, 2)
                F.Cells(lig, 1).Resize(, UBound(a)) = a
                lig = lig + 1
            End If
        Next c
        If a(6) = "" Then F.Cells(lig, 1).Resize(, UBound(a)) = a: lig = lig + 1
    Loop
End With
Application.ScreenUpdating = True
MsgBox "Extraction terminée"
End Sub
L'utilisation de la variable tableau a permet de gagner du temps.

On peut placer ce code dans la feuille "Résultat" pour lancer la macro :
VB:
Private Sub Worksheet_Activate()
Extraction 'lance la macro
End Sub
Bonne nuit.
 

Pièces jointes

Bonjour le forum,

La macro précédente utilise la plage sejour.CurrentRegion ce n'est pas forcément pertinent si des lignes vides sont ajoutées.

Avec cette macro la ligne "TVA" limite la recherche des nombres négatifs :
VB:
Sub Extraction()
Dim F As Worksheet, lig&, sejour As Range, DL&, ligdeb&, x$, a(1 To 7), c As Range, s, ub%
Application.ScreenUpdating = False
Set F = Sheets("Résultat")
F.Rows("2:" & Rows.Count).ClearContents 'RAZ
lig = 2 '1ère ligne de destination
With Sheets("FACTURES")
    Set sejour = .Cells(Rows.Count, 1)
    DL = sejour.End(xlUp).Row 'dernière ligne
    Do
        Set sejour = .Columns(1).Find("SEJOUR", sejour, xlValues, xlPart)
        If sejour.Row = ligdeb Then Exit Do
        If ligdeb = 0 Then ligdeb = sejour.Row
        x = sejour & "/"
        Erase a 'efface le tableau a
        a(1) = Trim(Mid(x, 9, InStr(x, "/") - 9)) 'nom
        x = "/ CHB"
        Set c = sejour.EntireRow.Find(x)
        If Not c Is Nothing Then a(2) = Mid(c, InStr(c, x) + 2) 'chambre
        x = Replace(Replace(UCase(sejour(4)), ".", "/"), "DU", "")
        s = Split(x, "AU"): ub = UBound(s)
        If ub > -1 Then If IsDate(s(0)) Then a(3) = CDate(s(0)) 'date arrivée
        If ub > 0 Then If IsDate(s(1)) Then a(4) = CDate(s(1)) 'date départ
        x = sejour(2)
        a(5) = Trim(Mid(x, InStr(x, ":") + 1)) 'facture n°
        For Each c In sejour(5, 5).Resize(DL - sejour(4).Row, 2) 'colonnes E ou F
            If UCase(.Cells(c.Row, 2)) Like "*TVA*" Then Exit For 'limite la zone de recherche
            If c < 0 Then
                a(6) = c: a(7) = .Cells(c.Row, 2)
                F.Cells(lig, 1).Resize(, UBound(a)) = a 'restitution
                lig = lig + 1
            End If
        Next c
        If a(6) = "" Then F.Cells(lig, 1).Resize(, UBound(a)) = a: lig = lig + 1 'restitution
    Loop
End With
Application.ScreenUpdating = True
MsgBox "Extraction terminée"
End Sub
A+
 

Pièces jointes

- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
18
Affichages
645
Retour