IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Access Discussion :

inet_addr me rend une valeur négative


Sujet :

VBA Access

  1. #1
    Membre du Club
    Inscrit en
    Mars 2008
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 169
    Points : 68
    Points
    68
    Par défaut inet_addr me rend une valeur négative
    Bonjour,
    Je convertis une adresse IP en numérique pour la comparer.
    Mon problème est que les valeurs au dessus de a.b.c.128 sortent en négatif.
    Ce qui fait que a.b.c.255 est inférieur à a.b.c.1.
    J'ai mis ce code dans la section d'initialisation, mais qu'est-ce que je pourrais faire faux ?
    Merci d'avance pour l'aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Public Declare Function inet_addr Lib "wsock32.dll" (ByVal addr As String) As Long
    Public Declare Function inet_ntoa Lib "wsock32.dll" (ByVal addr As Long) As Long
    Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
    Public Const INADDR_NONE As Long = &HFFFFFFFF

  2. #2
    Expert éminent
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    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 : 4 485
    Points : 7 759
    Points
    7 759
    Par défaut
    Bonsoir,

    inet_addr retourne un entier long non signé, ce qui n'existe pas dans VB, où les entiers de type Long sont signés.

    Pour contourner le problème tu peux utiliser une variable de type Double.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim dblAddr As Double
    dblAddr = inet_addr(ip_addr)
    ' 2^31 = 2147483648#
    If dblAddr < 0 Then
       dblAddr = (dblAddr And &H7FFFFFFF) + 2147483648#
    End If
    A+

  3. #3
    Membre du Club
    Inscrit en
    Mars 2008
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 169
    Points : 68
    Points
    68
    Par défaut
    Bonjour,
    merci pour la réponse. Je comprends le problème, mais par contre je ne sais pas si j'ai bien compris la solution.
    En fait j'ai 2 utilisations à faire de cette fonction. comparer les adresses saisies par l'utilisateur pour m'assurer que le début de la plage est bien inférieure à la fin et par ailleurs dans une requete SQL comparer à la valeur saisie. Sachant que les adresses peuvent être de classe C B voire des demi classe.
    Pour le premier besoin j'ai testé comme cela, ça va en classe C, mais pas en classe B, je suppose qu'il faudrait adapter la constante en fonction de la classe ? (ce qui m'est impossible)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Private Sub test()
    Dim a, b As Double
    a = inet_addr("192.64.5.200")
    b = inet_addr("192.64.5.150")
    ' 2^31 = 2147483648#
    If a < 0 Then
       a = (a And &H7FFFFFFF) + 2147483648#
    End If
    If b < 0 Then
       b = (b And &H7FFFFFFF) + 2147483648#
    End If
    MsgBox b - a
    End Sub
    pour le deuxième besoin je suppose, que cela veut dire que je dois détourner inet_addr pour le réencapsuler dans une fonction qui contourne en faisait la même chose ?
    Merci de la réponse

  4. #4
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    Bonjour,
    Je viens de regarder sur le Net
    Voici un module qui marche et qui semple plus convivial que ta proposition

    Dans un module tu poses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
     
    Option Compare Database
    Option Explicit
     
    ' VBA MODULE: Get all IP Addresses of your machine
    ' (c) 2005 Wayne Phillips (http://www.everythingaccess.com)
    ' Written 18/05/2005
    '
    ' REQUIREMENTS: Windows 98 or above, Access 97 and above
    '
    ' Please read the full tutorial here:
    ' http://www.everythingaccess.com/tutorials.asp?ID=Get-all-IP-Addresses-of-your-machine
    '
    ' Please leave the copyright notices in place.
    ' Thank you.
     
    ' Note: you may have more than one IP Address assigned to a machine and the
    ' localhost loopback 127.0.0.1 is also returned.  An optional parameter can be given
    ' to the function GetIPAddresses to filter the loopback address.
     
     
     
    'A couple of API functions we need in order to query the IP addresses in this machine
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Private Declare Function GetIpAddrTable Lib "Iphlpapi" (pIPAdrTable As Byte, pdwSize As Long, ByVal Sort As Long) As Long
     
    'The structures returned by the API call GetIpAddrTable...
    Type IPINFO
        dwAddr As Long         ' IP address
        dwIndex As Long         ' interface index
        dwMask As Long         ' subnet mask
        dwBCastAddr As Long     ' broadcast address
        dwReasmSize As Long    ' assembly size
        Reserved1 As Integer
        Reserved2 As Integer
    End Type
     
    Public Function ConvertIPAddressToString(longAddr As Long) As String
     
        Dim IPBytes(3) As Byte
        Dim lngCount As Long
     
        'Converts a long IP Address to a string formatted 255.255.255.255
        'Note: Could use inet_ntoa instead
     
        CopyMemory IPBytes(0), longAddr, 4 ' IP Address is stored in four bytes (255.255.255.255)
     
        'Convert the 4 byte values to a formatted string
        While lngCount < 4
     
            ConvertIPAddressToString = ConvertIPAddressToString + _
                                        CStr(IPBytes(lngCount)) + _
                                        IIf(lngCount < 3, ".", "")
     
            lngCount = lngCount + 1
     
        Wend
     
    End Function
     
    Public Sub GetIPAddresses(Optional blnFilterLocalhost As Boolean = False)
     
        Dim Ret As Long, Tel As Long
        Dim bytBuffer() As Byte
        Dim IPTableRow As IPINFO
        Dim lngCount As Long
        Dim lngBufferRequired As Long
        Dim lngStructSize As Long
        Dim lngNumIPAddresses As Long
        Dim strIPAddress As String
     
    On Error GoTo ErrorHandler:
     
        Call GetIpAddrTable(ByVal 0&, lngBufferRequired, 1)
     
        If lngBufferRequired > 0 Then
     
            ReDim bytBuffer(0 To lngBufferRequired - 1) As Byte
     
            If GetIpAddrTable(bytBuffer(0), lngBufferRequired, 1) = 0 Then
     
                'We've successfully obtained the IP Address details...
     
                'How big is each structure row?...
                lngStructSize = LenB(IPTableRow)
     
                'First 4 bytes is a long indicating the number of entries in the table
                CopyMemory lngNumIPAddresses, bytBuffer(0), 4
     
                While lngCount < lngNumIPAddresses
     
                    'bytBuffer contains the IPINFO structures (after initial 4 byte long)
                    CopyMemory IPTableRow, _
                                bytBuffer(4 + (lngCount * lngStructSize)), _
                                lngStructSize
     
                    strIPAddress = ConvertIPAddressToString(IPTableRow.dwAddr)
     
                    If Not ((strIPAddress = "127.0.0.1") _
                            And blnFilterLocalhost) Then
     
                        'Replace this with whatever you want to do with the IP Address...
                        Debug.Print strIPAddress
     
                    End If
     
                    lngCount = lngCount + 1
     
                Wend
     
            End If
     
        End If
     
    Exit Sub
     
    ErrorHandler:
        MsgBox "An error has occured in GetIPAddresses():" & vbCrLf & vbCrLf & _
                Err.Description & " (" & CStr(Err.Number) & ")"
     
    End Sub
    et tu le lances par bonne continuation
    "Always look at the bright side of life." Monty Python.

  5. #5
    Expert éminent
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    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 : 4 485
    Points : 7 759
    Points
    7 759
    Par défaut
    Bonjour,

    Je me demande si ton problème ne vient de ça (trouvé ici)
    When an Internet address is viewed as a 32-bit integer quantity on the Intel architecture, the bytes referred to above appear as "d.c.b.a''. That is, the bytes on an Intel processor are ordered from right to left.
    Voici une proposition de fonction où a est l'octet de poids le plus fort et d l'octet de poids le plus faible, dans une adresse a.b.c.d
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Function ipadrToDbl(ipadr As Variant) As Double
    Dim strAdr As String, strBytes() As String, i As Integer
    Dim dblAdr As Double, poids As Double
     
    strAdr = Nz(ipadr, "")
    strBytes = Split(strAdr, ".")
    poids = 16777216#
    For i = LBound(strBytes) To UBound(strBytes)
        dblAdr = dblAdr + CDbl(strBytes(i)) * poids
        poids = poids / 256
    Next
    ipadrToDbl = dblAdr
    End Function
    Exemples
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    adr            ipadrToDbl
    -----------    -----------
    192.0.0.1      3221225473
    192.0.0.50     3221225522
    121.0.0.100    2030043236
    121.0.0.150    2030043286
    A+

  6. #6
    Membre du Club
    Inscrit en
    Mars 2008
    Messages
    169
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 169
    Points : 68
    Points
    68
    Par défaut
    Bonjour,
    merci pour ce tuyau. Effectivement j'avais vu cela dans un forum, mais n'avais pas fait le rapprochement.
    En attendant j'avais fait cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Public Function IpToNb(ByRef IP As Variant) As Variant
    Dim ipDecompose As Variant
        If IP = "" Or IsNull(IP) Then
            IpToNb = INADDR_NONE
            Exit Function
        End If
        If inet_addr(IP) = INADDR_NONE Then
            IpToNb = INADDR_NONE
            Exit Function
        Else
            ipDecompose = Split(IP, ".")
            IpToNb = (ipDecompose(0) * 256 ^ 3) + (ipDecompose(1) * 256 ^ 2) + (ipDecompose(2) * 256) + ipDecompose(3)
        End If
    End Function
    Ca se resssemble, mais c'est peut être mieux comme tu proposes, je vais faire un mixte des 2 codes.

    Merci beaucoup

Discussions similaires

  1. Réponses: 4
    Dernier message: 11/07/2008, 11h42
  2. FormatFloat affiche une valeur négative
    Par defluc dans le forum Langage
    Réponses: 6
    Dernier message: 05/03/2008, 13h44
  3. SQL*LOADER : Charger une valeur négative
    Par coraziari_l dans le forum SQL
    Réponses: 1
    Dernier message: 24/01/2008, 11h22
  4. Réponses: 3
    Dernier message: 16/01/2008, 07h12
  5. Pixel avec une valeur négative
    Par Minouchka dans le forum Traitement d'images
    Réponses: 8
    Dernier message: 24/10/2007, 10h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo