Microsoft 365 Problème d'enchainement dans un programme VBA

VBA_dev_Anne_Marie

XLDnaute Occasionnel
Bonjour,

J'ai un programme pour, premièrement, effacer les données, ensuite appliquer la formule et les figer.
Quand je lance les subroutines pas à pas, les résultats sont correctes.
Quand je lance le programme Sub Mes_donnees(), via le bouton, j'obtiens N/A Requesting data... dans la cellule (1,1).

Je ne trouve pas pourquoi. Voici mon code :

VB:
Option Explicit



Sub Fichier_vide()

Dim ws As Object

For Each ws In Worksheets
 
       With ws
                If .Cells(1, 1).Value <> "" Then
                   .Cells(1, 1).CurrentRegion.ClearContents
                End If
          
    End With
    
 Next
 
End Sub


Sub Donnees_fin()
 
 
    'sbf_120
  
   Sheets("sbf_120").Cells(1, 1).Formula = "=BQL(""Members('SBF120 INDEX')"", ""ID_ISIN,NAME"")"
 
    
    'dj600
  
   Sheets("dj600").Cells(1, 1).Formula = "=BQL(""Members('SXXP INDEX')"", ""ID_ISIN,NAME"")"
  
  
    
    'sp_500
  
   Sheets("sp_500").Cells(1, 1).Formula = "=BQL(""Members('SPX INDEX')"", ""ID_ISIN,NAME"")"
 

End Sub


'On fige les formules

Sub ConvertFormulasToValuesAllWorksheets()

    Dim ws As Worksheet, rng As Range

    For Each ws In ActiveWorkbook.Worksheets

        For Each rng In ws.UsedRange

            If rng.HasFormula Then

                rng.Formula = rng.Value

            End If

        Next rng

    Next ws

End Sub
 
Sub Mes_donnees()
  Call Fichier_vide
  Call Donnees_fin
  Call ConvertFormulasToValuesAllWorksheets
End Sub

Merci pour votre aide !
 

laurent950

XLDnaute Accro
Bonjour @MarieParis

j'ai adapté ce code à votre besoin, je vous laisse le lien pour l'exemple (ci-dessous)
N/A Requesting data... dans la cellule (1,1)
Cela signifie que votre macro doit « attendre » que les formules soient complètement actualisées avant de continuer.

VB:
Option Explicit
'
Sub Fichier_vide()
Dim ws As Worksheet
For Each ws In Worksheets
    With ws
        If .Cells(1, 1).Value <> "" Then
            .Cells(1, 1).CurrentRegion.ClearContents
        End If
    End With
 Next
End Sub
'
Sub Donnees_fin()
    If cal_sheet(Sheets("sbf_120")) = True Then
    'sbf_120 / ' Continuer après que la feuille a été calculée
        Sheets("sbf_120").Cells(1, 1).Formula = "=BQL(""Members('SBF120 INDEX')"", ""ID_ISIN,NAME"")"
    End If
    If cal_sheet(Sheets("dj600")) = True Then
    'dj600 / ' Continuer après que la feuille a été calculée
        Sheets("dj600").Cells(1, 1).Formula = "=BQL(""Members('SXXP INDEX')"", ""ID_ISIN,NAME"")"
    End If
    If cal_sheet(Sheets("sp_500")) = True Then
    'sp_500 / ' Continuer après que la feuille a été calculée
        Sheets("sp_500").Cells(1, 1).Formula = "=BQL(""Members('SPX INDEX')"", ""ID_ISIN,NAME"")"
    End If
End Sub
'On fige les formules
Sub ConvertFormulasToValuesAllWorksheets()
Dim ws As Worksheet, rng As Range
    For Each ws In ActiveWorkbook.Worksheets
        For Each rng In ws.UsedRange
            If rng.HasFormula Then
                rng.Formula = rng.Value
            End If
        Next rng
    Next ws
End Sub
'
Sub Mes_donnees()
  Call Fichier_vide
  Call Donnees_fin
  Call ConvertFormulasToValuesAllWorksheets
End Sub
'Cette fonction renvoie Vrai lorsque la feuille active est complètement calculé
'si faux, il y a besoin de calculer encore une pause de 5 secondes est laissé pour effectuer les calcules
Function cal_sheet(ByVal ws As Worksheet) As Boolean
Dim tmp As Boolean
    tmp = False
Dim c As Object
MsgBox ws.Name
    ActiveSheet.Calculate
        With ActiveSheet.UsedRange
            Set c = .Find("request", LookIn:=xlValues)
            If Not c Is Nothing Then
                Application.OnTime Now + TimeValue("00:00:05"), "Donnees_fin"
                tmp = False
            Else
                tmp = True
            End If
        End With
        cal_sheet = tmp
End Function
 

VBA_dev_Anne_Marie

XLDnaute Occasionnel
Bonjour @MarieParis

j'ai adapté ce code à votre besoin, je vous laisse le lien pour l'exemple (ci-dessous)
N/A Requesting data... dans la cellule (1,1)
Cela signifie que votre macro doit « attendre » que les formules soient complètement actualisées avant de continuer.

VB:
Option Explicit
'
Sub Fichier_vide()
Dim ws As Worksheet
For Each ws In Worksheets
    With ws
        If .Cells(1, 1).Value <> "" Then
            .Cells(1, 1).CurrentRegion.ClearContents
        End If
    End With
 Next
End Sub
'
Sub Donnees_fin()
    If cal_sheet(Sheets("sbf_120")) = True Then
    'sbf_120 / ' Continuer après que la feuille a été calculée
        Sheets("sbf_120").Cells(1, 1).Formula = "=BQL(""Members('SBF120 INDEX')"", ""ID_ISIN,NAME"")"
    End If
    If cal_sheet(Sheets("dj600")) = True Then
    'dj600 / ' Continuer après que la feuille a été calculée
        Sheets("dj600").Cells(1, 1).Formula = "=BQL(""Members('SXXP INDEX')"", ""ID_ISIN,NAME"")"
    End If
    If cal_sheet(Sheets("sp_500")) = True Then
    'sp_500 / ' Continuer après que la feuille a été calculée
        Sheets("sp_500").Cells(1, 1).Formula = "=BQL(""Members('SPX INDEX')"", ""ID_ISIN,NAME"")"
    End If
End Sub
'On fige les formules
Sub ConvertFormulasToValuesAllWorksheets()
Dim ws As Worksheet, rng As Range
    For Each ws In ActiveWorkbook.Worksheets
        For Each rng In ws.UsedRange
            If rng.HasFormula Then
                rng.Formula = rng.Value
            End If
        Next rng
    Next ws
End Sub
'
Sub Mes_donnees()
  Call Fichier_vide
  Call Donnees_fin
  Call ConvertFormulasToValuesAllWorksheets
End Sub
'Cette fonction renvoie Vrai lorsque la feuille active est complètement calculé
'si faux, il y a besoin de calculer encore une pause de 5 secondes est laissé pour effectuer les calcules
Function cal_sheet(ByVal ws As Worksheet) As Boolean
Dim tmp As Boolean
    tmp = False
Dim c As Object
MsgBox ws.Name
    ActiveSheet.Calculate
        With ActiveSheet.UsedRange
            Set c = .Find("request", LookIn:=xlValues)
            If Not c Is Nothing Then
                Application.OnTime Now + TimeValue("00:00:05"), "Donnees_fin"
                tmp = False
            Else
                tmp = True
            End If
        End With
        cal_sheet = tmp
End Function
Merci beaucoup !
 

eriiic

XLDnaute Barbatruc
Bonjour,

il existe une instruction vba pour savoir si le recalcul est terminé.
Il suffit de boucler dessus et d'attendre la fin avant de continuer :
VB:
    Do Until Application.CalculationState = xlDone
        DoEvents
    Loop

D'autre part, boucler sur toutes les cellules est très lent. Il est préférable de tout faire d'un coup :
Code:
    Dim pl As Range
    On Error Resume Next
    Set pl = Cells.SpecialCells(xlCellTypeFormulas) ' sélectionner les formules
    On Error GoTo 0
    If Not pl Is Nothing Then pl = pl.Value ' coller valeur
eric
 

VBA_dev_Anne_Marie

XLDnaute Occasionnel
Bonjour @MarieParis

j'ai adapté ce code à votre besoin, je vous laisse le lien pour l'exemple (ci-dessous)
N/A Requesting data... dans la cellule (1,1)
Cela signifie que votre macro doit « attendre » que les formules soient complètement actualisées avant de continuer.

VB:
Option Explicit
'
Sub Fichier_vide()
Dim ws As Worksheet
For Each ws In Worksheets
    With ws
        If .Cells(1, 1).Value <> "" Then
            .Cells(1, 1).CurrentRegion.ClearContents
        End If
    End With
 Next
End Sub
'
Sub Donnees_fin()
    If cal_sheet(Sheets("sbf_120")) = True Then
    'sbf_120 / ' Continuer après que la feuille a été calculée
        Sheets("sbf_120").Cells(1, 1).Formula = "=BQL(""Members('SBF120 INDEX')"", ""ID_ISIN,NAME"")"
    End If
    If cal_sheet(Sheets("dj600")) = True Then
    'dj600 / ' Continuer après que la feuille a été calculée
        Sheets("dj600").Cells(1, 1).Formula = "=BQL(""Members('SXXP INDEX')"", ""ID_ISIN,NAME"")"
    End If
    If cal_sheet(Sheets("sp_500")) = True Then
    'sp_500 / ' Continuer après que la feuille a été calculée
        Sheets("sp_500").Cells(1, 1).Formula = "=BQL(""Members('SPX INDEX')"", ""ID_ISIN,NAME"")"
    End If
End Sub
'On fige les formules
Sub ConvertFormulasToValuesAllWorksheets()
Dim ws As Worksheet, rng As Range
    For Each ws In ActiveWorkbook.Worksheets
        For Each rng In ws.UsedRange
            If rng.HasFormula Then
                rng.Formula = rng.Value
            End If
        Next rng
    Next ws
End Sub
'
Sub Mes_donnees()
  Call Fichier_vide
  Call Donnees_fin
  Call ConvertFormulasToValuesAllWorksheets
End Sub
'Cette fonction renvoie Vrai lorsque la feuille active est complètement calculé
'si faux, il y a besoin de calculer encore une pause de 5 secondes est laissé pour effectuer les calcules
Function cal_sheet(ByVal ws As Worksheet) As Boolean
Dim tmp As Boolean
    tmp = False
Dim c As Object
MsgBox ws.Name
    ActiveSheet.Calculate
        With ActiveSheet.UsedRange
            Set c = .Find("request", LookIn:=xlValues)
            If Not c Is Nothing Then
                Application.OnTime Now + TimeValue("00:00:05"), "Donnees_fin"
                tmp = False
            Else
                tmp = True
            End If
        End With
        cal_sheet = tmp
End Function
Bonjour,
Le code marche, mais j'ai ajouté des pauses dans l'exécution des fonctions car le programme ne s'arrêtait pas :
VB:
Sub Mes_donnees()
   Call Fichier_vide
   Application.OnTime Now + TimeValue("00:00:05"), "Donnees_fin"
   Application.OnTime Now + TimeValue("00:00:20"), "ConvertFormulasToValuesAllWorksheets"
End Sub

Est-ce que vous connaissez une fonction qui permet d'exécuter le programme (via un buton) seulement en cas de connexion Bloomberg, sinon afficher le message d'alerte ? Merci beaucoup pour votre aide.
 

Discussions similaires

Réponses
1
Affichages
164
Réponses
7
Affichages
318
Réponses
0
Affichages
147

Statistiques des forums

Discussions
312 176
Messages
2 085 962
Membres
103 067
dernier inscrit
el_privach