Précédent   Forum des professionnels en informatique > Logiciels > Microsoft Office > Access > VBA Access
VBA Access Le forum pour les questions relatives au code VBA sous Access, et à son environnement de développement VBE.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 12/07/2011, 15h44   #1
Membre du Club
 
Inscription : octobre 2005
Messages : 304
Détails du profil
Informations forums :
Inscription : octobre 2005
Messages : 304
Points : 59
Points : 59
Par défaut Type Mismatch sur une cellule Excel contenant une formule

Bonjour à tous, je lis depuis Access des fichiers excel pour alimenter des tables access.
Je souhaite controler que dans les cellules des fichiers excel, on ai bien renseigné une valeur et qu'elle soit numérique.
Certaines cellules contiennent des formules et quand les formules ne résulte pas, par exemple une division par 0, on a dans la cellule #DIV/0!.

Vu que j'ai une dizaine de cellule a controler et pour ne pas faire ces controles dans la procédure principal, j'ai crée une fonction dans laquelle je passe le contenu de ces cellules. Les parametres de cette fonction sont déclarés en string.

Et bien entendu quand on a #DIV/0! dans la cellule j'ai une erreur de type mismtach a l'appel de la fonction de controle.

Je ne sais pas trop comment gérer cela, si quelqu'un à déja rencontrer ce type de soucis ça serait cool s'il pouvait m'aider.

Merci beaucoup
_developpeur_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 17h39   #2
Membre du Club
 
Inscription : octobre 2005
Messages : 304
Détails du profil
Informations forums :
Inscription : octobre 2005
Messages : 304
Points : 59
Points : 59
Bonjour à tous et merci à ceux qui se sont intéressé à mon problème.

J'ai peu être trouvé une solution mais je ne sais pas si c'est très propre et j'espère que certains d'entre vous pourront me conseiller.

J'ai créer des variables de type Variant et j'ai affecté le contenu des cellules dans ces variables et la il n'y a plus d'erreur de type mismatch.

Dans la fonction qui va faire les controles, j'ai également déclarer les paramètres en type variant et la plus de problème à l'appel de la fonction.

Ensuite je peux tester si la valeur de la variable est null et si elle est numérique.

Mais bon je sais pas si c'est la bonne solution...
Le code :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
'Variable pour tester que les données dans le fichier excel sont saisie et numériques pour les cellules numériques
Dim NBTotalUO As Variant
Dim PrixUnitaireUO As Variant
Dim CoutTotalService As Variant
Dim CoutUnitaireUO As Variant
Dim RevenuPrevisionnelService As Variant
Dim Ecart As Variant
 
Dim BControleLigneService As Boolean
 
'Controle des données de la ligne service
NBTotalUO = xls.Cells(iNumLigne, NumColFinClient + 1)
PrixUnitaireUO = xls.Cells(iNumLigne, NumColFinClient + 2)
CoutTotalService = xls.Cells(iNumLigne, NumColFinClient + 3)
CoutUnitaireUO = xls.Cells(iNumLigne, NumColFinClient + 4)
RevenuPrevisionnelService = xls.Cells(iNumLigne, NumColFinClient + 5)
Ecart = xls.Cells(iNumLigne, NumColFinClient + 6)
 
BControleLigneService = fnControleLigneService(xls.Cells(iNumLigne, 2), xls.Cells(iNumLigne, 20), NBTotalUO, PrixUnitaireUO, CoutTotalService, CoutUnitaireUO, RevenuPrevisionnelService, Ecart)
La fonction :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
Public Function fnControleLigneService(NomService As String, TypeVentilation As String, NBTotalUO As Variant, PrixUnitaireUO As Variant, CoutTotalService As Variant, CoutUnitaireUO As Variant, RevenuPrevisionelService As Variant, Ecart As Variant) As Boolean
 
fnControleLigneService = True
 
If TypeVentilation <> "%" And TypeVentilation <> "valeur" Then
    'Ecriture de la log
    Print #1, "Pour le service " & NomService & ", le type de ventilation est incorrect"
    fnControleLigneService = False
End If
 
If IsNull(NBTotalUO) = False Then
    If IsNumeric(NBTotalUO) = False Then
        Print #1, "Pour le service " & NomService & ", le nombre total d'UO doit être une valeur numérique"
        fnControleLigneService = False
    End If
Else
    Print #1, "Pour le service " & NomService & ", le nombre total d'UO n'est pas renseigné"
    fnControleLigneService = False
End If
 
If IsNull(PrixUnitaireUO) = False Then
    If IsNumeric(PrixUnitaireUO) = False Then
        Print #1, "Pour le service " & NomService & ", le Prix Unitaire de l'UO doit être une valeur numérique"
        fnControleLigneService = False
    End If
Else
    Print #1, "Pour le service " & NomService & ", le Prix Unitaire de l'UO n'est pas renseigné"
    fnControleLigneService = False
End If
 
If IsNull(CoutTotalService) = False Then
    If IsNumeric(CoutTotalService) = False Then
        Print #1, "Pour le service " & NomService & ", le cout total du service doit être une valeur numérique"
        fnControleLigneService = False
    End If
Else
    Print #1, "Pour le service " & NomService & ", le Cout Total service n'est pas renseigné"
    fnControleLigneService = False
End If
 
If IsNull(CoutUnitaireUO) = False Then
    If IsNumeric(CoutUnitaireUO) = False Then
        Print #1, "Pour le service " & NomService & ", le cout unitaire de l'UO doit être une valeur numérique"
        fnControleLigneService = False
    End If
Else
    Print #1, "Pour le service " & NomService & ", le cout unitaire de l'UO n'est pas renseigné"
    fnControleLigneService = False
End If
 
If IsNull(RevenuPrevisionelService) = False Then
    If IsNumeric(RevenuPrevisionelService) = False Then
        Print #1, "Pour le service " & NomService & ", le revenu previsionel du service doit être une valeur numérique"
        fnControleLigneService = False
    End If
Else
    Print #1, "Pour le service " & NomService & ", le revenu previsionel du service n'est pas renseigné"
    fnControleLigneService = False
End If
 
If IsNull(Ecart) = False Then
    If IsNumeric(Ecart) = False Then
        Print #1, "Pour le service " & NomService & ", l'écart doit être une valeur numérique"
        fnControleLigneService = False
    End If
Else
    Print #1, "Pour le service " & NomService & ", l'écart n'est pas renseigné"
    fnControleLigneService = False
End If
 
End Function
Merci.
_developpeur_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 19h13   #3
Membre du Club
 
Inscription : octobre 2005
Messages : 304
Détails du profil
Informations forums :
Inscription : octobre 2005
Messages : 304
Points : 59
Points : 59
Dans la fonction de controle, j'ai un probleme, la fonction isnull renvoi false quand la cellule du fichier excel est vide. je m'attendais a avoir true puisque la cellule est vide.

Quelqu'un a une idée ?

Merci beaucoup de votre aide.
_developpeur_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/07/2011, 11h25   #4
Membre du Club
 
Inscription : octobre 2005
Messages : 304
Détails du profil
Informations forums :
Inscription : octobre 2005
Messages : 304
Points : 59
Points : 59
Bonjour, je pense que ce serait mieux de détecter si une cellule dans excel contient une formule et si cette formule à aboutit plutot que d'affecter le contenu de la formule a une variable de type variant.
Ca serait plus propre mais je sais pas si c'est possible.
Merci
_developpeur_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/07/2011, 18h49   #5
Rédacteur
 
Avatar de LedZeppII
 
Homme
Maintenance données produits
Inscription : décembre 2005
Messages : 3 939
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Maintenance données produits
Secteur : Distribution

Informations forums :
Inscription : décembre 2005
Messages : 3 939
Points : 6 278
Points : 6 278
Bonjour,

A priori, on peut savoir si une cellule est en erreur, en testant le type de sa propriété Value, avec VarType(..).

Exemple de code Access qui lit des cellules Excel :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Dim xlApp As Excel.Application ' Application Excel
Dim xlWbk As Excel.Workbook    ' Classeur Excel
Dim xlSht As Excel.Worksheet   ' Feuille Excel
Dim blnExcelRunning As Boolean
Dim strClasseur As String
Dim rg As Excel.Range, lgRow As Long
 
' Classeur à ouvrir
strClasseur = "C:\FichierTest.xls"
 
'Ouverture de l'application
On Error Resume Next
Set xlApp = GetObject(, "Excel.Application")
On Error GoTo 0
If xlApp Is Nothing Then
   ' Excel n'est pas ouvert (aucune instance)
   Set xlApp = CreateObject("Excel.Application")
Else
   blnExcelRunning = True
End If
xlApp.Visible = True
 
' Ouverture du fichier Excel
' 2ème argument de la méthode Open :
'      1 pour demander à l'utilisateur s'il faut mettre à jour les liaison
'      2 pour ne pas mettre à jour les liaisons
'      3 pour mettre à jour les liaisons
'      0 (non documenté) ignore les liaisons, y compris les liaisons rompues
Set xlWbk = xlApp.Workbooks.Open(strClasseur, 0)
Set xlSht = xlWbk.ActiveSheet
 
' Lit les cellules C2 à C19 qui contiennent des formules
For lgRow = 2 To 19
    Set rg = xlSht.Range("C" & lgRow)
    If VarType(rg.Value) = vbError Then
       Debug.Print lgRow, "Erreur", VarType(rg.Value), rg.Formula
    Else
       Debug.Print lgRow, rg.Value, VarType(rg.Value), rg.Formula
    End If
Next
 
' Fin :  Libération variables objets et fermeture objets
 
' Libération variable objet Feuille Excel
Set xlSht = Nothing
' Fermeture Classeur
xlWbk.Close False
' Libération variable objet classeur Excel
Set xlWbk = Nothing
' Si c'est ce code qui a ouvert Excel, on le ferme.
If Not blnExcelRunning Then xlApp.Quit
' Libération variable objet application Excel
Set xlApp = Nothing
Remarque:
Dans mon code j'utilise la méthode Range pour faire référence à une cellule.
C'est équivalent à Cells(..,..) dans ton code.
Les deux renvoie un objet de type Excel.Range.


Pour tester les cellules vides, j'utilise la fonction VBA IsEmpty(..).
La notion de Null n'existe pas dans Excel.
C'est Empty.
Par exemple, pour vider une cellule référencée par un objet rg de type Excel.Range :
Code :
       If Not IsEmpty(rg.Value) Then rg = Empty
A+
LedZeppII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/07/2011, 11h13   #6
Membre du Club
 
Inscription : octobre 2005
Messages : 304
Détails du profil
Informations forums :
Inscription : octobre 2005
Messages : 304
Points : 59
Points : 59
Bonjour LedZeppII et merci pour ta réponse, je vais utiliser
Pour tester mes cellules.

Mais comme j'ai une dizaine de cellule a controler j'ai créer une fonction pour le faire qui renvoie vrai si les controles sont ok et faux sinon.

Pour ce faire si je déclare les paremetres de cette fonction en string, quand la cellule est en erreur ça fait un type mismatch.
Par contre, quand je déclare les parametre en type variant, la il n'y a plus de problème. Penses-tu que ce soit une bonne solution ?

Si vraiment tu me dis que ce n'est pas propre ben je mettrais tous mes controles dans la procédure principal sans faire de fonction... Ca alourdira un peu la procédure principal mais tant pis.
Merci beaucoup
_developpeur_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/07/2011, 12h59   #7
Rédacteur
 
Avatar de LedZeppII
 
Homme
Maintenance données produits
Inscription : décembre 2005
Messages : 3 939
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Maintenance données produits
Secteur : Distribution

Informations forums :
Inscription : décembre 2005
Messages : 3 939
Points : 6 278
Points : 6 278
Bonjour,
Citation:
Envoyé par _developpeur_ Voir le message
Par contre, quand je déclare les paramètres en type variant, la il n'y a plus de problème. Penses-tu que ce soit une bonne solution ?
Oui. Dans l'aide d'Excel la définition de la propriété Value d'un objet Excel.Range est
Citation:
Cette propriété renvoie ou définit une valeur de type Variant qui représente la valeur de la plage spécifiée.
J'ai testé avec mon code exemple et ça fonctionne.
J'ai ajouté la déclaration d'une variable de type Variant
Code :
Dim vCellValue As Variant
modifié ma boucle
Code :
1
2
3
4
5
6
' Lit les cellules C2 à C19 qui contiennent des formules
For lgRow = 2 To 19
    Set rg = xlSht.Range("C" & lgRow)
    vCellValue = rg
    OuvrirClasseurAvecErreurDbgCell lgRow, vCellValue
Next
et ajouté une fonction OuvrirClasseurAvecErreurDbgCell
Code :
1
2
3
4
5
6
7
Function OuvrirClasseurAvecErreurDbgCell(lgRow As Long, vCellValue As Variant)
If VarType(vCellValue) = vbError Then
   Debug.Print lgRow, "Erreur", VarType(vCellValue)
Else
   Debug.Print lgRow, vCellValue, VarType(vCellValue)
End If
End Function
A+
LedZeppII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/07/2011, 14h10   #8
Membre du Club
 
Inscription : octobre 2005
Messages : 304
Détails du profil
Informations forums :
Inscription : octobre 2005
Messages : 304
Points : 59
Points : 59
Super j'ai tapé dans le mille avec la variable de type variant. Et j'utilise a présent VarType pour savoir si la cellule est en erreur. C'est propre et c'est exactement ce que je voulais merci beaucoup A bientot.
_developpeur_ est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 06h36.


 
 
 
 
Partenaires

Hébergement Web