2011-02-11 3 views
4

VBA 매크로로 IP 주소를 추출해야합니다. 이 코드는 작동하지만 명령 대화 상자가 간략하게 표시되어 잘 보이지 않습니다. 수정을 사용하여 "자동으로"할 수 있습니까?"조용히"IP 주소를 검색하는 Word VBA

Sub getIP() 

Set objShell = CreateObject("WScript.Shell") 
Set objExecObject = objShell.Exec("%comspec% /c ipconfig.exe") 
Do Until objExecObject.StdOut.AtEndOfStream 
    strLine = objExecObject.StdOut.ReadLine() 
    strIP = InStr(strLine, "Address") 
    If strIP <> 0 Then 
     IPArray = Split(strLine, ":") 
     strIPAddress = IPArray(1) 
    End If 
Loop 
SynapseForm.LabelIP.Caption = strIPAddress 

End Sub 

업데이트는,이 작품, 임시 파일에 쓸 Wscript.Shell을 사용하여 변형을 발견 "자동으로"

Sub getIPAddress() 

Dim IP_Address: IP_Address = GetIP() 

If IP_Address = "0.0.0.0" Or IP_Address = "" Then 
MsgBox "No IP Address found.", , "" 
Else 
MsgBox IP_Address 
'MsgBox IP_Address, , "IP address" 
End If 

End Sub 

Function GetIP() 

Dim ws: Set ws = CreateObject("WScript.Shell") 
Dim fso: Set fso = CreateObject("Scripting.FileSystemObject") 

Dim TmpFile: TmpFile = fso.GetSpecialFolder(2) & "/ip.txt" 
Dim ThisLine, IP 

If ws.Environment("SYSTEM")("OS") = "" Then 
ws.Run "winipcfg /batch " & TmpFile, 0, True 
Else 
ws.Run "%comspec% /c ipconfig > " & TmpFile, 0, True 
End If 

With fso.GetFile(TmpFile).OpenAsTextStream 
Do While Not .AtEndOfStream 
ThisLine = .ReadLine 
If InStr(ThisLine, "Address") <> 0 Then 
IP = Mid(ThisLine, InStr(ThisLine, ":") + 2) 
End If 
Loop 
.Close 
End With 

'WinXP (NT? 2K?) leaves a carriage return at the end of line 
If IP <> "" Then 
If Asc(Right(IP, 1)) = 13 Then IP = Left(IP, Len(IP) - 1) 
End If 

GetIP = IP 

fso.GetFile(TmpFile).Delete 

Set fso = Nothing 
Set ws = Nothing 

End Function 

답변

5

이 방법이 더 쉽습니다. WMI를 사용합니다.

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
Set colItems = objWMIService.ExecQuery(_ 
    "SELECT * FROM Win32_NetworkAdapterConfiguration", , 48) 
For Each objItem In colItems 
    If Not IsNull(objItem.IPAddress) Then 
     ''Commented line 
     ''Debug.Print "IPAddress: " & Join(objItem.IPAddress, ",") 
     ''Message box 
     MsgBox "IPAddress: " & Join(objItem.IPAddress, ",") 
     ''String for later use 
     strIPAddress = strIPAddress & Join(objItem.IPAddress, ",") 
    End If 
Next 
''Later 
SynapseForm.LabelIP.Caption = strIPAddress 
+0

확실히 간결하게 보입니다 :-) msgbox가 IP pls (미안 매우 VBA 무지한)라고 표시하는 것을 서브에서 어떻게 사용하는지 말해 주시겠습니까 – Saul

+0

@Saul 나는 다양한 옵션을 추가했습니다. – Fionnuala

+0

환상적인 Remou입니다, 많은 감사합니다. 그것은 Word 2003과 함께 아름답게 작동합니다. 모든 최신 버전에서 사용할 수 있습니까? 내가 묻는 것은 WMI (모든 것이 무엇이든)가 모든 Windows 및 Word 설치에 있다는 것입니다. – Saul

1

아래 Remou의 방법은이 코드를 시도만큼 좋은하지?

편집 : 감사 Belizarius.

다음 코드는 다음과 같습니다 (테스트를 거쳐 저에게 도움이 됨, 상기 출처에서 가져온 것입니다).

코드 끝에있는 샘플 (MyIP 기능).

희망이 있습니다.

Private Declare Function GetComputerName Lib "kernel32" _ 
    Alias "GetComputerNameA" _ 
    (ByVal lpBuffer As String, nSize As Long) As Long 

' ******** Code Start ******** 
'This code was originally written by Dev Ashish. 
'It is not to be altered or distributed, 
'except as part of an application. 
'You are free to use it in any application, 
'provided the copyright notice is left unchanged. 
' 
'Code Courtesy of 
'Dev Ashish 
' 
Private Const MAX_WSADescription = 256 
Private Const MAX_WSASYSStatus = 128 
Private Const AF_INET = 2 

Private Type WSADATA 
    wversion As Integer 
    wHighVersion As Integer 
    szDescription(MAX_WSADescription) As Byte 
    szSystemStatus(MAX_WSASYSStatus) As Byte 
    wMaxSockets As Long 
    wMaxUDPDG As Long 
    dwVendorInfo As Long 
End Type 

Private Type HOSTENT 
    hName As Long 
    hAliases As Long 
    hAddrType As Integer 
    hLength As Integer 
    hAddrList As Long 
End Type 

' returns the standard host name for the local machine 
Private Declare Function apiGetHostName _ 
    Lib "wsock32" Alias "gethostname" _ 
    (ByVal name As String, _ 
    ByVal nameLen As Long) _ 
    As Long 

' retrieves host information corresponding to a host name 
' from a host database 
Private Declare Function apiGetHostByName _ 
    Lib "wsock32" Alias "gethostbyname" _ 
    (ByVal hostname As String) _ 
    As Long 

' retrieves the host information corresponding to a network address 
Private Declare Function apiGetHostByAddress _ 
    Lib "wsock32" Alias "gethostbyaddr" _ 
    (addr As Long, _ 
    ByVal dwLen As Long, _ 
    ByVal dwType As Long) _ 
    As Long 

' moves memory either forward or backward, aligned or unaligned, 
' in 4-byte blocks, followed by any remaining bytes 
Private Declare Sub sapiCopyMem _ 
    Lib "kernel32" Alias "RtlMoveMemory" _ 
    (Destination As Any, _ 
    Source As Any, _ 
    ByVal Length As Long) 

' converts a string containing an (Ipv4) Internet Protocol 
' dotted address into a proper address for the IN_ADDR structure 
Private Declare Function apiInetAddress _ 
    Lib "wsock32" Alias "inet_addr" _ 
    (ByVal cp As String) _ 
    As Long 

' function initiates use of Ws2_32.dll by a process 
Private Declare Function apiWSAStartup _ 
    Lib "wsock32" Alias "WSAStartup" _ 
    (ByVal wVersionRequired As Integer, _ 
    lpWsaData As WSADATA) _ 
    As Long 

Private Declare Function apilstrlen _ 
    Lib "kernel32" Alias "lstrlen" _ 
    (ByVal lpString As Long) _ 
    As Long 

Private Declare Function apilstrlenW _ 
    Lib "kernel32" Alias "lstrlenW" _ 
    (ByVal lpString As Long) _ 
    As Long 

' function terminates use of the Ws2_32.dll 
Private Declare Function apiWSACleanup _ 
    Lib "wsock32" Alias "WSACleanup" _ 
    () As Long 

Function fGetHostIPAddresses(strHostName As String) As Collection 
' 
' Resolves the English HostName and returns 
' a collection with all the IPs bound to the card 
' 
On Error GoTo ErrHandler 
Dim lngRet As Long 
Dim lpHostEnt As HOSTENT 
Dim strOut As String 
Dim colOut As Collection 
Dim lngIPAddr As Long 
Dim abytIPs() As Byte 
Dim i As Integer 

    Set colOut = New Collection 

    If fInitializeSockets() Then 
     strOut = String$(255, vbNullChar) 
     lngRet = apiGetHostByName(strHostName) 
     If lngRet Then 

      Call sapiCopyMem(_ 
        lpHostEnt, _ 
        ByVal lngRet, _ 
        Len(lpHostEnt)) 

      Call sapiCopyMem(_ 
        lngIPAddr, _ 
        ByVal lpHostEnt.hAddrList, _ 
        Len(lngIPAddr)) 

      Do While (lngIPAddr) 
       With lpHostEnt 
        ReDim abytIPs(0 To .hLength - 1) 
        strOut = vbNullString 
        Call sapiCopyMem(_ 
         abytIPs(0), _ 
         ByVal lngIPAddr, _ 
         .hLength) 
        For i = 0 To .hLength - 1 
         strOut = strOut & abytIPs(i) & "." 
        Next 
        strOut = Left$(strOut, Len(strOut) - 1) 
        .hAddrList = .hAddrList + Len(.hAddrList) 
        Call sapiCopyMem(_ 
          lngIPAddr, _ 
          ByVal lpHostEnt.hAddrList, _ 
          Len(lngIPAddr)) 
        If Len(Trim$(strOut)) Then colOut.Add strOut 
       End With 
      Loop 
     End If 
    End If 
    Set fGetHostIPAddresses = colOut 
ExitHere: 
    Call apiWSACleanup 
    Set colOut = Nothing 
    Exit Function 
ErrHandler: 
    With Err 
     MsgBox "Error: " & .Number & vbCrLf & .Description, _ 
      vbOKOnly Or vbCritical, _ 
      .Source 
    End With 
    Resume ExitHere 
End Function 

Function fGetHostName(strIPAddress As String) As String 
' 
' Looks up a given IP address and returns the 
' machine name it's bound to 
' 
On Error GoTo ErrHandler 
Dim lngRet As Long 
Dim lpAddress As Long 
Dim strOut As String 
Dim lpHostEnt As HOSTENT 

    If fInitializeSockets() Then 
     lpAddress = apiInetAddress(strIPAddress) 
     lngRet = apiGetHostByAddress(lpAddress, 4, AF_INET) 
     If lngRet Then 
      Call sapiCopyMem(_ 
       lpHostEnt, _ 
       ByVal lngRet, _ 
       Len(lpHostEnt)) 
      fGetHostName = fStrFromPtr(lpHostEnt.hName, False) 
     End If 
    End If 
ExitHere: 
    Call apiWSACleanup 
    Exit Function 
ErrHandler: 
    With Err 
     MsgBox "Error: " & .Number & vbCrLf & .Description, _ 
      vbOKOnly Or vbCritical, _ 
      .Source 
    End With 
    Resume ExitHere 
End Function 

Private Function fInitializeSockets() As Boolean 
Dim lpWsaData As WSADATA 
Dim wVersionRequired As Integer 

    wVersionRequired = fMakeWord(2, 2) 
    fInitializeSockets = (_ 
     apiWSAStartup(wVersionRequired, lpWsaData) = 0) 

End Function 

Private Function fMakeWord(_ 
          ByVal low As Integer, _ 
          ByVal hi As Integer) _ 
          As Integer 
Dim intOut As Integer 
    Call sapiCopyMem(_ 
     ByVal VarPtr(intOut) + 1, _ 
     ByVal VarPtr(hi), _ 
     1) 
    Call sapiCopyMem(_ 
     ByVal VarPtr(intOut), _ 
     ByVal VarPtr(low), _ 
     1) 
    fMakeWord = intOut 
End Function 

Private Function fStrFromPtr(_ 
            pBuf As Long, _ 
            Optional blnIsUnicode As Boolean) _ 
            As String 
Dim lngLen As Long 
Dim abytBuf() As Byte 

    If blnIsUnicode Then 
     lngLen = apilstrlenW(pBuf) * 2 
    Else 
     lngLen = apilstrlen(pBuf) 
    End If 
    ' if it's not a ZLS 
    If lngLen Then 
     ReDim abytBuf(lngLen) 
     ' return the buffer 
     If blnIsUnicode Then 
      'blnIsUnicode is True not tested 
      Call sapiCopyMem(abytBuf(0), ByVal pBuf, lngLen) 
      fStrFromPtr = abytBuf 
     Else 
      ReDim Preserve abytBuf(UBound(abytBuf) - 1) 
      Call sapiCopyMem(abytBuf(0), ByVal pBuf, lngLen) 
      fStrFromPtr = StrConv(abytBuf, vbUnicode) 
     End If 
    End If 
End Function 
' ******** Code End ******** 

Function ReturnComputerName() As String 

    Dim rString As String * 255 
    Dim sLen As Long 
    Dim tString As String 

    tString = "" 

    On Error Resume Next 

    sLen = GetComputerName(rString, 255) 
    sLen = InStr(1, rString, Chr(0)) 

    If sLen > 0 Then 
     tString = Left(rString, sLen - 1) 
    Else 
     tString = rString 
    End If 

    On Error GoTo 0 
    ReturnComputerName = UCase(Trim(tString)) 

End Function 

Public Function MyIP() As String 
    Debug.Print fGetHostIPAddresses(ReturnComputerName).item(1) 
End Function 
+0

여기에 코드의 중요한 부분을 적절한 속성으로 게시해야합니다. –

+0

ARG는 엄청나게 큰 비교입니다. 그걸 매크로라고 어떻게 부를까요? 나는 기계 이름이 필요 없으며, 각 기계는 단지 하나의 네트워크 주소를 가질 것이고, 필자는 문자열을 IP로 가져와야 할 필요가있다. – Saul

관련 문제